Bagikan melalui


Pemicu alat MCP untuk Azure Functions

Gunakan pemicu alat MCP untuk menentukan titik akhir alat di server Model Content Protocol (MCP). Model dan agen bahasa klien dapat menggunakan alat untuk melakukan tugas tertentu, seperti menyimpan atau mengakses cuplikan kode.

Untuk informasi tentang pengaturan dan detail konfigurasi, lihat gambaran umum.

Contoh

Nota

Untuk C#, ekstensi MCP Azure Functions hanya mendukung model pekerja yang terisolasi.

Kode ini membuat titik akhir untuk mengekspos alat bernama SaveSnippet yang mencoba mempertahankan cuplikan kode bernama ke penyimpanan 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;
}

Kode ini membuat titik akhir untuk mengekspos alat bernama GetSnippet yang mencoba mengambil cuplikan kode berdasarkan nama dari penyimpanan 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;
}

Properti alat untuk fungsi dikonfigurasi GetSnippet dalam 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();

Tip

Contoh di atas menggunakan string literal untuk hal-hal seperti nama alat "get_snippets" dalam fungsi dan Program.cs . Pertimbangkan untuk menggunakan string konstanta bersama untuk menjaga hal-hal tetap sinkron di seluruh proyek Anda.

Untuk contoh kode lengkap, lihat SnippetTool.cs.

Kode ini membuat titik akhir untuk mengekspos alat bernama SaveSnippets yang mencoba mempertahankan cuplikan kode bernama ke penyimpanan 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.";
}

Kode ini membuat titik akhir untuk mengekspos alat bernama GetSnippets yang mencoba mengambil cuplikan kode berdasarkan nama dari penyimpanan 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.";
    }
}

Untuk contoh kode lengkap, lihat Snippets.java.

Contoh kode untuk JavaScript saat ini tidak tersedia. Lihat contoh TypeScript untuk panduan umum menggunakan Node.js.

Kode ini membuat titik akhir untuk mengekspos alat bernama savesnippet yang mencoba mempertahankan cuplikan kode bernama ke penyimpanan 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,
});

Kode ini menangani pemicu savesnippet :

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

Kode ini membuat titik akhir untuk mengekspos alat bernama getsnippet yang mencoba mengambil cuplikan kode berdasarkan nama dari penyimpanan 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,
});

Kode ini menangani pemicu getsnippet :

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

Untuk contoh kode lengkap, lihat snippetsMcpTool.ts.

Kode ini menggunakan mcp_tool_trigger dekorator untuk membuat titik akhir untuk mengekspos alat bernama save_snippet yang mencoba mempertahankan cuplikan kode bernama ke penyimpanan 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"

Kode ini menggunakan mcp_tool_trigger dekorator untuk membuat titik akhir untuk mengekspos alat bernama get_snippet yang mencoba mengambil cuplikan kode berdasarkan nama dari penyimpanan 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

Untuk contoh kode lengkap, lihat function_app.py.

Penting

Ekstensi MCP saat ini tidak mendukung aplikasi PowerShell.

Atributs

Pustaka C# digunakan McpToolTriggerAttribute untuk menentukan pemicu fungsi.

Konstruktor atribut membutuhkan parameter berikut:

Pengaturan Deskripsi
ToolName (Wajib) nama alat yang sedang diekspos oleh titik akhir pemicu MCP.
Deskripsi (Opsional) deskripsi yang ramah tentang titik akhir alat untuk klien.

Lihat Penggunaan untuk mempelajari cara menentukan properti titik akhir sebagai parameter input.

Anotasi

Anotasi @McpToolTrigger membuat fungsi yang mengekspos titik akhir alat di server MCP jarak jauh Anda.

Anotasi tersebut mendukung opsi konfigurasi berikut:

Pengaturan Deskripsi
Nama (Wajib) nama alat yang sedang diekspos oleh titik akhir pemicu MCP.
deskripsi (Opsional) deskripsi yang ramah tentang titik akhir alat untuk klien.

Anotasi @McpToolProperty menentukan properti individual untuk alat Anda. Setiap parameter properti dalam fungsi Anda harus diannotasi dengan anotasi ini.

Anotasi @McpToolProperty mendukung opsi konfigurasi berikut:

Pengaturan Deskripsi
Nama (Wajib) nama properti alat yang diekspos ke klien.
propertyType (Wajib) jenis properti alat. Jenis yang valid adalah: string, , numberinteger, boolean, object.
deskripsi (Opsional) deskripsi tentang apa yang dilakukan properti alat.
Diperlukan (Opsional) jika diatur ke true, properti alat diperlukan sebagai argumen untuk panggilan alat. Secara default menjadi false.

Dekorator

Hanya berlaku untuk model pemrograman Python v2.

Dekorator mcp_tool_trigger memerlukan paket versi 1.24.0 atau yang lebih baruazure-functions. Properti pemicu MCP berikut didukung pada mcp_tool_trigger:

Harta benda Deskripsi
arg_name Nama variabel (biasanya context) digunakan dalam kode fungsi untuk mengakses konteks eksekusi.
tool_name (Diperlukan) Nama alat server MCP yang diekspos oleh titik akhir fungsi.
deskripsi Deskripsi alat server MCP yang diekspos oleh titik akhir fungsi.
tool_properties Representasi string JSON dari satu atau beberapa objek properti yang mengekspos properti alat ke klien.

