Funktionsweise
Endpunkt
| Function | Mcp (DataBridge/Functions/McpApi.cs) |
| Route | POST /api/mcp (JSON-RPC-Austausch); GET /api/mcp liefert bewusst 405 — siehe Bekannte Einschränkung |
| Auth-Level | Function (Function Key als ?code=-Query-Parameter) |
| Protokoll | MCP über Streamable HTTP, stateless — jede POST-Anfrage ist ein eigenständiger JSON-RPC-Austausch, es gibt keine langlebige Server-Session |
Der Server ist damit direkt an einer laufenden Function App (lokal oder in Azure) ansprechbar, ohne eigenen Prozess oder zusätzliche Infrastruktur. Da die Authentifizierung über den normalen Azure-Functions-Mechanismus läuft (Function Key), lässt sich der Server ohne zusätzliche Identity-Provider-Konfiguration einrichten — der Key kann als Query-Parameter oder als Header übergeben werden, je nachdem, was der jeweilige Client unterstützt (siehe Nutzung).
Interner Aufbau
Der Mcp-Function-Trigger baut pro HTTP-Anfrage einen eigenen
StreamableHttpServerTransport auf und
delegiert die eigentliche Tool-Logik an den IMcpToolService (DataBridge.Core/Services/Mcp/),
der wiederum dieselben Service-Interfaces (IJobService, IMappingService,
IServiceBusService, IConnectionService) aufruft wie die klassischen HTTP-Funktionen — es gibt
keine internen Selbstaufrufe zwischen den Functions. McpApi.cs bleibt dadurch auf die reine
Protokoll-Anbindung beschränkt (Tool-Registrierung, Transport), analog zum dünnen Zuschnitt von
JobApi/MappingApi. Die eigentliche Tool-Logik (Init-Guard, Job-/Mapping-Lesezugriff,
Service-Bus-Delegation, Connector-Auflösung) liegt in IMcpToolService, testbar unabhängig vom
Protokoll-Layer. Details zur Service-Schicht: Architektur.
Die [Description]-Attribute und Standardwerte für die Tool-Parameter liegen bewusst auf den
Methoden von IMcpToolService selbst (reines System.ComponentModel, keine Abhängigkeit von
ModelContextProtocol in DataBridge.Core) — McpApi.cs bindet die Tools direkt auf diese
Service-Methoden, ohne zusätzliche Wrapper-Methoden.
Bekannte Einschränkung: GET auf /api/mcp
Manche MCP-Clients (typischerweise Remote-Clients, die den Endpunkt über eine echte
Azure-Deployment-URL statt lokal ansprechen) versuchen nach dem initialize-POST zusätzlich
einen GET auf denselben Endpunkt, um einen optionalen Server-zu-Client-SSE-Stream zu öffnen
(Teil der Streamable-HTTP-Spezifikation).
Da dieser Server stateless ist (keine Session, kein Server-Push), unterstützt er diesen
Stream bewusst nicht. Die Route ist deshalb zusätzlich zum POST-Handler mit einem eigenen
GET-Handler registriert, der spezifikationskonform mit 405 Method Not Allowed (statt einem
nicht aussagekräftigen, von Azure Functions automatisch erzeugten 404) antwortet:
[Function("McpGet")]
public IActionResult HandleMcpGetRequest(
[HttpTrigger(AuthorizationLevel.Function, "get", Route = "mcp")] HttpRequest req)
{
req.HttpContext.Response.Headers.Append("Allow", "POST");
return new StatusCodeResult(StatusCodes.Status405MethodNotAllowed);
}
Manche Clients interpretieren 405 als „kein SSE-Support, aber Server ist erreichbar" und
fallen automatisch auf reines POST zurück; ein 404 liest sich dagegen wie „Endpunkt existiert
nicht" und lässt die Verbindung fehlschlagen. Ohne diesen Handler tritt das Problem nur bei
Remote-/Azure-Deployments zuverlässig auf — lokal (Claude Code über .mcp.json) sendet der
Client i. d. R. keinen GET-Probe-Request, daher blieb es dort unbemerkt.