Teilen über


Schnellstart: Hostserver, die mit MCP-SDKs auf Azure-Funktionen erstellt wurden

In dieser Schnellstartanleitung erfahren Sie, wie Sie auf McP-Servern (Azure Functions Model Context Protocol) hosten, die Sie mit offiziellen MCP-SDKs erstellen. Mit dem Hosting des Flex Consumption Plans können Sie die serverlose Skalierung von Azure Functions, das Nutzungsabhängige Abrechnungsmodell und die integrierten Sicherheitsfunktionen nutzen. Es ist perfekt für MCP-Server, die den streambaren HTTP-Transport verwenden.

In diesem Artikel wird ein MCP-Beispielserverprojekt verwendet, das mit offiziellen MCP-SDKs erstellt wurde.

Tipp

Funktionen bieten auch eine MCP-Erweiterung, mit der Sie MCP-Server mithilfe des Azure Functions-Programmiermodells erstellen können. Weitere Informationen finden Sie in der Schnellstartanleitung: Erstellen eines benutzerdefinierten MCP-Remoteservers mit Azure Functions.

Da der neue Server in einem Flex-Verbrauchsplan ausgeführt wird, der einem nutzungsgerechten Abrechnungsmodell folgt, entstehen beim Abschluss dieser Schnellstartanleitung geringe Kosten von ein paar Cent oder weniger in Ihrem Azure-Konto.

Von Bedeutung

Während das Hosten Ihrer MCP-Server mit benutzerdefinierten Handlern für alle Sprachen unterstützt wird, enthält dieses Schnellstartszenario derzeit nur Beispiele für C#, Python und TypeScript. Um diese Schnellstartanleitung abzuschließen, wählen Sie oben im Artikel eine dieser unterstützten Sprachen aus.

Voraussetzungen

Hinweis

Dieses Beispiel erfordert, dass Sie über die Berechtigung zum Erstellen einer Microsoft Entra-App im azure-Abonnement verfügen, das Sie verwenden.

Erste Schritte mit einem Beispielprojekt

Am einfachsten können Sie beginnen, ein MCP-Serverbeispielprojekt zu klonen, das mit offiziellen MCP-SDKs erstellt wurde:

  1. Öffnen Sie in Visual Studio Code einen Ordner oder Arbeitsbereich, in dem Sie Ihr Projekt erstellen möchten.
  1. Führen Sie im Terminal diesen Befehl aus, um das .NET-Beispiel zu initialisieren:

    azd init --template mcp-sdk-functions-hosting-dotnet -e mcpsdkserver-dotnet
    

    Mit diesem Befehl werden die Projektdateien aus dem Vorlagen-Repository abgerufen und das Projekt im aktuellen Ordner initialisiert. Das -e-Flag legt einen Namen für die aktuelle Umgebung fest. In azdder Umgebung wird ein eindeutiger Bereitstellungskontext für Ihre App verwaltet, und Sie können mehrere definieren. Sie wird auch in Namen der Ressourcen verwendet, die Sie in Azure erstellen.

  1. Führen Sie im Terminal diesen Befehl aus, um das TypeScript-Beispiel zu initialisieren:

    azd init --template mcp-sdk-functions-hosting-node  -e mcpsdkserver-node
    

    Mit diesem Befehl werden die Projektdateien aus dem Vorlagen-Repository abgerufen und das Projekt im aktuellen Ordner initialisiert. Das -e-Flag legt einen Namen für die aktuelle Umgebung fest. In azdder Umgebung wird ein eindeutiger Bereitstellungskontext für Ihre App verwaltet, und Sie können mehrere definieren. Sie wird auch in Namen der Ressourcen verwendet, die Sie in Azure erstellen.

  1. Führen Sie im Terminal diesen Befehl aus, um das Python-Beispiel zu initialisieren:

    azd init --template mcp-sdk-functions-hosting-python -e mcpsdkserver-python
    

    Mit diesem Befehl werden die Projektdateien aus dem Vorlagen-Repository abgerufen und das Projekt im aktuellen Ordner initialisiert. Das -e-Flag legt einen Namen für die aktuelle Umgebung fest. In azdder Umgebung wird ein eindeutiger Bereitstellungskontext für Ihre App verwaltet, und Sie können mehrere definieren. Sie wird auch in Namen der Ressourcen verwendet, die Sie in Azure erstellen.

Die Codeprojektvorlage ist für einen MCP-Server mit Tools, die auf öffentliche Wetter-APIs zugreifen.

Lokales Ausführen des MCP-Servers

