Sdílet prostřednictvím


Rychlý start: Vytvoření vlastního vzdáleného serveru MCP pomocí Azure Functions

V tomto rychlém startu vytvoříte vlastní vzdálený server MCP (Model Context Protocol) z projektu šablony pomocí Azure Developer CLI (azd). Server MCP používá rozšíření serveru MCP služby Azure Functions k poskytování nástrojů pro modely, agenty a asistenty AI. Po místním spuštění projektu a ověření kódu pomocí GitHub Copilotu ho nasadíte do nové aplikace funkcí bez serveru ve službě Azure Functions, která dodržuje aktuální osvědčené postupy pro zabezpečená a škálovatelná nasazení.

Návod

Funkce také umožňují nasadit existující projekt kódu serveru MCP do aplikace plánu Flex Consumption, aniž byste museli provádět změny projektu kódu. Další informace najdete v tématu Rychlý start: Hostování existujících serverů MCP ve službě Azure Functions.

Vzhledem k tomu, že nová aplikace běží v plánu Flex Consumption, který se řídí fakturačním modelem platíte pouze za to, co využijete, znamená dokončení tohoto rychlého startu malé náklady, několik centů nebo méně USD, na vašem účtu Azure.

Důležité

Vytváření vlastních serverů MCP je podporováno pro všechny jazyky Functions, ale tento scénář rychlého startu v současné době obsahuje příklady pouze pro C#, Python a TypeScript. K dokončení tohoto rychlého startu vyberte jeden z těchto podporovaných jazyků v horní části článku.

Tento článek podporuje verzi 4 programovacího modelu Node.js pro Azure Functions.

Tento článek podporuje verzi 2 programovacího modelu Pythonu pro Azure Functions.

Požadavky

  • Java 17 Developer Kit
    • Pokud používáte jinou podporovanou verzi Javy, musíte aktualizovat soubor pom.xml projektu.
    • Nastavte proměnnou JAVA_HOME prostředí na umístění instalace správné verze sady Java Development Kit (JDK).
  • Apache Maven 3.8.x

Inicializace projektu

azd init Pomocí příkazu vytvořte místní projekt kódu Azure Functions ze šablony.

  1. V editoru Visual Studio Code otevřete složku nebo pracovní prostor, ve kterém chcete vytvořit projekt.
  1. V terminálu spusťte tento azd init příkaz:

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

    Tento příkaz načte soubory projektu z úložiště šablony a inicializuje projekt v aktuální složce. Příznak -e nastaví název aktuálního prostředí. V azdprostředí udržuje jedinečný kontext nasazení pro vaši aplikaci a můžete definovat více než jeden. Používá se také v názvu skupiny prostředků, kterou vytvoříte v Azure.

  1. V místním terminálu nebo příkazovém řádku spusťte tento azd init příkaz:

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

    Tento příkaz načte soubory projektu z úložiště šablony a inicializuje projekt v aktuální složce. Příznak -e nastaví název aktuálního prostředí. V azdprostředí udržuje jedinečný kontext nasazení pro vaši aplikaci a můžete definovat více než jeden. Používá se také v názvech prostředků, které vytvoříte v Azure.

  1. V místním terminálu nebo příkazovém řádku spusťte tento azd init příkaz:

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

    Tento příkaz načte soubory projektu z úložiště šablony a inicializuje projekt v aktuální složce. Příznak -e nastaví název aktuálního prostředí. V azdprostředí udržuje jedinečný kontext nasazení pro vaši aplikaci a můžete definovat více než jeden. Používá se také v názvech prostředků, které vytvoříte v Azure.

  1. V místním terminálu nebo příkazovém řádku spusťte tento azd init příkaz:

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

    Tento příkaz načte soubory projektu z úložiště šablony a inicializuje projekt v aktuální složce. Příznak -e nastaví název aktuálního prostředí. V azdprostředí udržuje jedinečný kontext nasazení pro vaši aplikaci a můžete definovat více než jeden. Používá se také v názvech prostředků, které vytvoříte v Azure.

Spuštění emulátoru úložiště

Emulátor Azurite použijte k simulaci připojení účtu služby Azure Storage při místním spuštění projektu kódu.

  1. Pokud jste to ještě neudělali, nainstalujte Azurite.

  2. Stiskněte klávesu F1. Na paletě příkazů vyhledejte a spusťte příkaz Azurite: Start pro spuštění emulátoru místního úložiště.

