Axiom MCP β Cloudflare Worker App
Edge-hosted MCP server + minimal UI, built with Hono and Cloudflare Workers. It handles OAuth with Axiom, manages session state via Durable Objects, uses KV for lightweight storage, and exposes an SSE endpoint for MCP clients.
Whatβs Here
- Worker entry at
src/index.ts (Hono routes, SSE at /sse).
- Durable Object
AxiomMCP for per-user/session state.
- KV bindings for OAuth/session data.
- Minimal UI under
src/ui/* with a landing page and setup help.
Quick Start
From the repo root:
npm ci
npm run dev -w apps/mcp
Config uses Wrangler variables/secrets. For local dev, create apps/mcp/.dev.vars with at least:
COOKIE_ENCRYPTION_KEY="<32+ char random>"
AXIOM_OAUTH_CLIENT_ID="<client id>"
AXIOM_OAUTH_CLIENT_SECRET="<client secret>"
Optional tracing vars are defined in wrangler.jsonc if you want OpenTelemetry.
Endpoints
/ β UI + docs
/sse β MCP SSE endpoint for clients/inspectors
/oauth/* β OAuth login/callback flow
Try with MCP Inspector:
npx @modelcontextprotocol/inspector@latest
Test, Type Check, Lint
npm test -w apps/mcp
npm run test:watch -w apps/mcp
npm run type-check -w apps/mcp
Deploy
Set secrets with Wrangler, then:
npm run deploy -w apps/mcp
npm run deploy:staging -w apps/mcp
npm run deploy:prod -w apps/mcp
Bindings, routes, and env-specific config live in wrangler.jsonc.
See Also
packages/mcp β shared MCP tooling/telemetry used by this app.
- Root
README.md β repo-wide scripts, linting, and workflow.
-
OAuth Provider (Dual-Role)
- Acts as OAuth server for MCP clients (authorization code flow)
- Acts as OAuth client to Axiom (token exchange)
- Manages encrypted cookies and state validation
-
Durable Object (AxiomMCP)
- Maintains user authentication state across requests
- Provides consistent API client instance
- Handles MCP protocol registration and tool dispatch
-
OpenTelemetry Integration
- Traces every request with detailed spans
- Exports to both console (dev) and Axiom (prod)
- Provides debugging context for OAuth and MCP operations
-
Smart Tool Layer
- Imports intelligent tools from
@axiom/mcp
- Adds authentication context
- Handles tool registration based on available integrations
- Optional OTel tools can be enabled with
with-otel=1 URL param
Runtime URL Parameters
You can tune the server behavior per-connection using query params:
max-age: Integer. Caps the total number of table cells the server will format per tool response (affects CSV output shaping). Example: ?max-age=500.
with-otel: Boolean (1 or true). Enables the OpenTelemetry tool family when your organization has OTel integrations detected. Example: ?with-otel=1.
These can be combined with org-id header or query param when using header-based auth.
π§ͺ Testing & Development
Testing Strategy
npm test
npm run test:watch
npx @modelcontextprotocol/inspector@latest
Development Workflow
npm run type-check
npm run lint
npm run gen:types
Debugging Tips
-
OAuth Issues
- Check KV namespace for stored states
- Verify cookie encryption key consistency
- Use browser DevTools to inspect redirects
-
MCP Connection Problems
- Test with MCP Inspector first
- Check Durable Object logs in Cloudflare dashboard
- Verify SSE endpoint is accessible
-
Tool Errors
- Enable console tracing with
ENVIRONMENT=dev
- Check OpenTelemetry spans for detailed errors
- Verify API credentials and permissions
- Edge Deployment: Runs on Cloudflare's global network for <50ms latency
- Durable Objects: Provide consistent state with single-threaded execution
- KV Caching: OAuth states cached for fast validation
- Streaming Responses: SSE enables real-time tool results
π Security Features
- Encrypted State: All OAuth state encrypted with AES-GCM
- PKCE Flow: Proof Key for Code Exchange prevents auth interception
- Token Isolation: Access tokens never exposed to clients
- Request Validation: All inputs sanitized and validated