Skip to main content
Glama
Abhishek-B-R

agnost-workers-mcp

by Abhishek-B-R

Cloudflare Workers MCP + Agnost trackMCP

Add Agnost AI analytics to an MCP server running on Cloudflare Workers

Agnost's MCP docs cover TypeScript, Python FastMCP, Go, and Anthropic. Nothing for Workers. This repo is that missing page: a remote MCP server on Cloudflare Workers with trackMCP wired in, one-command deploy, session reuse, retries, checkpoints, and a deliberate failure path so you can prove Events land in app.agnost.ai.

Official docs: MCP overview · TypeScript SDK

MCP client  →  Cloudflare Worker (/mcp)  →  Agnost capture-session / capture-event
                      │
                      └─ Workers-native trackMCP (src/lib/track-mcp.ts)

Install

git clone https://github.com/Abhishek-B-R/agnost-workers-mcp
cd agnost-workers-mcp
npm install
cp .dev.vars.example .dev.vars
# paste your org id from app.agnost.ai → Settings → Organization

Related MCP server: Remote MCP Server on Cloudflare

Integrate

import { trackMCP, checkpoint } from "./lib/track-mcp";

trackMCP(server, env.AGNOST_ORG_ID, {
  env: env as Record<string, string | undefined>,
  waitUntil: (p) => ctx.waitUntil(p),
  identify: (request) => ({
    userId: request?.headers?.["x-user-id"] || "anonymous",
    email: request?.headers?.["x-user-email"],
  }),
});

Same call shape as the npm package. The implementation is Workers-native because agnost@0.2.1 does not record events on Workers. Details in WHAT-BROKE.md.

Options

trackMCP(server, orgId, {
  disableInput: false,
  disableOutput: false,
  endpoint: "https://api.agnost.ai",
  maxRetries: 2,
  requestTimeoutMs: 5000,
  identify: (request, env) => ({
    userId: request?.headers?.["x-user-id"] || "anonymous",
    email: request?.headers?.["x-user-email"],
  }),
  waitUntil: (p) => ctx.waitUntil(p),
});

Checkpoints

server.registerTool("simulate_pipeline", { ... }, async ({ query }) => {
  checkpoint("fetch_start", { query });
  // ...
  checkpoint("fetch_done", { rows: 3 });
  return { content: [{ type: "text", text: "..." }] };
});

Checkpoints appear as a timeline in the Agnost dashboard.

What this template proves (not a hello-world)

Tool

Why it exists

hello

Minimal happy path for first Event

simulate_pipeline

Multi-step checkpoint timeline

fail_on_purpose

Failed tool calls still visible in Events

whoami

Confirms identify() header wiring

Under the hood:

  • nodejs_als only (not full nodejs_compat) so concurrent requests get isolated checkpoint stores via AsyncLocalStorage

  • Session reuse keyed by org + user + mcp-session-id, so consecutive calls form one conversation instead of one session per call

  • fetch with cache: "no-store", retries on 5xx/429, payload truncation, waitUntil so analytics outlive the response

  • Analytics never breaks the tool: network failures are logged and swallowed

Deploy

npx wrangler secret put AGNOST_ORG_ID
npm run deploy

One command after the secret is set.

  • Docs page: https://<worker>.workers.dev/

  • MCP: https://<worker>.workers.dev/mcp

Local:

npm run dev
npm run verify

Client examples: examples/claude-desktop.json, examples/cursor-mcp.json.

Verify

  1. Call tools (MCP Inspector, curl, or npm run verify):

curl -sS -X POST https://<worker>.workers.dev/mcp \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -H 'MCP-Protocol-Version: 2025-03-26' \
  -H 'x-user-id: verify-1' \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"curl","version":"0.0.1"}}}'

curl -sS -X POST https://<worker>.workers.dev/mcp \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json, text/event-stream' \
  -H 'MCP-Protocol-Version: 2025-03-26' \
  -H 'x-user-id: verify-1' \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"simulate_pipeline","arguments":{"query":"edge","steps":3}}}'
  1. Open app.agnost.ai. Check Events first, then Tool calls.

  2. You should see latency, checkpoints, and (if you called it) a failed fail_on_purpose.

What appears in Agnost AI

  • Tool calls for each tools/call

  • Events for every tracked call

  • Checkpoint timeline when checkpoint() is used

  • Failed tool calls remain visible with error details

  • Repeated calls from the same x-user-id share a session inside one Worker isolate

Troubleshooting

  • Set AGNOST_ORG_ID via wrangler secret put (prod) or .dev.vars (local). Must be a UUID.

  • Call trackMCP after creating the server. Tools registered after it are still wrapped.

  • Pass waitUntil from the Worker ExecutionContext so analytics finish after the response.

  • If you try import { trackMCP } from "agnost" on Workers, read WHAT-BROKE.md.

Repo layout

src/
  index.ts              Worker entry + docs landing page
  tools.ts              Demo tools (hello / pipeline / fail / whoami)
  lib/
    track-mcp.ts        Workers-native trackMCP + checkpoint
    http.ts             fetch client (no cache:default, retries)
    session.ts          isolate session cache
    als.ts              AsyncLocalStorage checkpoint context
scripts/verify.mjs      End-to-end MCP smoke
tests/                  Unit tests (vitest)
examples/               Claude Desktop + Cursor MCP configs
WHAT-BROKE.md           Exact break in agnost@0.2.1 + upstream fix list

Why Workers

Built while running an MCP server and Cloudflare Queues in production (Social0). A Workers path for Agnost is the natural fourth language next to TypeScript, Python, and Go.

License

MIT

Related MCP Connectors

Related MCP Servers