Metadata-Version: 2.4
Name: lingtai-whatsapp
Version: 0.1.0
Summary: LingTai WhatsApp Cloud API MCP server
Project-URL: Homepage, https://github.com/Lingtai-AI/lingtai-whatsapp
Project-URL: Repository, https://github.com/Lingtai-AI/lingtai-whatsapp
Project-URL: LingTai, https://lingtai.ai
Author: LingTai contributors
License: MIT
License-File: LICENSE
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Requires-Python: >=3.10
Requires-Dist: mcp>=1.0.0
Description-Content-Type: text/markdown

# lingtai-whatsapp

LingTai MCP server for the official Meta WhatsApp Business Platform / Cloud API.

This package intentionally targets the **official WhatsApp Cloud API only**. It does **not** implement or recommend unofficial WhatsApp Web bridges (Baileys/whatsmeow style), because those violate WhatsApp's Terms of Service and can ban numbers.

## Install

```bash
pip install lingtai-whatsapp
```

For local development before the first PyPI release:

```bash
pip install -e .
```

`src/lingtai_whatsapp/licc.py` is vendored from the first-party LingTai MCP repos and implements the LICC v1 inbox callback contract. Keep it synchronized with sibling packages (`lingtai-telegram`, `lingtai-feishu`, `lingtai-wechat`, `lingtai-imap`) when the protocol changes.

## What it provides

- MCP stdio server: `python -m lingtai_whatsapp`
- Omnibus `whatsapp` tool with actions: `send`, `reply`, `react`, `check`, `read`, `search`, `contacts`, `add_contact`, `remove_contact`, `templates`, `accounts`, `status`
- LICC v1 inbox callback for inbound WhatsApp messages
- Local message/contact persistence under the hosted agent directory
- Optional stdlib HTTP webhook receiver for Meta GET verification + signed POST callbacks
- MCP resources for setup/onboarding/status:
  - `lingtai://manifest`
  - `lingtai://skills/whatsapp`
  - `lingtai://docs/configuration`
  - `lingtai://docs/troubleshooting`
  - `lingtai://status`
  - `lingtai://onboarding/whatsapp`
  - `lingtai://onboarding/html-template`

## Configuration

Set `LINGTAI_WHATSAPP_CONFIG` to a JSON file. LingTai normally wires this through `init.json`'s `mcp.whatsapp.env` entry.

```json
{
  "accounts": [
    {
      "alias": "main",
      "access_token": "EAAG...",
      "phone_number_id": "123456789",
      "waba_id": "987654321",
      "app_secret": "...",
      "verify_token": "choose-a-random-webhook-token",
      "api_version": "v20.0",
      "display_phone_number": "+1 555 0100",
      "webhook": {
        "public_url": "https://example.com/webhooks/whatsapp",
        "host": "127.0.0.1",
        "port": 8088,
        "path": "/webhooks/whatsapp"
      },
      "templates": [
        {"name": "hello_world", "language": "en_US"}
      ]
    }
  ]
}
```

Required per account:

| Field | Purpose |
| --- | --- |
| `alias` | Local LingTai account name. Defaults to `default` if omitted. |
| `access_token` | Meta system-user/permanent access token with WhatsApp messaging permissions. |
| `phone_number_id` | Meta phone number id used by `/{phone_number_id}/messages`. |
| `waba_id` or `business_account_id` | WhatsApp Business Account id for operator reference/onboarding. |
| `app_secret` | Used to verify `X-Hub-Signature-256` on webhook POST callbacks. |
| `verify_token` | Random operator-chosen token used for Meta webhook GET verification. |

Optional:

- `api_version` defaults to `v20.0`.
- `display_phone_number` is informational only.
- `webhook` starts a local HTTP listener when `port` is present.
- `templates` is a local list of approved template names/languages the agent can inspect with `whatsapp(action="templates")`.

Secrets are plaintext by LingTai addon convention, but all tool/resource status results are redacted: access tokens, app secrets, and verify tokens are never echoed.

## LingTai activation

When used as a curated LingTai MCP, the agent's `init.json` should include:

```json
{
  "addons": ["whatsapp"],
  "mcp": {
    "whatsapp": {
      "type": "stdio",
      "command": "/Users/<you>/.lingtai-tui/runtime/venv/bin/python",
      "args": ["-m", "lingtai_whatsapp"],
      "env": {
        "LINGTAI_WHATSAPP_CONFIG": ".secrets/whatsapp.json"
      }
    }
  }
}
```

Then create `.secrets/whatsapp.json` using the schema above and run `system(action="refresh")` from the agent.

## Webhook setup

Meta requires a public HTTPS callback URL for inbound WhatsApp messages and delivery statuses. This MCP can run a local HTTP server if the first account's config includes `webhook.port`:

```json
"webhook": {
  "public_url": "https://example.com/webhooks/whatsapp",
  "host": "127.0.0.1",
  "port": 8088,
  "path": "/webhooks/whatsapp"
}
```

Expose that local listener with your preferred HTTPS reverse proxy/tunnel (Cloudflare Tunnel, ngrok, Caddy, nginx, etc.), then configure Meta's callback URL to `public_url` and verify it with the same `verify_token` stored in config.

Webhook behavior:

- `GET <path>?hub.mode=subscribe&hub.verify_token=...&hub.challenge=...` returns the challenge when the token matches.
- `POST <path>` validates `X-Hub-Signature-256` when `app_secret` is present, stores incoming messages, and pushes LICC inbox events to the hosting LingTai agent.
- For multi-account configs, inbound POSTs are routed by `metadata.phone_number_id`; unknown phone ids fall back to the default account.

## WhatsApp Cloud API constraints

- Free-form business replies are allowed only within the 24-hour customer-service window after a user's message.
- Outside the 24-hour window, use an approved message template.
- The Cloud API is for WhatsApp Business accounts; ordinary personal WhatsApp Web sessions are intentionally out of scope.

## Development

```bash
python -m pytest -q
```

The tests avoid real network calls. The send path uses Meta's Graph API only when credentials are present and the tool action is invoked.
