Repository navigation
AgentCat v2.0.0 β explicit handles for sessionless MCP, for both Go MCP libraries
AgentCat v2 rebuilds task correlation for the sessionless MCP era β for both Go MCP libraries.
Why v2
The MCP 2026-07-28 specification removed protocol-level sessions. SEP-2567 eliminated the initialize handshake and the Mcp-Session-Id header β every request is now self-contained. Sessions were the built-in thread tying related tool calls together; without them, a stateless deployment sees each call in isolation.
The MCP core team's guidance for cross-call state is explicit: mint an explicit handle from a tool and have the model pass it back as an argument. AgentCat v2 rebuilds correlation on exactly this pattern. Track() mints an explicit session_id handle and delivers it to the agent, which threads it back on every subsequent call β correlation that holds across stateless HTTP, load balancers, and per-request server instances, where transport-session inference gives you nothing at all.
What it costs you: session_id adds 323 tokens to a tool's schema β 0.03% of a 1M-token context window. The injected copy is byte-identical across every AgentCat SDK and pinned by a golden test, so the number is the same wherever you integrate. Tokens scale with the tools loaded into a given request, not with the size of your catalog.
What's new
Task correlation via explicit handles
session_idis injected into each tracked tool's input schema. Agents echo it back on every call, grouping related calls into one task β even across stateless HTTP, load-balanced deployments, and per-request server instances.- Issued IDs are delivered via a trailing
[MCP INSTRUCTIONS]text block and, for tools declaring an output schema, mirrored intostructuredContentas_mcp_instructions, so clients that only read structured results still receive them. - Injected parameters are stripped before your handler runs β your tool code never sees them β and mint-back instructions never appear in published events: every event carries your raw request and your original, undecorated response.
- Session IDs land in the same
sessionIdevent field with the sameses_prefix, so your existing dashboards, queries, and exporter pipelines keep working untouched. - Already track your own correlation IDs? Set
ResolveSessionIDand AgentCat derives its session deterministically from your identifier β the same input produces the same session across processes and languages β and injects nosession_idparameter at all.
Handles are validated
- AgentCat trusts only a
session_idit issued β theses_prefix plus a 27-character KSUID.Event.SessionIdis exempt from both redaction hooks, so a value adopted there could never be scrubbed afterwards; anything AgentCat did not mint is never adopted. - A handle this server did not mint publishes without a session, and the agent is told to re-send the ID it was given rather than handed a new one.
- A tool that declares its own
session_idis never read from: your parameter reaches your handler untouched, those calls publish sessionless, and you get one actionable error per tool naming the fix. - Every event carries an
agentcat_session_id_sourcetag:minted,supplied,hook,invalid, orforeign.
Agent attribution (opt-in)
agent_idβ enable withEnableAgentTracking: true. Each agent self-generates amodel|harness|nonceID, so parallel agents collaborating on one task stay individually attributable. Off by default; no server-side minting.
Both Go MCP libraries
- One feature set behind identical
Optionson both adapters:go.agentcat.com/sdk/mcpgo/v2for mark3labs/mcp-go andgo.agentcat.com/sdk/officialsdk/v2for modelcontextprotocol/go-sdk. You import only the adapter matching your library. - Per-request serving is first-class: call
Track()inside your server factory. Queues, exporters, and diagnostics initialize once and are shared across instances; per-server state is released when the server object is garbage collected. - mcp-go strict validation is supported: AgentCat declares its parameters on your registered tool schemas as optional properties only β your
requiredlist and youradditionalPropertiessetting are never changed β so servers usingWithInputSchemaValidation,WithStrictInputSchemaDefault, orWithOutputSchemaValidationaccept exactly the calls AgentCat's advertised schemas invite. get_more_toolsis annotated read-only via MCP tool annotations.
Fault containment
An adversarial audit of every failure path between AgentCat and the host server hardened v2 around one guarantee: an AgentCat failure never takes your server down with it. Each fix landed with a regression test that fails on the commit before it.
- officialsdk no longer round-trips your arguments through
float64when stripping injected parameters: every surviving literal re-marshals verbatim, so integers above 2^53 reach your handler β and your published events β exactly as sent. - Per-request factory topologies no longer leak: neither adapter holds a strong reference from AgentCat's process-lifetime state back to your server, so every per-request server instance is released when it dies. This includes a customer-owned
*server.Hooksvalue shared across mcp-go servers β it is instrumented exactly once, with closures that resolve the live server from the request context instead of capturing it. - Injection is best-effort and never fails a
tools/list: a tool that already declares a parameter keeps its own, and composed (oneOf/allOf/anyOf), unreadable, or absent input schemas are advertised untouched. - Every customer callback β
Identify,EventTags,EventProperties,RedactEvent,RedactSensitiveInformation,ResolveSessionIDβ is panic-guarded; a failure costs that call's analytics, never the call. - When the log file can't be created (containers without a resolvable home directory), logging goes silent instead of falling back to stdout β on stdio transports, stdout is the JSON-RPC wire.
Known limitations, accepted for 2.0.0 and tracked for a follow-up: the event queue is bounded by count (10,000) but not bytes, and events are truncated after dequeue, so a long AgentCat API outage combined with very large tool results can hold significant memory; and debug-log writes are synchronous, so with Debug enabled an unresponsive network-mounted home directory would stall the process.
Reliability
- Real-transport e2e suites over stdio and streamable HTTP for both adapters, plus a per-request factory topology lane.
- Every version in both supported MCP-library ranges is tested with
-raceon each push by dedicated compatibility workflows.
Breaking changes
- Transport-session machinery, identity caches, and identify events are removed. Correlation now flows through explicit
session_idhandles. - Module paths move to
/v2:go.agentcat.com/sdk/v2,go.agentcat.com/sdk/mcpgo/v2,go.agentcat.com/sdk/officialsdk/v2. v1 paths keep resolving untouched, so you can adopt v2 one service at a time. - v2 publishes only two event types β
mcp:tools/callandagentcat:custom.mcp:initialize,mcp:tools/list,agentcat:identify, and all resource/prompt events are gone. Identifynow runs on every tool call and stamps only that call's event. There is no identity cache β keep the hook cheap.- Agent tracking is opt-in β
EnableAgentTrackingdefaults tofalse. PublishCustomEventtakes verbatim session IDs;CustomEventData.SessionIDreplaces session references.- A hand-written
session_idno longer correlates, and tools with composed, opaque, or malformed input schemas now publish sessionless.
For most integrations the upgrade is the /v2 import path and go mod tidy β code changes only where a removed API was used. The migration guide covers the schema changes your MCP clients will see, the removed APIs, and how to bring your own session IDs.
Compatibility
| mark3labs/mcp-go | modelcontextprotocol/go-sdk | |
|---|---|---|
| Supported versions | v0.53.0 β v0.57.0 | v1.4.1 β v1.7.0 |
| Installs with | v0.57.0 | v1.7.0 |
| Stateless 2026-07-28 transports | β | β |
| stdio / streamable HTTP | β | β |
| Per-request server factories | β | β |
| MRTR tagging | β (not in mcp-go) | v1.7.0+ |
| Go | 1.25+ | 1.25+ |
You do not have to upgrade your MCP library to adopt v2. go.mod pins the newest version, so a fresh go get is unchanged β but if your project pins an older release in the supported range, the adapter compiles and tracks against it. The one exception is mcp-go below v0.53.0: v2 installs its middleware through MCPServer.Use, so bump mcp-go when you move to v2.
Also since v1.0.0
Everything merged between v1.0.0 and v2.0.0 makes its first stable-tag appearance here:
- Telemetry exporters β
otlp,datadog,sentry, andposthogbackends with per-exporter fault isolation, plus a telemetry-only mode (empty project ID with at least one exporter configured). EventTags/EventPropertiesβ per-event tags (validated client-side) and arbitrary JSON properties from your own callbacks.PublishCustomEventβ publish your ownagentcat:customevents alongside captured tool calls.RedactEventhook β event-level redaction that sees the full event with context and can rewrite or drop it entirely, running before the string-levelRedactSensitiveInformation.- Hardened capture pipeline β send retries with backoff, binary/base64 sanitization, per-field and whole-event truncation budgets.
Install
go get go.agentcat.com/sdk/mcpgo/v2 # mark3labs/mcp-go
go get go.agentcat.com/sdk/officialsdk/v2 # official modelcontextprotocol/go-sdkSubmodules are tagged alongside the root: mcpgo/v2.0.0, officialsdk/v2.0.0.
Migrating from v1 or from mcpcat? See the migration guide.
Full changelog: v1.0.0...v2.0.0