In breve
Un tutorial passo passo per la code mode di AnythingMCP: avvia il code runner, attiva la code mode e salva un code tool che legge gli ultimi ordini dall'ERP (weclapp) e l'account con le trattative aperte dal CRM (HubSpot) in una sola chiamata. Sola lettura, con i permessi di chi chiama, tracciato nell'audit.
TL;DR: Prima di una chiamata con un cliente, un commerciale chiede all'assistente una panoramica: gli ultimi ordini dall'ERP e il responsabile dell'account e le trattative aperte dal CRM. Senza code mode servono quattro o cinque chiamate a strumenti, ciascuna letta per intero dal modello. Con un code tool salvato ne basta una: customer_overview(customer) esegue un breve programma JavaScript che effettua le chiamate, tiene ciò che conta e restituisce un unico riepilogo compatto. Questo tutorial costruisce quel tool su un AnythingMCP self-hosted (v0.52.1 o successiva) con weclapp come ERP e HubSpot come CRM; lo stesso schema funziona con qualsiasi coppia di connettori.
Cosa ti serve
- AnythingMCP self-hosted v0.52.1 o successiva. La code mode arriverà presto su AnythingMCP Cloud.
- Due connettori con strumenti di lettura, qui weclapp e HubSpot, installati e funzionanti.
- Diritti di amministratore nel workspace.
Sei nuovo all'idea? Cos'è la code mode MCP? spiega perché un solo programma è meglio di tante chiamate a strumenti.
Passo 1 — Avvia il code runner
Il codice non viene mai eseguito dentro AnythingMCP stesso. Gira in un container code-runner separato e, senza di esso, ogni esecuzione di codice viene rifiutata. Aggiungi al tuo .env:
COMPOSE_PROFILES=code-runner
CODE_RUNNER_URL=ws://code-runner:8777
Se usi già dei profili, elencali insieme, ad esempio COMPOSE_PROFILES=files,code-runner. Poi:
docker compose up -d
Il runner non contiene segreti, non pubblica porte e non ha alcuna rotta verso internet; solo il backend comunica con lui, sulla rete Docker interna. Come isola ogni esecuzione: Esecuzione sicura del codice per gli agenti AI.
Passo 2 — Attiva la code mode per il server MCP
La code mode è disattivata di default per ogni server MCP, e i code tool salvati vengono rifiutati su un server con code mode off. Imposta la code mode del server usato dal tuo team commerciale su tools (solo code tool salvati). inline offre inoltre all'agente code_execute e code_propose_tool; per questo tutorial non ti serve.
Nella dashboard apri Server MCP e poi il server. Nella scheda Impostazioni del server in alto imposta Modalità codice su Solo code tool salvati e clicca Salva. Poi riconnetti il client AI.
Preferisci l'API? PUT /api/mcp-servers/<id> con {"codeMode": "tools"} fa lo stesso. L'impostazione c'è dalla v0.52.1; sulla v0.52.0 aggiorna prima.
Passo 3 — Annota gli id dei due connettori
Un code tool dichiara quali connettori il suo programma può chiamare. Apri ciascun connettore nella dashboard: il suo id è l'ultima parte dell'indirizzo, /connectors/<id>. Copia gli id del connettore weclapp e di quello HubSpot.
Passo 4 — Crea il code tool
Apri il connettore weclapp, vai su MCP Tools e clicca Add Tool. Imposta Tool Type su Code Tool, poi compila:
- Tool Name:
customer_overview - Description: "Overview of one customer before a call: the last 10 orders from the ERP, the CRM account and its open deals. Pass the company name or part of it." La descrizione è ciò che l'AI legge per decidere quando chiamare il tool, quindi indica cosa restituisce.
- Input Parameters: un solo parametro,
customer, di tipo string, obbligatorio.

