MCP Worker (swapps-mcp-worker)¶
The MCP Worker (repository swapps-mcp-worker) is a remote Model Context Protocol (MCP) server that wraps the swapps-app REST API (Django + DRF, also known internally as the "IDK API"). It runs as a TypeScript Cloudflare Worker, so anyone in the organization can use it without installing anything locally — they only register a URL and a personal token in their MCP client.
It is read-only, and it is the remote equivalent of the local Python MCP server in tools/swapps-app-mcp/.
What it does¶
- Exposes 18 read-only MCP tools that map onto
swapps-appendpoints (clients, contracts, services, installments, level-rates, reports, tasks, time entries, Celery task status, plus a generic GET escape hatch). See Tools reference. - Speaks the MCP Streamable HTTP transport at the
/mcproute, so MCP clients (Claude Code, Claude Desktop) can connect over plain HTTPS. - Authenticates each caller with a per-user edge token at the edge, then calls the downstream API with a single shared service token — the two are never the same and the edge token is never forwarded downstream.
Transport and routing¶
| Aspect | Value |
|---|---|
| Transport | MCP Streamable HTTP (@modelcontextprotocol/sdk + the agents MCP handler) |
| MCP route | POST /mcp (clients must send Accept: application/json, text/event-stream) |
| Health route | GET /health → { "status": "OK", "ts": "<iso>" } |
| Production URL | https://mcp.swapps.com/mcp (custom domain) or https://swapps-mcp-worker.<account>.workers.dev/mcp |
| Auth header | Authorization: token <edge-token> (or Authorization: Bearer <edge-token>); fallback X-MCP-Token: <edge-token> |
Read-only by design
Every tool issues a GET against the downstream API. There is no create / update / delete path, and even the generic api_request tool is a GET-only escape hatch. The downstream service token should belong to a dedicated read-only DRF user (defense in depth).
Role in the platform¶
(Claude Code / Desktop)"] -->|"Streamable HTTP
POST /mcp + edge token"| Worker subgraph CF["Cloudflare"] Worker["swapps-mcp-worker
(MCP server, TypeScript)"] Auth["validateEdgeToken
(EDGE_TOKENS map)"] Worker --> Auth end Worker -->|"Authorization: Token {service token}"| API["swapps-app API
(app.swapps.com/api)"]
The flow on each request:
- The MCP client sends
POST /mcpwith the user's edge token in a header. - The Worker validates the edge token against the
EDGE_TOKENSmap (a JSONtoken -> usernamemap). An unknown/missing token returns401. A valid token resolves to ausernameand emits an audit log line. - The Worker builds a fresh MCP server instance (required per request by the SDK) and dispatches the JSON-RPC method.
- Tool calls reach the downstream
swapps-appAPI authenticated with the single read-only service token (SWAPPS_API_TOKEN), never the caller's edge token.
Bindings, vars and secrets¶
| Name | Kind | Purpose |
|---|---|---|
SWAPPS_API_TOKEN |
Secret | Single read-only service DRF token used for all downstream API calls. |
EDGE_TOKENS |
Secret | JSON map of per-user edge token → username, e.g. {"<token>":"dev@swapps.com"}. |
SWAPPS_API_BASE_URL |
Var | Base URL of the swapps-app API. Defaults to https://app.swapps.com/api. |
SWAPPS_API_USER_AGENT |
Var | User-Agent sent downstream (keeps the Cloudflare WAF /api skip rule happy). Defaults to swapps-mcp/1.0. |
There are no KV namespaces, Durable Objects, or queues; the Worker is stateless. See Architecture for details and Development for local setup and deployment.
Sections¶
- Tools reference — every MCP tool, its inputs and behavior.
- Architecture — project structure and how the MCP server/transport is wired on Workers.
- Development — local dev, testing, env vars, deployment and registering it in an MCP client.