agnost-workers-mcp
by Abhishek-B-R
README.md
# 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](https://app.agnost.ai).
Official docs: [MCP overview](https://docs.agnost.ai/mcp-overview.md) · [TypeScript SDK](https://docs.agnost.ai/typescript-sdk.md)
```
MCP client → Cloudflare Worker (/mcp) → Agnost capture-session / capture-event
│
└─ Workers-native trackMCP (src/lib/track-mcp.ts)
```
## Install
```bash
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
```
## Integrate
```ts
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](./WHAT-BROKE.md).
### Options
```ts
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
```ts
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
```bash
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:
```bash
npm run dev
npm run verify
```
Client examples: [examples/claude-desktop.json](./examples/claude-desktop.json), [examples/cursor-mcp.json](./examples/cursor-mcp.json).
## Verify
1. Call tools (MCP Inspector, curl, or `npm run verify`):
```bash
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}}}'
```
2. Open [app.agnost.ai](https://app.agnost.ai). Check **Events** first, then **Tool calls**.
3. 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](./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
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues