Delen via


Quickstart: Een aangepaste externe MCP-server bouwen met behulp van Azure Functions

In deze quickstart maakt u een aangepaste MCP-server (Remote Model Context Protocol) op basis van een sjabloonproject met behulp van de Azure Developer CLI (azd). De MCP-server maakt gebruik van de Azure Functions MCP-serverextensie om hulpprogramma's te bieden voor AI-modellen, agents en assistenten. Nadat u het project lokaal hebt uitgevoerd en uw code hebt gecontroleerd met behulp van GitHub Copilot, implementeert u het in een nieuwe serverloze functie-app in Azure Functions die de huidige aanbevolen procedures volgt voor veilige en schaalbare implementaties.

Aanbeveling

Met Functions kunt u ook een bestaand MCP-servercodeproject implementeren in een Flex Consumption-plan-app zonder dat u wijzigingen hoeft aan te brengen in uw codeproject. Zie quickstart: Bestaande MCP-servers hosten in Azure Functions voor meer informatie.

Omdat de nieuwe app wordt uitgevoerd op het Flex Consumption-abonnement, dat volgt op een factureringsmodel voor betalen naar wat u gebruikt, zal het voltooien van deze quickstart resulteren in een kleine kost van een paar dollarcenten of minder op uw Azure-account.

Belangrijk

Hoewel het maken van aangepaste MCP-servers wordt ondersteund voor alle Functions-talen, heeft dit quickstartscenario momenteel alleen voorbeelden voor C#, Python en TypeScript. Als u deze quickstart wilt voltooien, selecteert u een van deze ondersteunde talen bovenaan het artikel.

Dit artikel ondersteunt versie 4 van het Node.js programmeermodel voor Azure Functions.

Dit artikel ondersteunt versie 2 van het Python-programmeermodel voor Azure Functions.

Vereiste voorwaarden

Het project initialiseren

Gebruik de azd init opdracht om een lokaal Azure Functions-codeproject te maken op basis van een sjabloon.

  1. Open in Visual Studio Code een map of werkruimte waar u uw project wilt maken.
  1. Voer in terminal de volgende azd init opdracht uit:

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

    Met deze opdracht worden de projectbestanden opgehaald uit de sjabloonopslagplaats en wordt het project in de huidige map geïnitialiseerd. Met -e de vlag wordt een naam ingesteld voor de huidige omgeving. In azdde omgeving wordt een unieke implementatiecontext voor uw app onderhouden en kunt u meer dan één definiëren. Deze wordt ook gebruikt in de naam van de resourcegroep die u in Azure maakt.

  1. Voer deze azd init opdracht uit in uw lokale terminal of opdrachtprompt:

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

    Met deze opdracht worden de projectbestanden opgehaald uit de sjabloonopslagplaats en wordt het project in de huidige map geïnitialiseerd. Met -e de vlag wordt een naam ingesteld voor de huidige omgeving. In azdde omgeving wordt een unieke implementatiecontext voor uw app onderhouden en kunt u meer dan één definiëren. Deze wordt ook gebruikt in de namen van de resources die u in Azure maakt.

  1. Voer deze azd init opdracht uit in uw lokale terminal of opdrachtprompt:

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

    Met deze opdracht worden de projectbestanden opgehaald uit de sjabloonopslagplaats en wordt het project in de huidige map geïnitialiseerd. Met -e de vlag wordt een naam ingesteld voor de huidige omgeving. In azdde omgeving wordt een unieke implementatiecontext voor uw app onderhouden en kunt u meer dan één definiëren. Deze wordt ook gebruikt in de namen van de resources die u in Azure maakt.

  1. Voer deze azd init opdracht uit in uw lokale terminal of opdrachtprompt:

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

    Met deze opdracht worden de projectbestanden opgehaald uit de sjabloonopslagplaats en wordt het project in de huidige map geïnitialiseerd. Met -e de vlag wordt een naam ingesteld voor de huidige omgeving. In azdde omgeving wordt een unieke implementatiecontext voor uw app onderhouden en kunt u meer dan één definiëren. Deze wordt ook gebruikt in de namen van de resources die u in Azure maakt.

De opslagemulator starten