Visual Studio Code ist in Azure Functions Core Tools integriert, damit Sie dieses Projekt auf Ihrem lokalen Entwicklungscomputer ausführen können.

  1. Öffnen von Terminal im Editor (Ctrl+Shift+` )
  1. Führen Sie im Stammverzeichnis func start aus, um den Server zu starten. Im Terminalbereich wird die Ausgabe aus den Core Tools angezeigt.
  1. Führen Sie im Stammverzeichnis npm install aus, um Abhängigkeiten zu installieren, und führen Sie anschließend npm run build aus.
  2. Führen Sie zum Starten des Servers die Ausführung aus func start.
  1. Führen Sie im Stammverzeichnis die Ausführung uv run func start aus, um eine virtuelle Umgebung zu erstellen, Abhängigkeiten zu installieren und den Server zu starten.

Testen des Servers mithilfe von GitHub Copilot

Führen Sie die folgenden Schritte aus, um Ihren Server mithilfe von GitHub Copilot in Visual Studio Code zu überprüfen:

  1. Öffnen Sie die Datei mcp.json im Verzeichnis .vscode.

  2. Starten Sie den Server, indem Sie oberhalb der Konfiguration die Schaltfläche local-mcp-server" auswählen.

  3. Stellen Sie im Fenster " Copilot-Chat " sicher, dass das Agent-Modell ausgewählt ist, wählen Sie das Symbol "Tools konfigurieren " aus, und stellen Sie sicher, dass MCP Server:local-mcp-server sie im Chat aktiviert ist.

  4. Führen Sie diese Eingabeaufforderung im Chat aus:

    Return the weather forecast for New York City using #local-mcp-server
    

    Copilot sollte eines der Wettertools aufrufen, um diese Frage zu beantworten. Wenn Sie zum Ausführen des Tools aufgefordert werden, wählen Sie "In diesem Arbeitsbereich zulassen " aus, damit Sie diese Berechtigung nicht mehr zulassen müssen.

Nachdem Sie die Toolfunktionalität lokal überprüft haben, können Sie den Server beenden und den Projektcode in Azure bereitstellen.

In Azure bereitstellen

Dieses Projekt ist so konfiguriert, dass der azd up-Befehl verwendet wird, um dieses Projekt in einer neuen Funktions-App in einem Flex-Verbrauchsplan in Azure bereitzustellen. Das Projekt enthält eine Reihe von Bicep-Dateien, die azd verwendet, um eine sichere Bereitstellung zu erstellen, die bewährten Methoden entspricht.

  1. Melden Sie sich bei Azure an:

    azd login
    
  2. Konfigurieren von Visual Studio Code als vorautorisierte Clientanwendung:

    azd env set PRE_AUTHORIZED_CLIENT_IDS aebc6443-996d-45c2-90f0-388ff96faa56
    

    Eine vorautorisierte Anwendung kann sich bei Ihrem MCP-Server authentifizieren und darauf zugreifen, ohne dass weitere Zustimmungsaufforderungen erforderlich sind.

  3. Drücken Sie in Visual Studio Code F1, um die Befehlspalette zu öffnen. Suchen und ausführen Sie den Befehl Azure Developer CLI (azd): Package, Provision and Deploy (up). Melden Sie sich dann mit Ihrem Azure-Konto an.

  4. Wenn Sie dazu aufgefordert werden, stellen Sie die folgenden erforderlichen Bereitstellungsparameter bereit:

    Parameter Description
    Azure-Abonnement Das Abonnement, in dem Ihre Ressourcen erstellt werden.
    Azure-Standort Die Azure-Region, in der die Ressourcengruppe erstellt werden soll, die die neuen Azure-Ressourcen enthält. Es werden nur Regionen angezeigt, die den Flex-Verbrauchsplan derzeit unterstützen.

    Nachdem der Befehl erfolgreich abgeschlossen wurde, werden Links zu den ressourcen angezeigt, die Sie erstellt haben, und den Endpunkt für ihren bereitgestellten MCP-Server. Notieren Sie sich ihren Funktions-App-Namen, den Sie für den nächsten Abschnitt benötigen.

    Tipp

    Wenn beim Ausführen des azd up Befehls ein Fehler auftritt, führen Sie einfach den Befehl erneut aus. Sie können azd up wiederholt ausführen, da dabei das Erstellen von Ressourcen übersprungen wird, die bereits vorhanden sind. Sie können azd up auch erneut anrufen, wenn Sie Updates für Ihren Dienst bereitstellen.

Herstellen einer Verbindung mit dem Remote-MCP-Server

Ihr MCP-Server wird jetzt in Azure ausgeführt. Um GitHub Copilot mit Ihrem Remoteserver zu verbinden, konfigurieren Sie ihn in Ihren Arbeitsbereichseinstellungen.

  1. Wechseln Sie in der mcp.json Datei zu dem Remoteserver, indem Sie "Beenden " für die local-mcp-server Konfiguration und " Starten " für die remote-mcp-server Konfiguration auswählen.

  2. Wenn Sie zur Domäne der Funktions-App aufgefordert werden, geben Sie den Namen Ihrer Funktions-App ein, die Sie im vorherigen Abschnitt angegeben haben. Wenn Sie aufgefordert werden, sich bei Microsoft zu authentifizieren, wählen Sie "Zulassen" und dann Ihr Azure-Konto aus.

  3. Überprüfen Sie den Remoteserver, indem Sie eine Frage wie folgt stellen:

    Return the weather forecast for Seattle using #remote-mcp-server.
    

    Copilot ruft eines der Wettertools auf, um die Abfrage zu beantworten.

Tipp

Sie können die Ausgabe eines Servers anzeigen, indem Sie "Weitere" auswählen...>Ausgabe anzeigen. Die Ausgabe enthält nützliche Informationen zu möglichen Verbindungsfehlern. Sie können auch das Zahnradsymbol auswählen, um die Protokollebenen in Ablaufverfolgungen zu ändern und so weitere Details zu den Interaktionen zwischen dem Client (Visual Studio Code) und dem Server zu erhalten.

Überprüfen des Codes (optional)

Sie können den Code überprüfen, der den MCP-Server definiert:

Der MCP-Servercode wird im Projektstamm definiert. Der Server verwendet das offizielle C#MCP SDK, um diese wetterbezogenen Tools zu definieren:

using ModelContextProtocol;
using ModelContextProtocol.Server;
using System.ComponentModel;
using System.Globalization;
using System.Text.Json;

namespace QuickstartWeatherServer.Tools;

[McpServerToolType]
public sealed class WeatherTools
{
    [McpServerTool, Description("Get weather alerts for a US state.")]
    public static async Task<string> GetAlerts(
        HttpClient client,
        [Description("The US state to get alerts for. Use the 2 letter abbreviation for the state (e.g. NY).")] string state)
    {
        using var jsonDocument = await client.ReadJsonDocumentAsync($"/alerts/active/area/{state}");
        var jsonElement = jsonDocument.RootElement;
        var alerts = jsonElement.GetProperty("features").EnumerateArray();

        if (!alerts.Any())
        {
            return "No active alerts for this state.";
        }

        return string.Join("\n--\n", alerts.Select(alert =>
        {
            JsonElement properties = alert.GetProperty("properties");
            return $"""
                    Event: {properties.GetProperty("event").GetString()}
                    Area: {properties.GetProperty("areaDesc").GetString()}
                    Severity: {properties.GetProperty("severity").GetString()}
                    Description: {properties.GetProperty("description").GetString()}
                    Instruction: {properties.GetProperty("instruction").GetString()}
                    """;
        }));
    }

    [McpServerTool, Description("Get weather forecast for a location.")]
    public static async Task<string> GetForecast(
        HttpClient client,
        [Description("Latitude of the location.")] double latitude,
        [Description("Longitude of the location.")] double longitude)
    {
        var pointUrl = string.Create(CultureInfo.InvariantCulture, $"/points/{latitude},{longitude}");
        using var jsonDocument = await client.ReadJsonDocumentAsync(pointUrl);
        var forecastUrl = jsonDocument.RootElement.GetProperty("properties").GetProperty("forecast").GetString()
            ?? throw new Exception($"No forecast URL provided by {client.BaseAddress}points/{latitude},{longitude}");

        using var forecastDocument = await client.ReadJsonDocumentAsync(forecastUrl);
        var periods = forecastDocument.RootElement.GetProperty("properties").GetProperty("periods").EnumerateArray();

        return string.Join("\n---\n", periods.Select(period => $"""
                {period.GetProperty("name").GetString()}
                Temperature: {period.GetProperty("temperature").GetInt32()}°F
                Wind: {period.GetProperty("windSpeed").GetString()} {period.GetProperty("windDirection").GetString()}
                Forecast: {period.GetProperty("detailedForecast").GetString()}
                """));
    }
}

Sie können die vollständige Projektvorlage im GitHub-Repository für das Azure Functions-Hosting des .NET MCP SDK einsehen.

Der MCP-Servercode wird in der server.py Datei definiert. Der Server verwendet das offizielle Python MCP SDK, um wetterbezogene Tools zu definieren. Dies ist die Definition des get_forecast Tools:

import os
import sys
import warnings
import logging
from typing import Any
from pathlib import Path

import httpx
from azure.identity import OnBehalfOfCredential, ManagedIdentityCredential
from mcp.server.fastmcp import FastMCP
from fastmcp.server.dependencies import get_http_request
from starlette.requests import Request
from starlette.responses import HTMLResponse

# Initialize FastMCP server
mcp = FastMCP("weather", stateless_http=True)

# Constants
NWS_API_BASE = "https://api.weather.gov"
USER_AGENT = "weather-app/1.0"
@mcp.tool()
async def get_forecast(latitude: float, longitude: float) -> str:
    """Get weather forecast for a location.

    Args:
        latitude: Latitude of the location
        longitude: Longitude of the location
    """
    # First get the forecast grid endpoint
    points_url = f"{NWS_API_BASE}/points/{latitude},{longitude}"
    points_data = await make_nws_request(points_url)

    if not points_data:
        return "Unable to fetch forecast data for this location."

    # Get the forecast URL from the points response
    forecast_url = points_data["properties"]["forecast"]
    forecast_data = await make_nws_request(forecast_url)

    if not forecast_data:
        return "Unable to fetch detailed forecast."

    # Format the periods into a readable forecast
    periods = forecast_data["properties"]["periods"]
    forecasts = []
    for period in periods[:5]:  # Only show next 5 periods
        forecast = f"""
{period['name']}:
Temperature: {period['temperature']}°{period['temperatureUnit']}
Wind: {period['windSpeed']} {period['windDirection']}
Forecast: {period['detailedForecast']}
"""
        forecasts.append(forecast)

    return "\n---\n".join(forecasts)

Sie können die vollständige Projektvorlage im GitHub-Repository für das Azure Functions-Hosting des Python MCP SDK einsehen.

Der MCP-Servercode wird im src Ordner definiert. Der Server verwendet das offizielle Node.js MCP SDK, um wetterbezogene Tools zu definieren. Dies ist die Definition des get-forecast Tools:

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { z } from "zod";
import { ManagedIdentityCredential, OnBehalfOfCredential } from '@azure/identity';

const NWS_API_BASE = "https://api.weather.gov";
const USER_AGENT = "weather-app/1.0";

// Function to create a new server instance for each request (stateless)
export const createServer = () => {
  const server = new McpServer({
    name: "weather",
    version: "1.0.0",
  });
  server.registerTool(
    "get-forecast",
    {
      title: "Get Weather Forecast",
      description: "Get weather forecast for a location",
      inputSchema: {
        latitude: z.number().min(-90).max(90).describe("Latitude of the location"),
        longitude: z
          .number()
          .min(-180)
          .max(180)
          .describe("Longitude of the location"),
      },
      outputSchema: z.object({
        forecast: z.string(),
      }),
    },
    async ({ latitude, longitude }) => {
      // Get grid point data
      const pointsUrl = `${NWS_API_BASE}/points/${latitude.toFixed(4)},${longitude.toFixed(4)}`;
      const pointsData = await makeNWSRequest<PointsResponse>(pointsUrl);

      if (!pointsData) {
        const output = { forecast: `Failed to retrieve grid point data for coordinates: ${latitude}, ${longitude}. This location may not be supported by the NWS API (only US locations are supported).` };
        return {
          content: [{ type: "text", text: JSON.stringify(output) }],
          structuredContent: output,
        };
      }

      const forecastUrl = pointsData.properties?.forecast;
      if (!forecastUrl) {
        const output = { forecast: "Failed to get forecast URL from grid point data" };
        return {
          content: [{ type: "text", text: JSON.stringify(output) }],
          structuredContent: output,
        };
      }

      // Get forecast data
      const forecastData = await makeNWSRequest<ForecastResponse>(forecastUrl);
      if (!forecastData) {
        const output = { forecast: "Failed to retrieve forecast data" };
        return {
          content: [{ type: "text", text: JSON.stringify(output) }],
          structuredContent: output,
        };
      }

      const periods = forecastData.properties?.periods || [];
      if (periods.length === 0) {
        const output = { forecast: "No forecast periods available" };
        return {
          content: [{ type: "text", text: JSON.stringify(output) }],
          structuredContent: output,
        };
      }

      // Format forecast periods
      const formattedForecast = periods.map((period: ForecastPeriod) =>
        [
          `${period.name || "Unknown"}:`,
          `Temperature: ${period.temperature || "Unknown"}°${period.temperatureUnit || "F"}`,
          `Wind: ${period.windSpeed || "Unknown"} ${period.windDirection || ""}`,
          `${period.shortForecast || "No forecast available"}`,
          "---",
        ].join("\n"),
      );

      const forecastText = `Forecast for ${latitude}, ${longitude}:\n\n${formattedForecast.join("\n")}`;
      const output = { forecast: forecastText };

      return {
        content: [{ type: "text", text: forecastText }],
        structuredContent: output,
      };
    },
  );
  return server;
}

Sie können die vollständige Projektvorlage im GitHub-Repository für das Hosting des Azure Functions TypeScript MCP SDK anzeigen.

Bereinigen von Ressourcen

Wenn Sie mit ihrem MCP-Server und den zugehörigen Ressourcen fertig sind, verwenden Sie diesen Befehl, um die Funktions-App und die zugehörigen Ressourcen aus Azure zu löschen, um weitere Kosten zu vermeiden:

azd down