Condividi tramite


Trigger dello strumento MCP per Funzioni di Azure

Usare il trigger dello strumento MCP per definire gli endpoint degli strumenti in un server MCP (Model Content Protocol). I modelli e gli agenti del linguaggio client possono usare strumenti per eseguire attività specifiche, ad esempio l'archiviazione o l'accesso ai frammenti di codice.

Per informazioni sui dettagli di impostazione e configurazione, vedere la panoramica.

Esempio

Annotazioni

Per C#, l'estensione MCP di Funzioni di Azure supporta solo il modello di lavoro isolato.

Questo codice crea un endpoint per esporre uno strumento denominato SaveSnippet che tenta di rendere persistente un frammento di codice denominato nell'archivio BLOB.

private const string BlobPath = "snippets/{mcptoolargs.snippetname}.json";

[Function(nameof(SaveSnippet))]
[BlobOutput(BlobPath)]
public string SaveSnippet(
    [McpToolTrigger("save_snippet", "Saves a code snippet into your snippet collection.")]
        ToolInvocationContext context,
    [McpToolProperty("snippetname", "The name of the snippet.", isRequired: true)]
        string name,
    [McpToolProperty("snippet", "The code snippet.", isRequired: true)]
        string snippet
)
{
    return snippet;
}

Questo codice crea un endpoint per esporre uno strumento denominato GetSnippet che tenta di recuperare un frammento di codice in base al nome dall'archivio BLOB.

private const string BlobPath = "snippets/{mcptoolargs.snippetname}.json";

[Function(nameof(GetSnippet))]
public object GetSnippet(
    [McpToolTrigger("get_snippets", "Gets code snippets from your snippet collection.")]
        ToolInvocationContext context,
    [BlobInput(BlobPath)] string snippetContent
)
{
    return snippetContent;
}

Le proprietà dello strumento per la GetSnippet funzione sono configurate in Program.cs:

var builder = FunctionsApplication.CreateBuilder(args);

builder.ConfigureFunctionsWebApplication();

builder.Services
    .AddApplicationInsightsTelemetryWorkerService()
    .ConfigureFunctionsApplicationInsights();

builder
    .ConfigureMcpTool("get_snippets")
    .WithProperty("snippetname", "string", "The name of the snippet.", required: true);

builder.Build().Run();

Suggerimento

L'esempio precedente usava stringhe letterali per elementi come il nome dello strumento "get_snippets" sia nella Program.cs funzione. Prendere invece in considerazione l'uso di stringhe costanti condivise per mantenere sincronizzate le cose nel progetto.

Per l'esempio di codice completo, vedere SnippetTool.cs.

Questo codice crea un endpoint per esporre uno strumento denominato SaveSnippets che tenta di rendere persistente un frammento di codice denominato nell'archivio BLOB.

@FunctionName("SaveSnippets")
@StorageAccount("AzureWebJobsStorage")
public String saveSnippet(
        @McpToolTrigger(
                name = "saveSnippets",
                description = "Saves a text snippet to your snippets collection."
        )
        String mcpToolInvocationContext,
        @McpToolProperty(
                name = "snippetName",
                propertyType = "string",
                description = "The name of the snippet.",
                required = true
        )
        String snippetName,
        @McpToolProperty(
                name = "snippet",
                propertyType = "string",
                description = "The content of the snippet.",
                required = true
        )
        String snippet,
        @BlobOutput(name = "outputBlob", path = "snippets/{mcptoolargs.snippetName}.json")
        OutputBinding<String> outputBlob,
        final ExecutionContext context
) {
    // Log the entire incoming JSON for debugging
    context.getLogger().info(mcpToolInvocationContext);

    // Log the snippet name and content
    context.getLogger().info("Saving snippet with name: " + snippetName);
    context.getLogger().info("Snippet content:\n" + snippet);

    // Write the snippet content to the output blob
    outputBlob.setValue(snippet);

    return "Successfully saved snippet '" + snippetName + "' with " + snippet.length() + " characters.";
}

Questo codice crea un endpoint per esporre uno strumento denominato GetSnippets che tenta di recuperare un frammento di codice in base al nome dall'archivio BLOB.

@FunctionName("GetSnippets")
@StorageAccount("AzureWebJobsStorage")
public String getSnippet(
        @McpToolTrigger(
                name = "getSnippets",
                description = "Gets a text snippet from your snippets collection."
        )
        String mcpToolInvocationContext,
        @McpToolProperty(
                name = "snippetName",
                propertyType = "string",
                description = "The name of the snippet.",
                required = true
        )
        String snippetName,
        @BlobInput(name = "inputBlob", path = "snippets/{mcptoolargs.snippetName}.json")
        String inputBlob,
        final ExecutionContext context
) {
    // Log the entire incoming JSON for debugging
    context.getLogger().info(mcpToolInvocationContext);

    // Log the snippet name and the fetched snippet content from the blob
    context.getLogger().info("Retrieving snippet with name: " + snippetName);
    context.getLogger().info("Snippet content:");
    context.getLogger().info(inputBlob);

    // Return the snippet content or a not found message
    if (inputBlob != null && !inputBlob.trim().isEmpty()) {
        return inputBlob;
    } else {
        return "Snippet '" + snippetName + "' not found.";
    }
}

