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

# Stateless Servers

> Set up AgentCat for a stateless MCP server for better horizontal scaling support.

## What are stateless MCP servers?

Today many MCP servers use a stateful implementation where the client maintains a persistent connection. AgentCat'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.

AgentCat works for stateless MCP servers that pass an identity function. It uses the user's identity and client to group sessions.

<Info>
  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.
</Info>

## Setup

Pass the `stateless` option when tracking your server:

<CodeGroup>
  ```typescript TypeScript theme={null}
  agentcat.track(mcpServer, "proj_YOUR_PROJECT_ID", {
    stateless: true
  });
  ```

  ```python Python theme={null}
  agentcat.track(server, "proj_YOUR_PROJECT_ID",
               agentcat.AgentCatOptions(stateless=True))
  ```

  ```go Go theme={null}
  mcpcat.Track(s, "proj_YOUR_PROJECT_ID", &mcpcat.Options{
      Stateless: true,
  })
  ```
</CodeGroup>

This is the recommended approach — it's clear, reliable, and works with any transport or framework.

<Note>
  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`.
</Note>

## How sessions are grouped

When AgentCat 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. AgentCat 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, so `identify` runs every time. Keep your identify function lightweight by avoiding expensive API calls or database lookups if possible.

<Warning>
  Without an identify function, stateless tracking is severely limited. Every event becomes its own anonymous session with no way to group them.
</Warning>

Learn more about setting up user identification in [Identifying Users](/sdk/identifying-users).
