mcp-server
Zwei MCP-Server, ein Produkt, zwei Protokollrevisionen
Derselbe Warenkorb, zweimal implementiert: einmal auf der alten zustandsbehafteten MCP-Spezifikation
(2025-11-25), einmal auf der neuen zustandslosen (2026-07-28). Führe sie nebeneinander aus
und beobachte, wie einer von ihnen umkippt.
Das Ziel ist nicht funktionierender Code – es geht darum zu verstehen, warum sich die Spezifikation geändert hat. Jedes Experiment hier ist so gestaltet, dass der Fehler laut ist und der Grund auf der Leitung sichtbar wird.
Was ist MCP? (drei Sätze)
MCP – das Model Context Protocol – ist ein Standardweg, damit eine KI-Anwendung Werkzeuge aufrufen kann, die jemand anderes geschrieben hat. Es ersetzt N Anwendungen × M Integrationen durch N + M, so wie das Language Server Protocol ersetzt hat, dass jeder Editor seinen eigenen TypeScript-Support schrieb. Konkret sind es JSON-RPC-2.0-Nachrichten mit vereinbarten Methodennamen, gesendet über stdio oder HTTP.
Längere Version, falls das zu schnell vorbeiging: docs/01 – warum MCP existiert.
Related MCP server: Online Boutique AI Assistant MCP Server
Was dieses Repo demonstriert
Fünf Werkzeuge – catalog_list, cart_create, cart_add_item, cart_view,
cart_checkout – mit identischen Namen in beiden Servern und identischer Geschäftslogik
in einem gemeinsamen cart-core-Paket, das nichts von MCP weiß. Der einzige
Unterschied zwischen den beiden Servern ist die Protokollebene, die genau das ist, was untersucht wird.
Vier Dinge, die du beobachten kannst:
server-oldkann seinen eigenen Handshake hinter einem einfachen Round-Robin-Lastverteiler nicht abschließen.server-newbemerkt nicht, dass der Lastverteiler existiert.Starte
server-oldmitten im Gespräch neu und der Warenkorb ist weg, dauerhaft, mit keiner Anfrage, die der Client senden kann, um ihn wiederherzustellen.„Diesen Betrag bestätigen?“ kostet
server-oldeinen offen gehaltenen Socket für die gesamte menschliche Denkzeit (1522ms gemessen).server-newerledigt das in zwei unabhängigen Anfragen, 4ms + 15ms, und kann auf einer anderen Maschine fertig werden als auf der, auf der es begonnen hat.Stabile Listenreihenfolge und Cache-Hinweise – und die Rechnung, die zeigt, warum ein fehlendes
.sort()etwa 4.200 $/Jahr wert ist.
Die Server sind bewusst nicht umgestaltet, um Protokollcode zu teilen. Es gibt Duplikation zwischen ihnen mit Absicht, damit du jeden direkt durchlesen und diffen kannst.
Stelle sicher, dass du die Leitung siehst
Beide Server drucken jede Anfrage auf HTTP-Ebene: Methode, Pfad, alle MCP-Header, die JSON-RPC-Methode und -Parameter, welche Instanz sie bearbeitet hat, und die Antwort einschließlich resultType. Nichts ist hinter SDK-Abstraktionen versteckt. Wenn
du während eines Experiments nur eine Sache liest, lies die farbigen Logzeilen.
Voraussetzungen
Node.js 20 oder neuer (entwickelt auf 25.5).
node -vzum Prüfen.Ein Terminal, das ANSI-Farben darstellt – die Logs stützen sich stark darauf.
Ports 3000–3002, 3011, 3012 frei.
Keine Datenbank, kein Docker, kein Cloud-Konto. Gemeinsamer Zustand ist eine JSON-Datei.
Null Python irgendwo in diesem Repo.
Installation
git clone <this repo>
cd mcp-server
npm install
npm run typecheck # should print nothing and exit 0npm install richtet einen npm-Workspace ein, der zwei Generationen des MCP-SDK gleichzeitig enthält. Sie haben unterschiedliche Paketnamen, koexistieren also ohne
Aliasing-Tricks:
Paket | Version | Verwendet von |
| 1.30.0 |
|
| 2.0.0 |
|
Die vier Experimente, in Reihenfolge
Jedes ist ein Befehl. Jedes startet und stoppt seine eigenen Server – kein zweites Terminal nötig. Lies die verlinkte Ausarbeitung nach dem Ausführen; jedes erklärt, was du gerade gesehen hast und warum.
Reihenfolge | Befehl | Was es lehrt |
1 |
| Zwei Instanzen hinter einem Lastverteiler – der alte Server schafft es nicht einmal, Hallo zu sagen; der neue ist unbeeindruckt. Beginne hier. |
2 |
| Neustart mitten im Gespräch – wo der Warenkorb tatsächlich lebte und warum „einfach Redis hinzufügen“ nur halb funktioniert. |
3 |
| Vor dem Checkout bestätigen – 1522ms gehaltener Socket vs. zwei 4ms-Anfragen und warum der alte Weg nie serverless laufen kann. |
4 |
| Cache-Hinweise und stabile Reihenfolge – Cache-Treffer per Zähler statt Stoppuhr beweisen und das Geldargument für |
Lies dann die Architekturdokumente, die die vier verbinden:
01 – warum MCP existiert – das N×M-Problem und was MCP ist und nicht ist. Lies zuerst, wenn du neu bei MCP bist.
02 – die alte Architektur – der Handshake, die Session-ID und jeder operative Schmerzpunkt, zurückverfolgt zu seiner Ursache.
03 – die neue Architektur – Handles, MRTR, Cache-Hinweise und was du aufgibst.
04 – Seite an Seite – jede Änderung im Release, wo du sie hier findest, und eine ehrliche Liste dessen, was dieses Repo nicht abdeckt.
Manuell steuern
Es lohnt sich, mindestens einmal zu tun, weil du das Tempo wählst und jede Logzeile lesen kannst, während sie erscheint.
# Old server (port 3001)
npm run old:server
npm run client -- --target old --scenario basic
npm run client -- --target old --scenario checkout
npm run client -- --target old --scenario checkout --decline
# New server (port 3002)
npm run new:server
npm run client -- --target new --scenario basic
npm run client -- --target new --scenario checkout
npm run client -- --target new --scenario discover # server/discover — new spec onlyZwei Instanzen plus ein Lastverteiler, manuell:
PORT=3002 INSTANCE_ID=A npm run new:server
PORT=3012 INSTANCE_ID=B npm run new:server
PORT=3000 TARGETS=http://localhost:3002,http://localhost:3012 npm run lb
npm run client -- --target new --url http://localhost:3000/mcp --scenario basicBeobachte beide Server-Terminals: Dieselbe Warenkorb-ID erscheint in Anfragen, die von jeder bearbeitet werden, und keiner kümmert sich darum.
Mit curl herumstochern
Der direkteste Weg, zu fühlen, wie selbstbeschreibend eine Anfrage der neuen Spezifikation ist. Starte
npm run new:server, dann:
# A complete, valid request — note how much has to be in it
curl -s -X POST http://localhost:3002/mcp \
-H 'content-type: application/json' \
-H 'accept: application/json, text/event-stream' \
-H 'mcp-protocol-version: 2026-07-28' \
-H 'mcp-method: tools/call' \
-H 'mcp-name: catalog_list' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{
"name":"catalog_list","arguments":{},
"_meta":{"io.modelcontextprotocol/protocolVersion":"2026-07-28",
"io.modelcontextprotocol/clientInfo":{"name":"curl","version":"1"},
"io.modelcontextprotocol/clientCapabilities":{}}}}'Jetzt brich es Stück für Stück und beobachte, wie sich der Fehler ändert:
Änderung | Erwartet |
|
|
|
|
den |
|
den |
|
|
|
| 405 – der GET-Endpunkt ist weg |
Mach dasselbe gegen den alten Server und dir wird gesagt, du sollst zuerst initialize aufrufen.
Repo-Struktur
packages/
cart-core/ the actual product. zero MCP knowledge. shared by both servers.
server-old/ MCP 2025-11-25. sessions, handshake, held-open streams.
server-new/ MCP 2026-07-28. stateless, handles, MRTR, cache hints.
client-demo/ both clients — one per SDK generation.
round-robin/ ~50-line load balancer. no stickiness, on purpose.
experiments/ four runnable scripts + a write-up each.
docs/ the four architecture notes.
.cart-store/ server-new's shared state. a JSON file. delete it freely.Lesereihenfolge für den Code: cart-core/src/cart.ts (was das Produkt tut) →
server-old/src/index.ts → server-new/src/index.ts. Der Protokollcode in beiden
Servern ist Zeile für Zeile kommentiert; die Verkabelung nicht.
npm run clean entfernt Build-Ausgabe und .cart-store.
Glossar
Begriffe, die überall verwendet werden, in der Reihenfolge, in der sie dich beißen werden.
Lastverteiler – eine Box vor mehreren identischen Kopien deines Servers, die
eingehende Anfragen auf sie verteilt. Die Standardrichtlinie ist Round-Robin: sende
jede Anfrage an die nächste Kopie in der Liste. Sie nimmt an, dass jede Kopie jede Anfrage beantworten kann, was genau die Annahme ist, die die alte MCP-Spezifikation brach. Hier ist es
packages/round-robin, etwa 50 Zeilen.
Session – eine serverseitige Erinnerung an einen Client, die mehrere Anfragen umfasst. Am
2025-11-25 prägte der Server eine Mcp-Session-Id während des Handshakes, der
Client wiederholte sie bei jeder Anfrage, und der Server verwendete sie als Schlüssel in eine
In-Memory-Karte. Die Session-ID ist ein Zeiger in den Heap eines Prozesses, was
die Quelle allen Ärgers ist.
Zustandslos – der Server behält nichts zwischen Anfragen. Jede Anfrage trägt alles, was nötig ist, um sie zu bedienen. Beachte, was das nicht bedeutet: Es gibt immer noch einen Warenkorb, und er wird immer noch gespeichert. Was verschwunden ist, ist Zustand, der in einem bestimmten Prozess gehalten wird, implizit, schlüsselbasiert auf Verbindung. Anwendungszustand in einer gemeinsamen Datenbank ist perfekt kompatibel mit einem zustandslosen Protokoll.
Sticky Session (Sitzungsaffinität) – den Lastverteiler so konfigurieren, dass alle Anfragen von einem Client zur selben Serverkopie zurückkehren, normalerweise durch Hashen eines Cookies oder eines Headers. Der Standard-Workaround für ein zustandsbehaftetes Protokoll. Es funktioniert, und es kostet dich gleichmäßige Lastverteilung, schmerzlose Deployments, nützliches Autoscaling und einen Lastverteiler, der dein Anwendungsprotokoll nicht verstehen muss. Kostenliste in docs/02.
Elicitation – ein Server, der den Endbenutzer mitten in einer Operation eine Frage stellt („Summe ist $180,36, bestätigen?“). In der alten Spezifikation sendete der Server seine eigene Anfrage an den Client über einen offen gehaltenen Stream und blockierte innerhalb des Tool-Handlers, während ein Mensch darüber nachdachte. Diese einzelne Funktion erforderte einen laufenden Prozess, einen offenen Socket und garantierte Weiterleitung zurück zur selben Box.
MRTR (Multi Round-Trip Requests) – wie 2026-07-28 Elicitation stattdessen macht.
Der Server gibt ein normales 200 mit resultType: "input_required" zurück, die
Fragen in inputRequests und einen undurchsichtigen signierten requestState. Diese Anfrage ist
vorbei – nichts wird gehalten. Der Client sammelt die Antworten und sendet eine neue Anfrage
(neue JSON-RPC-ID), die inputResponses und denselben requestState trägt. Der
In-Flight-Zustand reiste durch den Client, statt in einem Prozess zu sitzen,
weshalb Runde 2 von einer völlig anderen Maschine bedient werden kann.
Handle – eine vom Server geprägte Kennung, die als gewöhnliche Tool-Ausgabe zurückgegeben und dann als gewöhnliches Argument zurückgegeben wird. cart_create gibt cartId zurück;
cart_add_item nimmt es entgegen. So ersetzt 2026-07-28 Session-Zustand, und der
Unterschied zum alten Design ist, wer den Schlüssel hält: der Transport, unsichtbar,
versus der Client, in einem Wert, den das Modell lesen und weitergeben kann. Einschränkung: Ein Handle
allein ist ein Inhaber-Token – es muss auf einen authentifizierten Benutzer beschränkt werden, was
docs/04
ehrlich behandelt.
Prompt-Caching – LLM-Anbieter cachen das Präfix eines Prompts: Sende dieselben
Anfangsbytes erneut und der Anbieter verwendet seinen berechneten Zustand wieder, statt diese Token erneut zu verarbeiten, zu etwa einem Zehntel des Eingabepreises. Zwei
Eigenschaften machen es fragil: Der Abgleich erfolgt auf exakte Bytes, und es ist
positional von vorne. Wenn also deine Tool-Liste oder dein Katalog im Präfix sitzt
und zwei Einträge die Plätze tauschen, verlierst du den Rabatt auf jedes Token nach dem
Tausch. Deshalb sagt 2026-07-28, dass Server Listen in einer
deterministischen Reihenfolge zurückgeben SOLLEN, und warum
listProducts() nach einer eindeutigen id sortiert
statt nach Name oder Preis – ein eindeutiger Schlüssel ergibt eine totale Ordnung ohne Gleichstände, die eine Sortierimplementierung unterschiedlich auflösen könnte. Durchgerechnetes Beispiel, mit Preisen:
Experiment 04.
Wenn du dir nur drei Dinge merkst
„Zustandslos“ bedeutet nicht „kein Zustand“ – es bedeutet keinen Zustand, der an einen Prozess gebunden ist. Der Warenkorb existiert weiterhin. Er ist dorthin gezogen, wo jede Instanz ihn erreichen kann.
Sticky Sessions waren eine echte Lösung mit echten Kosten, und eine dieser Kosten war, dass deine Infrastruktur dein Anwendungsprotokoll parsen musste.
MRTR, nicht Zustandslosigkeit, hat Serverless freigeschaltet. Zustandslosigkeit brachte MCP hinter einen Lastverteiler. Elicitation brauchte immer noch einen Prozess, der am Leben blieb, während ein Mensch einen Dialog las – und genau das hat Serverless entfernt.
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 Connectors
Hosted MCP for e-commerce: live product catalog, stock, and pricing for AI agents.
Remote MCP for Living Stack offer discovery and buyer-authorized checkout preparation.
Remote MCP for Universal Cart merchant readiness MCP, structured receipts, audit logs, and reviewer-
Agent-native commerce with trusted catalog, durable carts, and Stripe Checkout via MCP and UCP.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceA Model Context Protocol server that enables AI assistants to interact with a complete e-commerce application, providing authentication, product browsing, and shopping cart management through standardized MCP tools.
- AlicenseNot gradedqualityDmaintenanceMCP server for Online Boutique AI Assistant that exposes 18 e-commerce microservice functions via the Model Context Protocol, enabling any MCP client to manage products, carts, checkout, payments, and shipping.MIT
- FlicenseNot gradedqualityDmaintenanceEnables AI assistants to manage products, shopping carts, and orders in an online store through a well-defined MCP API.
- AlicenseAqualityCmaintenanceA UCP-compliant MCP storefront server that exposes product catalog operations (search, cart, checkout) as MCP tools, following UCP schema version 2026-04-08.5MIT
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/ritik913553/mcp-server'
If you have feedback or need assistance with the MCP directory API, please join our Discord server