Guida introduttiva: Creare un server MCP remoto personalizzato usando Funzioni di Azure

In questa guida introduttiva si crea un server MCP (Remote Model Context Protocol) personalizzato da un progetto modello usando l'interfaccia della riga di comando di Azure Developer (azd). Questo server MCP usa l'estensione server MCP Funzioni di Azure per fornire strumenti per modelli, agenti e assistenti di intelligenza artificiale. È anche possibile usare l'estensione server MCP per creare app MCP interattive.

Dopo aver eseguito il progetto in locale e aver verificato il codice usando GitHub Copilot, distribuirlo in una nuova app per le funzioni serverless in Funzioni di Azure che segue le procedure consigliate correnti per distribuzioni sicure e scalabili.

Poiché la nuova app viene eseguita nel piano di consumo Flex, che segue un modello di fatturazione paga ciò che usi, il completamento di questo quickstart comporta un costo ridotto a pochi centesimi di dollaro statunitense o meno nell'account Azure.

Importante

Sebbene creazione di server MCP personalizzati sia supportato per tutti i linguaggi di Funzioni, questo scenario di avvio rapido include attualmente solo esempi per C#, Java, JavaScript, Python e TypeScript. Per completare questa guida introduttiva, selezionare una di queste lingue supportate nella parte superiore dell'articolo.

Questo articolo supporta la versione 4 del modello di programmazione Node.js per Funzioni di Azure.

Questo articolo supporta la versione 2 del modello di programmazione Python per Funzioni di Azure.

Prerequisiti

  • .NET 8.0 SDK

Inizializzare il progetto

Usare il comando azd init per creare un progetto di codice Funzioni di Azure locale da un modello.

  1. In Visual Studio Code aprire una cartella o un'area di lavoro in cui si vuole creare il progetto.
  1. Nel terminale eseguire questo azd init comando:

    azd init --template remote-mcp-functions-dotnet -e mcpserver-dotnet
    

    Questo comando esegue il pull dei file di progetto dal repository template e inizializza il progetto nella cartella corrente. Il flag -e imposta un nome per l'ambiente corrente. In azdl'ambiente mantiene un contesto di distribuzione univoco per l'app ed è possibile definire più di uno. Fa anche parte del nome del gruppo di risorse creato in Azure.

  1. Nel terminale locale o nel prompt dei comandi eseguire questo azd init comando:

    azd init --template remote-mcp-functions-java -e mcpserver-java
    

    Questo comando esegue il pull dei file di progetto dal repository template e inizializza il progetto nella cartella corrente. Il flag -e imposta un nome per l'ambiente corrente. In azdl'ambiente mantiene un contesto di distribuzione univoco per l'app ed è possibile definire più di uno. Fa anche parte dei nomi delle risorse che crei in Azure.

  1. Nel terminale locale o nel prompt dei comandi eseguire questo azd init comando:

    azd init --template remote-mcp-functions-javascript -e mcpserver-js
    

    Questo comando esegue il pull dei file di progetto dal repository template e inizializza il progetto nella cartella corrente. Il flag -e imposta un nome per l'ambiente corrente. In azdl'ambiente mantiene un contesto di distribuzione univoco per l'app ed è possibile definire più di uno. Fa anche parte dei nomi delle risorse che crei in Azure.

  1. Nel terminale locale o nel prompt dei comandi eseguire questo azd init comando:

    azd init --template remote-mcp-functions-typescript -e mcpserver-ts
    

    Questo comando esegue il pull dei file di progetto dal repository template e inizializza il progetto nella cartella corrente. Il flag -e imposta un nome per l'ambiente corrente. In azdl'ambiente mantiene un contesto di distribuzione univoco per l'app ed è possibile definire più di uno. Fa anche parte dei nomi delle risorse che crei in Azure.

  1. Nel terminale locale o nel prompt dei comandi eseguire questo azd init comando:

    azd init --template remote-mcp-functions-python -e mcpserver-python
    

    Questo comando esegue il pull dei file di progetto dal repository template e inizializza il progetto nella cartella corrente. Il flag -e imposta un nome per l'ambiente corrente. In azdl'ambiente mantiene un contesto di distribuzione univoco per l'app ed è possibile definire più di uno. Fa anche parte dei nomi delle risorse che crei in Azure.