Per l'esempio di codice completo, vedere Snippets.java.

Il codice di esempio per JavaScript non è attualmente disponibile. Vedere gli esempi di TypeScript per indicazioni generali sull'uso di Node.js.

Questo codice crea un endpoint per esporre uno strumento denominato savesnippet che tenta di rendere persistente un frammento di codice denominato nell'archivio BLOB.

import { app, InvocationContext, input, output, arg } from "@azure/functions";

app.mcpTool("saveSnippet", {
  toolName: SAVE_SNIPPET_TOOL_NAME,
  description: SAVE_SNIPPET_TOOL_DESCRIPTION,
  toolProperties: {
    [SNIPPET_NAME_PROPERTY_NAME]: arg.string().describe(SNIPPET_NAME_PROPERTY_DESCRIPTION),
    [SNIPPET_PROPERTY_NAME]: arg.string().describe(SNIPPET_PROPERTY_DESCRIPTION)
  },
  extraOutputs: [blobOutputBinding],
  handler: saveSnippet,
});

Questo codice gestisce il savesnippet trigger:

export async function saveSnippet(
  _toolArguments: unknown,
  context: InvocationContext
): Promise<string> {
  console.info("Saving snippet");

  // Get snippet name and content from the tool arguments
  const mcptoolargs = context.triggerMetadata.mcptoolargs as {
    snippetname?: string;
    snippet?: string;
  };

  const snippetName = mcptoolargs?.snippetname;
  const snippet = mcptoolargs?.snippet;

  if (!snippetName) {
    return "No snippet name provided";
  }

  if (!snippet) {
    return "No snippet content provided";
  }

  // Save the snippet to blob storage using the output binding
  context.extraOutputs.set(blobOutputBinding, snippet);

  console.info(`Saved snippet: ${snippetName}`);
  return snippet;
}

Questo codice crea un endpoint per esporre uno strumento denominato getsnippet che tenta di recuperare un frammento di codice in base al nome dall'archivio BLOB.

import { app, InvocationContext, input, output, arg } from "@azure/functions";

app.mcpTool("getSnippet", {
  toolName: GET_SNIPPET_TOOL_NAME,
  description: GET_SNIPPET_TOOL_DESCRIPTION,
  toolProperties: {
    [SNIPPET_NAME_PROPERTY_NAME]: arg.string().describe(SNIPPET_NAME_PROPERTY_DESCRIPTION)
  },
  extraInputs: [blobInputBinding],
  handler: getSnippet,
});

Questo codice gestisce il getsnippet trigger:

export async function getSnippet(
  _toolArguments: unknown,
  context: InvocationContext
): Promise<string> {
  console.info("Getting snippet");

  // Get snippet name from the tool arguments
  const mcptoolargs = context.triggerMetadata.mcptoolargs as {
    snippetname?: string;
  };
  const snippetName = mcptoolargs?.snippetname;

  console.info(`Snippet name: ${snippetName}`);

  if (!snippetName) {
    return "No snippet name provided";
  }

  // Get the content from blob binding - properly retrieving from extraInputs
  const snippetContent = context.extraInputs.get(blobInputBinding);

  if (!snippetContent) {
    return `Snippet '${snippetName}' not found`;
  }

  console.info(`Retrieved snippet: ${snippetName}`);
  return snippetContent as string;
}

Per l'esempio di codice completo, vedere snippetsMcpTool.ts.

Questo codice usa l'elemento mcp_tool_trigger Decorator per creare un endpoint per esporre uno strumento denominato save_snippet che tenta di rendere persistente un frammento di codice denominato nell'archivio BLOB.

@app.mcp_tool_trigger(
    arg_name="context",
    tool_name="save_snippet",
    description="Save a snippet with a name.",
    tool_properties=tool_properties_save_snippets_json,
)
@app.blob_output(arg_name="file", connection="AzureWebJobsStorage", path=_BLOB_PATH)
def save_snippet(file: func.Out[str], context) -> str:
    content = json.loads(context)
    snippet_name_from_args = content["arguments"][_SNIPPET_NAME_PROPERTY_NAME]
    snippet_content_from_args = content["arguments"][_SNIPPET_PROPERTY_NAME]

    if not snippet_name_from_args:
        return "No snippet name provided"

    if not snippet_content_from_args:
        return "No snippet content provided"

    file.set(snippet_content_from_args)
    logging.info(f"Saved snippet: {snippet_content_from_args}")
    return f"Snippet '{snippet_content_from_args}' saved successfully"