Místní spuštění serveru MCP

Visual Studio Code se integruje s nástroji Azure Functions Core, které vám umožní spustit tento projekt na místním vývojovém počítači pomocí emulátoru Azurite.

  1. Pokud chcete funkci spustit místně, stiskněte klávesu F5 nebo ikonu Spustit a ladit na panelu aktivit na levé straně. Na panelu Terminálu se zobrazí výstup nástrojů Core Tools. Aplikace se spustí na panelu Terminálu a zobrazí se název funkcí, které jsou spuštěné místně.

  2. Poznamenejte si místní koncový bod serveru MCP (například http://localhost:7071/runtime/webhooks/mcp), který používáte ke konfiguraci GitHub Copilotu v editoru Visual Studio Code.

Ověření pomocí GitHub Copilotu

Pokud chcete ověřit kód, přidejte spuštěný projekt jako server MCP pro GitHub Copilot v editoru Visual Studio Code:

  1. Stiskněte klávesu F1. Na paletě příkazů vyhledejte a spusťte MCP: Přidat server.

  2. Jako typ přenosu zvolte HTTP (Server-Sent Events).

  3. Zadejte adresu URL koncového bodu MCP, který jste zkopírovali v předchozím kroku.

  4. Použijte vygenerované ID serveru a vyberte Pracovní prostor a uložte připojení serveru MCP k nastavení pracovního prostoru.

  5. Otevřete paletu příkazů a spusťte MCP: Zobrazte servery a ověřte, že je server, který jste přidali, uvedený a spuštěný.

  6. V chatu Copilot vyberte režim agenta a spusťte tuto výzvu:

    Say Hello
    

    Po zobrazení výzvy ke spuštění nástroje vyberte Povolit v tomto pracovním prostoru , abyste nemuseli dál udělovat oprávnění. Výzva se spustí a vrátí Hello World odpověď a informace o spuštění funkce se zapíšou do protokolů.

  7. Teď vyberte kód v jednom ze souborů projektu a spusťte tento příkaz:

    Save this snippet as snippet1
    

    Copilot uloží fragment kódu a odpoví na vaši žádost s informacemi o tom, jak pomocí nástroje načíst fragment kódu getSnippets . Znovu můžete zkontrolovat spuštění funkce v protokolech a ověřit, že se funkce spustila saveSnippets .

  8. V chatu Copilot spusťte tuto výzvu:

    Retrieve snippet1 and apply to NewFile
    

    Copilot načte fragmenty kódu, přidá ho do souboru s názvem NewFilea udělá cokoli jiného, co si myslí, že je potřeba k tomu, aby fragment kódu fungoval ve vašem projektu. Protokoly služby Functions ukazují, že koncový bod getSnippets byl volán.

  9. Až budete hotovi s testováním, stisknutím kombinace kláves Ctrl+C zastavte hostitele functions.

Kontrola kódu (volitelné)

Můžete si projít kód, který definuje nástroje serveru MCP:

Kód funkce pro nástroje serveru MCP je definován ve src složce. Atribut McpToolTrigger zveřejňuje funkce jako nástroje SERVERU MCP:

[Function(nameof(SayHello))]
public string SayHello(
    [McpToolTrigger(HelloToolName, HelloToolDescription)] ToolInvocationContext context
)
{
    logger.LogInformation("Saying hello");
    return "Hello I am MCP Tool!";
}
    [Function(nameof(GetSnippet))]
    public object GetSnippet(
        [McpToolTrigger(GetSnippetToolName, GetSnippetToolDescription)]
            ToolInvocationContext context,
        [BlobInput(BlobPath)] string snippetContent
    )
    {
        return snippetContent;
    }

    [Function(nameof(SaveSnippet))]
    [BlobOutput(BlobPath)]
    public string SaveSnippet(
        [McpToolTrigger(SaveSnippetToolName, SaveSnippetToolDescription)]
            ToolInvocationContext context,
        [McpToolProperty(SnippetNamePropertyName, SnippetNamePropertyDescription, true)]
            string name,
        [McpToolProperty(SnippetPropertyName, SnippetPropertyDescription, true)]
            string snippet
    )
    {
        return snippet;
    }
}

Kompletní šablonu projektu můžete zobrazit v úložišti GitHub serveru Azure Functions .NET MCP .

