> ## Documentation Index
> Fetch the complete documentation index at: https://mcp-use.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

<AgentInstructions>

## Submitting Feedback

If you encounter incorrect, outdated, or confusing documentation on this page, submit feedback:

POST https://mcp-use.com/docs/feedback

```json
{
  "path": "/python/server/sessions",
  "feedback": "Description of the issue"
}
```

Only submit feedback when you have something specific and actionable to report.

</AgentInstructions>

# Session Management

> Using session IDs in MCP servers

Sessions keep per-client state (caching, auth, limits). Managed by the MCP SDK via `mcp-session-id` HTTP header (spec: [https://modelcontextprotocol.io/specification/2025-11-25/basic/transports#session-management](https://modelcontextprotocol.io/specification/2025-11-25/basic/transports#session-management)).

## How it works

* SDK generates a UUID when no session header is present.
* Server returns it in `mcp-session-id` on initialize.
* Client sends the header on all requests.
* Server reuses the session; middleware sees it as `context.session_id`.

## Get session ID

```python theme={null}
# Middleware
sid = context.session_id or "anonymous"

# Tool
@server.tool()
def session_id() -> dict:
    sid = server._get_session_id_from_request()
    return {"session_id": sid, "short": sid[:8] if sid else None}
```

## Per-session patterns (minimal)

**State / rate limit / cache key** by `context.session_id or "anonymous"`:

```python theme={null}
class SessionState(Middleware):
    def __init__(self): self.counts = defaultdict(int)
    async def on_request(self, ctx, nxt):
        sid = ctx.session_id or "anonymous"
        self.counts[sid] += 1
        return await nxt(ctx)
```

Per-session cache:

```python theme={null}
class SessionCache(Middleware):
    def __init__(self): self.c = defaultdict(dict)
    async def on_read_resource(self, ctx, nxt):
        sid = ctx.session_id or "anonymous"
        uri = str(ctx.message.uri)
        cache = self.c[sid]
        if uri in cache: return cache[uri]
        res = await nxt(ctx); cache[uri] = res; return res
```

## Notes

* Only available on Streamable HTTP transport; stdio has no sessions.
* Use per-session storage to avoid data leakage.
* Keep session data lean; expire if needed.