Questo codice usa l'elemento mcp_tool_trigger Decorator per creare un endpoint per esporre uno strumento denominato get_snippet che tenta di recuperare un frammento di codice in base al nome dall'archivio BLOB.

@app.mcp_tool_trigger(
    arg_name="context",
    tool_name="get_snippet",
    description="Retrieve a snippet by name.",
    tool_properties=tool_properties_get_snippets_json,
)
@app.blob_input(arg_name="file", connection="AzureWebJobsStorage", path=_BLOB_PATH)
def get_snippet(file: func.InputStream, context) -> str:
    """
    Retrieves a snippet by name from Azure Blob Storage.

    Args:
        file (func.InputStream): The input binding to read the snippet from Azure Blob Storage.
        context: The trigger context containing the input arguments.

    Returns:
        str: The content of the snippet or an error message.
    """
    snippet_content = file.read().decode("utf-8")
    logging.info(f"Retrieved snippet: {snippet_content}")
    return snippet_content

Per l'esempio di codice completo, vedere function_app.py.

Importante

L'estensione MCP attualmente non supporta le app di PowerShell.

Attributi

Le librerie C# usano McpToolTriggerAttribute per definire il trigger di funzione.

Il costruttore dell'attributo accetta i parametri seguenti:

Parametro Descrizione
ToolName (Obbligatorio) nome dello strumento esposto dall'endpoint del trigger MCP.
Descrizione (Facoltativo) Descrizione descrittiva dell'endpoint dello strumento per i client.

Vedere Utilizzo per informazioni su come definire le proprietà dell'endpoint come parametri di input.

Annotazioni

L'annotazione @McpToolTrigger crea una funzione che espone un endpoint dello strumento nel server MCP remoto.

L'annotazione supporta le opzioni di configurazione seguenti:

Parametro Descrizione
nome (Obbligatorio) nome dello strumento esposto dall'endpoint del trigger MCP.
descrizione (Facoltativo) Descrizione descrittiva dell'endpoint dello strumento per i client.

L'annotazione @McpToolProperty definisce le singole proprietà per gli strumenti. Ogni parametro della proprietà nella funzione deve essere annotato con questa annotazione.

L'annotazione @McpToolProperty supporta le opzioni di configurazione seguenti:

Parametro Descrizione
nome (Obbligatorio) nome della proprietà dello strumento esposta ai client.
propertyType (Obbligatorio) tipo della proprietà dello strumento. I tipi validi sono: string, numberinteger, boolean, , object.
descrizione (Facoltativo) descrizione delle operazioni della proprietà dello strumento.
obbligatorio (Facoltativo) se impostato su true, la proprietà dello strumento è necessaria come argomento per le chiamate agli strumenti. Il valore predefinito è false.

Decoratori

Si applica solo al modello di programmazione Python v2.

L'elemento mcp_tool_trigger decorator richiede la versione 1.24.0 o successiva del azure-functions pacchetto. Le proprietà del trigger MCP seguenti sono supportate in mcp_tool_trigger:

Proprietà Descrizione
arg_name Nome della variabile (in genere context) usato nel codice della funzione per accedere al contesto di esecuzione.
tool_name (Obbligatorio) Nome dello strumento server MCP esposto dall'endpoint della funzione.
descrizione Descrizione dello strumento server MCP esposto dall'endpoint della funzione.
tool_properties Rappresentazione di stringa JSON di uno o più oggetti proprietà che espongono proprietà dello strumento ai client.

Configurazione

Il trigger supporta queste opzioni di associazione, definite nel codice:

Opzioni Descrizione
tipo Deve essere impostato su mcpToolTrigger. Usato solo con definizioni generice.
toolName (Obbligatorio) Nome dello strumento server MCP esposto dall'endpoint della funzione.
descrizione Descrizione dello strumento server MCP esposto dall'endpoint della funzione.
toolProperties Matrice di toolProperty oggetti che espongono proprietà dello strumento ai client.
extraOutputs Se definito, invia l'output della funzione a un'altra associazione.
gestore Metodo che contiene il codice della funzione effettivo.

Per esempi completi, vedere la sezione di esempio.

Uso

Il trigger dello strumento MCP può essere associato ai tipi seguenti:

TIPO Descrizione
ToolInvocationContext Oggetto che rappresenta la chiamata allo strumento, inclusi il nome e gli argomenti dello strumento per la chiamata.
Tipi serializzabili JSON Funzioni tenta di deserializzare gli argomenti dello strumento in un tipo POCO (Plain-Old CLR Object). Questo tipo viene usato anche per definire le proprietà degli strumenti.