Passo 5 — Scrivi il programma
Il Program è il corpo di una funzione JavaScript asincrona. Gli input del tool sono in args; amcp.run(name, args) chiama un altro tool e restituisce il suo risultato come JSON già analizzato (e genera un errore se il tool fallisce). Ciò che fai return è ciò che riceve l'AI.
// Input: args.customer, a company name or part of it.
const name = String(args.customer ?? '').trim();
if (!name) return { error: 'Pass a customer name.' };
// ERP (weclapp): the customer, then its latest sales orders.
const parties = await amcp.run('weclapp_list_customers', {
filter: `company-ilike=%${name}%`,
pageSize: 5,
});
const customer = (parties.result ?? [])[0];
if (!customer) return { error: `No customer matching "${name}" in the ERP.` };
const orders = await amcp.run('weclapp_list_sales_orders', {
filter: `customerId-eq=${customer.id}`,
sort: '-orderDate',
pageSize: 10,
});
// CRM (HubSpot): the company record and its open deals.
const companies = await amcp.run('hubspot_search_objects', {
object_type: 'companies',
query: customer.company,
properties: ['name', 'domain', 'hubspot_owner_id', 'lifecyclestage'],
limit: 1,
});
const company = companies.results?.[0];
let deals = [];
if (company) {
const found = await amcp.run('hubspot_search_objects', {
object_type: 'deals',
filter_groups: [{ filters: [
{ propertyName: 'associations.company', operator: 'EQ', value: company.id },
{ propertyName: 'hs_is_closed', operator: 'EQ', value: 'false' },
] }],
properties: ['dealname', 'amount', 'dealstage', 'closedate'],
limit: 20,
});
deals = found.results ?? [];
}
// Only this goes back to the model.
return {
customer: { number: customer.customerNumber, name: customer.company },
lastOrders: (orders.result ?? []).map((o) => ({
number: o.orderNumber, date: o.orderDate, status: o.status, net: o.netAmount,
})),
crm: company
? { owner: company.properties.hubspot_owner_id, stage: company.properties.lifecyclestage }
: null,
openDeals: deals.map((d) => ({
name: d.properties.dealname, amount: d.properties.amount,
stage: d.properties.dealstage, close: d.properties.closedate,
})),
};
I nomi dei campi sono quelli restituiti dalle API di weclapp e HubSpot. Prima di fare affidamento su un campo, esegui una volta lo strumento sottostante nel suo pannello Test e guarda il risultato; all'interno del programma, await amcp.describe('weclapp_list_sales_orders') restituisce lo schema di input di un tool.
Una nota sul collegamento. Questo programma abbina l'azienda del CRM per nome, il che è sufficiente per un briefing. Se salvi il numero cliente dell'ERP in una proprietà di HubSpot, filtra invece su quella e la corrispondenza sarà esatta.
Passo 6 — Dichiara cosa può usare il programma
Uses (connectors) elenca i connettori, e facoltativamente i tool esatti, che il programma può chiamare. Incolla i due id del passo 3:
[
{ "connectorId": "<weclapp connector id>", "tools": ["weclapp_list_customers", "weclapp_list_sales_orders"] },
{ "connectorId": "<hubspot connector id>", "tools": ["hubspot_search_objects"] }
]
Indicare i tool è facoltativo (senza "tools" l'intero connettore è consentito), ma un elenco breve rende il tool facile da revisionare. Sono accettati solo connettori dello stesso workspace. Un tool fuori da questo elenco genera un errore, anche se l'utente potrebbe chiamarlo direttamente.
Passo 7 — Esegui come invoker, in sola lettura
- Run as: Invoker (the caller's own permissions). Ogni chiamata interna viene verificata rispetto al ruolo della persona che usa il tool. Un commerciale senza accesso a HubSpot riceve un errore sulla parte HubSpot, esattamente come se avesse chiamato HubSpot direttamente. (Definer esegue invece con la curatela dell'autore, come una stored procedure; è pensato per gli amministratori ed Enterprise.)
- Allow write tools: off. Il programma può così chiamare solo strumenti di sola lettura;
weclapp_list_*ehubspot_search_objectssono letture. I code tool con scrittura abilitata richiedono Enterprise.
Clicca Create Tool.
Passo 8 — Provalo da Claude o ChatGPT
Verifica prima il programma con il pulsante Test del tool nella dashboard: esegue il codice nel code runner, con le stesse regole di una chiamata reale. Poi provalo da un client AI connesso al server MCP. Il tool è disponibile su ogni server che ha il connettore weclapp e la code mode attivata. Riconnetti o aggiorna gli strumenti nel tuo client AI e chiedi:
"I'm calling Lindenhof Bau in ten minutes. What did they order recently, who owns the account, and are there open deals?"
L'assistente chiama customer_overview una sola volta e scrive il briefing dal risultato compatto, invece di leggere elenchi completi di ordini e record del CRM. Se qualcosa non va, il risultato del tool ti dice cosa: una chiamata fuori da Uses ('hubspot_search_objects' is not a tool this code tool can use), un errore restituito dall'API o un timeout. Correggi il programma, salva e chiedi di nuovo.
Cosa succede a ogni chiamata
- Un'esecuzione, un record. Ogni chiamata del tool viene registrata come esecuzione di codice, e ogni chiamata a un tool effettuata dal programma compare nell'audit log come qualsiasi altra chiamata, con l'utente.
- Limiti. Un'esecuzione può durare fino a 10 secondi, effettuare fino a 500 chiamate a tool (16 alla volta) e restituire fino a 1 MB. Un programma che supera un limite si interrompe con un errore chiaro e non influisce su nient'altro.
- Nessuna nidificazione. Un code tool non può chiamare un altro code tool.
- Solo sui tuoi server. I code tool sono serviti sui server MCP del workspace, mai sull'endpoint condiviso
/mcp.
Piani
Code tool salvati per edizione, come annunciato con la v0.52: Community 3, Starter 5, Team 20, Enterprise illimitati. I code tool con scrittura abilitata e "run as definer" sono Enterprise. Confronta i piani.
FAQ
Devo conoscere JavaScript?
Basta un po' di JavaScript: await, oggetti, map e filter. Puoi anche lasciare che sia l'agente a scrivere una bozza del programma e a proporlo come tool per la tua revisione.
Il programma può chiamare direttamente un'API esterna? No. Non ha accesso alla rete. Può chiamare solo i tool MCP elencati in Uses; per raggiungere un'altra API, aggiungila prima come connettore.
Su quale connettore deve risiedere il code tool? Su uno qualsiasi di quelli che usa; il tool compare ovunque quel connettore sia assegnato. Scegli quello il cui pubblico deve ricevere il tool.
Correlati
- Cos'è la code mode MCP?
- Esecuzione sicura del codice per gli agenti AI: come funziona il runner isolato
- Ricette per la code mode: fatturato mensile, riconciliazione fatture, 100 consultazioni di prezzi
- L'agente propone un code tool, l'amministratore lo approva
- Gestisci il tuo ERP con l'AI: weclapp
- Distribuisci AnythingMCP con Docker Compose
- Collega weclapp e HubSpot a Claude
Questa guida ti è stata utile?