Skip to main content
GOWA serves a Model Context Protocol endpoint from the same process as the REST API. Any MCP client that supports the streamable HTTP transport can send messages, read chats and manage groups through it.
  • URL: http://<host>:3000<APP_BASE_PATH>/mcp (default http://localhost:3000/mcp)
  • Enabled by default. Disable with MCP_ENABLED=false or --mcp-enabled=false.
  • Stateless: no session handshake to keep alive between calls.
Upgrading from an older release? The standalone ./whatsapp mcp command and its SSE endpoint on port 8080 (/sse) are gone. Run ./whatsapp rest and point clients at /mcp. The old one-tool-per-operation set was replaced by the consolidated tools below.

Connect a client

/mcp sits behind the same Basic Auth as the REST API. Send the Authorization header, plus X-Device-Id if you run more than one device:
YWRtaW46Y2hhbmdlbWU= is base64("admin:changeme"); generate yours with echo -n 'user:pass' | base64. Omit Authorization if Basic Auth is off, and X-Device-Id if there is only one device. The exact config format depends on the client. If a client can only launch stdio servers, use a bridge such as mcp-remote.

Tools

GOWA exposes six tools. Each takes a type (send) or action (all others) argument that selects the operation. Notes on arguments:
  • whatsapp_send always needs type and phone. Media is sent by URL only (image_url, video_url, audio_url, file_url, sticker_url); MCP cannot upload local files. link needs link and caption; forward needs message_id.
  • whatsapp_send accepts the schedule fields (scheduled_at, timezone, recurrence, weekdays, day_of_month, end_at, occurrence_limit). Manage the result with whatsapp_schedule (get, pause, resume and cancel need schedule_id).
  • whatsapp_message needs phone (the chat) and message_id; edit also needs message.
  • whatsapp_chat: get_messages needs chat_jid; archive needs chat_jid and archived.
  • whatsapp_app: login_code needs phone.
Your MCP client shows the full input schema of each tool.

Device selection

Each call resolves its device in this order:
  1. The device_id argument on the tool call.
  2. The X-Device-Id header on the MCP connection.
  3. The only registered device, when exactly one exists.
Otherwise the call fails with device identification required: set the X-Device-Id header or pass device_id. See Multi-device.

Remote clients with OAuth

Hosted clients such as Claude custom connectors cannot attach a Basic Auth header. For them, GOWA can run an OAuth 2.1 authorization server for /mcp. It is off by default.
Requirements and behavior:
  • APP_BASIC_AUTH must be set: the authorization page signs users in with those same accounts. Startup fails without it.
  • Issuer and resource must be the public HTTPS URLs clients see, not internal addresses like http://gowa:3000.
  • With OAuth on, /mcp accepts a Bearer token or Basic Auth. Tokens are not accepted on REST or UI routes.
  • Clients register themselves (RFC 7591 dynamic client registration). Registrations are limited to 40 per hour and 1,000 stored clients; unused ones are pruned after 24 hours.
  • PKCE S256 is mandatory. Codes expire after 5 minutes, access tokens after 1 hour; refresh tokens rotate, and reusing an old one revokes the whole token family. Only SHA-256 hashes of tokens are stored, in MCP_OAUTH_DB_URI (default file:storages/oauth.db).
Endpoints, relative to the issuer: /oauth/authorize, /oauth/token, /oauth/register. Discovery metadata uses path-insertion well-known URLs at the domain root, so with APP_BASE_PATH=/gowa your proxy must route:
Check discovery from outside:
Then add https://gowa.example.com/mcp as a custom connector and sign in with an APP_BASIC_AUTH account.
Make sure Cloudflare Access, bot challenges or auth proxies in front of GOWA do not intercept the well-known, /oauth/* or /mcp paths. Rate-limit failed logins on /oauth/authorize at your proxy.