Skip to content

Latest commit

 

History

History
190 lines (138 loc) · 6.75 KB

File metadata and controls

190 lines (138 loc) · 6.75 KB

MCP clients

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.

Transports

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_TOKEN

The 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, resources, prompts

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/list

Claude Desktop (stdio)

Claude 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.

1. Ensure the stack is up

docker compose up -d postgres redis
pnpm migrate
# Optional: keep the main app running for live bridge + workers
docker compose up -d app

2. Add the server config

macOS: ~/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 --dir path. Relative paths break when Claude’s cwd differs.
  • You can omit keys already exported in the environment if your host injects them; explicit env is clearer for debugging.
  • LOG_LEVEL=silent keeps MCP stdio clean (MCP uses stdout for protocol frames).
  • Restart Claude Desktop after saving.

3. Confirm

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 other remote MCP clients)

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.

1. Run the HTTP MCP 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 set

2. Publish a reachable HTTPS URL

ChatGPT 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>.example

Terminate 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.

3. Create the connector in ChatGPT

Exact labels vary by ChatGPT build; the usual path:

  1. Enable Developer mode (Settings → Apps / Connectors / Advanced — wherever your build exposes it).
  2. Settings → Connectors → Create (or “Add MCP server”).
  3. 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.

4. Generic remote client snippet

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" -N

Compatibility note

MCP 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.

Operational guidance

  • Draft ≠ send. Instruct users and models that whatsapp_send_message stages 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.

Related