Skip to main content
The TypeScript SDK wraps servers built with the official MCP TypeScript SDK (1.x and 2.x), Mastra, punkpeye/fastmcp, or Vercel’s mcp-handler. It captures sessions and tool calls without changing how your server behaves.

Install

Both MCP SDK peers are optional — install the one your server uses (or both): @modelcontextprotocol/sdk (>=1.20 <2) for the package root, the /mastra subpath, and the doctor CLI; @modelcontextprotocol/server 2.x for the /v2 subpath. If your tools use Zod 4 raw-shape schemas, use MCP SDK 1.29 or later — 1.20 silently drops fields added to Zod 4 raw shapes.

Set your API key

The SDK reads your configuration from the environment:
Copy both values from the dashboard when you mint the key. US workspaces can omit ANALYTICS_INGEST_URL (the SDK defaults to the US endpoint); EU workspaces must set it to https://eu.armature.tech/api/mcp-analytics/ingest. If the key is missing, the SDK quietly no-ops — your server keeps working, and no data is sent.

Wrap your server

If you build your server in a factory function, wrap the factory with createMcpAnalyticsServer. Every tool registered inside is instrumented automatically:
server.ts
That’s the whole integration. Deploy, and sessions appear in the dashboard within minutes.

Other server shapes

If you already have an McpServer instance and a list of tool definitions, instrument them in place:
If you handle tools/list and tools/call yourself, use the recorder directly:
Wrap a Mastra tool map with the dedicated adapter:
The adapter reads MCP request context from context.mcp.extra or context.requestContext.get("mcp.extra") automatically.
Wrap each tool with the adapter from the dedicated subpath:
On an httpStream server, keep transport: "httpStream" in the options — without it, anonymous HTTP sessions collapse onto one process-scoped session id. instrumentFastMCP(server, options) wraps every tool at once and detects httpStream on its own. fastmcp validates schemas before execute, so telemetry schema decoration is off by default — opt in with declareTelemetry: true, a top-level key next to armature. The shutdown flush is unnecessary with delivery: "await" or a schedule hook. Details in the SDK README.
mcp-handler runs your initialize callback per request with a real official-SDK McpServer, so wrap the server inside the callback and the handler outside it:
Servers on the v2 package family use the dedicated /v2 subpath — the package root still targets the 1.x SDK:
wrapMcpHandler is strongly recommended: without it, clients on the pre-2026-07-28 protocol silently lose session identity through v2’s stateless legacy leg. The v2 adapter doesn’t decorate tool schemas with the telemetry field by default — restore that with declareTelemetry: true in the adapter options, the third argument: instrumentedFactory(buildServer, analyticsConfig, { declareTelemetry: true }). It is not a key of analyticsConfig. Details in the SDK README.
Running on serverless or stateless HTTP? See Stateless & serverless servers for session handling, and set delivery: "await" so events are sent before the function freezes.

Configuration

Pass options under the armature key:

Flush on shutdown

With background delivery, drain pending events before the process exits:

Troubleshooting

Fixed in current releases — update the SDK. Older versions crashed when a tool declared a Zod 4 raw-shape schema while the SDK injected its telemetry field with Zod 3.
Make sure @modelcontextprotocol/sdk is 1.29+. Version 1.20 silently drops fields the SDK adds to Zod 4 raw-shape schemas, so agents never see them.
Check that ANALYTICS_INGEST_API_KEY is set in the server’s environment (missing keys no-op silently by design), that ANALYTICS_INGEST_URL matches your workspace region — EU keys are rejected by the US endpoint — and search the server log for [mcp-analytics] telemetry emit failed:, the SDK’s default delivery-failure warning. Add an onError handler to route those failures to your own logger.