Kód funkce pro nástroje serveru MCP je definován ve src/main/java/com/function/ složce. Poznámka @McpToolTrigger zveřejňuje funkce jako nástroje SERVERU MCP:

            description = "The messages to be logged.",
            isRequired = true,
            isArray = true)
        String messages,
        final ExecutionContext functionExecutionContext
) {
    functionExecutionContext.getLogger().info("Hello, World!");
    functionExecutionContext.getLogger().info("Tool Name: " + mcpToolInvocationContext.getName());
    functionExecutionContext.getLogger().info("Transport Type: " + mcpToolInvocationContext.getTransportType());
    
    // Handle different transport types
    if (mcpToolInvocationContext.isHttpStreamable()) {
        functionExecutionContext.getLogger().info("Session ID: " + mcpToolInvocationContext.getSessionid());
    } else if (mcpToolInvocationContext.isHttpSse()) {
        if (mcpToolInvocationContext.getClientinfo() != null) {
            functionExecutionContext.getLogger().info("Client: " + 
                mcpToolInvocationContext.getClientinfo().get("name").getAsString() + " v" +
    // Write the snippet content to the output blob
    outputBlob.setValue(snippet);
    
    return "Successfully saved snippet '" + snippetName + "' with " + snippet.length() + " characters.";
}

/**
 * Azure Function that handles retrieving a text snippet from Azure Blob Storage.
 * <p>
 * The function is triggered by an MCP Tool Trigger. The snippet name is provided
 * as an MCP tool property, and the snippet content is read from the blob at the 
 * path derived from the snippet name.
 *
 * @param mcpToolInvocationContext The JSON input from the MCP tool trigger.
 * @param snippetName   The name of the snippet to retrieve, provided as an MCP tool property.
 * @param inputBlob     The Azure Blob input binding that fetches the snippet content.
 * @param functionExecutionContext       The execution context for logging.
 */
@FunctionName("GetSnippets")
@StorageAccount("AzureWebJobsStorage")
public String getSnippet(
        @McpToolTrigger(
            name = "getSnippets",
            description = "Gets a text snippet from your snippets collection.")
        String mcpToolInvocationContext,
        @McpToolProperty(
            name = SNIPPET_NAME_PROPERTY_NAME,
            propertyType = "string",
            description = "The name of the snippet.",
            isRequired = true)
        String snippetName,
        @BlobInput(name = "inputBlob", path = BLOB_PATH)
        String inputBlob,
        final ExecutionContext functionExecutionContext
) {
    // Log the entire incoming JSON for debugging
    functionExecutionContext.getLogger().info(mcpToolInvocationContext);

    // Log the snippet name and the fetched snippet content from the blob

Kompletní šablonu projektu můžete zobrazit v úložišti GitHub serveru Azure Functions Java MCP.

Kód funkce pro nástroje serveru MCP je definován v src/function_app.py souboru. Poznámky k funkcím MCP zpřístupňují tyto funkce jako nástroje serveru MCP:

tool_properties_save_snippets_json = json.dumps([prop.to_dict() for prop in tool_properties_save_snippets_object])
tool_properties_get_snippets_json = json.dumps([prop.to_dict() for prop in tool_properties_get_snippets_object])


@app.generic_trigger(
    arg_name="context",
    type="mcpToolTrigger",
    toolName="hello_mcp",
    description="Hello world.",
    toolProperties="[]",
)
def hello_mcp(context) -> None:
    """

@app.generic_trigger(
    arg_name="context",
    type="mcpToolTrigger",
    toolName="save_snippet",
    description="Save a snippet with a name.",
    toolProperties=tool_properties_save_snippets_json,
)
@app.generic_output_binding(arg_name="file", type="blob", 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"

Kompletní šablonu projektu můžete zobrazit v úložišti GitHub serveru Azure Functions Python MCP.

Kód funkce pro nástroje serveru MCP je definován ve src složce. Registrace funkce MCP zveřejňuje tyto funkce jako nástroje serveru MCP:

export async function mcpToolHello(_toolArguments:unknown, context: InvocationContext): Promise<string> {
    console.log(_toolArguments);
    // Get name from the tool arguments
    const mcptoolargs = context.triggerMetadata.mcptoolargs as {
        name?: string;
    };
    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.',
    toolProperties:{
        name: arg.string().describe('Required property to identify the caller.').optional()
    },
    handler: mcpToolHello
});
// SaveSnippet function - saves a snippet with a name
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;
}

Kompletní šablonu projektu můžete zobrazit v úložišti Azure Functions TypeScript MCP Server GitHub.

Po místním ověření serverových nástrojů MCP můžete projekt publikovat do Azure.

Nasazení do Azure

Tento projekt je nakonfigurovaný tak, aby pomocí azd up příkazu nasadil tento projekt do nové aplikace funkcí v plánu Flex Consumption v Azure. Projekt obsahuje sadu souborů Bicep, které azd používá k vytvoření zabezpečeného nasazení do plánu spotřeby Flex, který dodržuje osvědčené postupy.

  1. V editoru Visual Studio Code stisknutím klávesy F1 otevřete paletu příkazů. Vyhledejte a spusťte příkaz Azure Developer CLI (azd): Package, Provison and Deploy (up). Pak se přihlaste pomocí svého účtu Azure.

  2. Pokud ještě nejste přihlášení, ověřte se pomocí svého účtu Azure.

  3. Po zobrazení výzvy zadejte tyto požadované parametry nasazení:

    Parameter Description
    Předplatné Azure Předplatné, ve kterém se vaše prostředky vytvářejí.
    Umístění Azure Oblast Azure, ve které se má vytvořit skupina prostředků, která obsahuje nové prostředky Azure. Zobrazí se pouze oblasti, které aktuálně podporují plán Flex Consumption.

    Po úspěšném dokončení příkazu se zobrazí odkazy na prostředky, které jste vytvořili.

Připojení ke vzdálenému serveru MCP

Váš server MCP je teď spuštěný v Azure. Když k nástrojům přistupujete, musíte do požadavku zahrnout systémový klíč. Tento klíč poskytuje stupeň řízení přístupu pro klienty, kteří přistupují ke vzdálenému serveru MCP. Po získání tohoto klíče můžete ke vzdálenému serveru připojit GitHub Copilot.

  1. Spusťte tento skript, který používá azd Azure CLI k vytištění adresy URL serveru MCP i systémového klíče (mcp_extension) potřebného pro přístup k nástrojům:

    eval $(azd env get-values --output dotenv)
    MCP_EXTENSION_KEY=$(az functionapp keys list --resource-group $AZURE_RESOURCE_GROUP \
        --name $AZURE_FUNCTION_NAME --query "systemKeys.mcp_extension" -o tsv)
    printf "MCP Server URL: %s\n" "https://$SERVICE_API_NAME.azurewebsites.net/runtime/webhooks/mcp"
    printf "MCP Server key: %s\n" "$MCP_EXTENSION_KEY"
    
  2. V editoru Visual Studio Code stisknutím klávesy F1 otevřete paletu příkazů, vyhledejte a spusťte příkaz MCP: Open Workspace Folder MCP Configuraton, který otevře mcp.json konfigurační soubor.

  3. mcp.json V konfiguraci vyhledejte pojmenovaný server MCP, který jste přidali dříve, změňte url hodnotu na adresu URL vzdáleného serveru MCP a přidejte headers.x-functions-key prvek, který obsahuje zkopírovaný přístupový klíč serveru MCP, jak je znázorněno v tomto příkladu:

    {
        "servers": {
            "remote-mcp-function": {
                "type": "http",
                "url": "https://contoso.azurewebsites.net/runtime/webhooks/mcp",
                "headers": {
                    "x-functions-key": "A1bC2dE3fH4iJ5kL6mN7oP8qR9sT0u..."
                }
            }
        }
    }
    
  4. Výběrem tlačítka Start nad názvem vašeho serveru v otevřeném mcp.json okně restartujte vzdálený server MCP, tentokrát pomocí nasazené aplikace.

Ověřte své nasazení

Nyní můžete nechat GitHub Copilot používat vaše vzdálené nástroje MCP stejně, jako kdyby běžely lokálně, ale nyní kód běží bezpečně v Azure. Přehrajte stejné příkazy, které jste použili dříve, abyste měli jistotu, že všechno funguje správně.

Vyčistěte zdroje

Po dokončení práce se serverem MCP a souvisejícími prostředky pomocí tohoto příkazu odstraňte aplikaci funkcí a související prostředky z Azure, abyste se vyhnuli dalším nákladům:

azd down --no-prompt

Poznámka:

Tato --no-prompt možnost dává azd pokyn k odstranění skupiny prostředků bez vašeho potvrzení. Tento příkaz nemá vliv na místní projekt kódu.

Další kroky