Partage via


Déclencheur d’outil MCP pour Azure Functions

Utilisez le déclencheur d’outil MCP pour définir des points de terminaison d’outil dans un serveur MCP (Model Content Protocol). Les modèles de langage client et les agents peuvent utiliser des outils pour effectuer des tâches spécifiques, telles que le stockage ou l’accès à des extraits de code.

Pour plus d’informations sur les détails d’installation et de configuration, consultez la vue d’ensemble.

Exemple :

Remarque

Pour C#, l’extension MCP Azure Functions prend uniquement en charge le modèle worker isolé.

Ce code crée un point de terminaison pour exposer un outil nommé SaveSnippet qui tente de conserver un extrait de code nommé dans le stockage d’objets 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;
}

Ce code crée un point de terminaison pour exposer un outil nommé GetSnippet qui tente de récupérer un extrait de code par nom à partir du stockage d’objets 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;
}

Les propriétés de l’outil pour la GetSnippet fonction sont configurées dans 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();

Conseil / Astuce

L’exemple ci-dessus a utilisé des chaînes littérales pour des éléments tels que le nom de l’outil « get_snippets » dans les deux Program.cs et la fonction. Envisagez plutôt d’utiliser des chaînes de constantes partagées pour synchroniser les éléments dans votre projet.

Pour obtenir l’exemple de code complet, consultez SnippetTool.cs.

Ce code crée un point de terminaison pour exposer un outil nommé SaveSnippets qui tente de conserver un extrait de code nommé dans le stockage d’objets 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.";
}

Ce code crée un point de terminaison pour exposer un outil nommé GetSnippets qui tente de récupérer un extrait de code par nom à partir du stockage d’objets 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.";
    }
}

Pour obtenir l’exemple de code complet, consultez Snippets.java.

L’exemple de code pour JavaScript n’est actuellement pas disponible. Consultez les exemples TypeScript pour obtenir des conseils généraux à l’aide de Node.js.

Ce code crée un point de terminaison pour exposer un outil nommé savesnippet qui tente de conserver un extrait de code nommé dans le stockage d’objets 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,
});

Ce code gère le savesnippet déclencheur :

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;
}

Ce code crée un point de terminaison pour exposer un outil nommé getsnippet qui tente de récupérer un extrait de code par nom à partir du stockage d’objets 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,
});

Ce code gère le getsnippet déclencheur :

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;
}

Pour obtenir l’exemple de code complet, consultez snippetsMcpTool.ts.

Ce code utilise le mcp_tool_trigger décorateur pour créer un point de terminaison pour exposer un outil nommé save_snippet qui tente de conserver un extrait de code nommé dans le stockage d’objets 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"

Ce code utilise le mcp_tool_trigger décorateur pour créer un point de terminaison pour exposer un outil nommé get_snippet qui tente de récupérer un extrait de code par nom à partir du stockage d’objets 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

Pour obtenir l’exemple de code complet, consultez function_app.py.

Important

L’extension MCP ne prend actuellement pas en charge les applications PowerShell.

Attributs

Les bibliothèques C# utilisent McpToolTriggerAttribute pour définir le déclencheur de fonction.

Le constructeur de l’attribut accepte les paramètres suivants :

Paramètre Descriptif
ToolName (Obligatoire) nom de l’outil exposé par le point de terminaison du déclencheur MCP.
Description (Facultatif) description conviviale du point de terminaison d’outil pour les clients.

Consultez Utilisation pour savoir comment définir les propriétés du point de terminaison en tant que paramètres d’entrée.

Commentaires

L’annotation @McpToolTrigger crée une fonction qui expose un point de terminaison d’outil dans votre serveur MCP distant.

L’annotation prend en charge les options de configuration suivantes :

Paramètre Descriptif
name (Obligatoire) nom de l’outil exposé par le point de terminaison du déclencheur MCP.
description (Facultatif) description conviviale du point de terminaison d’outil pour les clients.

L’annotation @McpToolProperty définit des propriétés individuelles pour vos outils. Chaque paramètre de propriété de votre fonction doit être annoté avec cette annotation.

L’annotation @McpToolProperty prend en charge les options de configuration suivantes :

Paramètre Descriptif
name (Obligatoire) nom de la propriété outil qui est exposée aux clients.
propertyType (Obligatoire) type de la propriété de l’outil. Les types valides sont : string, , numberinteger, boolean, object.
description (Facultatif) description de ce que fait la propriété de l’outil.
obligatoire (Facultatif) si la valeur est définie true, la propriété de l’outil est requise en tant qu’argument pour les appels d’outils. La valeur par défaut est false.

Décorateurs

S'applique uniquement au modèle de programmation Python v2.

Le mcp_tool_trigger décorateur nécessite la version 1.24.0 ou ultérieure du azure-functions package. Les propriétés de déclencheur MCP suivantes sont prises en charge sur mcp_tool_trigger:

Propriété Descriptif
arg_name Nom de variable (généralement context) utilisé dans le code de fonction pour accéder au contexte d’exécution.
tool_name (Obligatoire) Nom de l’outil serveur MCP exposé par le point de terminaison de fonction.
description Description de l’outil serveur MCP exposé par le point de terminaison de fonction.
tool_properties Représentation sous forme de chaîne JSON d’un ou plusieurs objets de propriété qui exposent les propriétés de l’outil aux clients.