Quando si esegue l'associazione a un tipo serializzabile JSON, è anche possibile includere un parametro di tipo ToolInvocationContext per accedere alle informazioni sulla chiamata dello strumento.

Proprietà degli strumenti

I client MCP richiamano strumenti con argomenti per fornire dati e contesto per l'operazione dello strumento. I client sanno come raccogliere e passare questi argomenti in base alle proprietà annunciate dallo strumento come parte del protocollo. È quindi necessario definire le proprietà dello strumento nel codice della funzione.

Quando si definisce una proprietà dello strumento, è facoltativa per impostazione predefinita e il client può ometterlo quando si richiama lo strumento. È necessario contrassegnare in modo esplicito le proprietà come richiesto se lo strumento non può funzionare senza di essi.

Annotazioni

Le versioni precedenti dell'anteprima dell'estensione MCP hanno reso necessarie per impostazione predefinita tutte le proprietà degli strumenti. Questo comportamento è cambiato a partire dalla versione 1.0.0-preview.7e ora è necessario contrassegnare in modo esplicito le proprietà come richiesto.

In C# è possibile definire le proprietà per gli strumenti in diversi modi. L'approccio usato è una questione di preferenza per lo stile del codice. Le opzioni sono:

  • La funzione accetta parametri di input usando l'attributo McpToolProperty .
  • Si definisce un tipo personalizzato con le proprietà e la funzione viene associata a tale tipo.
  • Usare per FunctionsApplicationBuilder definire le proprietà nel Program.cs file.

È possibile definire una o più proprietà dello strumento applicando l'attributo McpToolProperty ai parametri di tipo binding di input nella funzione.

Il McpToolPropertyAttribute tipo supporta queste proprietà:

Proprietà Descrizione
NomeProprietà Nome della proprietà dello strumento esposta ai client.
Descrizione Descrizione delle operazioni della proprietà dello strumento.
È obbligatorio (Facoltativo) Se impostato su true, la proprietà dello strumento è obbligatoria come argomento per le chiamate agli strumenti. Il valore predefinito è false.

Il tipo di proprietà viene dedotto dal tipo del parametro a cui si applica l'attributo. Ad esempio [McpToolProperty("snippetname", "The name of the snippet.", true)] string name , definisce una proprietà dello strumento obbligatoria denominata snippetname di tipo string nei messaggi MCP.

È possibile visualizzare questi attributi usati nello SaveSnippet strumento negli esempi.

In Java si definiscono le proprietà degli strumenti usando l'annotazione @McpToolProperty sui singoli parametri di funzione. Ogni parametro che rappresenta una proprietà dello strumento deve essere annotato con questa annotazione, specificando il nome della proprietà, il tipo, la descrizione e se è obbligatorio.

È possibile visualizzare queste annotazioni usate negli esempi.

È possibile configurare le proprietà degli strumenti nel campo della definizione del toolProperties trigger, ovvero una rappresentazione di stringa di una matrice di ToolProperty oggetti.

Un ToolProperty oggetto ha questa struttura:

{
    "propertyName": "Name of the property",
    "propertyType": "Type of the property",
    "description": "Optional property description",
    "isRequired": true|false,
    "isArray": true|false
}

I campi di un ToolProperty oggetto sono:

Proprietà Descrizione
propertyName Nome della proprietà dello strumento esposta ai client.
propertyType Tipo della proprietà dello strumento. I tipi validi sono: string, numberinteger, boolean, , object. Vedere isArray per i tipi di matrice.
descrizione Descrizione delle operazioni della proprietà dello strumento.
isRequired (Facoltativo) Se impostato su true, la proprietà dello strumento è obbligatoria come argomento per le chiamate agli strumenti. Il valore predefinito è false.
isArray (Facoltativo) Se impostato su true, la proprietà dello strumento è una matrice del tipo di proprietà specificato. Il valore predefinito è false.

Puoi fornire il toolProperties campo come un array di ToolProperty oggetti, oppure puoi usare gli arg helper da @azure/functions per definire proprietà in modo più sicuro per i tipi:

  toolProperties: {
    [SNIPPET_NAME_PROPERTY_NAME]: arg.string().describe(SNIPPET_NAME_PROPERTY_DESCRIPTION)
  }

Per ulteriori informazioni, vedere Esempi.

impostazioni host.json

Il file host.json contiene le impostazioni che controllano i comportamenti dei trigger MCP. Per informazioni dettagliate sulle impostazioni disponibili, vedere la sezione impostazioni host.json .

Estensione OpenAI di Azure per Funzioni di Azure