Compartilhar via


Gatilho da ferramenta MCP para o Azure Functions

Use o gatilho da ferramenta MCP para definir pontos de extremidade de ferramenta em um servidor MCP (Model Content Protocol ). Os agentes e modelos de linguagem do cliente podem usar ferramentas para executar tarefas específicas, como armazenar ou acessar snippets de código.

Para obter informações sobre a instalação e detalhes de configuração, confira a visão geral.

Exemplo

Observação

Para C#, a extensão MCP do Azure Functions dá suporte apenas ao modelo de trabalho isolado.

Esse código cria um ponto de extremidade para expor uma ferramenta nomeada SaveSnippet que tenta persistir um snippet de código nomeado no armazenamento de blobs.

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

Esse código cria um ponto de extremidade para expor uma ferramenta nomeada GetSnippet que tenta recuperar um snippet de código pelo nome do armazenamento de blobs.

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

As propriedades da ferramenta para a GetSnippet função são configuradas em 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();

Dica

O exemplo acima usou cadeias de caracteres literais para itens como o nome da ferramenta "get_snippets" em ambos Program.cs e na função. Considere, em vez disso, usar cadeias de caracteres constantes compartilhadas para manter as coisas em sincronia em seu projeto.

Para obter o exemplo de código completo, consulte SnippetTool.cs.

Esse código cria um ponto de extremidade para expor uma ferramenta nomeada SaveSnippets que tenta persistir um snippet de código nomeado no armazenamento de blobs.

@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.";
}

Esse código cria um ponto de extremidade para expor uma ferramenta nomeada GetSnippets que tenta recuperar um snippet de código pelo nome do armazenamento de blobs.

@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.";
    }
}

Para obter o exemplo de código completo, consulte Snippets.java.

O código de exemplo para JavaScript não está disponível no momento. Consulte os exemplos de TypeScript para obter diretrizes gerais usando Node.js.

Esse código cria um ponto de extremidade para expor uma ferramenta nomeada savesnippet que tenta persistir um snippet de código nomeado no armazenamento de blobs.

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

Esse código manipula o savesnippet gatilho:

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

Esse código cria um ponto de extremidade para expor uma ferramenta nomeada getsnippet que tenta recuperar um snippet de código pelo nome do armazenamento de blobs.

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

Esse código manipula o getsnippet gatilho:

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

Para obter o exemplo de código completo, consulte snippetsMcpTool.ts.

Esse código usa o mcp_tool_trigger decorador para criar um ponto de extremidade para expor uma ferramenta nomeada save_snippet que tenta persistir um snippet de código nomeado no armazenamento de blobs.

@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"

Esse código usa o mcp_tool_trigger decorador para criar um ponto de extremidade para expor uma ferramenta nomeada get_snippet que tenta recuperar um snippet de código pelo nome do armazenamento de blobs.

@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

Para obter o exemplo de código completo, consulte function_app.py.

Importante

Atualmente, a extensão MCP não dá suporte a aplicativos do PowerShell.

Atributos

As bibliotecas C# usam McpToolTriggerAttribute para definir o gatilho de função.

O construtor do atributo recebe os seguintes parâmetros:

Parâmetro Descrição
ToolName (Obrigatório) nome da ferramenta que está sendo exposta pelo ponto de extremidade do gatilho MCP.
Descrição (Opcional) descrição amigável do ponto de extremidade da ferramenta para clientes.

Consulte Uso para saber como definir propriedades do ponto de extremidade como parâmetros de entrada.

Anotações

A @McpToolTrigger anotação cria uma função que expõe um ponto de extremidade de ferramenta em seu servidor MCP remoto.

A anotação dá suporte às seguintes opções de configuração:

Parâmetro Descrição
name (Obrigatório) nome da ferramenta que está sendo exposta pelo ponto de extremidade do gatilho MCP.
descrição (Opcional) descrição amigável do ponto de extremidade da ferramenta para clientes.

A @McpToolProperty anotação define propriedades individuais para suas ferramentas. Cada parâmetro de propriedade em sua função deve ser anotado com essa anotação.

A @McpToolProperty anotação dá suporte às seguintes opções de configuração:

Parâmetro Descrição
name (Obrigatório) nome da propriedade da ferramenta que é exposta aos clientes.
propertyType (Obrigatório) tipo da propriedade da ferramenta. Os tipos válidos são: string, , number, integer, boolean, object.
descrição (Opcional) descrição do que a propriedade de ferramenta faz.
obrigatório (Opcional) se definido como true, a propriedade da ferramenta é necessária como um argumento para chamadas de ferramenta. Usa false como padrão.

Decoradores

Aplica-se apenas ao modelo de programação do Python v2.

O mcp_tool_trigger decorador requer a versão 1.24.0 ou posterior do azure-functions pacote. As seguintes propriedades de gatilho MCP têm suporte em mcp_tool_trigger:

Propriedade Descrição
arg_name O nome da variável (geralmente context) usado no código de função para acessar o contexto de execução.
tool_name (Obrigatório) O nome da ferramenta de servidor MCP exposta pelo ponto de extremidade da função.
descrição Uma descrição da ferramenta de servidor MCP exposta pelo ponto de extremidade da função.
tool_properties A representação da cadeia de caracteres JSON de um ou mais objetos de propriedade que expõem propriedades da ferramenta aos clientes.