Paramétrage

Le déclencheur prend en charge ces options de liaison, qui sont définies dans votre code :

Paramètres Descriptif
type Cette propriété doit être définie sur mcpToolTrigger. Utilisé uniquement avec les définitions génériques.
toolName (Obligatoire) Nom de l’outil serveur MCP exposé par le point de terminaison de fonction.
description Description de l’outil serveur MCP exposé par le point de terminaison de fonction.
toolProperties Tableau d’objets toolProperty qui exposent les propriétés de l’outil aux clients.
extraOutputs Quand elle est définie, envoie la sortie de la fonction à une autre liaison.
gestionnaire Méthode qui contient le code de fonction réel.

Pour obtenir des exemples complets, consultez la section Exemple.

Utilisation

Le déclencheur d’outil MCP peut être lié aux types suivants :

Type Descriptif
ToolInvocationContext Objet représentant l’appel de l’outil, y compris le nom et les arguments de l’outil pour l’appel.
Types sérialisables JSON Functions tente de désérialiser les arguments de l’outil dans un type d’objet CLR (POCO) simple. Ce type est également utilisé pour définir les propriétés de l’outil.

Lors de la liaison à un type sérialisable JSON, vous pouvez éventuellement inclure un paramètre de type ToolInvocationContext pour accéder aux informations d’appel de l’outil.

Propriétés de l’outil

Les clients MCP appellent des outils avec des arguments pour fournir des données et un contexte pour l’opération de l’outil. Les clients savent comment collecter et transmettre ces arguments en fonction des propriétés publiées par l’outil dans le cadre du protocole. Vous devez donc définir les propriétés de l’outil dans votre code de fonction.

Lorsque vous définissez une propriété d’outil, elle est facultative par défaut et le client peut l’omettre lors de l’appel de l’outil. Vous devez marquer explicitement les propriétés comme obligatoires si l’outil ne peut pas fonctionner sans eux.

Remarque

Les versions antérieures de l’aperçu de l’extension MCP ont rendu toutes les propriétés d’outil requises par défaut. Ce comportement a changé à partir de la version 1.0.0-preview.7, et maintenant, vous devez marquer explicitement les propriétés comme requis.

En C#, vous pouvez définir des propriétés pour vos outils de plusieurs façons. Quelle approche vous utilisez est une question de préférence de style de code. Les options sont les suivantes :

  • Votre fonction prend des paramètres d’entrée à l’aide de l’attribut McpToolProperty .
  • Vous définissez un type personnalisé avec les propriétés et la fonction est liée à ce type.
  • Vous utilisez la propriété FunctionsApplicationBuilder pour définir des propriétés dans votre Program.cs fichier.

Vous pouvez définir une ou plusieurs propriétés d’outil en appliquant l’attribut McpToolProperty aux paramètres de style de liaison d’entrée dans votre fonction.

Le McpToolPropertyAttribute type prend en charge ces propriétés :

Propriété Descriptif
PropertyName Nom de la propriété outil qui est exposée aux clients.
Description Description de ce que fait la propriété de l’outil.
Est obligatoire (Facultatif) Si la valeur est définie true, la propriété de l’outil est requise en tant qu’argument pour les appels d’outils. La valeur par défaut est false.

Le type de propriété est déduit du type du paramètre auquel vous appliquez l’attribut. Par exemple [McpToolProperty("snippetname", "The name of the snippet.", true)] string name , définit une propriété d’outil requise nommée snippetname de type string dans les messages MCP.

Vous pouvez voir ces attributs utilisés dans l’outil SaveSnippet dans les exemples.

En Java, vous définissez des propriétés d’outil à l’aide de l’annotation @McpToolProperty sur des paramètres de fonction individuels. Chaque paramètre qui représente une propriété d’outil doit être annoté avec cette annotation, en spécifiant le nom de la propriété, le type, la description et si elle est requise.

Vous pouvez voir ces annotations utilisées dans les exemples.

Vous pouvez configurer les propriétés d’outil dans le champ de la définition du toolProperties déclencheur, qui est une représentation sous forme de chaîne d’un tableau d’objets ToolProperty .

Un ToolProperty objet a cette structure :

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

Les champs d’un ToolProperty objet sont les suivants :

Propriété Descriptif
propertyName Nom de la propriété outil qui est exposée aux clients.
propertyType Type de la propriété outil. Les types valides sont : string, , numberinteger, boolean, object. Consultez isArray les types de tableaux.
description Description de ce que fait la propriété de l’outil.
isRequired (Facultatif) Si la valeur est définie true, la propriété de l’outil est requise en tant qu’argument pour les appels d’outils. La valeur par défaut est false.
isArray (Facultatif) Si la valeur est définie true, la propriété de l’outil est un tableau du type de propriété spécifié. La valeur par défaut est false.

Vous pouvez fournir le toolProperties champ sous forme d’un tableau d’objets ToolProperty , ou vous pouvez utiliser les arg aides de @azure/functions pour définir des propriétés de manière plus sûre pour les types :

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

Pour plus d’informations, consultez Exemples.

Paramètres host.json

Le fichier host.json contient des paramètres qui contrôlent les comportements des déclencheurs MCP. Consultez la section Paramètres host.json pour plus d’informations concernant les paramètres disponibles.

Extensions Azure OpenAI pour Azure Functions