Avviare l'emulatore di archiviazione

Usare l'emulatore Azurite per simulare una connessione dell'account Archiviazione di Azure durante l'esecuzione del progetto di codice in locale.

  1. Se non è già stato fatto, installare Azurite.

  2. Premere F1. Nel riquadro comandi cercare ed eseguire il comando Azurite: Start per avviare l'emulatore di archiviazione locale.

Eseguire il server MCP in locale

In una finestra del terminale passare alla cartella del FunctionsMcpTool progetto:

cd src/FunctionsMcpTool

In una finestra del terminale passare alla cartella del FunctionsMcpTool progetto:

cd samples/FunctionsMcpTool

Visual Studio Code si integra con Funzioni di Azure Core tools per consentire l'esecuzione di questo progetto nel computer di sviluppo locale. Per avviare l'applicazione delle funzioni in locale, premere F5 o selezionare l'icona Esegui e correggi errori nella barra delle attività a sinistra.

Il pannello Terminale visualizza l'output di Core Tools. L'app viene avviata nel pannello Terminale ed è possibile visualizzare i nomi delle funzioni in esecuzione in locale.

Verificare usando GitHub Copilot

Il modello di progetto include un .vscode/mcp.json file che definisce già un local-mcp-function server che punta all'endpoint MCP locale. Usare questa configurazione per verificare il codice usando GitHub Copilot in Visual Studio Code:

  1. Aprire il .vscode/mcp.json file e selezionare il pulsante Start sopra la local-mcp-function configurazione.

  2. Nella finestra Copilot Chat assicurarsi che sia selezionata l'icona Agent, selezionare l'icona Configurare gli strumenti e verificare che MCP Server:local-mcp-function sia abilitato nella chat.

  3. Esegui questo comando:

    Say Hello
    

    Quando viene richiesto di eseguire lo strumento, selezionare Consenti in questa area di lavoro in modo da non dover continuare a concedere l'autorizzazione. Il prompt viene eseguito e restituisce una risposta Hello World e le informazioni sull'esecuzione della funzione vengono scritte nei log.

  4. Selezionare ora il codice in uno dei file di progetto ed eseguire questa richiesta:

    Save this snippet as snippet1
    

    Copilot archivia il frammento di codice e risponde alla richiesta con informazioni su come recuperare il frammento usando lo strumento getSnippets. Anche in questo caso, è possibile esaminare l'esecuzione della funzione nei log e verificare che la saveSnippets funzione sia stata eseguita.

  5. In Copilot chat, eseguire il seguente prompt:

    Retrieve snippet1 and apply to NewFile
    

    Copilot recupera i frammenti di codice, lo aggiunge a un file denominato NewFile ed esegue qualsiasi altra operazione necessaria per rendere il frammento di codice funzionante nel progetto. I log di Funzioni mostrano che l'endpoint getSnippets è stato chiamato.

  6. Alla fine dei test, premi Ctrl+C per arrestare l'host delle funzioni.

Esaminare il codice (facoltativo)

È possibile esaminare il codice che definisce gli strumenti server MCP:

Il codice della funzione per gli strumenti server MCP viene definito nella src/functions cartella . La registrazione della funzione MCP espone queste funzioni come strumenti del server MCP:

const PROPERTY_TYPE = "string";

// Hello function - responds with hello message
async function mcpToolHello(_toolArguments, context) {
    console.log(_toolArguments);
    // Get name from the tool arguments
    const mcptoolargs = context.triggerMetadata.mcptoolargs;
    const name = mcptoolargs?.name;

    console.info(`Hello ${name}, I am MCP Tool!`);
    
    return `Hello ${name || 'World'}, I am MCP Tool!`;
}

// Register the hello tool
app.mcpTool('hello', {
    toolName: 'hello',
    description: 'Simple hello world MCP Tool that responses with a hello message.',
  const mcptoolargs = context.triggerMetadata.mcptoolargs;

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

// Register the GetSnippet tool
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,
});

È possibile visualizzare il modello di progetto completo nel repository MCP Server Funzioni di Azure JavaScript GitHub.

