Recorded sessions
Two recorded exchanges with the demo server, one per era of the protocol, and the browser debug page that calls a server by hand. Each message is listed in order: the request the client sent, then the reply the server gave.
MCP 2026-07-28 · 2025-11-25 · 2024-11-05 · Streamable HTTP · stdio
Revision 2026‑07‑28 — stateless
No handshake. Every request names its version in _meta, and the server answers it on its own. Client and server keep no shared state between calls.
List, call, read
Field names are the ones on the wire. resultType and the _meta server info are this revision's additions; the tools array is cut to two entries to fit the page.
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list",
"params": {
"_meta": {
"io.modelcontextprotocol/protocolVersion": "2026-07-28",
"io.modelcontextprotocol/clientCapabilities": {}
}
}
}
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"tools": [
{ "name": "add", "title": "Add", "description": "Add two numbers",
"inputSchema": { "type": "object",
"properties": { "a": { "type": "number" }, "b": { "type": "number" } },
"required": ["a", "b"] } },
{ "name": "greet", "title": "Greet", "description": "Greet someone by name",
"inputSchema": { "type": "object",
"properties": { "name": { "type": "string" } }, "required": ["name"] } }
],
"resultType": "complete",
"_meta": { "io.modelcontextprotocol/serverInfo": { "name": "demo", "version": "1.0.0" } },
"ttlMs": 0,
"cacheScope": "private"
}
}
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "add",
"arguments": { "a": 2, "b": 3 },
"_meta": { "io.modelcontextprotocol/protocolVersion": "2026-07-28", "io.modelcontextprotocol/clientCapabilities": {} }
}
}
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"content": [ { "type": "text", "text": "{\"sum\":5}" } ],
"structuredContent": { "sum": 5 },
"isError": false,
"resultType": "complete",
"_meta": { "io.modelcontextprotocol/serverInfo": { "name": "demo", "version": "1.0.0" } }
}
}
{
"jsonrpc": "2.0",
"id": 3,
"method": "resources/read",
"params": {
"uri": "config://app",
"_meta": { "io.modelcontextprotocol/protocolVersion": "2026-07-28", "io.modelcontextprotocol/clientCapabilities": {} }
}
}
{
"jsonrpc": "2.0",
"id": 3,
"result": {
"contents": [ { "uri": "config://app", "mimeType": "application/json", "text": "{\"theme\":\"dark\"}" } ],
"resultType": "complete",
"_meta": { "io.modelcontextprotocol/serverInfo": { "name": "demo", "version": "1.0.0" } },
"ttlMs": 0,
"cacheScope": "private"
}
}
Revision 2025‑11‑25 — the handshake
The older shape. A client opens with initialize, reads the server's capabilities, and only then lists, calls and renders. moonmcp answers every revision back to 2024‑11‑05 without a config change.
initialize, then work
A request that does not name a version falls back to this handshake. The same server, the same tools — only the opening moves differ.
{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2025-11-25",
"capabilities": {},
"clientInfo": { "name": "claude-desktop", "version": "1.0.0" }
}
}
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"protocolVersion": "2025-11-25",
"capabilities": {
"tools": { "listChanged": false },
"resources": { "subscribe": false, "listChanged": false },
"prompts": { "listChanged": false }
},
"serverInfo": { "name": "demo", "version": "1.0.0" },
"instructions": "Arithmetic and greetings, for trying a client out."
}
}
{
"jsonrpc": "2.0",
"method": "notifications/initialized"
}
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": { "name": "greet", "arguments": { "name": "leo" } }
}
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"content": [ { "type": "text", "text": "hello, leo" } ],
"isError": false
}
}
{
"jsonrpc": "2.0",
"id": 3,
"method": "prompts/get",
"params": { "name": "review", "arguments": { "code": "fn f() { 1 }" } }
}
{
"jsonrpc": "2.0",
"id": 3,
"result": {
"description": "Ask for a code review",
"messages": [
{ "role": "user", "content": { "type": "text", "text": "Review this code:\nfn f() { 1 }" } }
]
}
}
The debug page
Give to_asgi a path and a browser page appears beside the endpoint: it lists every capability, fills a form from each input schema, and shows the JSON-RPC request beside the reply — in either era.
Run it yourself
The captures above are the demo server over Streamable HTTP. Build it for native and the documentation page is served at /docs next to the endpoint:
moon run src/examples/http --target nativeThen open http://127.0.0.1:12000/docs. to_asgi(docs=None) leaves it off.