Sessions and transport

The server speaks MCP's Streamable HTTP transport at one URL, https://api.pawsitivefuture.org/mcp.

Why it has sessions

A change asks the person to confirm it. That confirmation is a request the server sends the client in the middle of a tool call, and the answer comes back on a separate POST. Only a session ties the two together, so /mcp is stateful.

  • A client opens a session with initialize and carries the Mcp-Session-Id it is given on every request after.
  • One JSON-RPC message per request. MCP removed batching in the 2025-06-18 revision, so a session is opened by an initialize on its own.
  • A session belongs to the person who opened it. Another person presenting the id gets the same 404 as an unknown one.
  • DELETE /mcp ends a session. A session idle for 30 minutes is closed. GET /mcp answers 405.
  • Sessions are held in memory, so a client that receives 404 starts a new one with initialize.

Raw examples

Every request carries the access token and both content types. This opens a session:

bash
curl -i https://api.pawsitivefuture.org/mcp \
  -H 'Authorization: Bearer <access token>' \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -d '{
    "jsonrpc": "2.0", "id": 1, "method": "initialize",
    "params": {
      "protocolVersion": "2025-06-18",
      "capabilities": { "elicitation": {} },
      "clientInfo": { "name": "my-client", "version": "1.0.0" }
    }
  }'

The response carries the Mcp-Session-Id header. After the notifications/initialized notification, list the tools and call one with that header on each request:

json
{ "jsonrpc": "2.0", "id": 2, "method": "tools/list" }
json
{
  "jsonrpc": "2.0",
  "id": 3,
  "method": "tools/call",
  "params": { "name": "get_auth_me", "arguments": {} }
}

Declaring elicitation in capabilities matters: without it the client cannot be asked to confirm, and every changing tool is refused. Each tool's page has its own example call.