mCP 2.0
Zustandsloses MCP, zustandsbehaftete Anwendung
Ein minimales JavaScript-Projekt, das die wichtigsten Anfrage-/Antwortmuster von MCP 2026-07-28
mit dem MCP TypeScript SDK v2 demonstriert.
Die Demo umfasst:
Zustandslose HTTP-Anfragen ohne
Mcp-Session-Id.Von der Anwendung verwalteter Zustand, der über explizite Handles adressiert wird.
Anfragen mit mehreren Round-Trips zur Benutzerbestätigung.
Fortschrittsaktualisierungen, die auf eine einzelne Operation begrenzt sind.
Cache-fähige Tool-Erkennung mit TTL und Freigabebereich.
Ausführen
Erfordert Node.js 20 oder neuer.
npm install
npm run demoDer Befehl startet einen Server auf einem verfügbaren lokalen Port, führt jedes Szenario aus, gibt die Ergebnisse aus und fährt den Server herunter. Das Löschbeispiel verwendet einen virtuellen Dateisatz im Speicher und berührt niemals Dateien auf der Festplatte.
Führen Sie die Integrationstests wie folgt aus:
npm testUm den Server für einen anderen MCP-Client weiterlaufen zu lassen:
npm run serverDer Endpunkt ist http://127.0.0.1:3000/mcp. Setzen Sie PORT, um den Port zu überschreiben.
Related MCP server: MCP RC Long-Running Task Prototype
1. Zustandslose Anfragen
MCP 2026-07-28 entfernt HTTP-Sitzungen auf Protokollebene. Dieses Projekt erstellt für jede Anfrage einen neuen McpServer, sodass jede Anfrage jede Serverinstanz erreichen kann:
const mcpHandler = createMcpHandler(
() => createStateServer(demoFiles),
{
legacy: "reject",
onerror: (error) => console.error("MCP error:", error),
},
);Der Client wählt explizit die moderne Protokollrevision aus:
const client = new Client(
{ name: "state-demo-client", version: "0.1.0" },
{
capabilities: { elicitation: { form: {} } },
versionNegotiation: {
mode: { pin: "2026-07-28" },
},
},
);Der in einer McpServer-Instanz gespeicherte Zustand verschwindet daher nach dieser Anfrage. Wenn Sie den ephemeren Zähler der Demo zweimal aufrufen, erhalten Sie von zwei verschiedenen Serverinstanzen jeweils 1.
2. Zustandsbehaftete Anwendungsdaten
Zustandsloses MCP erfordert keine zustandslose Anwendung. Dauerhafter Zustand befindet sich außerhalb des pro Anfrage erstellten MCP-Servers und wird über ein explizites Handle ausgewählt:
const countersById = new Map();
server.registerTool(
"create-counter",
{
outputSchema: z.object({ counterId: z.uuid(), value: z.number() }),
},
async () => {
const counterId = randomUUID();
countersById.set(counterId, 0);
const structuredContent = { counterId, value: 0 };
return {
content: [{ type: "text", text: JSON.stringify(structuredContent) }],
structuredContent,
};
},
);Der Client führt das Handle zwischen ansonsten unabhängigen Aufrufen mit:
const created = await client.callTool({ name: "create-counter" });
const { counterId } = created.structuredContent;
await client.callTool({
name: "increment-counter",
arguments: { counterId },
});Die In-Memory-Map ist nur ein Platzhalter. Ein Produktionsserver sollte eine Datenbank oder einen gemeinsamen Speicher verwenden, Handles an den authentifizierten Principal binden und bei jedem Abruf Autorisierung und Ablauf erzwingen.
3. Bestätigung über mehrere Round-Trips
Ein Tool, das weitere Eingaben benötigt, gibt input_required zurück. Der Client erhält die Antwort und wiederholt die ursprüngliche Anfrage mit inputResponses, sodass der Server keine zweite JSON-RPC-Anfrage auf dem Operations-Stream initiiert.
server.registerTool(
"delete-files",
{
inputSchema: z.object({ files: z.array(z.string()).min(1) }),
annotations: { destructiveHint: true },
},
async ({ files }, ctx) => {
const confirmation = acceptedContent(
ctx.mcpReq.inputResponses,
"confirm",
confirmationSchema,
);
if (confirmation === undefined) {
return inputRequired({
inputRequests: {
confirm: inputRequired.elicit({
message: `Delete ${files.length} virtual files?`,
requestedSchema: confirmationSchema,
}),
},
});
}
if (!confirmation.confirm) {
return {
content: [{ type: "text", text: "Cancelled" }],
structuredContent: { status: "cancelled", deleted: [] },
};
}
const deleted = files.filter((file) => demoFiles.delete(file));
return {
content: [{ type: "text", text: `Deleted: ${deleted.join(", ")}` }],
structuredContent: { status: "deleted", deleted },
};
},
);Das SDK kann die Anfrage über den normalen Elicitation-Handler erfüllen und automatisch wiederholen:
client.setRequestHandler("elicitation/create", async (request) => {
const confirm = await askUser(request.params.message);
return {
action: "accept",
content: { confirm },
};
});Die Bestätigung ist eine Sache der Benutzererfahrung, nicht der Autorisierung. Der Server muss den Aufrufer weiterhin authentifizieren und die Berechtigung zum Löschen von Dateien unabhängig durchsetzen.
4. Anfragespezifischer Fortschritt
Der Fortschritt bleibt an die Anfrage gebunden, die die Arbeit gestartet hat. Parallele Operationen erhalten nur ihre eigenen Aktualisierungen, anstatt sich einen globalen Ereignisstream zu teilen.
server.registerTool(
"run-work",
{ inputSchema: z.object({ job: z.string() }) },
async ({ job }, ctx) => {
const progressToken = ctx.mcpReq._meta?.progressToken;
for (const progress of [10, 30, 70]) {
if (progressToken !== undefined) {
await ctx.mcpReq.notify({
method: "notifications/progress",
params: {
progressToken,
progress,
total: 100,
message: `${job}: ${progress}%`,
},
});
}
}
return {
content: [{ type: "text", text: `${job}: complete` }],
structuredContent: { job, status: "complete" },
};
},
);Jeder Client-Aufruf liefert seinen eigenen Fortschritts-Callback:
await Promise.all([
client.callTool(
{ name: "run-work", arguments: { job: "alpha" } },
{ onprogress: (update) => alphaProgress.push(update) },
),
client.callTool(
{ name: "run-work", arguments: { job: "beta" } },
{ onprogress: (update) => betaProgress.push(update) },
),
]);5. Cache-Fähigkeit
Cache-fähige Antworten enthalten eine Frische-Lebensdauer und eine Freigaberichtlinie. Dies reduziert den wiederholten Discovery-Verkehr, wenn sich ein Agent mit vielen MCP-Servern verbindet.
Dieser Server kennzeichnet seinen Tool-Katalog als fünf Minuten lang wiederverwendbar:
const server = new McpServer(
{ name: "mcp-state-demo", version: "0.1.0" },
{
cacheHints: {
"tools/list": {
ttlMs: 300_000,
cacheScope: "public",
},
},
},
);Der Client verwendet frische Einträge automatisch:
await client.listTools(); // network request; stores the result
await client.listTools(); // cache hit; no network request
await client.listTools(undefined, {
cacheMode: "refresh",
}); // forces a network request and updates the cacheDie Felder gelten für tools/list-, prompts/list-, resources/list-, resources/templates/list- und resources/read-Ergebnisse.
publicerlaubt Clients und gemeinsamen Zwischeninstanzen, das Ergebnis über Benutzer hinweg wiederzuverwenden.privatebeschränkt die Wiederverwendung auf den anfragenden Autorisierungskontext. Wenn ein Cache-Speicher gemeinsam genutzt wird, setzen Sie diecachePartitiondes Clients auf eine stabile Principal-Kennung.
Eine TTL ist eine Frische-Schätzung. Listenänderungs-Benachrichtigungen können zwischengespeicherte Kataloge ungültig machen, bevor ihre TTL abläuft.
Projektstruktur
src/server.js MCP server and tool implementations
src/demo.js Client exercising all five scenarios
test/state.test.js Integration tests for every scenarioDie MCP-Pakete sind auf 2.0.0 festgelegt, einschließlich der hier verwendeten inputRequired-, acceptedContent-, Cache- und anfragespezifischen Fortschritts-APIs.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceA reference implementation demonstrating proper MCP server patterns with HTTP transport, featuring session management, progress notifications, and example tools for testing server functionality. Serves as a clean template for building MCP servers with streamable responses and comprehensive error handling.7
- FlicenseNot gradedqualityCmaintenanceDemonstrates MCP 2026-07-28 behavior for long-running tool calls, task lifecycle (get, update, cancel), and elicitation clarification during async tasks.
- AlicenseNot gradedqualityCmaintenanceEducational MCP server demonstrating the 2026-07-28 stateless protocol with raw Starlette, no SDK, featuring tools, request state handles, MRTR elicitation, and subscriptions.MIT
- AlicenseNot gradedqualityBmaintenanceDemo MCP server for ACEL, a runtime verification middleware that blocks a rule-violating tool call before it executes. 5 tools (authenticate, read/validate/delete records, send payment) showing ACEL enforcing call ordering and state preconditions live via the official MCP SDK's middleware hook.MIT
Related MCP Connectors
AI Reasoning Cache & Consensus Layer with 11 MCP tools via Streamable HTTP.
Hash-chained HMAC-signed audit log MCP for A2A (agent-to-agent) calls. Every tool-call, agent-ha...
Workflow diagnostics, capability routing, and x402 settlement for MCP-compatible agents.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/weijianzhg/mcp-2-0'
If you have feedback or need assistance with the MCP directory API, please join our Discord server