Gebruik de Azurite-emulator om een Azure Storage-accountverbinding te simuleren bij het lokaal uitvoeren van uw codeproject.

  1. Als u dat nog niet hebt gedaan, installeert u Azurite.

  2. Druk op F1. Zoek en voer in het opdrachtenpalet de opdracht Azurite: Start uit om de lokale opslagemulator te starten.

Uw MCP-server lokaal uitvoeren

Visual Studio Code kan worden geïntegreerd met Azure Functions Core-hulpprogramma's , zodat u dit project kunt uitvoeren op uw lokale ontwikkelcomputer met behulp van de Emulator Van Azurite.

  1. Als u de functie lokaal wilt starten, drukt u op F5 of het pictogram Uitvoeren en foutopsporing in de activiteitenbalk aan de linkerkant. In het terminalvenster wordt de uitvoer van Core Tools weergegeven. Uw app wordt gestart in het terminalvenster en u kunt de naam zien van de functies die lokaal worden uitgevoerd.

  2. Noteer het lokale MCP-servereindpunt (zoals http://localhost:7071/runtime/webhooks/mcp), dat u gebruikt om GitHub Copilot te configureren in Visual Studio Code.

Verifiëren met GitHub Copilot

Als u uw code wilt controleren, voegt u het actieve project toe als een MCP-server voor GitHub Copilot in Visual Studio Code:

  1. Druk op F1. Zoek en voer MCP uit in het opdrachtenpalet : Server toevoegen.

  2. Kies HTTP (Server-Sent Events) voor het transporttype.

  3. Voer de URL in van het MCP-eindpunt dat u in de vorige stap hebt gekopieerd.

  4. Gebruik de gegenereerde server-id en selecteer Werkruimte om de MCP-serververbinding op te slaan met uw werkruimte-instellingen.

  5. Open het opdrachtenpalet en voer MCP uit: Lijstservers en controleer of de server die u hebt toegevoegd, wordt vermeld en uitgevoerd.

  6. Selecteer in Copilot-chat de agentmodus en voer deze prompt uit:

    Say Hello
    

    Wanneer u wordt gevraagd om het hulpprogramma uit te voeren, selecteert u Toestaan in deze werkruimte zodat u niet steeds opnieuw toestemming hoeft te geven. De prompt wordt uitgevoerd en retourneert een Hello World-antwoord, en informatie over de uitvoering van de functie wordt naar de logboeken geschreven.

  7. Selecteer nu wat code in een van uw projectbestanden en voer deze prompt uit:

    Save this snippet as snippet1
    

    Copilot slaat het fragment op en reageert op uw aanvraag met informatie over het ophalen van het fragment met behulp van het getSnippets hulpprogramma. Nogmaals, u kunt de uitvoering van de functie in de logboeken controleren en controleren of de saveSnippets functie is uitgevoerd.

  8. Voer in Copilot-chat deze prompt uit:

    Retrieve snippet1 and apply to NewFile
    

    Copilot haalt de fragmenten op, voegt het toe aan een bestand met de naam NewFileen doet wat het ook nodig vindt om het codefragment in uw project te laten werken. In de Functions-logboeken ziet u dat het getSnippets eindpunt is aangeroepen.

  9. Wanneer u klaar bent met testen, drukt u op Ctrl+C om de Functions-host te stoppen.

De code bekijken (optioneel)

U kunt de code controleren waarmee de MCP-serverhulpprogramma's worden gedefinieerd:

De functiecode voor de MCP-serverhulpprogramma's wordt gedefinieerd in de src map. Het McpToolTrigger kenmerk maakt de functies beschikbaar als MCP Server-hulpprogramma's:

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

U kunt de volledige projectsjabloon bekijken in de GitHub-opslagplaats van Azure Functions .NET MCP Server .

De functiecode voor de MCP-serverhulpprogramma's wordt gedefinieerd in de src/main/java/com/function/ map. De @McpToolTrigger aantekening maakt de functies beschikbaar als MCP Server-hulpprogramma's:

            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

U kunt de volledige projectsjabloon bekijken in de GitHub-opslagplaats van Azure Functions Java MCP Server .

De functiecode voor de MCP-serverhulpprogramma's wordt gedefinieerd in het src/function_app.py bestand. De annotaties van de MCP-functie maken deze functies beschikbaar als hulpprogramma's van de MCP-server.

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"

U kunt de volledige projectsjabloon weergeven in de GitHub-opslagplaats van Azure Functions Python MCP Server .

De functiecode voor de MCP-serverhulpprogramma's wordt gedefinieerd in de src map. De registratie van de MCP-functie maakt deze functies beschikbaar als hulpmiddelen voor MCP Server:

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

U kunt de volledige projectsjabloon bekijken in de GitHub-opslagplaats van Azure Functions TypeScript MCP Server .

Nadat u de MCP-serverhulpprogramma's lokaal hebt gecontroleerd, kunt u het project publiceren naar Azure.

Implementeren in Azure

Dit project is geconfigureerd om de azd up opdracht te gebruiken om dit project te implementeren in een nieuwe functie-app in een Flex Consumption-abonnement in Azure. Het project bevat een set Bicep-bestanden die azd wordt gebruikt om een veilige implementatie te maken voor een Flex-verbruiksplan dat de aanbevolen procedures volgt.

  1. Druk in Visual Studio Code op F1 om het opdrachtenpalet te openen. Zoek en voer de opdracht Azure Developer CLI (azd): Package, Provison and Deploy (up)uit. Meld u vervolgens aan met uw Azure-account.

  2. Als u nog niet bent aangemeld, moet u zich verifiëren met uw Azure-account.

  3. Geef de volgende vereiste implementatieparameters op wanneer u hierom wordt gevraagd:

    Kenmerk Description
    Azure-abonnement Abonnement waarin uw resources worden gemaakt.
    Azure-locatie Azure-regio waarin de resourcegroep wordt gemaakt die de nieuwe Azure-resources bevat. Alleen regio's die momenteel ondersteuning bieden voor het Flex Consumption-abonnement, worden weergegeven.

    Nadat de opdracht is voltooid, ziet u koppelingen naar de resources die u hebt gemaakt.

Verbinding maken met uw externe MCP-server

Uw MCP-server wordt nu uitgevoerd in Azure. Wanneer u toegang hebt tot de hulpprogramma's, moet u een systeemsleutel in uw aanvraag opnemen. Deze sleutel biedt een mate van toegangsbeheer voor clients die toegang hebben tot uw externe MCP-server. Nadat u deze sleutel hebt gemaakt, kunt u GitHub Copilot verbinden met uw externe server.

  1. Voer dit script uit dat gebruikmaakt van azd Azure CLI om zowel de URL van de MCP-server als de systeemsleutel (mcp_extension) af te drukken die nodig is voor toegang tot de hulpprogramma's:

    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. Druk in Visual Studio Code op F1 om het opdrachtenpalet te openen, de opdracht MCP: Open Workspace Folder MCP Configuratonte zoeken en uit te voeren, waarmee het mcp.json configuratiebestand wordt geopend.

  3. Zoek in de mcp.json configuratie de benoemde MCP-server die u eerder hebt toegevoegd, wijzig de waarde in de url URL van uw externe MCP-server en voeg een headers.x-functions-key element toe, dat de gekopieerde MCP-servertoegangssleutel bevat, zoals in dit voorbeeld:

    {
        "servers": {
            "remote-mcp-function": {
                "type": "http",
                "url": "https://contoso.azurewebsites.net/runtime/webhooks/mcp",
                "headers": {
                    "x-functions-key": "A1bC2dE3fH4iJ5kL6mN7oP8qR9sT0u..."
                }
            }
        }
    }
    
  4. Selecteer de knop Start boven de servernaam in het geopende mcp.json bestand om de externe MCP-server opnieuw op te starten, deze keer met behulp van uw geïmplementeerde app.

Uw implementatie controleren

U kunt nu GitHub Copilot gebruiken voor uw externe MCP-hulpprogramma's, net zoals u lokaal hebt gedaan, maar nu wordt de code veilig uitgevoerd in Azure. Dezelfde opdrachten die u eerder hebt gebruikt, opnieuw afspelen om ervoor te zorgen dat alles correct werkt.

De hulpbronnen opschonen

Wanneer u klaar bent met het werken met uw MCP-server en gerelateerde resources, gebruikt u deze opdracht om de functie-app en de bijbehorende resources uit Azure te verwijderen om verdere kosten te voorkomen:

azd down --no-prompt

Opmerking

De --no-prompt optie geeft azd aan om uw resourcegroep zonder bevestiging van u te verwijderen. Deze opdracht heeft geen invloed op uw lokale codeproject.

Volgende stappen