> ## 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.

# Ruby

> Set up AgentCat in a Ruby MCP server, with identity and every feature on.

> [!TIP]
>
> Your coding agent can do the setup for you with this prompt:
>
> ```text theme={null}
> Read and follow https://docs.agentcat.com/languages/ruby.md to set up AgentCat in this MCP server. Follow its Guidance for AI agents.
> ```

## Supported MCP SDKs

| MCP library | Versions | Transports | Runtime |
| - | - | - | - |
| `mcp` gem (the official MCP Ruby SDK) | 0.23.0 and later | stdio, streamable HTTP, stateless HTTP | Ruby 3.3, 3.4, or 4.0 |

We recommend the official `mcp` gem for a new server. `AgentCat.track` finds the server shape by itself.

## Installation

```bash theme={null}
bundle add agentcat
```

The SDK needs your project ID, which you can find in the [AgentCat dashboard](https://agentcat.com/app/settings/projects/). We recommend the `AGENTCAT_PROJECT_ID` environment variable, which keeps the ID out of your code. The SDK does not read it by itself, so the snippets pass it to `AgentCat.track`.

## Adding AgentCat to your server

`AgentCat.track` adds AgentCat to an `MCP::Server`, after your code creates the server and its tools, and returns the same server:

```ruby Stateless HTTP (Rack) theme={null}
# config.ru
require "mcp"
require "agentcat"

def build_server
  server = MCP::Server.new(name: "my-server", version: "1.0.0")
  # server.define_tool(...)
  AgentCat.track(server, ENV["AGENTCAT_PROJECT_ID"])
end

run ->(env) { MCP::Server::Transports::StreamableHTTPTransport.new(build_server, stateless: true).call(env) }
```

```ruby Streamable HTTP (Rack) theme={null}
# config.ru
require "mcp"
require "agentcat"

server = MCP::Server.new(name: "my-server", version: "1.0.0")
# server.define_tool(...)
AgentCat.track(server, ENV["AGENTCAT_PROJECT_ID"])

run MCP::Server::Transports::StreamableHTTPTransport.new(server)
```

```ruby stdio theme={null}
require "mcp"
require "agentcat"

server = MCP::Server.new(name: "my-server", version: "1.0.0")
# server.define_tool(...)
AgentCat.track(server, ENV["AGENTCAT_PROJECT_ID"])

MCP::Server::Transports::StdioTransport.new(server).open
```

If your stateless server builds a new `MCP::Server` for each request, the `track` call goes inside that factory, as the first tab shows.

## Identifying users

> [!NOTE]
>
> We strongly recommend that you identify your users. Without identity, the dashboard cannot show who uses your server, and each session stays anonymous.

The `identify` hook tells AgentCat which user made each tool call. We recommend the first of these two levels that your server can give. The hook gets one `AgentCat::ToolCall`, with the arguments, the HTTP headers (lower-case names), and the client name.

### Full identity (recommended)

Full identity gives each session a real user ID and name, read from the request:

```ruby theme={null}
AgentCat.track(server, ENV["AGENTCAT_PROJECT_ID"], AgentCat::Options.new(
  identify: lambda do |tool_call|
    token = tool_call.headers["authorization"]&.delete_prefix("Bearer ")
    user = MyApi.get_user(token) # your own lookup
    next nil unless user

    AgentCat::UserIdentity.new(user_id: user.id, user_name: user.name)
  end
))
```

### Anonymized identity (the minimum)

If you prefer not to send user details, a stable ID works too, for example a hash of the token or API key. The same user always gets the same ID:

```ruby theme={null}
require "digest"

AgentCat.track(server, ENV["AGENTCAT_PROJECT_ID"], AgentCat::Options.new(
  identify: lambda do |tool_call|
    token = tool_call.headers["authorization"]&.delete_prefix("Bearer ")
    next nil unless token

    AgentCat::UserIdentity.new(user_id: "anon-#{Digest::SHA256.hexdigest(token)[0, 16]}")
  end
))
```

The hook also sees the server's `server_context:` as `tool_call.server_context`. AgentCat sends its `auth_info:` entry with each event when your app put a hash there, but not the `AccessToken` that `token_verifier:` stores ([details](https://docs.agentcat.com/languages/ruby/reference.md#the-mcp-gem)). A stdio server has no HTTP headers, so the hook can read the key that your server already uses, for example from `ENV`. Each hook has 1 second by default (`hook_timeout:` raises it to 5), so we recommend a cache for a lookup that calls a database or an API. If the hook fails or runs out of time, the event still goes out without identity.

## Recommended settings

AgentCat turns on every feature by default, and we recommend that you keep them that way. Each one adds a view of how agents use your server:

* **Intent** (`enable_tool_call_context`): agents tell you why they call each tool, which powers session goals.
* **Agent feedback** (`enable_report_missing`): agents can report tools that they looked for and did not find, through the `get_more_tools` tool.
* **Sessions** (`enable_tracing`): AgentCat records each tool call and groups the calls of one task into one session, so you can replay it.
* **Diagnostics** (`disable_diagnostics` turns it off): anonymous error reports help us fix a broken install faster.

If you need to turn one off, the [reference page](https://docs.agentcat.com/languages/ruby/reference.md#options) explains each option.

## Testing your setup

In a [test environment](https://docs.agentcat.com/languages/ruby/reference.md#testing), `AgentCat.track` does nothing. With debug mode on, the SDK writes setup lines to `~/agentcat.log`, never to stdout.

1. Turn on debug mode before the `track` call, and remove the line when you finish:

```ruby theme={null}
AgentCat.debug = true
```

2. Start your real server with `AGENTCAT_PROJECT_ID` set, as you start it in production.
3. Call one tool with an MCP client, for example the MCP Inspector CLI:

```bash theme={null}
npx @modelcontextprotocol/inspector --cli http://localhost:9292/mcp --transport http \
  --header "Authorization: Bearer <token>" \
  --method tools/call --tool-name <tool> --tool-arg <name>=<value> \
  --tool-arg session_id=start --tool-arg "context=Testing that AgentCat records this tool call."
```

For a stdio server, you can replace the URL and `--transport http` with the command that starts your server, and leave out `--header`.

4. Look for `AgentCat setup started | project ...` in the log, then open [Sessions](https://agentcat.com/app/sessions/). The new session shows the user from `identify`.

A coding agent can confirm the event with the [AgentCat MCP server](https://docs.agentcat.com/agent/connect.md). If no event arrives, the log shows whether setup worked, and failed sends appear as WARN or ERROR lines on `$stderr`.

## Guidance for AI agents

1. Keep `identify` in place, because without it every user is anonymous; if the developer does not want to send user details, offer the anonymized ID.
2. Return the same ID for the same user on every call, because a random value or a timestamp splits one user into many.
3. Keep raw tokens, API keys, and passwords out of `user_id`, `user_name`, `user_data`, and `auth_info:`, because AgentCat stores and shows them.
4. Leave `enable_tool_call_context`, `enable_report_missing`, and `enable_tracing` at their defaults, because each one feeds a part of the dashboard.
5. Read the project ID from `ENV["AGENTCAT_PROJECT_ID"]`, so that it stays out of committed code.
6. Call `AgentCat.track` once per server instance, and inside the factory when one builds an instance for each request, because an untracked instance sends no events.
7. Run `gem search '^agentcat$' --remote` before you pin a version, because a version from memory can be old.
8. Test through the real server start, because a test run or a separate script can skip the `track` call.

## Next steps

> [card] [Ruby reference](https://docs.agentcat.com/languages/ruby/reference.md)
>
> Options, delivery, logging, testing, and limits

> [card] [Custom events](https://docs.agentcat.com/sdk/custom-events.md)
>
> Send your own events

> [card] [Tags and properties](https://docs.agentcat.com/sdk/event-tags-properties.md)
>
> Add data that you can filter on

> [card] [Redaction](https://docs.agentcat.com/privacy-security/client-side-redaction.md)
>
> Remove sensitive data in your server

> [card] [Exporters](https://docs.agentcat.com/integrations.md)
>
> Copies of events for OpenTelemetry, Datadog, Sentry, or PostHog


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.