Salta ai contenuti

Strumenti personalizzati

Gli strumenti personalizzati permettono di estendere il server MCP di Guida con funzionalità specifiche dello spazio di lavoro. Definisci gli strumenti in tools.json e qualsiasi agente IA connesso potrà invocarli.

Crea un file tools.json nel percorso principale (root) dello spazio di lavoro:

{
"tools": [
{
"name": "search-products",
"description": "Cerca nel catalogo prodotti per parola chiave",
"script": "scripts/search-products.js",
"timeout": 30,
"parameters": {
"type": "object",
"properties": {
"keyword": {
"type": "string",
"description": "Parola chiave di ricerca"
},
"maxResults": {
"type": "number",
"description": "Numero massimo di risultati da restituire (predefinito: 10)"
}
},
"required": ["keyword"]
}
}
]
}
CampoObbligatorioDescrizione
nameNome dello strumento esposto tramite MCP (deve essere univoco)
descriptionDescrizione leggibile mostrata negli elenchi degli strumenti
scriptPercorso dello script relativo al percorso principale (root) dello spazio di lavoro
timeoutNoTimeout di esecuzione in secondi
parametersNoJSON Schema che descrive i parametri di input
headersNoIntestazioni HTTP iniettate nelle chiamate g.http.makeHttpRequest()

Il campo parameters usa JSON Schema per descrivere gli input dello strumento. L’agente IA vede lo schema e fornisce argomenti corrispondenti.

Dentro lo script, i parametri sono disponibili come g.tool.args:

async function main() {
const keyword = g.tool.args.keyword;
const maxResults = g.tool.args.maxResults || 10;
await g.nav.navigateToUrl("https://store.example.com/search?q=" + keyword);
// ... estrai i risultati ...
return results.slice(0, maxResults);
}

Il valore restituito dalla funzione main() diventa il risultato dello strumento, inviato all’agente IA.

Usa segnaposto {{SECRET_NAME}} nelle intestazioni per iniettare credenziali di accesso senza esporli all’IA:

{
"tools": [
{
"name": "fetch-api-data",
"description": "Scarica dati dall'API interna",
"script": "scripts/api-fetch.js",
"headers": {
"Authorization": "Bearer {{API_TOKEN}}",
"X-Api-Key": "{{API_KEY}}"
}
}
]
}

Le intestazioni vengono risolte al momento dell’esecuzione usando le credenziali di accesso salvati nel pannello Credenziali di accesso (Secrets) di Guida. L’agente IA non vede mai i valori delle intestazioni: vede solo il nome dello strumento e lo schema dei parametri.

Le intestazioni risolte vengono iniettate automaticamente in qualsiasi chiamata g.http.makeHttpRequest() eseguita dallo script.

Quando un agente IA invoca uno strumento personalizzato:

  1. Guida carica lo script dallo spazio di lavoro
  2. Il pragma @timeout viene elaborato
  3. I parametri sono disponibili come g.tool.args
  4. Le intestazioni vengono risolte (i segnaposto delle credenziali di accesso vengono sostituiti con i valori decrittati)
  5. Lo script viene eseguito con ScriptTaskOrigin.Mcp: significa che g.secrets.getSecret() è bloccato
  6. Il valore restituito da main() viene serializzato e inviato all’agente

Tre strumenti MCP integrati gestiscono gli strumenti personalizzati:

StrumentoDescrizione
GetWorkspaceToolsElenca tutti gli strumenti personalizzati con i relativi schemi dei parametri
ExecuteWorkspaceToolEsegue uno strumento personalizzato con parametri
ReloadWorkspaceToolsRicarica tools.json dopo le modifiche
{
"tools": [
{
"name": "create-ticket",
"description": "Crea un ticket di supporto nel sistema di ticketing",
"script": "scripts/create-ticket.js",
"timeout": 15,
"headers": {
"Authorization": "Bearer {{TICKETING_API_KEY}}"
},
"parameters": {
"type": "object",
"properties": {
"title": { "type": "string", "description": "Titolo del ticket" },
"body": { "type": "string", "description": "Descrizione del ticket" },
"priority": { "type": "string", "enum": ["low", "medium", "high"] }
},
"required": ["title", "body"]
}
}
]
}
scripts/create-ticket.js
async function main() {
try {
const response = await g.http.makeHttpRequest({
url: "https://api.ticketing.example.com/tickets",
method: "POST",
body: JSON.stringify({
title: g.tool.args.title,
body: g.tool.args.body,
priority: g.tool.args.priority || "medium"
}),
headers: { "Content-Type": "application/json" }
});
const ticket = JSON.parse(response.body);
return { ticketId: ticket.id, url: ticket.url };
} catch (e) {
return { error: e.message };
}
}