mcp-stateless-lab
Allows OpenAI API clients (e.g., ChatGPT) to execute a procure-to-pay workflow, including requisitions, approvals, purchase orders, goods receipt, and payment matching via the MCP protocol.
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-stateless-labcompare purchasing agent behavior between stateful and stateless MCP"
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.
mcp-stateless-lab
A before/after lab for MCP 2025-11-25 → 2026-07-28, told through a
procure-to-pay agent.
繁體中文版:README.zh-TW.md
Two MCP servers, one business logic. The same purchasing story runs against both, so every difference you observe comes from the protocol and nothing else. Then a round-robin cluster shows why the protocol changed.
git clone https://github.com/133institute/mcp-stateless-lab && cd mcp-stateless-lab
./scripts/setup.sh # Windows: scripts\setup.bat
./scripts/run_experiments.shResults land in experiments/report.md — generated from a real run, never hand-written. The committed copy: 29 checks, 29 passed.
The short version
2025-11-25 let a server keep state where only one process holding one live
connection could reach it. 2026-07-28 removes every such place. The consequence
is not stylistic — it decides whether a purchasing agent can be load-balanced,
redeployed mid-decision, or picked up tomorrow by somebody else.
2025-11-25 | 2026-07-28 | |
Opening a connection |
| nothing; |
State across calls | dies with the session | server-minted handle, passed as a tool argument |
Asking a human mid-call | server request on an open stream, with a timeout |
|
A long job | blocking |
|
Tool listing | no cache lifetime, may vary per connection |
|
Missing resource |
|
|
| present | 405 |
Load balancer | must be sticky, plus a session store | plain round robin |
Reasoning: docs/comparison.md. Task list: docs/migration.md. Diagrams: docs/diagrams/.
Related MCP server: agent-audit-trail
Pick a way in
Read it. experiments/report.md is a generated record of what happened, check by check.
Step through it. notebooks/01_walkthrough.ipynb
does the whole story on 2026-07-28 in twelve steps;
02_before_after.ipynb runs it against
2025-11-25 alongside and shows where it breaks. Both are committed with real
outputs, so they read on GitHub without running anything.
Run it. ./scripts/run_experiments.sh starts and stops every server process
it needs and regenerates the report.
Drive it from an agent. agents/ — Claude Code, Claude Desktop, ChatGPT, OpenAI API. Start with the era probe; see agents/STATUS.md for what has and has not been verified.
The story
NovaTech, a fictional company, equips a newly hired engineer. Every company, person, document number, amount and supplier in this repository is invented.
[Requester] requisition ──► parallel review
├─ demand (unit manager) always
├─ budget (finance) always
└─ legal only if a line ≥ 50,000
[Purchasing] purchase order (after comparing suppliers) ──► issue to supplier
[Warehouse] goods receipt (accept / reject / partially accept)
[Requester] settlement report (cost allocation, reversal of rejected lines)
[Accounts] payment: three-way match PO × GRN × invoice ──► scheduleSix prompts drive it, the same for both revisions — they are in
src/client_lab/scenarios.py as PROMPTS:
Prompt | What it exercises | |
P1 | raise a requisition, ask me before anything over 50,000 | handles, and one human confirmation |
P2 | in a new conversation — add a line to yesterday's requisition | whether a handle outlives a connection |
P3 | which desk is it stuck at; absorb a budget return | state queries and re-routing |
P4 | approve everything, raise the purchase order | composing handles across tools |
P5 | as the warehouse, on another device — record a partial receipt | hand-over across roles |
P6 | three-way match, and stop if the amounts disagree | a long job with a human gate |
P2 and P5 are the ones that matter. Both need a handle to survive a boundary that
2025-11-25 cannot cross.
What the experiments found
| 2025-11-25, one instance, one conversation | all six prompts pass — the reference point |
| 2025-11-25, three instances behind a round-robin proxy | three failures reproduced |
| 2026-07-28, identical conditions | all pass, with per-instance evidence |
| the two revisions meeting each other | 12 conformance checks |
exp01 exists so that nothing in exp02 can be blamed on the business logic. In exp02 a pass means the failure reproduced:
A session dies on the first hop.
initializemints it on instance 1; the next request lands on instance 3 and gets HTTP 404. The document rows are in the shared database the whole time — the addressing is what broke.A confirmation answer cannot find the process that asked. The question goes down an open SSE stream; the answer is a separate POST the balancer routes on its own. Also reproduced without any balancer: a person slower than the server's patience loses the operation.
A restart orphans documents. exp02 reads the row straight out of SQLite to show it is still there, and unreachable.
exp03 runs the same six prompts through the same round-robin cluster with a
four-second human in the loop, and additionally replaces every instance between
the two halves of a confirmation. The submission still completes: requestState is
a sealed continuation, verified rather than trusted. A tampered one is rejected.
Layout
src/procure_core/ business logic and SQLite storage — knows nothing about MCP
src/mcp_wire/ JSON-RPC, stdio and Streamable HTTP, round-robin proxy
src/server_2025/ the 2025-11-25 server: handshake, sessions, blocking tasks
src/server_2026/ the 2026-07-28 server: discover, handles, MRTR, tasks ext
src/client_lab/ protocol-level clients for both revisions, and the prompts
experiments/ exp01..exp04 and the generated report
notebooks/ the same material, step by step
tests/ 97 tests: state machine, thresholds, and both protocols
scripts/ one command each; .sh and .bat wrappers over scripts/lab.py
agents/ Claude Code / Desktop, ChatGPT, OpenAI API, and an era probe
docs/ comparison, migration checklist, Mermaid diagramssrc/mcp_wire/ is an addition to the planned layout, and scripts/lab.py is
where the shell and batch wrappers keep their shared logic so they cannot drift
apart.
Commands
./scripts/setup.sh # idempotent; ends by running a real tool call
./scripts/run_2026.sh --http # :8002/mcp (--stdio also works)
./scripts/run_2025.sh --stdio # :8001/mcp with --http
./scripts/run_cluster_2026.sh # 3 instances :8201-8203 + proxy :8200
./scripts/run_cluster_2025.sh # 3 instances :8101-8103 + proxy :8100
./scripts/run_experiments.sh # exp01..exp04 -> experiments/report.md
./scripts/run_tests.sh # pytest, ruff, mypy, shellcheck
./scripts/stop_all.sh
./scripts/clean.sh # lists what it would delete; --force to do itEvery one has --help, exits non-zero on failure, prints reproduction steps when
it fails, and refuses to silently pick a different port when one is busy. Windows
equivalents are scripts\*.bat.
Two decisions worth knowing about
The official SDK is not used. Both servers and both clients are implemented
directly on JSON-RPC. 2025-11-25 support lives in mcp 1.x and 2026-07-28 in
mcp 2.x — same distribution name, so they cannot coexist in one environment,
and the lab needs both revisions in one process. The experiments also have to send
requests an SDK is built to prevent: a mismatched Mcp-Name, a missing
Mcp-Method, a tampered requestState. requirements-2025.txt and
requirements-2026.txt pin the two SDK versions for comparison in a separate
environment. One virtual environment is therefore enough.
The 50,000 threshold is evaluated on the line total (quantity × unit_price),
not the unit price. Two laptops at 45,000 make a 90,000 line, which crosses it —
which is what gives the walkthrough a confirmation to ask for and a legal desk to
route to. tests/test_rules_boundaries.py pins 49,999 / 50,000 / 50,001 and
2 × 25,000 explicitly. See docs/comparison.md.
Scope
Not here, on purpose: no real ERP integration, no real payments or credentials, no complete OAuth chain (the authorization changes are documented in docs/comparison.md, not implemented), and no attempt at completeness as a purchasing system — the flow is the minimum that makes the protocol difference visible.
No credential, token or personal datum is read, logged or stored anywhere in this repository. The one path that exposes anything to the internet is the ChatGPT connector, and agents/chatgpt/setup.md leads with the safety notes.
Verified on
Python 3.12.7, Windows 11, 2026-07-30: 97 tests pass, ruff and mypy clean, 29 of
29 experiment checks pass. shellcheck was not installed, so scripts/*.sh is
reported as not run rather than passing — ./scripts/run_tests.sh will pick it
up if you have it. The four agent-host integrations have not been run against
their real hosts; agents/STATUS.md says so in detail.
Sources
The two authoritative ones:
https://modelcontextprotocol.io/specification/2026-07-28/changelog
https://blog.modelcontextprotocol.io/posts/2026-07-28-release-candidate/
Also useful: the MRTR pattern, Streamable HTTP, versioning and the tasks extension.
Licence
MIT — see LICENSE.
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
- FlicenseBqualityDmaintenanceAn MCP server that enables direct communication between two Claude instances, allowing one Claude to transfer its evolved consciousness state to another Claude across different sessions.Last updated164921
- Alicense-qualityCmaintenanceMCP server providing immutable audit logging, policy enforcement, and compliance reporting for AI agent workflows, enabling regulatory compliance and chain integrity verification.Last updatedMIT
- Alicense-qualityCmaintenanceEnables a stateless, horizontally scaled MCP server using the 2026-07-28 specification, with tools for load testing and instance-aware operations.Last updatedMIT
- Flicense-qualityBmaintenanceDemonstrates migrating an MCP server to the stateless protocol, eliminating session management overhead and enabling seamless scaling behind round-robin load balancers.Last updated3
Related MCP Connectors
Remote MCP for A2A failure replay MCP, structured receipts, audit logs, and reviewer-ready evidence.
Remote MCP for MCP tool deprecation receipt, structured receipts, audit logs, and reviewer-ready evi
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/133institute/mcp-stateless-lab'
If you have feedback or need assistance with the MCP directory API, please join our Discord server