mcp-stateless
Skill7 starsChanged 18 days agoMITView on GitHub
MCP knowledge pack for the stateless 2026-07-28 revision.
In this repository15 other files it gives its agents.
- askamaSkill
- cargo-toml-optimizationSkill
- clean-codeSkill
- clean-flutterSkill
- clean-rustSkill
- clean-shellSkill
- docs-syncSkill
- emulator-testingSkill
- maudSkill
- name-checkSkill
- ratatui-patternsSkill
- terminal-uxSkill
- todoSkill
- ux-patternsSkill
- webapp-testingSkill
The file
We split this skill into the rules it gives an agent
1 rule. About 0 are common, 0 are distinctive, and 1 is very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈0
Distinctive · estimate
This author's own choices. Worth a look.
1
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 18
Never write MCP wire code from memory: Read references/wire.md first.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
MCP Stateless
The Model Context Protocol went stateless in revision 2026-07-28. It is the largest break since launch: the initialize handshake, the session id, the standalone SSE stream, and server-initiated requests are all gone. Every request now carries everything a server needs to answer it.
Model training data predates this revision. An MCP server written from memory speaks the 2025-11-25 protocol and will be rejected by a modern client. The failure is not a compile error and often not a runtime error either: a handshake-era server and a modern client fail in ways that read like a config problem. Work from the reference files here, and check anything version-sensitive against the live spec.
Hard Rules
- Never write MCP wire code from memory. Read
references/wire.mdfirst. If a claim here is older than the revision you are targeting, the live spec wins. - State is a lie the connection tells you. A server MUST NOT infer anything from a previous request on the same connection: not the protocol version, not capabilities, not client identity, not conversation continuity. One stdio process is not one session. A client may interleave unrelated requests on it.
- State that must span requests gets an explicit server-minted handle passed back as an ordinary parameter. There is no session to hang it on.
- A server MUST answer
server/discover. It is the only way left to advertise what the server supports, and it is how a dual-era client tells a modern server from a legacy one. - Every result carries
resultType. Omitting it marks the server as legacy. A result with noresultTypeMUST be read as"complete". - Servers never send JSON-RPC requests. Sampling, elicitation, and roots all run through multi round-trip requests: the server answers with
input_required, the client retries. Readreferences/mrtr.mdbefore wiring any of the three. requestStatecomes back from the client unverified. Sign or encrypt it. A stateless server that trusts an echoed blob has handed the client its internal state machine.- Verify with a live handshake against the real binary. A green build proves nothing about protocol conformance, and the old smoke-test recipe (pipe an
initializeframe) now tests a method that no longer exists. Recipe inreferences/sdks.md.
What Changed
2025-11-25 and earlier | 2026-07-28 | Silent-failure risk if you keep the old shape |
initialize + notifications/initialized | Removed. Per-request _meta carries version, capabilities, identity | High. A modern client gets an implementation-defined error, or worse, silence |
Mcp-Session-Id header, DELETE to end a session | Removed. Servers ignore the header and never mint one | High. Session-keyed caches and per-session state silently serve the wrong tenant |
| Capabilities exchanged once at connect | server/discover (servers MUST implement), plus per-request io.modelcontextprotocol/clientCapabilities | High. A server reading capabilities from a remembered handshake reads nothing |
| Results had no discriminator | Every result MUST carry resultType: "complete" or "input_required" | Medium. Clients treat a missing field as "complete", so a real MRTR reply gets mis-parsed |
Server sends sampling/createMessage, elicitation/create, roots/list as requests | MRTR: server returns InputRequiredResult, client retries the original request with inputResponses | High. The old pattern is explicitly no longer supported |
Standalone HTTP GET SSE stream; resources/subscribe / unsubscribe | subscriptions/listen: one long-lived POST-response stream, client opts into notification types | Medium. A modern-only server SHOULD answer GET with 405 |
Last-Event-ID resumption, SSE event ids | Removed. A broken stream loses the in-flight request; the client re-issues with a new request id | Medium. Resumption code silently never fires |
ping, logging/setLevel, notifications/roots/list_changed | Removed from the core protocol | Medium. Kept in SDKs only for legacy sessions |
| Log verbosity set once per session | Per-request io.modelcontextprotocol/logLevel in _meta. A server MUST NOT emit notifications/message for a request that omitted it | Medium. Log notifications stop arriving and nothing reports an error |
| List results were plain | tools/list, prompts/list, resources/list, resources/templates/list, resources/read, server/discover MUST carry ttlMs + cacheScope | Low. Clients default to "immediately stale" and re-fetch every time |
| Streamable HTTP POST carried no routing metadata | Mcp-Method + Mcp-Name headers REQUIRED, validated against the body; mismatch is 400 + -32020 | High on HTTP. A gateway routing on headers and a server executing the body is the vulnerability this closes |
| Tasks were experimental core | The io.modelcontextprotocol/tasks extension. tasks/list and tasks/result are gone | Medium. No compatibility shim |
Resource-not-found was -32002 | -32602 (Invalid Params). Accept -32002 inbound from older servers | Low |
Deprecated, Not Yet Removed
Still in the spec, still functional. New code SHOULD NOT adopt them. The removal clocks differ per feature, so read the column rather than assuming one date.
| Feature | Migrate to | Earliest removal |
| Roots | Directories or files as tool parameters, resource URIs, or server configuration | First revision on or after 2027-07-28 |
| Sampling | The LLM provider's API directly | First revision on or after 2027-07-28 |
| Logging | stderr on stdio; OpenTelemetry for structured observability | First revision on or after 2027-07-28 |
| OAuth Dynamic Client Registration | Client ID Metadata Documents | First revision on or after 2027-07-28 |
includeContext: "thisServer" / "allServers" | Omit the field, or "none" | Follows Sampling |
HTTP+SSE transport (the 2024-11-05 one) | Streamable HTTP | Three months after SEP-2596 reaches Final, which may already have elapsed |
The specification now runs a formal feature lifecycle (Active, Deprecated, Removed) with a minimum twelve-month deprecation window and a published registry, so a feature disappearing without notice is no longer the failure mode. Checking the registry before adopting anything is.
Files
Load the one matching the task. Do not load them all.
| Task touches | File |
Wire shapes: _meta keys, server/discover, resultType, error codes, HTTP headers, caching, subscriptions, transports | references/wire.md |
Sampling, elicitation, roots, InputRequiredResult, requestState and its security | references/mrtr.md |
| Porting an existing server or client, supporting both eras, what breaks silently | references/migrate.md |
| Which SDK version speaks which revision, per-SDK API shape, how to smoke-test a built server | references/sdks.md |
What This Skill Does Not Cover
- Server design: which tools to expose, how to carve a large API surface, deployment model, bundling for local install. That is a product question, and the official
mcp-server-devplugin (anthropics/claude-plugins-official) runs a discovery interview for it. Check its pinned versions before trusting its protocol claims; as of 2026-08 its version-pin file records the MCP spec claims as last verified 2026-03, which is the2025-11-25era. - MCP Apps / UI widgets beyond how the extension is negotiated.
- Authorization in depth. The revision tightened OAuth (issuer validation, credentials keyed by issuer,
application_typeon registration, Client ID Metadata Documents over DCR).references/migrate.mdlists what changed; the auth spec pages are the authority.
Live Docs on Demand
The spec ships agent-readable markdown: append .md to any spec URL.
| Need | URL |
| Page index | https://modelcontextprotocol.io/llms.txt |
| Revision changelog | https://modelcontextprotocol.io/specification/2026-07-28/changelog.md |
Statelessness, _meta, error codes | .../specification/2026-07-28/basic/index.md |
| Version negotiation, extensions, dual-era matrix | .../specification/2026-07-28/basic/versioning.md |
| Deprecated-features registry | .../specification/2026-07-28/deprecated.md |
| Full schema reference | .../specification/2026-07-28/schema.md |
Fetch the schema page before asserting any field name. Field names in this skill were read from the spec; field names in a model's memory were not.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

