A local WhatsApp gateway with HTTP and MCP interfaces.
ChatRail connects applications, automations, and AI runtimes to WhatsApp without pretending to be the AI agent itself.
Apps / Automations / AI
|
HTTP / MCP
|
ChatRail
|
WhatsApp
ChatRail owns the WhatsApp session, normalizes identities, persists operational state, exposes a loopback HTTP API, and provides an MCP interface. Your application or AI runtime supplies the business logic.
- Connects to WhatsApp through whatsapp-web.js or Baileys.
- Persists local authentication so QR pairing is normally one-time.
- Exposes a local HTTP API on 127.0.0.1:3333 by default.
- Exposes an MCP stdio bridge backed by that HTTP API.
- Sends text messages with registration checks, deduplication, and idempotency.
- Resolves modern WhatsApp @lid identities without treating opaque LIDs as phone numbers.
- Lists observed chats, messages, replies, delivery/read acknowledgements, and unresolved identities.
- Reads the actual WhatsApp unread counters and returns a best-effort snapshot of recent inbound messages for those unread chats, including groups, without marking anything as read.
- Normalizes media in unread listings to message types instead of leaking thumbnail/base64 payloads.
- Stores contact display metadata when WhatsApp exposes it.
- Keeps the real WhatsApp provider in one process; MCP never creates a second competing session.
- Node.js 20 or newer
- npm
- Internet access
- A WhatsApp account able to pair WhatsApp Web
Install ChatRail globally:
npm install -g @pedroantonnio/chatrail
chatrail init
chatrail startThe first command installs the CLI. The init command creates the runtime directory under your user profile, normally ~/.chatrail, including the local configuration file and data directories.
On first use with the default auto provider, ChatRail normally starts whatsapp-web.js and prints a QR code. Scan it from WhatsApp under linked devices.
Useful CLI commands:
chatrail start
chatrail status
chatrail doctor
chatrail homeThe local API defaults to:
http://127.0.0.1:3333
Keep the ChatRail daemon running:
chatrail startRegister the lightweight MCP bridge with Codex:
codex mcp add chatrail -- npx -y @pedroantonnio/chatrail-mcpVerify the registration:
codex mcp listThe MCP bridge talks to the local ChatRail HTTP API. It does not create another WhatsApp client.
Run these steps once:
chatrail init
chatrail startOn the first WhatsApp connection, complete the QR pairing if ChatRail asks for it. Keep that terminal running while ChatRail is in use.
Then register the MCP bridge with Codex:
codex mcp add chatrail -- npx -y @pedroantonnio/chatrail-mcpYou only need to register the MCP server once.
After the initial setup, the normal workflow is:
1. Start ChatRail with: chatrail start
2. Leave that terminal running.
3. Open Codex.
4. Ask Codex to use ChatRail for the WhatsApp task you want.
You do not need to start chatrail-mcp yourself. Codex launches the MCP bridge automatically when it needs it.
The ChatRail daemon does need to be running because the MCP bridge connects to its local HTTP API at http://127.0.0.1:3333 by default.
You can confirm the daemon is available before opening Codex with:
chatrail statusOnce registered, you can ask Codex things such as:
Use ChatRail to check my unread WhatsApp chats.
The MCP package is intentionally separate from the daemon package so MCP clients do not need to install the WhatsApp provider and browser dependencies.
Clone and install:
git clone https://github.com/pedroantonnio/ChatRail.git
cd ChatRail
npm install
Copy-Item .env.example .env
npm run verify
npm startWhen a ChatRail project .env is present in the repository, local development keeps using the repository directory for runtime state. Global installations use ~/.chatrail by default. CHATRAIL_HOME can override the runtime location explicitly.
The repository still includes the MCP implementation for development and tests.
Start the daemon:
npm startRun the repository MCP entrypoint manually only for debugging or MCP inspector use:
npm run mcpFor normal Codex use, let Codex start the published stdio bridge itself.
Core tools include:
- get_status
- get_health
- list_recipients
- register_recipient
- send_message
- list_sends
- list_messages
- list_replies
- get_reply_state
- list_chats
- list_unread_chats
- mark_read
- list_events
- list_unresolved
See MCP.md for integration details.
Important routes:
| Method | Route | Purpose |
|---|---|---|
| GET | /health | API/provider health |
| GET | /status | Runtime status and safeguards |
| GET | /recipients | Registered outbound recipients |
| POST | /recipients | Register an outbound recipient |
| POST | /send | Send a text message |
| GET | /sends | Outbound send history |
| GET | /messages | Locally persisted messages |
| GET | /replies | Reply-eligible inbound messages |
| GET | /chats | Locally observed chat summaries |
| GET | /unread | Live unread counters plus recent inbound message snapshots |
| POST | /mark-read | Explicitly mark one recipient read |
| GET | /events | Persisted events |
| GET | /unresolved | Identities that could not be resolved safely |
| GET | /reply-state | Reply-tracking state |
See API.md.
ChatRail intentionally defaults to conservative outbound behavior:
- The HTTP server binds to loopback by default.
- Unregistered outbound recipients are blocked by default.
- Group sending is blocked by default.
- Duplicate sends are suppressed inside the configured dedupe window.
- Ambiguous @lid identifiers are not guessed into phone numbers.
- GET /unread is read-only and does not mark chats as read.
- If you bind the API outside loopback, configure API_TOKEN.
These controls reduce accidental actions. They are not a substitute for your own authorization, compliance, and rate-limit policies.
Recommended for a fresh install. It uses Chromium/Puppeteer and LocalAuth.
Supported as an alternative provider. auto prefers Baileys only when an existing Baileys credential set is present.
Provider behavior can change when WhatsApp Web changes. See KNOWN_UPSTREAM_LIMITATIONS.md.
Global installations store local configuration, authentication state, contact metadata, message state, and logs under ~/.chatrail by default.
Local repository development continues to use ignored paths such as data and logs when the project contains its local .env.
Never publish or commit WhatsApp authentication data, environment files, browser session data, message databases, or logs.
Run:
npm run verify
npm run verify:mcp
npm run pack:checkOther useful commands:
npm run doctor
npm run provider:smoke
npm run stress- @pedroantonnio/chatrail: daemon and CLI
- @pedroantonnio/chatrail-mcp: lightweight MCP stdio bridge
Releases are prepared for npm Trusted Publishing through GitHub Actions.
See SECURITY.md. Do not report leaked WhatsApp sessions, credentials, or other sensitive material in public issues.
MIT. Third-party dependencies retain their own licenses.
ChatRail is an independent, unofficial open-source project. It is not affiliated with, authorized by, maintained by, sponsored by, or endorsed by WhatsApp or Meta. WhatsApp is a trademark of its respective owner.
Use the project in accordance with applicable law, WhatsApp terms, and the consent and privacy expectations of the people you communicate with.