Il codice della funzione per gli strumenti server MCP viene definito nella src cartella . L'attributo McpToolTrigger espone le funzioni come strumenti del server MCP:

[Function(nameof(SayHello))]
public string SayHello(
    [McpToolTrigger(HelloToolName, HelloToolDescription)] ToolInvocationContext context
)
{
    logger.LogInformation("C# MCP tool trigger function processed a request.");
    return "Hello I am MCP Tool!";
}

public class SnippetsTool(ILogger<SnippetsTool> logger)
{
    private const string BlobPath = "snippets/{mcptoolargs.Name}.json";

    private static BlobServiceClient GetBlobServiceClient() =>
        new(Environment.GetEnvironmentVariable("AzureWebJobsStorage"));

    [Function(nameof(GetSnippet))]
    public Snippet? GetSnippet(
        [McpToolTrigger(GetSnippetToolName, GetSnippetToolDescription)]
            ToolInvocationContext context,
        [McpToolProperty(SnippetNamePropertyName, SnippetNamePropertyDescription, true)]
            string name,
        [BlobInput(BlobPath)] string? snippetContent
    )
    {
        if (snippetContent is null)
        {
            return null;
        }

        return new Snippet { Name = name, Content = snippetContent };
    }

È possibile visualizzare il modello di progetto completo nel repository Funzioni di Azure .NET MCP Server GitHub.

Il codice della funzione per gli strumenti server MCP viene definito nella samples/FunctionsMcpTool/src/main/java/com/function/ cartella . L'annotazione @McpToolTrigger espone le funzioni come strumenti del server MCP:

@FunctionName("HelloWorld")
public String logCustomTriggerInput(
        @McpToolTrigger(
                name = "helloWorld",
                description = "Says hello and logs the messages that are provided.")
        McpToolInvocationContext mcpToolInvocationContext,
        @McpToolProperty(
            name = "messages",
            propertyType = "string",
            description = "The messages to be logged.",
            isRequired = true,
            isArray = true)
        String messages,
        final ExecutionContext functionExecutionContext
) {
@FunctionName("SaveSnippets")
@StorageAccount("AzureWebJobsStorage")
public String saveSnippet(
        @McpToolTrigger(
                name = "saveSnippets",
                description = "Saves a text snippet to your snippets collection.")
        String mcpToolInvocationContext,
        @McpToolProperty(
            name = SNIPPET_NAME_PROPERTY_NAME,
            propertyType = "string",
            description = "The name of the snippet.",
            isRequired = true)
        String snippetName,
        @McpToolProperty(
            name = SNIPPET_PROPERTY_NAME,
            propertyType = "string",
            description = "The content of the snippet.",
            isRequired = true)
        String snippet,
        @BlobOutput(name = "outputBlob", path = BLOB_PATH)
        OutputBinding<String> outputBlob,
        final ExecutionContext functionExecutionContext
) {
    // Log the entire incoming JSON for debugging
    functionExecutionContext.getLogger().info(mcpToolInvocationContext);

    // Log the snippet name and content
    functionExecutionContext.getLogger().info("Saving snippet with name: " + snippetName);
    functionExecutionContext.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.";

È possibile visualizzare il modello di progetto completo nel repository Funzioni di Azure Java MCP Server GitHub.

Il codice della funzione per gli strumenti server MCP viene definito nel src/function_app.py file . Le annotazioni della funzione MCP espongono queste funzioni come strumenti del server MCP:

from hello_tool_with_auth import bp as auth_bp
app.register_blueprint(auth_bp)

# Constants for the Azure Blob Storage container, file, and blob path
_SNIPPET_NAME_PROPERTY_NAME = "snippetname"
_BLOB_PATH = "snippets/{mcptoolargs." + _SNIPPET_NAME_PROPERTY_NAME + "}.json"
    """Hello world."""
    return "Hello I am MCPTool!"


@app.mcp_tool()
@app.mcp_tool_property(arg_name="snippetname", description="The name of the snippet.")
@app.blob_input(arg_name="file", connection="AzureWebJobsStorage", path=_BLOB_PATH)
def get_snippet(file: func.InputStream, snippetname: str) -> str:
    """Retrieve a snippet by name from Azure Blob Storage."""
    snippet_content = file.read().decode("utf-8")
    logging.info(f"Retrieved snippet: {snippet_content}")
    return snippet_content


@app.mcp_tool()

È possibile visualizzare il modello di progetto completo nel repository Funzioni di Azure Python MCP Server GitHub.

Il codice della funzione per gli strumenti server MCP viene definito nella mcp-tools/src cartella . La registrazione della funzione MCP espone queste funzioni come strumenti del server MCP:

// Hello function - responds with hello message
export async function mcpToolHello(_toolArguments: unknown, context: InvocationContext): Promise<string> {
    const mcptoolargs = context.triggerMetadata.mcptoolargs as {
        name?: string;
    };
    const name = mcptoolargs?.name;

    context.log(`Hello ${name}, I am MCP Tool!`);

    return `Hello ${name || 'World'}, I am MCP Tool!`;
}

// Register the hello tool
app.mcpTool('hello', {
    toolName: 'hello',
    description: 'Simple hello world MCP Tool that responds with a hello message.',
    toolProperties: {
        name: arg.string().describe('Required property to identify the caller.').optional()
    },
    handler: mcpToolHello
});
// Register the GetSnippet tool
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,
});

// Register the SaveSnippet tool
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,
});

