W Agent exposes WhatsApp history and draft staging through the Model Context Protocol. Any MCP-capable client can list chats, search, read summaries, and stage replies for owner approval. Nothing on this surface bypasses the outbox pipeline described in security.md.
| Transport | When to use | Auth |
|---|---|---|
| stdio | Claude Desktop and local MCP hosts that spawn a subprocess | Process isolation; no bearer token |
| HTTP + SSE | Remote or browser-hosted clients (e.g. ChatGPT custom connectors), Inspector over the network | MCP_AUTH_TOKEN via Authorization: Bearer, X-MCP-Token, or ?token= |
pnpm mcp # stdio (reads .env)
pnpm mcp:http # HTTP+SSE on MCP_PORT (default 3100); requires MCP_AUTH_TOKENThe main app also starts HTTP+SSE when MCP_AUTH_TOKEN is set.
Remote endpoints:
| Method | Path | Notes |
|---|---|---|
GET |
/sse |
Open the SSE stream |
POST |
/messages?sessionId=… |
Client JSON-RPC |
GET |
/health |
Liveness (no auth) |
Expose HTTP MCP only behind TLS (reverse proxy or tunnel). Treat MCP_AUTH_TOKEN like a password.
Tools
| Name | Behavior |
|---|---|
whatsapp_list_chats |
Recent chats |
whatsapp_get_history |
Recent messages for a JID |
whatsapp_search |
Hybrid semantic + FTS search |
whatsapp_get_summary |
Rolling chat summary |
whatsapp_contacts |
Contact lookup |
whatsapp_send_message |
Stages a draft + owner notify (does not send immediately) |
Resources (subscribe-capable where implemented)
| URI | Description |
|---|---|
whatsapp://chats |
Chat catalog |
whatsapp://chat/{jid}/history |
Recent history |
whatsapp://chat/{jid}/summary |
Summary / memory |
Prompts: summarize_chat, draft_reply_in_my_tone, weekly_digest.
Verify locally with MCP Inspector:
npx @modelcontextprotocol/inspector --cli pnpm mcp --method tools/list
npx @modelcontextprotocol/inspector --cli pnpm mcp --method resources/list
npx @modelcontextprotocol/inspector --cli pnpm mcp --method prompts/listClaude Desktop spawns W Agent as a local MCP server. Postgres (and Redis, if embeddings/search workers are expected from this process) must be reachable from the same machine.
docker compose up -d postgres redis
pnpm migrate
# Optional: keep the main app running for live bridge + workers
docker compose up -d appmacOS: ~/Library/Application Support/Claude/claude_desktop_config.json
Linux: ~/.config/Claude/claude_desktop_config.json
Windows: %APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"w-agent": {
"command": "pnpm",
"args": ["--dir", "/absolute/path/to/whatsapp-agent", "mcp"],
"env": {
"OPENAI_API_KEY": "sk-…",
"DATABASE_URL": "postgres://w_agent:w_agent@127.0.0.1:5432/w_agent",
"REDIS_URL": "redis://127.0.0.1:6379",
"LOG_LEVEL": "silent",
"EMBEDDING_MODEL": "text-embedding-3-small",
"AGENT_MODEL": "gpt-4o-mini"
}
}
}
}Notes:
- Prefer an absolute
--dirpath. Relative paths break when Claude’s cwd differs. - You can omit keys already exported in the environment if your host injects them; explicit
envis clearer for debugging. LOG_LEVEL=silentkeeps MCP stdio clean (MCP uses stdout for protocol frames).- Restart Claude Desktop after saving.
In a Claude chat, the W Agent tools should appear under the MCP server list. Ask it to list chats or summarize a JID you know exists in Postgres.
ChatGPT and similar hosts typically attach remote MCP servers over HTTP. W Agent’s current remote transport is HTTP + SSE (GET /sse + POST /messages). Product UIs change; the values below match this repository’s server.
# In .env
MCP_AUTH_TOKEN=replace-with-a-long-random-secret
MCP_PORT=3100
pnpm mcp:http
# or run the full app with MCP_AUTH_TOKEN setChatGPT cannot call localhost on your laptop. Use a tunnel or reverse proxy, for example:
# Example with a tunnel CLI you already trust
# Expose http://127.0.0.1:3100 → https://<subdomain>.exampleTerminate TLS at the proxy. Forward to the MCP port. Do not put the bearer token in the public URL query string if the connector UI supports an API key / header field.
Exact labels vary by ChatGPT build; the usual path:
- Enable Developer mode (Settings → Apps / Connectors / Advanced — wherever your build exposes it).
- Settings → Connectors → Create (or “Add MCP server”).
- Fill in:
| Field | Value |
|---|---|
| Name | w-agent (or similar) |
| Server URL | https://<your-host>/sse — include the /sse path |
| Authentication | API key / bearer — value = your MCP_AUTH_TOKEN |
If the UI only offers “no auth”, do not expose the server on the public internet; restrict by network policy or use a proxy that injects the bearer header.
For hosts that accept a JSON MCP remote descriptor (shape differs by product; adapt field names):
{
"mcpServers": {
"w-agent": {
"url": "https://<your-host>/sse",
"headers": {
"Authorization": "Bearer replace-with-a-long-random-secret"
}
}
}
}Equivalent curl check (health is unauthenticated; tools are not):
curl -sS "https://<your-host>/health"
curl -sS -H "Authorization: Bearer $MCP_AUTH_TOKEN" "https://<your-host>/sse" -NMCP is moving toward Streamable HTTP and OAuth for remote servers. W Agent today ships the SSE + POST /messages transport with a shared bearer token. If a client requires OAuth-only Streamable HTTP, use stdio locally or place a compatible gateway in front until this repo adds that transport.
- Draft ≠ send. Instruct users and models that
whatsapp_send_messagestages an approval item. - Least privilege. Separate tokens for dashboard vs MCP; rotate if a client laptop is lost.
- Same database. MCP reads the Postgres filled by the ingest workers. A paired bridge (or imported history) must exist for tools to return useful data.
- Owner notify. Drafts notify the linked WhatsApp account (or
OWNER_NOTIFY_JID). The bridge must be connected for that notify path.
- architecture.md — MCP layer in the stack
- security.md — token and injection posture
- ../README.md — quickstart