Hinweis
Dies ist ein sich entwickelndes Feature. Siehe Problem Nr. 36 zur laufenden Diskussion.
Was ist MCP?
Model Context Protocol (MCP) ist ein offener Standard zum Verbinden von KI-Assistenten mit externen Tools und Datenquellen. MCP-Server können:
- Ausführen von Code oder Skripts
- Abfragedatenbanken
- Auf Dateisysteme zugreifen
- Aufrufen externer APIs
- Und vieles mehr
Servertypen
Das SDK unterstützt zwei Arten von MCP-Servern:
| Typ | Description | Anwendungsfall |
|---|---|---|
| Local/Stdio | Wird als Teilprozess ausgeführt, kommuniziert über stdin/stdout | Lokale Tools, Dateizugriff, benutzerdefinierte Skripts |
| HTTP/SSE | Remoteserver, auf den über HTTP zugegriffen wird | Gemeinsame Dienste, in der Cloud gehostete Tools |
Configuration
Überprüfen der Konfiguration und des Lebenszyklus
session.rpc.mcp.listConfigured() ist ein parameterloser, passiver Bestandslesevorgang.
Es startet oder startet Server nicht neu, authentifiziert nicht, wendet die Sandbox-Richtlinie nicht an und wartet nicht auf den Serverstart. Die Konfigurationsermittlung und Richtlinienfilterung bestimmen, welche Server angezeigt werden und welche enabled-Werte sie haben.
Für diesen experimentellen RPC ist eine aufeinander abgestimmte SDK-/Runtime-Version erforderlich. Die frühere Vorabantwort erlaubte, dass live weggelassen wird; SDKs, die den erforderlichen Lebenszyklusvertrag verwenden, unterstützen dieses ältere Antwort-Shape nicht. Wenn Sie eine externe Laufzeit bereitstellen, aktualisieren Sie sie zusammen mit dem SDK. Die Gesamtprotokollversion ist unverändert und identifiziert diese experimentelle Vertragsrevision nicht.
Jeder Eintrag enthält live.status. Ein konfigurierter Server ohne materialisierte Laufzeitserver meldet den vorhandenen not_configured-Status, auch wenn enabled``true ist. Ein Laufzeitserver, der explizit gestoppt wurde, meldet stopped. Materialisierte Server melden ihren tatsächlichen Lebenszyklus, einschließlich pending, connected, needs-auth und failed; Fehler umfassen live.error, wenn verfügbar.
Konfiguration und Lebenszyklus beschreiben unterschiedliche Aspekte. Wenn sich die URL, Authentifizierung oder Konfigurationsquelle eines Servers ändert, während eine alte Verbindung aktiv bleibt, meldet der Bestand weiterhin den tatsächlichen Lebenszyklus der Verbindung. Ein Status bedeutet nicht, dass die neueste Konfiguration angewendet wurde. Die Laufzeit ist für diese Beobachtung maßgeblich; Clients dürfen den zwischengespeicherten Zustand nicht basierend auf dem Servernamen ersetzen.
Inventory wiederholt das gleichzeitige Ersetzen von Graphen eine begrenzte Anzahl von Malen und gibt einen Fehler zurück, wenn keine konsistente Momentaufnahme erhalten werden kann.
live wird nie weggelassen, um eine Racebedingung in einem Graphen zu verbergen.
Ein reines startServer oder restartServer mit Namensangabe löst nur den angeforderten Server auf und initialisiert ihn, nachdem eine kalte Sitzung fortgesetzt wurde, ohne zuvor list aufzurufen.
Dies umfasst Benutzer- und Plug-In-Konfigurationen und den über githubMcpToolConfig konfigurierten integrierten GitHub-Server. Es startet keine anderen konfigurierten Server und setzt weder den deaktivierten Zustand noch die Authentifizierungsanforderungen, die Sandbox-Richtlinie oder die Rangfolge von Konfigurationsquellen außer Kraft.
Node.js / TypeScript
import { CopilotClient } from "@github/copilot-sdk";
const client = new CopilotClient();
const session = await client.createSession({
model: "gpt-5",
mcpServers: {
// Local MCP server (stdio)
"my-local-server": {
type: "local",
command: "node",
args: ["./mcp-server.js"],
env: { DEBUG: "true" },
cwd: "./servers",
tools: ["*"], // "*" = all tools, [] = none, or list specific tools
timeout: 30000,
},
// Remote MCP server (HTTP)
"github": {
type: "http",
url: "https://api.githubcopilot.com/mcp/",
headers: { "Authorization": "Bearer ${TOKEN}" },
tools: ["*"],
},
},
});
Python
import asyncio
from copilot import CopilotClient
from copilot.session import PermissionHandler
async def main():
client = CopilotClient()
await client.start()
session = await client.create_session(on_permission_request=PermissionHandler.approve_all, model="gpt-5", mcp_servers={
# Local MCP server (stdio)
"my-local-server": {
"type": "local",
"command": "python",
"args": ["./mcp_server.py"],
"env": {"DEBUG": "true"},
"cwd": "./servers",
"tools": ["*"],
"timeout": 30000,
},
# Remote MCP server (HTTP)
"github": {
"type": "http",
"url": "https://api.githubcopilot.com/mcp/",
"headers": {"Authorization": "Bearer ${TOKEN}"},
"tools": ["*"],
},
})
response = await session.send_and_wait("List my recent GitHub notifications")
print(response.data.content)
await client.stop()
asyncio.run(main())
Go
package main
import (
"context"
"log"
copilot "github.com/github/copilot-sdk/go"
)
func main() {
ctx := context.Background()
client := copilot.NewClient(nil)
if err := client.Start(ctx); err != nil {
log.Fatal(err)
}
defer client.Stop()
session, err := client.CreateSession(ctx, &copilot.SessionConfig{
Model: "gpt-5",
MCPServers: map[string]copilot.MCPServerConfig{
"my-local-server": copilot.MCPStdioServerConfig{
Command: "node",
Args: []string{"./mcp-server.js"},
Tools: []string{"*"},
},
},
})
if err != nil {
log.Fatal(err)
}
defer session.Disconnect()
// Use the session...
}
.NET
using GitHub.Copilot;
await using var client = new CopilotClient();
await using var session = await client.CreateSessionAsync(new SessionConfig
{
Model = "gpt-5",
McpServers = new Dictionary<string, McpServerConfig>
{
["my-local-server"] = new McpStdioServerConfig
{
Command = "node",
Args = new List<string> { "./mcp-server.js" },
Tools = new List<string> { "*" },
},
},
});
Deaktivieren konfigurierter Server pro Sitzung
Legen Sie disabledMcpServers auf genaue MCP-Servernamen fest, die nicht in einer Sitzung ausgeführt werden dürfen.
Die Einstellung ist auf die individuelle Erstellungs- oder Fortsetzungsanforderung festgelegt; es ändert keine globalen MCP-Einstellungen oder die Serverkonfiguration.
const session = await client.createSession({
mcpServers: {
filesystem: { type: "local", command: "npx", args: ["-y", "@modelcontextprotocol/server-filesystem", "."] },
github: { type: "http", url: "https://api.githubcopilot.com/mcp/" },
},
disabledMcpServers: ["github"],
});
| SDK | Konfigurationseigenschaft |
|---|---|
| Node.js | disabled |
| Python | disabled_mcp_ |
| Go | Disabled |
| .NET | Disabled |
| Java | set |
| Rust | with_disabled_ |
Bei der Sitzungserstellung und beim Fortsetzen nach einem Kaltstart werden deaktivierte Server nicht gestartet, und die Laufzeitumgebung stößt deren Authentifizierung nicht an. Ein Fortsetzen im residenten Modus kann einen Server, den die Laufzeitumgebung bereits gestartet hat, nicht rückgängig machen. Namen werden exakt abgeglichen.
Auflisten und Abrufen von Prompts
Der experimentell generierte MCP-Namespace stellt die Wire-JSON-RPC-Methoden session.mcp.prompts.list und session.mcp.prompts.get bereit. Verwenden Sie die unten aufgeführten sprachspezifischen SDK-Zugriffsmethoden, um diese aufzurufen. Diese Methoden zielen auf einen verbundenen Server in der aktuellen Sitzung ab. Sie kombinieren keine Ergebnisse von mehreren Servern.
| SDK | Prompts auflisten | Eingabeaufforderung abrufen |
|---|---|---|
| Node.js | session.rpc.mcp.prompts.list(...) | session.rpc.mcp.prompts.get(...) |
| Python | session.rpc.mcp.prompts.list(...) | session.rpc.mcp.prompts.get(...) |
| Go | session.RPC.MCP.Prompts().List(...) | session.RPC.MCP.Prompts().Get(...) |
| .NET | session.Rpc.Mcp.Prompts.List | session.Rpc.Mcp.Prompts.Get |
| Java | session.get | session.get |
| Rust | session.rpc().mcp().prompts().list(...) | session.rpc().mcp().prompts().get(...) |
Die Auflistung erfordert serverName und akzeptiert eine optionale opake cursor. Jeder Aufruf gibt eine Seite mit typierten Eingabeaufforderungsdefinitionen und einem optionalen nextCursor zurück.
Übergeben Sie diesen Cursor in einem anderen Listenaufruf, um die nächste Seite anzufordern. Definitionen umfassen Namen, optionale Titel und Beschreibungen sowie Argumentdefinitionen.
Eine ausgelassene Argumentflagge required bleibt von false verschieden.
Das Abrufen eines Prompts erfordert serverName und promptName, mit einem optionalen arguments Wörterbuch, dessen Werte Zeichenfolgen sind. Das Weglassen von arguments führt dazu, dass die Argumente der MCP-Anfrage fehlen; die Übergabe von {} sendet ein ausdrücklich leeres Wörterbuch.
Die Laufzeit behält diese Unterscheidung für den Server bei. Das Ergebnis enthält eine optionale Beschreibung und sortierte Nachrichten mit typisierten Rollen und undurchsichtigem JSON content.
Überprüfen Sie den type jedes Inhaltsblocks, bevor Sie ihn interpretieren. Der Inhalt wird nicht in Text abgeflacht. Geschachtelte Ressourcen, Anmerkungen, Metadaten, unbekannte Inhaltstypen und zusätzliche Inhaltsfelder behalten ihre JSON-Struktur bei. Servererweiterungen für Typdeskriptoren, Nachrichten und Ergebnis-Envelopes sind verfügbar unter additionalProperties. Eine Servererweiterung selbst namens additionalProperties wird als Eintrag in dieser Map beibehalten, nicht mit ihr zusammengeführt.
Der Diskriminator der obersten Ebene resultType: "complete" des Protokolls wird von der Laufzeit verwendet. Er wird nicht als SDK-Feld oder Servererweiterung zurückgegeben.
Anfragen schlagen explizit fehl, wenn die Laufzeit die unformatierte Antwort nicht beibehalten kann, einschließlich stdio-Antwortframes, die den Grenzwert von 1 MiB-Aufnahme überschreiten.
Die zurückgegebenen Prompt-Nachrichten werden nicht automatisch an das Modell gesendet oder zum Ausführen von Tools oder zum Abrufen von Referenzressourcen verwendet. Ihre Anwendung entscheidet, wie das Ergebnis verwendet werden soll. Bei der Generierung dieses Ergebnisses kann ein MCP-Server Sampling oder Elicitation über Mehrere Roundtrip-Fortsetzungen anfordern. Diese Anfragen verwenden dieselben konfigurierten Host-Responder wie andere MCP-Vorgänge; der Prompt-Abruf gewährt keine zusätzliche Berechtigung und umgeht die Entscheidung des Hosts nicht. Ein fehlender Responder oder ein Responder-Fehler führt zum Fehlschlagen der Anforderung, und eine Ablehnung der Elicitierung wird unverändert an den Server zurückgegeben. Nur-Zustand-Fortsetzungen rufen keinen der beiden Responder auf.
Listen Sie nach einem bestehenden mcp.prompts.list_changed-Sitzungsereignis die Aufforderungen des benannten Servers erneut auf, um die Ansicht Ihrer Anwendung zu aktualisieren.
Anwenden einer Sandbox-Richtlinie vor dem MCP-Start
Übergeben Sie sandboxConfig an resumeSession oder createSession, um die Sandkastenrichtlinie während der Erstellung anzuwenden, bevor entdeckte Root-Config-, Plugin- oder explizit konfigurierte MCP-Server gestartet werden. Sie akzeptiert dieselbe Konfiguration wie session.rpc.options.update({ sandboxConfig }).
const sandboxConfig = {
enabled: true,
sandboxMcpServers: true,
userPolicy: { network: { allowOutbound: false } },
};
const session = await client.createSession({
onPermissionRequest: approveAll,
sandboxConfig,
});
Erneutes Bereitstellen der Konfiguration beim Fortsetzen nach Kaltstart; Weglassen behält die aktuelle Richtlinie einer bestehenden Sitzung bei. Eine Wiederaufnahme aus dem residenten Zustand kann prozesse, die bereits gestartet wurden, nicht rückgängigmachen. Bei der Überprüfung der verwalteten Richtlinie wird dieselbe Direct-Host-Semantik wie bei einer Optionsaktualisierung verwendet: Eine widersprüchliche Anforderung führt dazu, dass das Erstellen oder Fortsetzen fehlschlägt, anstatt auf eine unsandboxierte Sitzung zurückzugreifen, wobei data.code im JSON-RPC-Fehler auf managed_sandbox_policy_conflict gesetzt ist. Die Laufzeit weist dieser expliziten Hostkonfiguration keine von den Einstellungen abgeleitete sandboxConfigSource zu.
Eine spätere Identische options.update({ sandboxConfig }) startet keine MCP-Server neu, auch wenn die verwaltete Richtlinie die Konfiguration normalisiert hat. Eine andere effektive MCP-Sandkastenrichtlinie behält das übliche Neustartverhalten bei.
Überprüfen Sie die von ConnectResult zurückgegebene Laufzeit server.connect (version) anhand der Mindestlaufzeitversion, die Ihre Anwendung für dieses Feature benötigt. Die SDK-Protokollversion ist kein Signal für Funktionsunterstützung pro Feature. Ältere Laufzeiten ignorieren unbekannte Felder zum Erstellen/Fortsetzen, sodass eine Anwendung, die sie unterstützt, beim Öffnen sandboxConfig senden und in einer nachfolgenden Optionsaktualisierung wiederholen kann. Dieses Update ist auf unterstützten Laufzeiten harmlos, aber ältere Runtimes können MCP weiterhin starten, bevor das Update eintrifft; ist eine unterstützte Laufzeitversion erforderlich, wenn die Beschränkung ab dem ersten Prozess obligatorisch ist.
Werkzeugkonfiguration
Mithilfe des tools Felds können Sie steuern, welche Tools für einen MCP-Server verfügbar sind.
Alle Werkzeuge zulassen
Verwenden Sie "*", um alle vom MCP-Server bereitgestellten Tools zu aktivieren:
tools: ["*"]
Bestimmte Tools zulassen
Stellen Sie eine Liste der Toolnamen bereit, um den Zugriff einzuschränken:
tools: ["bash", "edit"]
Nur die aufgeführten Tools sind für den Agent verfügbar.
Alle Tools deaktivieren
Verwenden Sie ein leeres Array, um alle Tools zu deaktivieren:
tools: []
Notes
- Das
toolsFeld definiert, welche Tools zulässig sind. - Es gibt keine separate
allowKonfiguration oderdisallowKonfiguration– der Toolzugriff wird direkt über diese Liste gesteuert.
Schnellstart: Dateisystem-MCP-Server
Hier ist ein vollständiges Arbeitsbeispiel mit dem offiziellen @modelcontextprotocol/server-filesystem MCP-Server:
import { CopilotClient } from "@github/copilot-sdk";
async function main() {
const client = new CopilotClient();
// Create session with filesystem MCP server
const session = await client.createSession({
mcpServers: {
filesystem: {
type: "local",
command: "npx",
args: ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"],
tools: ["*"],
},
},
});
console.log("Session created:", session.sessionId);
// The model can now use filesystem tools
const result = await session.sendAndWait({
prompt: "List the files in the allowed directory",
});
console.log("Response:", result?.data?.content);
await session.disconnect();
await client.stop();
}
main();
Ausgabe:
Session created: 18b3482b-bcba-40ba-9f02-ad2ac949a59a
Response: The allowed directory is `/tmp`, which contains various files
and subdirectories including temporary system files, log files, and
directories for different applications.
Tipp
Sie können jeden MCP-Server aus dem MCP-Serververzeichnis verwenden. Zu den beliebten Optionen gehören @modelcontextprotocol/server-github, @modelcontextprotocol/server-sqliteund @modelcontextprotocol/server-puppeteer.
Konfigurationsoptionen
Lokaler/stdio-Server
| Eigentum | Typ | Erforderlich | Description |
|---|---|---|---|
type | |||
"local" oder "stdio" | No | Servertyp (Standardmäßig lokal) | |
command | string | Yes | Auszuführende Befehl |
args | string[] | Yes | Befehlsargumente |
env | object | No | Umgebungsvariablen |
cwd | string | No | Arbeitsverzeichnis |
tools | string[] | No | Zu aktivierende Tools (["*"] für alle, [] für keine) |
timeout | number | No | Timeout in Millisekunden |
Remoteserver (HTTP/SSE)
| Eigentum | Typ | Erforderlich | Description |
|---|---|---|---|
type | |||
"http" oder "sse" | Yes | Servertyp | |
url | string | Yes | Server-URL |
headers | object | No | HTTP-Header (z. B. für Authentifizierung) |
oauthClientId | string | No | Nicht leere Client-ID für einen statisch konfigurierten OAuth-Client |
oauthScopes | string[] | No | Nicht leeres Array gültiger RFC 6749-Scope-Token. Erfordert oauthClientId; wird verwendet, wenn die Server-Challenge den Scope auslässt oder einen leeren Scope bereitstellt, vor dem Fallback für Metadaten geschützter Ressourcen |
oauthPublicClient | boolean | No | Gibt an, ob der konfigurierte OAuth-Client öffentlich ist und keinen geheimen Clientschlüssel erfordert. |
oauthGrantType | string | No | OAuth-Grant-Typ für den konfigurierten Client, z. B. client_credentials |
tools | string[] | No | Zu aktivierende Tools |
timeout | number | No | Timeout in Millisekunden |
OAuth-Inhaberschaft für Remote-Server
Wählen Sie für jeden Authentifizierungsversuch ein OAuth-Besitzmodell aus:
- Laufzeitverwalteter Loopback:
session.mcp.oauth.loginohne Umleitungs-URI aufrufen. Die Laufzeit öffnet einen lokalen Callback-Listener und übernimmt die Discovery, PKCE, State-Validierung, den Tokenaustausch, die Persistenz, die Aktualisierung und die erneute Verbindung. - Laufzeitverwalteter gehosteter Callback: Rufen Sie
session.mcp.oauth.loginmit einem vertrauenswürdigen öffentlichen HTTPS-Umleitungs-URI auf. Ihr Host empfängt den Callback, aber die Laufzeit verwaltet weiterhin das OAuth-Protokoll und die Anmeldeinformationen. - Vom Host verwaltete OAuth: Verwenden Sie den MCP-Authentifizierungsanforderungshandler des SDK, und geben Sie ein vom Host erworbenes Zugriffstoken zurück. Ihr Host besitzt die Autorisierung und den Refresh.
Registrieren Sie keinen vom Host verwalteten OAuth-Handler für einen Authentifizierungsversuch, der einen von der Laufzeit verwalteten gehosteten Rückruf verwendet. Warten Sie, bis der Remoteserver in den needs-auth-Status wechselt, und rufen Sie dann die generierte session.rpc.mcp.oauth.login-Methode direkt mit dem Servernamen und dem Rückruf-URI auf:
{
"serverName": "remote-mcp",
"redirectUri": "https://agent.example.com/oauth/callback"
}
Der ausgewählte statische, CIMD- oder dynamisch registrierte OAuth-Client muss diesen exakten URI angeben. Der URI muss HTTPS verwenden und darf keine Abfrage oder ein Fragment enthalten.
Wenn Browserinteraktion erforderlich ist, enthält das Ergebnis authorizationUrl und authorizationId. Öffnen Sie authorizationUrl im Browser des Benutzers, und behalten Sie authorizationId bei der Zielsitzung bei.
Rufen Sie nach der Umleitung des Autorisierungsservers an Ihren Endpunkt die generierte session.rpc.mcp.oauth.complete Methode auf:
{
"authorizationId": "<opaque-state>",
"callbackUrl": "https://agent.example.com/oauth/callback?code=...&state=..."
}
Erstellen Sie callbackUrl aus dem konfigurierten öffentlichen Redirect-Origin und dem Pfad sowie der ursprünglichen Abfrage des Rückrufs. Übergeben Sie keine interne Dienst-URL oder vertrauen Sie clientseitig bereitgestellten Forwarded oder X-Forwarded-* Headern. Die Laufzeit überprüft den Ursprung, den Port, den Pfad, den state-Parameter und die OAuth-Antwort, bevor die Übermittlung akzeptiert wird. Tokenaustausch, Persistenz und MCP-Neuverbindung setzen sich dann asynchron fort.
Übergeben eines abgelehnten Zugriffstokens an die Laufzeit
Für eine Host-OAuth-Anforderung mit reason: "refresh" und runtimeRefreshSupported: true kann Ihr Handler { "kind": "runtimeRefresh" } zurückgeben, anstatt ein Ersatz-Access-Token abzurufen.
Die Laufzeit führt eine nichtinteraktive Verlängerung mithilfe der vorhandenen gespeicherten Berechtigung innerhalb des ursprünglichen Autorisierungsvorgangs durch. Es startet keinen neuen Zustimmungsfluss oder ruft den unabhängigen authenticationStateChanged Aktualisierungs-RPC auf.
Der Ersatz behält seine Herkunft der gespeicherten Berechtigung bei, sodass die spätere Übernahme von gespeicherten Tokens mit Bereichsbindung weiterhin verfügbar ist. Ein direkt von einem Host bereitgestelltes Token ist nicht als gespeichertes Token gekennzeichnet und kann nicht von diesem Adoptionspfad überschrieben werden.
Gib diese Antwort nur zurück, wenn die ausstehende Anforderung Unterstützung angibt. Wenn die Fähigkeit fehlt, ist der Wert "false" und der Legacy-Token-/Abbruchvertrag bleibt erhalten. Wenn ein Handler die Übergabe für eine Anforderung ohne die entsprechende Funktionalität zurückgibt, sendet das SDK stattdessen cancelled, sodass die ausstehende Anforderung nicht geöffnet bleibt. Ein bereitgestelltes Token hat Vorrang vor der Übergabe, und ein Abbruch bleibt ein Abbruch.
| SDK | Fähigkeit | Ergebnis der Übergabe |
|---|---|---|
| Node.js | request.runtime | { kind: "runtimeRefresh" } |
| Python | request["runtime | {"kind": "runtimeRefresh"} |
| Go | ||
MCPAuth Capability-Argument | MCPAuth | |
| .NET | Mcp | Mcp |
| Java | ||
Mcp Capability-Argument | Mcp | |
| Rust | Mcp | Mcp |
Die Antwortakzeptanz bestätigt die Übergabe, nicht die Aktualisierung, erneute Verbindung oder den Toolabschluss. Für eine akzeptierte Übergabe wird mcp.oauth_completed einmal ausgegeben, wenn die ursprüngliche Autorisierungsreservierung ihren Endstatus erreicht. Es outcome verwendet nur die vorhandenen Werte: token bei erfolgreicher Wiederherstellung und cancelled bei abgebrochener oder fehlgeschlagener Wiederherstellung. Das persistente mcp.oauth_recovery_completed Ereignis trägt dasselbe requestId und serverName und unterscheidet das Terminalergebnis, einschließlich der erneuten Verbindung: succeeded, cancelled oder failed. SDK-Versionen, die diesem Ereignis vorausgehen, erhalten es als unbekannten Ereignistyp.
Bis die Laufzeit eine runtimeRefresh Antwort akzeptiert, behalten vorhandene Antworten ihre frühere Bedeutung bei. Eine Hostantwort { kind: "cancelled" } lehnt die Anforderung ab. Für eine refresh Anforderung kann die Laufzeit dann eine erneute Autorisierung anfordern.
Wenn kein Host antwortet, greift die Laufzeit auf die normale lokale OAuth-Verarbeitung zurück, einschließlich zwischengespeicherter Anmeldeinformationen, und gibt kein mcp.oauth_recovery_completed Ereignis aus.
Durch diese Änderung wird keine Hostantwort cancelled als „Beenden“ umklassifiziert. Der ursprüngliche Aufrufvorgang wird nur durch eine akzeptierte Übergabe runtimeRefresh beibehalten.
Nach der Annahme kann der ursprüngliche Aufruf nach der Installation der Anmeldeinformationen die Verbindung erneut herstellen und dabei die bestehende Sitzung sowie die Konfigurations-, Richtlinien- und Berechtigungsgrenzen beibehalten. Das Stoppen des Main Turn oder das Beenden der Sitzung bricht die ursprüngliche Autorisierungsreservierung ab; der gestoppte Aufruf kann später weder erneut versuchen noch ein Ergebnis veröffentlichen. Ein bereits ausgestellter rotierender Grant-Austausch kann den Ersetzungsvorgang nach dem Abbruch beenden, jedoch keine veralteten Anmeldedaten installieren, eine erneute Verbindung herstellen oder den abgebrochenen Aufruf fortsetzen.
Eine nicht verfügbare gespeicherte Berechtigung oder fehlgeschlagene Aktualisierung beendet den ursprünglichen Aufruf, ohne eine interaktive erneute Autorisierung anzufordern. Eine fehlgeschlagene erneute Verbindung beendet auch den Aufruf; Das erfolgreiche Abrufen eines Tokens ist kein erfolgreiches Toolergebnis.
Gleichzeitige Aufrufe schließen sich dem genauen laufenden Autorisierungsversuch an und erhalten das Terminalergebnis. Ein verbundener Server, ein beibehaltenes Zugriffstoken oder ein späterer erfolgreicher Versuch ist kein Beweis dafür, dass ihr Versuch erfolgreich war. Jeder verbleibende Aufruf prüft weiterhin den eigenen Katalog und die Tool-Berechtigung, bevor er es erneut versucht; ein zusammengeführter Fehler löst keine weitere interaktive Autorisierung aus.
OAuth-HTTP-Fristen gelten für einzelne Anfragen, nicht für die vollständige Übergabe oder die Abwicklung der Gewährung und Speicherung. Eine Stornierung kann erfolgen, bevor ein ausgegebener Exchange abgeschlossen ist, und die Freigabe der Sitzung wartet auf nachverfolgte Settlement-Worker. Es gibt keine allgemeine Abschlussfrist, sodass Hosts keine Stornierung, Übergabeakzeptanz oder HTTP-Timeout als Nachweis behandeln dürfen, dass alle Speicherarbeiten abgeschlossen sind.
Sitzungsbezogene MCP-Diagnose
Legen Sie diagnostics: { sources: { mcp: { level: "debug" } } } fest, wenn Sie eine Sitzung erstellen oder fortsetzen, um die MCP-Diagnose zu aktivieren. Jede Quelle ist standardmäßig auf off eingestellt.
Die aktivierten Ebenen sind error, warning, info, debug und trace. Diese Einstellung ist von der Prozessebene des Clients logLevel getrennt.
Warnung
Diagnoseeinträge können auf jeder aktivierten Ebene vom Benutzer oder vom Server bereitgestellte Inhalte enthalten: warning und höher können Server-Stderr enthalten, während debug und trace zusätzlich MCP-Nutzlasten, Toolargumente und Pfade enthalten können. Behandeln Sie jeden Eintrag als vertraulich. Laden Sie Einträge nicht automatisch als Telemetrie hoch, und exportieren Sie sie nicht ohne ausdrückliche Aktion des Hosts.
Die generierte session.rpc.diagnostics API ermöglicht Hosts das Konfigurieren und Lesen von sitzungsbezogenen, begrenzten In-Memory-Diagnosen. MCP ist die erste und derzeit einzige unterstützte Quelle. Wählen Sie sie beim Lesen explizit mit sources: ["mcp"] aus. Das Lesen aktiviert die Erfassung nicht. Verwenden Sie eine stoppbare Leseschleife pro Ausgabeoberfläche, und behalten Sie den Cursor bei. Eine Leseschleife besitzt ihren Cursor und die Darstellung; die Laufzeit besitzt Erfassung, Filterung, Aufbewahrung, Ablauf des Cursors und Wakeups.
import { approveAll, CopilotClient } from "@github/copilot-sdk";
const client = new CopilotClient();
const stop = new AbortController();
const appendLine = (line: string) => console.log(line);
await client.start();
const session = await client.createSession({
onPermissionRequest: approveAll,
diagnostics: { sources: { mcp: { level: "debug" } } },
});
try {
let cursor: string | undefined;
while (!stop.signal.aborted) {
const page = await session.rpc.diagnostics.read({
sources: ["mcp"],
cursor,
max: 100,
waitMs: 30_000,
});
if (page.cursorStatus === "expired") {
appendLine("MCP diagnostic entries were dropped.");
}
for (const entry of page.entries) {
const detail = entry.details.data ? ` ${entry.details.data}` : "";
appendLine(
`${entry.timestamp} [${entry.level}] [${entry.source}:${entry.details.serverName}] ${entry.message}${detail}`,
);
}
cursor = page.cursor;
}
} finally {
await session.disconnect();
await client.stop();
}
Das Abbruchsignal stoppt die Schleife nach Abschluss des aktuellen gebundenen Lesevorgangs; es wird nicht an den RPC-Aufruf übergeben. Durch Deaktivieren der Aufnahme wird ein ausstehender Lesevorgang fortgesetzt.
DER MCP-Start ist verzögert: Das Aktivieren oder Lesen der Diagnose startet keinen Server.
Konfigurieren Sie mcpServers beim Erstellen der Sitzung, und verwenden Sie die Sitzung dann entweder normal, oder rufen Sie bei einem installierten Server session.rpc.mcp.startServer({ serverName }) zur Fehlerbehebung bei der Initialisierung auf, ohne eine Modellanforderung zu senden.
Jeder Datensatz hat source: "mcp", Zeitstempel, Schweregrad, Nachricht und optional agentId für Nicht-Stamm-Agents. Sein typisiertes details enthält die Kategorie „Lebenszyklus“, „Protokoll“, „HTTP“ oder „stderr“, den Servernamen, ein neues connectionId für jeden Verbindungsversuch sowie optionale Protokollrichtung und Diagnosedaten.
Die MCP-Aufbewahrung ist auf 1.024 Datensätze und 4 MiB pro Sitzung begrenzt. Einzelne codierte Datensätze werden auf 16 KiB begrenzt und werden mit truncated gekennzeichnet, wenn sie gekürzt werden. Lesevorgänge lesen standardmäßig 100 Datensätze, akzeptieren maximal 500 Datensätze und lesen keine Daten anderer Reader aus.
Verwenden Sie droppedCount, wenn es auf einem abgelaufenen Cursor vorhanden ist, um den bekannten Verlustwert anzuzeigen.
Jeder erfolgreiche Lesevorgang gibt einen Cursor- und Cursorstatus zurück, einschließlich leerer Lesevorgänge. Behalten Sie den zurückgegebenen Cursor auch dann bei, wenn keine Datensätze eingehen. Ein Cursor gehört zur Quellauswahl; beginnen Sie ohne Cursor, wenn Sie diese Auswahl ändern.
Fehlende, leere, doppelte oder nicht unterstützte Quellen werden abgelehnt, ebenso wie falsch formatierte Cursor und ungültige numerische Grenzen. Weder Datensätze noch Aufzeichnungseinstellungen werden im Sitzungsverlauf gespeichert.
Rufen Sie session.rpc.diagnostics.configure({ sources: { mcp: { level: "off" } } }) auf, um die MCP-Erfassung zu deaktivieren und den beibehaltenen Puffer zu löschen. Die Konfiguration aktualisiert nur die explizit benannten Quellen und gibt die effektiven Quellebenen zurück. Leere oder unbekannte Quellkonfiguration wird abgelehnt; das Hinzufügen einer anderen unterstützten Quelle in Zukunft wird einen bestehenden Aufrufer nicht implizit dafür anmelden.
Beenden Sie auch die Leseschleife des Hosts; Lesevorgänge geben bei deaktivierter Protokollierung sofort zurück, anstatt zu warten. Ein ausstehender Long Poll wacht auf, wenn die Protokollierung deaktiviert ist. Das Auslassen von diagnostics beim Fortsetzen im Resident-Modus behält seine aktuelle Konfiguration bei. Für eine kaltgeladene Sitzung ist ein neuer Opt-in erforderlich.
Das Aktivieren der Diagnose aus dem Anfangszustand off kann die Erfassung für eine bereits aktive MCP-Verbindung starten. Nachdem die Diagnose deaktiviert configure({ sources: { mcp: { level: "off" } } })wurde, kann die erneute Aktivierung die Aufnahme für dieselbe Liveverbindung und die vorhandene Verbindungs-ID fortsetzen. Datensätze, die sich bereits in Verarbeitung befanden, als die Diagnose deaktiviert wurde, werden verworfen.
Die Laufzeit entfernt konfigurierte und strukturell erkannte Anmeldeinformationen aus der HTTP-Diagnose, bevor Einträge diese API erreichen, aber dies ist keine Garantie dafür, dass keine beliebigen vom Server bereitgestellten Geheimnisse enthalten sind. Es legt keine Anforderungs- oder Antwort-Header-Maps offen. Nur ausgewählte Metadaten, wie z. B. Content-Type, Accept und MCP-Protocol-Version, können erfasst werden, aber ihre Werte sind weiterhin nicht vertrauenswürdig und können vertrauliche Inhalte enthalten. Authentifizierungsheader, Cookies, Sitzungs-IDs, Abfragewerte, URL-Benutzerinfo und Fragmente werden weggelassen. URL-Pfade werden zur Problembehandlung beibehalten, platzieren Sie daher keine Anmeldeinformationen in Pfadsegmenten.
Protokollnutzlasten und Stderr können auch Benutzerinhalte oder beliebige vom Server bereitgestellte Geheimnisse enthalten.
Problembehandlung
Tools werden nicht angezeigt oder nicht aufgerufen
-
Überprüfen, ob der MCP-Server ordnungsgemäß gestartet wird
- Überprüfen Sie, ob der Befehl und die Argumente korrekt sind.
- Sicherstellen, dass der Serverprozess beim Start nicht abstürzt
- Suchen Sie in stderr nach der Fehlerausgabe
-
Überprüfen der Toolkonfiguration
- Stellen Sie sicher, dass
toolsauf["*"]festgelegt ist oder die spezifischen Tools auflistet, die Sie benötigen. - Ein leeres Array
[]bedeutet, dass keine Tools aktiviert sind.
- Stellen Sie sicher, dass
-
Überprüfen der Konnektivität für Remoteserver
- Sicherstellen, dass auf die URL zugegriffen werden kann
- Überprüfen, ob Authentifizierungsheader korrekt sind
Häufig auftretende Probleme
| Issue | Lösung |
|---|---|
| "MCP-Server nicht gefunden" | Überprüfen, ob der Befehlspfad korrekt und ausführbar ist |
| "Verbindung verweigert" (HTTP) | Überprüfen Sie die URL, und stellen Sie sicher, dass der Server ausgeführt wird. |
| Timeout-Fehler | Erhöhen Sie den timeout Wert oder überprüfen Sie die Serverleistung. |
| Tools funktionieren, werden aber nicht aufgerufen | Stellen Sie sicher, dass Ihre Eingabeaufforderung die Funktionalität des Tools eindeutig erfordert. |
Ausführliche Anleitungen zum Debuggen finden Sie unter MCP-Serverdebugginghandbuch.
Zugehörige Ressourcen
- Model Context Protocol - Spezifikation
- MCP-Serververzeichnis – MCP-Server der Community
- GitHub MCP Server - Offizieller GitHub MCP-Server
- Erstellen Sie Ihre erste Copilot-gestützte App – SDK-Grundlagen und benutzerdefinierte Tools
- Debughandbuch – SDK-weites Debuggen
Siehe auch
- MCP-Serverdebugginghandbuch – Detaillierte MCP-Problembehandlung
- Problem Nr. 9 – Ursprüngliche MCP-Tools– Verwendungsfrage
- Problem Nr. 36 – Problem mit der Nachverfolgung der MCP-Dokumentation