What are stateless MCP servers?
Today many MCP servers use a stateful implementation where the client maintains a persistent connection. MCPcat’s SDK can track a session across that connection naturally since it maintains a session ID when the client connects and associates all events with it. Stateless MCP servers don’t maintain a session ID and each request is an independent HTTP call with no persistent connection. This is most commonly done to support horizontal scaling. MCPcat works for stateless MCP servers that pass an identity function. It uses the user’s identity and client to group sessions.There are changes coming to the protocol and MCP SDKs to make servers stateless by default. For now, it’s currently opt-in for all SDKs.
Setup
Pass thestateless option when tracking your server:
If you’re using FastMCP with
stateless_http=True and don’t set the stateless option explicitly, the Python SDK will attempt to detect stateless mode automatically. You can explicitly force stateless mode off by setting stateless=False.How sessions are grouped
When MCPcat receives events without a session ID, it groups them using three dimensions: the identified user, the AI client (e.g., Claude Desktop, Cursor), and a 30-minute inactivity window. If two events come from the same user via the same client within 30 minutes of each other, they belong to the same session. Different AI clients get separate sessions, even for the same user. If someone is interacting via both Claude Desktop and Cursor simultaneously, those are distinct sessions. Events without an identified user (anonymous) each get their own isolated session. MCPcat can’t group what it can’t identify.| Event | User | Client | Timestamp | Assigned Session |
|---|---|---|---|---|
| 1 | alice | Claude Desktop | 10:00 | ses_001 |
| 2 | bob | Cursor | 10:02 | ses_002 |
| 3 | alice | Claude Desktop | 10:15 | ses_001 (reused, within 30 min) |
| 4 | alice | Cursor | 10:20 | ses_003 (different client) |
| 5 | alice | Claude Desktop | 10:55 | ses_004 (new session, >30 min from event 3) |
Why identifying users matters
In stateless mode, every request is independent, soidentify runs every time. Keep your identify function lightweight by avoiding expensive API calls or database lookups if possible.
Learn more about setting up user identification in Identifying Users.