kaption-mcp-remote
Officialby Kaption-AI
README.md
# kaption-mcp-remote
Cloud MCP relay for WhatsApp — lets AI assistants (Claude, ChatGPT, Cursor, etc.) interact with your WhatsApp conversations through the [Model Context Protocol](https://modelcontextprotocol.io/).
**Setup guide:** [kaptionai.com/mcp](https://kaptionai.com/mcp/) — connect WhatsApp to Claude, ChatGPT or Cursor.
**Live at:** [mcp.kaptionai.com](https://mcp.kaptionai.com) (canonical) and
mcp-ext.kaptionai.com (backward-compatible alias for existing connections)
The relay **cannot read your messages**. It forwards MCP tool calls between the AI client and the Kaption browser extension, which processes everything locally in your browser. Its source code is public (BUSL-1.1), so you can verify it yourself.
## Architecture
```
AI Client (Claude/ChatGPT/Cursor)
│
│ OAuth 2.1 + SSE/Streamable HTTP
▼
┌─────────────────────────────────────┐
│ Cloudflare Worker │
│ mcp.kaptionai.com │
│ │
│ ┌────────────┐ ┌──────────────┐ │
│ │ OAuthProv │ │ Next.js │ │
│ │ /sse /mcp │ │ /authorize │ │
│ │ /token │ │ /ext-auth │ │
│ │ /register │ │ / (landing) │ │
│ └─────┬──────┘ └──────────────┘ │
│ │ │
│ ┌─────▼──────┐ ┌──────────────┐ │
│ │ RelayMCP │ │ Deployment │ │
│ │ (DO) │ │ ChainDO │ │
│ └─────┬──────┘ └──────────────┘ │
│ │ │
│ ┌─────▼──────┐ │
│ │ RelayRoom │ ◄── WebSocket ──┐ │
│ │ (DO/accountRef) │ │ │
│ └────────────┘ │ │
└─────────────────────────────────┼──┘
│
Browser Extension
(WhatsApp Web tab)
```
### Durable Objects
| DO | Keyed By | Purpose |
|----|----------|---------|
| **RelayMCP** | OAuth session | McpAgent — registers tools, relays JSON-RPC to RelayRoom |
| **RelayRoom** | Opaque accountRef | WebSocket bridge to extension, auth handshake, request/response matching |
| **DeploymentChainDO** | `"main"` | Append-only hash chain for deployment transparency |
## Request Flow
1. AI client discovers the MCP server via `/.well-known/oauth-authorization-server`
2. Client registers dynamically via `POST /register` (RFC 7591)
3. User authenticates with WhatsApp OTP at `/authorize`
4. Client exchanges code for token at `/token`
5. Client sends tool calls via SSE (`/sse`) or Streamable HTTP (`/mcp`)
6. **RelayMCP** DO receives the call, routes to **RelayRoom** for the accountRef
7. **RelayRoom** forwards JSON-RPC to the extension over WebSocket
8. Extension executes in WhatsApp Web context, returns result
9. Result flows back: RelayRoom → RelayMCP → AI client
## Routing Table
| Path | Method | Auth | Handler |
|------|--------|------|---------|
| `/` | GET | — | Next.js landing page |
| `/authorize` | GET | — | Next.js OTP form (HMAC-signed oauthReqInfo) |
| `/authorize/send-otp` | POST | — | Next.js API route → rest-api |
| `/authorize/verify` | GET/POST | — | Next.js OTP verify → OAuthProvider completeAuthorization |
| `/authorize/reviewer-login` | POST | Static review credentials | Password completion for the configured synthetic review phone |
| `/register` | POST | — | OAuthProvider (RFC 7591 dynamic client registration) |
| `/token` | POST | — | OAuthProvider (token exchange) |
| `/sse` | GET | OAuth token | RelayMCP DO (SSE transport) |
| `/mcp` | POST | OAuth token | RelayMCP DO (Streamable HTTP) |
| `/ws/ext` | GET | JWT/token in auth msg | RelayRoom DO (WebSocket upgrade) |
| `/ext-auth/*` | Various | — | Next.js extension auth pages + API |
| `/transparency` | GET | — | DeploymentChainDO (chain history) |
| `/transparency/latest` | GET | — | DeploymentChainDO (latest entry) |
| `/transparency/verify` | GET | — | DeploymentChainDO (chain integrity) |
| `/transparency/gaps` | GET | CF token | Cross-reference CF deploys with chain |
| `/transparency/append` | POST | DEPLOY_API_KEY | Append entry (CI only) |
## MCP Tools
16 public tools are forwarded to the extension (the relay does not execute them):
| Tool | Description |
|------|-------------|
| `query` | Query conversations, contacts, messages, transcriptions, labels, communities, sessions |
| `summarize_conversation` | Get or generate a conversation summary |
| `manage_labels` | Add/remove/create/delete WhatsApp Business labels |
| `manage_notes` | Get/set contact notes (Business accounts) |
| `download_media` | Download image/video/audio/document from a message |
| `manage_chat` | Archive, pin, mute, mark read/unread, set/clear draft |
| `manage_reminders` | Create/list/complete/delete personal reminders |
| `manage_scheduled_messages` | Schedule messages for future delivery — from Kaption's number (bot, default) or from your own number on this computer (`mode: "local"`, also to groups) |
| `manage_lists` | Manage personal chat lists (custom categories) |
| `list_contacts`, `get_contact`, `get_contact_groups` | Read contacts and their group memberships |
| `list_groups`, `get_group` | Read cached or live group metadata |
| `export_contacts` | Export contacts as CSV or JSON |
| `get_analytics` | Analyze WhatsApp activity, rankings, response times, and exports |
`get_api_info` is local-only and is deliberately excluded from the cloud
surface because it returns private REST connection credentials.
## Deployment Security
Every deployment is cryptographically signed and recorded in a tamper-evident transparency chain. See [SECURITY.md](./SECURITY.md) for full details.
### Pipeline
```
GitHub Actions (push to main)
│
├─ 1. Run tests
├─ 2. Build worker (OpenNext + wrap)
├─ 3. SHA-256 manifest every generated code and asset file
├─ 4. Pre-deploy: Sigstore sign the manifest → Rekor log
├─ 5. Deploy to Cloudflare
├─ 6. Post-deploy: verify hash unchanged, sign attestation → Rekor
└─ 7. Append to transparency chain (hash-linked)
```
Daily heartbeat redeploys (6am UTC) ensure the chain stays active even without code changes.
### Deploys are gated — do NOT run `wrangler deploy` locally
All production deploys go through GitHub Actions. Multiple layers enforce this:
1. `wrangler.jsonc` is gitignored; `scripts/build-config.mjs` renders it from `wrangler.template.jsonc` and refuses to run unless `GITHUB_ACTIONS=true` + `GITHUB_RUN_ID` are set (or `KAPTIONAI_LOCAL_DEV=1` for dev).
2. `npm run predeploy` aborts unless those same CI env vars are present.
3. `main` is branch-protected: requires a reviewed PR + green `test`, `deploy`, and `verify` checks.
4. CODEOWNERS routes every PR through @kshmir.
To ship a change: open a PR → review + CI green → merge to `main` → Actions builds, signs (Sigstore), deploys, and appends to the transparency chain. `npx wrangler deploy` from a laptop will fail at step 1 because there is no `wrangler.jsonc` to deploy.
### Verify a Deployment
```bash
# 1. Check the transparency chain
curl -s https://mcp.kaptionai.com/transparency/latest | jq .
# 2. Verify chain integrity
curl -s https://mcp.kaptionai.com/transparency/verify | jq .
# 3. Verify Sigstore signature (requires cosign)
COMMIT=$(curl -s https://mcp.kaptionai.com/transparency/latest | jq -r '.event.commitSha')
cosign verify-blob \
--bundle build-manifest.sigstore.json \
--certificate-identity-regexp "https://github.com/Kaption-AI/mcp-extension-remote/.*" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
build-manifest.json
```
## API Endpoints
### Transparency API (public, no auth)
```bash
# Full chain history (paginated)
GET /transparency?limit=50&offset=0
# Latest deployment
GET /transparency/latest
# Verify chain integrity
GET /transparency/verify
```
### MCP (OAuth-protected)
```bash
# SSE transport (for Claude Code, Cursor)
GET /sse
# Streamable HTTP transport
POST /mcp
```
## Development
```bash
# Install dependencies
npm install
# Run tests
npm test
# Dev server (Next.js only — no Worker routing)
npm run dev
# Build the full worker (OpenNext + custom wrapper)
npm run build:worker
```
### Project Structure
```
src/
index.ts # Worker entry — Hono routing, OAuthProvider composition
relay-mcp.ts # RelayMCP Durable Object (McpAgent)
relay-room.ts # RelayRoom Durable Object (WebSocket bridge)
deployment-chain.ts # DeploymentChainDO (transparency log)
otp.ts # OTP generation, verification, JWT, HMAC, rate limiting
schemas.ts # Zod schemas for API request validation
tools.ts # MCP tool definitions (forwarded, not executed)
types.ts # TypeScript interfaces (Env, DeploymentEvent, etc.)
app/
page.tsx # Landing page (multilingual, client-side i18n)
layout.tsx # Root layout
i18n.ts # i18next init (8 languages)
locales/ # Translation JSON files
authorize/ # OAuth OTP flow pages + API routes
ext-auth/ # Extension auth pages + API routes
scripts/
wrap-worker.mjs # Post-build: wraps OpenNext output with custom routing
```
## Environment Variables
### Vars (wrangler.jsonc)
| Variable | Description |
|----------|-------------|
| `INTERNAL_API_BASE_URL` | Backend API base URL |
| `BUILD_HASH` | SHA-256 of worker bundle (set by CI) |
| `COMMIT_SHA` | Git commit SHA (set by CI) |
### Secrets (`wrangler secret put`)
| Secret | Description |
|--------|-------------|
| `INTERNAL_API_KEY` | API key for rest-api OTP endpoint |
| `DEPLOY_API_KEY` | API key for transparency chain append |
| `JWT_SECRET` | Shared JWT signing secret (same as rest-api, schedule, metadata workers) |
| `PHONE_REF_SECRET` | HMAC secret used to derive opaque durable account references from phone numbers |
| `EPHEMERAL_STATE_SECRET` | Encryption secret for short-lived login hints, verify tickets, and encrypted session phone payloads |
| `OPENAI_APPS_CHALLENGE_TOKEN` | Exact domain-verification token issued by the OpenAI plugin portal |
| `OPENAI_REVIEW_PASSWORD_SHA256` | Lowercase SHA-256 hex digest of the high-entropy reviewer password |
| `OPENAI_REVIEW_PHONE` | Phone number used as the dedicated review username and to derive the synthetic account's opaque reference |
The three `OPENAI_*` values are also configured as GitHub Actions repository
secrets. Add all three together, then run the manual **Test, Build & Deploy**
workflow. CI writes them to an ephemeral mode-`0600` file and passes that file
to `wrangler deploy --secrets-file`, so the review configuration ships in the
same signed, attested Worker version as the code. The workflow fails closed if
only part of the three-value set is present and deletes the temporary file
immediately after deployment. Existing Worker secrets not listed in that file
are preserved.
## Related Projects
- **[Kaption Extension](https://kaptionai.com/extension)** — Chrome/Edge/Firefox browser extension (the other side of the relay)
- **[@kaptionai/mcp-extension](https://www.npmjs.com/package/@kaptionai/mcp-extension)** — Local MCP bridge (runs on your machine, no cloud relay)
## License
[BUSL-1.1](./LICENSE)
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues