mcp-server
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mcp-serverShow me the catalog and add a laptop to my cart."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Two MCP servers, one product, two protocol revisions
The same shopping cart, implemented twice: once on the old stateful MCP spec
(2025-11-25), once on the new stateless one (2026-07-28). Run them side by
side and watch one of them fall over.
The goal is not working code — it's understanding why the spec changed. Every experiment here is designed so the failure is loud and the reason is visible on the wire.
What is MCP? (three sentences)
MCP — the Model Context Protocol — is a standard way for an AI application to call tools that someone else wrote. It replaces N applications × M integrations with N + M, the same way the Language Server Protocol replaced every editor writing its own TypeScript support. Concretely it's JSON-RPC 2.0 messages with agreed method names, sent over stdio or HTTP.
Longer version, if that went past too fast: docs/01 — why MCP exists.
Related MCP server: Online Boutique AI Assistant MCP Server
What this repo demonstrates
Five tools — catalog_list, cart_create, cart_add_item, cart_view,
cart_checkout — with identical names in both servers and identical business
logic in a shared cart-core package that knows nothing about MCP. The only
difference between the two servers is the protocol layer, which is exactly the
thing under study.
Four things you can watch happen:
server-oldcan't complete its own handshake behind a plain round-robin load balancer.server-newdoesn't notice the load balancer exists.Restart
server-oldmid-conversation and the cart is gone, permanently, with no request the client can send to recover it.Asking "confirm this total?" costs
server-olda held-open socket for the whole of human thinking time (1522ms measured).server-newdoes it in two independent requests, 4ms + 15ms, and can finish on a different machine than it started on.Stable list ordering and cache hints — and the arithmetic showing why a missing
.sort()is worth about $4,200/year.
The servers are deliberately not refactored to share protocol code. There is duplication between them on purpose, so you can read each one straight through and diff them.
Make sure you see the wire
Both servers print every request at the HTTP level: method, path, all MCP
headers, the JSON-RPC method and params, which instance handled it, and the
response including resultType. Nothing is hidden behind SDK abstractions. If
you only read one thing while an experiment runs, read the coloured log lines.
Prerequisites
Node.js 20 or newer (developed on 25.5).
node -vto check.A terminal that renders ANSI colour — the logs lean on it heavily.
Ports 3000–3002, 3011, 3012 free.
No database, no Docker, no cloud account. Shared state is a JSON file.
Zero Python anywhere in this repo.
Install
git clone <this repo>
cd mcp-server
npm install
npm run typecheck # should print nothing and exit 0npm install sets up an npm workspace containing two generations of the MCP
SDK at once. They have different package names, so they coexist with no
aliasing tricks:
Package | Version | Used by |
| 1.30.0 |
|
| 2.0.0 |
|
The four experiments, in order
Each is one command. Each starts and stops its own servers — no second terminal needed. Read the linked write-up after running it; each explains what you just saw and why.
Order | Command | What it teaches |
1 |
| Two instances behind a load balancer — the old server can't even finish saying hello; the new one is unbothered. Start here. |
2 |
| Restart mid-conversation — where the cart actually lived, and why "just add Redis" only half-works. |
3 |
| Confirm before checkout — 1522ms of held socket vs two 4ms requests, and why the old way can never run on serverless. |
4 |
| Cache hints and stable ordering — proving cache hits by counter rather than by stopwatch, and the money argument for |
Then read the architecture docs, which tie the four together:
01 — why MCP exists — the N×M problem, and what MCP is and isn't. Read first if you're new to MCP.
02 — the old architecture — the handshake, the session id, and every operational pain point traced to its cause.
03 — the new architecture — handles, MRTR, cache hints, and what you give up.
04 — side by side — every change in the release, where to find it here, and an honest list of what this repo doesn't cover.
Driving it by hand
Worth doing at least once, because you choose the pace and can read each log line as it appears.
# 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 onlyTwo instances plus a load balancer, manually:
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 basicWatch both server terminals: the same cart id appears in requests handled by each, and neither cares.
Poking at it with curl
The most direct way to feel how self-describing a new-spec request is. Start
npm run new:server, then:
# 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":{}}}}'Now break it one piece at a time and watch the error change:
Change | Expected |
|
|
|
|
drop the |
|
drop the |
|
|
|
| 405 — the GET endpoint is gone |
Do the same against the old server and you'll be told to initialize first.
Repo layout
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.Reading order for the code: cart-core/src/cart.ts (what the product does) →
server-old/src/index.ts → server-new/src/index.ts. The protocol-level code in
both servers is commented line by line; the plumbing is not.
npm run clean removes build output and .cart-store.
Glossary
Terms used throughout, in the order they'll bite you.
Load balancer — a box in front of several identical copies of your server that
spreads incoming requests across them. The default policy is round-robin: send
each request to the next copy in the list. It assumes any copy can answer any
request, which is exactly the assumption the old MCP spec broke. Here it's
packages/round-robin, about 50 lines.
Session — a server-side memory of a client, spanning multiple requests. On
2025-11-25 the server minted an Mcp-Session-Id during the handshake, the
client echoed it on every request, and the server used it as a key into an
in-memory map. The session id is a pointer into one process's heap, which is
where all the trouble comes from.
Stateless — the server keeps nothing between requests. Every request carries everything needed to serve it. Note what this does not mean: there's still a cart, and it's still stored. What's gone is state held in a particular process, implicitly, keyed by connection. Application state in a shared database is perfectly compatible with a stateless protocol.
Sticky session (session affinity) — configuring the load balancer so all requests from one client return to the same server copy, usually by hashing a cookie or a header. The standard workaround for a stateful protocol. It works, and it costs you even load distribution, painless deploys, useful autoscaling, and a load balancer that doesn't need to understand your application protocol. Cost list in docs/02.
Elicitation — a server asking the end user a question mid-operation ("total is $180.36, confirm?"). On the old spec the server sent its own request to the client over a held-open stream and blocked inside the tool handler while a human thought about it. That single feature required a live process, an open socket, and guaranteed routing back to the same box.
MRTR (Multi Round-Trip Requests) — how 2026-07-28 does elicitation instead.
The server returns a normal 200 with resultType: "input_required", the
questions in inputRequests, and an opaque signed requestState. That request is
over — nothing is held. The client gathers the answers and sends a new request
(new JSON-RPC id) carrying inputResponses and the same requestState. The
in-flight state travelled through the client instead of sitting in a process,
which is why round 2 can be served by a completely different machine.
Handle — a server-minted identifier returned as ordinary tool output, then
passed back as an ordinary argument. cart_create returns cartId;
cart_add_item takes it. This is how 2026-07-28 replaces session state, and the
difference from the old design is who holds the key: the transport, invisibly,
versus the client, in a value the model can read and pass along. Caveat: a handle
alone is a bearer token — it needs to be scoped to an authenticated user, which
docs/04
covers honestly.
Prompt caching — LLM providers cache the prefix of a prompt: send the same
opening bytes again and the provider reuses its computed state instead of
reprocessing those tokens, at roughly a tenth of the input price. Two
properties make it fragile: the match is on exact bytes, and it's
positional from the front. So if your tool list or catalog sits in the prefix
and two entries swap places, you lose the discount on every token after the
swap. That's why 2026-07-28 says servers SHOULD return lists in a
deterministic order, and why
listProducts() sorts by a unique id
rather than by name or price — a unique key gives a total order with no ties for
a sort implementation to resolve differently. Worked example, with prices:
experiment 04.
If you only remember three things
"Stateless" doesn't mean "no state" — it means no state pinned to a process. The cart still exists. It moved somewhere any instance can reach.
Sticky sessions were a real fix with real costs, and one of those costs was making your infrastructure parse your application protocol.
MRTR, not statelessness, is what unlocked serverless. Statelessness got MCP behind a load balancer. Elicitation still needed a process to stay alive while a human read a dialog — and that's precisely what serverless removed.
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.
31Remote 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