Konfigurasi

Pemicu mendukung opsi pengikatan ini, yang ditentukan dalam kode Anda:

Opsi Deskripsi
jenis Harus diatur ke mcpToolTrigger. Hanya digunakan dengan definisi umum.
toolName (Diperlukan) Nama alat server MCP yang diekspos oleh titik akhir fungsi.
deskripsi Deskripsi alat server MCP yang diekspos oleh titik akhir fungsi.
toolProperties Array toolProperty objek yang mengekspos properti alat ke klien.
extraOutputs Saat ditentukan, mengirim output fungsi ke pengikatan lain.
Handler Metode yang berisi kode fungsi aktual.

Lihat Bagian contoh untuk contoh lengkapnya.

Penggunaan

Pemicu alat MCP dapat mengikat ke jenis berikut:

Tipe Deskripsi
ToolInvocationContext Objek yang mewakili panggilan alat, termasuk nama alat dan argumen untuk panggilan.
Jenis yang bisa diserialisasikan JSON Fungsi mencoba untuk mendeserialisasi argumen alat ke dalam jenis objek CLR (POCO) lama biasa. Jenis ini juga digunakan untuk menentukan properti alat.

Saat mengikat jenis JSON yang dapat diserialisasikan, Anda juga dapat menyertakan parameter jenis ToolInvocationContext untuk mengakses informasi panggilan alat.

Properti alat

Klien MCP memanggil alat dengan argumen untuk menyediakan data dan konteks untuk operasi alat. Klien tahu cara mengumpulkan dan meneruskan argumen ini berdasarkan properti yang diiklankan alat sebagai bagian dari protokol. Oleh karena itu, Anda perlu menentukan properti alat dalam kode fungsi Anda.

Saat Anda menentukan properti alat, properti ini bersifat opsional secara default, dan klien dapat menghilangkannya saat memanggil alat. Anda perlu secara eksplisit menandai properti sebagaimana diperlukan jika alat tidak dapat beroperasi tanpa properti tersebut.

Nota

Versi pratinjau ekstensi MCP yang lebih lama membuat semua properti alat diperlukan secara default. Perilaku ini berubah pada versi 1.0.0-preview.7, dan sekarang Anda harus secara eksplisit menandai properti sesuai kebutuhan.

Di C#, Anda dapat menentukan properti untuk alat Anda dengan beberapa cara. Pendekatan mana yang Anda gunakan adalah masalah preferensi gaya kode. Opsinya adalah:

  • Fungsi Anda mengambil parameter input menggunakan McpToolProperty atribut .
  • Anda menentukan jenis kustom dengan properti, dan fungsi mengikat ke jenis tersebut.
  • Anda menggunakan FunctionsApplicationBuilder untuk menentukan properti dalam file Anda Program.cs .

Anda dapat menentukan satu atau beberapa properti alat dengan menerapkan McpToolProperty atribut ke parameter gaya pengikatan input dalam fungsi Anda.

Jenis ini McpToolPropertyAttribute mendukung properti ini:

Harta benda Deskripsi
PropertyName Nama properti alat yang diekspos ke klien.
Deskripsi Deskripsi tentang apa yang dilakukan properti alat.
Adalah Wajib (Opsional) Jika diatur ke true, properti alat diperlukan sebagai argumen untuk panggilan alat. Secara default menjadi false.

Jenis properti disimpulkan dari jenis parameter tempat Anda menerapkan atribut . Misalnya [McpToolProperty("snippetname", "The name of the snippet.", true)] string name menentukan properti alat yang diperlukan bernama snippetname jenis string dalam pesan MCP.

Anda dapat melihat atribut ini yang digunakan dalam SaveSnippet alat di Contoh.

Di Java, Anda menentukan properti alat dengan menggunakan @McpToolProperty anotasi pada parameter fungsi individual. Setiap parameter yang mewakili properti alat harus diannotasi dengan anotasi ini, menentukan nama properti, jenis, deskripsi, dan apakah diperlukan.

Anda dapat melihat anotasi ini yang digunakan dalam Contoh.

Anda dapat mengonfigurasi properti alat di bidang definisi toolProperties pemicu, yang merupakan representasi string dari ToolProperty array objek.

Objek ToolProperty memiliki struktur ini:

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

Bidang ToolProperty objek adalah:

Harta benda Deskripsi
propertyName Nama properti alat yang diekspos ke klien.
propertyType Jenis properti alat. Jenis yang valid adalah: string, , numberinteger, boolean, object. Lihat isArray untuk jenis array.
deskripsi Deskripsi tentang apa yang dilakukan properti alat.
isRequired (Opsional) Jika diatur ke true, properti alat diperlukan sebagai argumen untuk panggilan alat. Secara default menjadi false.
isArray (Opsional) Jika diatur ke true, properti alat adalah array dari jenis properti yang ditentukan. Secara default menjadi false.

Anda dapat menyediakan toolProperties bidang sebagai array objek ToolProperty , atau Anda dapat menggunakan arg pembantu dari @azure/functions untuk menentukan properti dengan cara yang lebih aman untuk jenis:

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

Untuk informasi selengkapnya, lihat contoh .

Pengaturan host.json

File host.json berisi pengaturan yang mengontrol perilaku pemicu MCP. Lihat bagian pengaturan host.json untuk detail pengaturan yang tersedia.

Ekstensi Azure OpenAI untuk Azure Functions