È possibile visualizzare il modello di progetto completo nel repository MCP Server Funzioni di Azure TypeScript GitHub.

Dopo aver verificato gli strumenti server MCP in locale, è possibile pubblicare il progetto in Azure.

Distribuire su Azure

Questo progetto è configurato per utilizzare azd al fine di distribuire l'applicazione in una nuova funzione su un piano a consumo flessibile in Azure. Il progetto include un set di file Bicep che azd usa per creare una distribuzione sicura in un piano Consumo Flessibile che segue le procedure consigliate.

  1. In Visual Studio Code premere F1 per aprire il riquadro comandi. Cercare ed eseguire il comando Azure Developer CLI (azd): Package, Provision and Deploy (up). Accedere quindi usando l'account Azure.

  2. Quando richiesto, selezionare questi parametri di distribuzione obbligatori:

    Parametro Description
    sottoscrizione Azure Sottoscrizione in cui vengono create le risorse.
    Area geografica di Azure Area di Azure in cui creare il gruppo di risorse che contiene le nuove risorse di Azure. Vengono visualizzate solo le aree che attualmente supportano il piano a consumo Flex.
    vnetEnabled False per ignorare la creazione di risorse di rete virtuale, semplificando la distribuzione.

    Al termine del comando, vengono visualizzati i collegamenti alle risorse create.

Connettersi al server MCP remoto

Il server MCP è ora in esecuzione in Azure. Il modello di progetto include una voce remote-mcp-function in .vscode/mcp.json già configurata per la connessione al server remoto. Poiché l'autorizzazione MCP predefinita è abilitata per impostazione predefinita, Visual Studio Code gestisce automaticamente il flusso di accesso OAuth quando ci si connette.

  1. Ottieni il nome dell'app per le funzioni dalla tua distribuzione eseguendo il comando seguente nel terminale:

    azd env get-value AZURE_FUNCTION_NAME
    
  2. In .vscode/mcp.jsonselezionare Avvia sopra la remote-mcp-function configurazione.

  3. Quando richiesto, immettere il nome dell'app per le funzioni del passaggio precedente.

  4. Visual Studio Code chiede di accedere con Microsoft Entra. Seguire le istruzioni di autenticazione per autorizzare l'accesso al server MCP remoto.

Verificare la distribuzione

È ora possibile avere GitHub Copilot usare gli strumenti MCP remoti come in locale, ma ora il codice viene eseguito in modo sicuro in Azure. Riprodurre gli stessi comandi usati in precedenza per assicurarsi che tutto funzioni correttamente.

Pulire le risorse

Al termine dell'uso del server MCP e delle risorse correlate, usare questo comando per eliminare l'app per le funzioni e le relative risorse da Azure per evitare di incorrere in ulteriori costi:

azd down 

Passaggi successivi