Configuração

O gatilho dá suporte a essas opções de associação, que são definidas em seu código:

Opções Descrição
tipo Deve ser definido como mcpToolTrigger. Usado apenas com definições genéricas.
toolName (Obrigatório) O nome da ferramenta de servidor MCP exposta pelo ponto de extremidade da função.
descrição Uma descrição da ferramenta de servidor MCP exposta pelo ponto de extremidade da função.
toolProperties Uma matriz de toolProperty objetos que expõe as propriedades da ferramenta aos clientes.
extraOutputs Quando definido, envia a saída da função para outra associação.
manipulador O método que contém o código de função real.

Consulte a Seção de exemplo para obter exemplos completos.

Uso

O gatilho da ferramenta MCP pode ser associado aos seguintes tipos:

Tipo Descrição
ToolInvocationContext Um objeto que representa a chamada de ferramenta, incluindo o nome da ferramenta e os argumentos da chamada.
Tipos serializáveis JSON O Functions tenta desserializar os argumentos da ferramenta em um tipo poco (objeto CLR) simples e antigo. Esse tipo também é usado para definir as propriedades da ferramenta.

Ao associar a um tipo serializável JSON, você também pode incluir um parâmetro do tipo ToolInvocationContext para acessar as informações de chamada da ferramenta.

Propriedades da ferramenta

Os clientes MCP invocam ferramentas com argumentos para fornecer dados e contexto para a operação da ferramenta. Os clientes sabem como coletar e passar esses argumentos com base nas propriedades que a ferramenta anuncia como parte do protocolo. Portanto, você precisa definir as propriedades da ferramenta em seu código de função.

Quando você define uma propriedade de ferramenta, ela é opcional por padrão e o cliente pode omitê-la ao invocar a ferramenta. Você precisará marcar explicitamente as propriedades conforme necessário se a ferramenta não puder operar sem elas.

Observação

As versões anteriores da versão prévia da extensão MCP tornaram todas as propriedades da ferramenta necessárias por padrão. Esse comportamento mudou a partir da versão 1.0.0-preview.7e agora você deve marcar explicitamente as propriedades conforme necessário.

Em C#, você pode definir propriedades para suas ferramentas de várias maneiras. Qual abordagem você usa é uma questão de preferência de estilo de código. As opções são:

  • Sua função usa parâmetros de entrada usando o McpToolProperty atributo.
  • Você define um tipo personalizado com as propriedades e a função se associa a esse tipo.
  • Você usa as FunctionsApplicationBuilder propriedades para definir em seu Program.cs arquivo.

Você pode definir uma ou mais propriedades de ferramenta aplicando o McpToolProperty atributo a parâmetros de estilo de associação de entrada em sua função.

O McpToolPropertyAttribute tipo dá suporte a essas propriedades:

Propriedade Descrição
Nome da propriedade Nome da propriedade de ferramenta que é exposta aos clientes.
Descrição Descrição do que a propriedade de ferramenta faz.
ÉObrigatório (Opcional) Se definido como true, a propriedade da ferramenta será necessária como um argumento para chamadas de ferramenta. Usa false como padrão.

O tipo de propriedade é inferido do tipo do parâmetro ao qual você aplica o atributo. Por exemplo [McpToolProperty("snippetname", "The name of the snippet.", true)] string name , define uma propriedade de ferramenta necessária chamada snippetname de tipo string em mensagens MCP.

Você pode ver esses atributos usados na SaveSnippet ferramenta nos Exemplos.

No Java, você define as propriedades da ferramenta usando a @McpToolProperty anotação em parâmetros de função individuais. Cada parâmetro que representa uma propriedade de ferramenta deve ser anotado com essa anotação, especificando o nome da propriedade, o tipo, a descrição e se ele é necessário.

Você pode ver essas anotações usadas nos Exemplos.

Você pode configurar as propriedades da ferramenta no campo da definição do toolProperties gatilho, que é uma representação de cadeia de caracteres de uma matriz de ToolProperty objetos.

Um ToolProperty objeto tem essa estrutura:

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

Os campos de um ToolProperty objeto são:

Propriedade Descrição
propertyName Nome da propriedade de ferramenta que é exposta aos clientes.
propertyType Tipo da propriedade da ferramenta. Os tipos válidos são: string, , number, integer, boolean, object. Consulte isArray os tipos de matriz.
descrição Descrição do que a propriedade de ferramenta faz.
isRequired (Opcional) Se definido como true, a propriedade da ferramenta será necessária como um argumento para chamadas de ferramenta. Usa false como padrão.
isArray (Opcional) Se definido como true, a propriedade da ferramenta é uma matriz do tipo de propriedade especificado. Usa false como padrão.

Você pode fornecer o toolProperties campo como um array de ToolProperty objetos, ou usar os arg helpers de @azure/functions para definir propriedades de uma forma mais segura para tipos:

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

Para obter mais informações, consulte Exemplos.

configurações de host.json

O arquivo host.json contém configurações que controlam os comportamentos do gatilho MCP. Confira a seção Configurações de host.json para obter detalhes em relação às configurações disponíveis.

Extensão do OpenAI do Azure para o Azure Functions