Skip to main content
Glama
README.md
# W Agent

[![CI](https://github.com/Chessing234/w-agent/actions/workflows/ci.yml/badge.svg)](https://github.com/Chessing234/w-agent/actions/workflows/ci.yml)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
[![Node.js](https://img.shields.io/badge/node-%3E%3D22-brightgreen.svg)](https://nodejs.org/)
[![pnpm](https://img.shields.io/badge/pnpm-9-orange.svg)](https://pnpm.io/)
[![Release](https://img.shields.io/github/v/release/Chessing234/w-agent?include_prereleases&sort=semver)](https://github.com/Chessing234/w-agent/releases)

**W Agent: your WhatsApp, with a brain.**  
A self-hosted bridge that gives an AI agent continuous, searchable context over your WhatsApp chats — and lets it reply for you, safely.

W Agent keeps your archive in **your** Postgres, stages every outbound draft for approval (unless you opt a chat into auto-send), and exposes the same context to Claude Desktop and other MCP clients. The WhatsApp transport is swappable: unofficial Baileys for personal companion use, or the official Meta Cloud API for business messaging.

> **Operational warning.** The default bridge uses Baileys (unofficial multi-device protocol) and carries real **account ban / restriction risk**. Prefer a dedicated number. For business workloads, set `WHATSAPP_PROVIDER=meta`. See [docs/security.md](docs/security.md) and [docs/providers.md](docs/providers.md).

<!-- Optional: drop a ~60s screen capture at docs/assets/demo.gif
![Demo](docs/assets/demo.gif)
-->

## Features

- **Provider-adapter WhatsApp bridge** — Baileys (personal / multi-device) or Meta Cloud API
- **Durable ingest** — inbound messages → BullMQ → Postgres (contacts, chats, messages, media)
- **History sync & backfill** — Baileys history chunks and on-demand per-chat backfill
- **Hybrid search** — OpenAI embeddings + pgvector merged with Postgres full-text search
- **Rolling chat summaries** — cheap-model memory on a message cadence
- **Engagement engine** — allowlists, group @-mentions, opt-in/out, owner `/agent` commands
- **Safety stack** — injection heuristics (+ optional LLM classifier), outbound chat lock, secret redaction
- **Approval outbox** — drafts notify the owner; approve in the dashboard (or per-chat auto-send)
- **Send hygiene** — quotas, quiet hours, typing delays, exponential WA rate-limit cooldown
- **MCP server** — stdio + HTTP/SSE tools, resources, and prompts
- **Ops** — watchdog, `/healthz`, atomic auth persistence, chaos + red-team scripts

## Architecture

```mermaid
flowchart TB
  subgraph clients [Clients]
    WA[WhatsApp]
    Dash[Dashboard]
    MCPC[MCP clients<br/>Claude / ChatGPT / custom]
  end

  subgraph bridge [Bridge]
    Prov["WhatsAppProvider<br/>baileys | meta"]
  end

  subgraph queues [Queues - Redis / BullMQ]
    IngestQ[ingest]
    EmbedQ[embed]
    SumQ[summary]
    Outbox[outbox sender]
  end

  subgraph storage [Storage]
    PG[(Postgres + pgvector)]
    Auth[(Auth / media volumes)]
  end

  subgraph agent [Agent + safety]
    Engage[Engagement]
    Guard[Injection guard]
    Loop[Agent loop + tools]
    Draft[Draft + owner notify]
  end

  subgraph mcp [MCP]
    Stdio[stdio]
    HTTPMCP[HTTP + SSE]
  end

  WA <--> Prov
  Prov -->|ProviderMessage| IngestQ
  IngestQ --> PG
  IngestQ --> EmbedQ
  EmbedQ --> PG
  IngestQ --> SumQ
  SumQ --> PG
  Prov --> Auth

  PG --> Engage
  Engage --> Guard
  Guard --> Loop
  Loop --> Draft
  Draft --> PG
  Dash --> PG
  Dash -->|approve| Outbox
  Outbox --> Prov

  MCPC --> Stdio
  MCPC --> HTTPMCP
  Stdio --> PG
  HTTPMCP --> PG
  Stdio --> Draft
  HTTPMCP --> Draft
```

Layer detail: [docs/architecture.md](docs/architecture.md). Provider trade-offs: [docs/providers.md](docs/providers.md).

## Quickstart

Requires **Docker**, **Node.js 22+**, and **pnpm 9+**.

```bash
git clone https://github.com/Chessing234/w-agent.git
cd w-agent

cp .env.example .env
# Required: OPENAI_API_KEY
# Recommended: DASHBOARD_TOKEN (long random secret)

docker compose up -d --build
pnpm install && pnpm migrate

# Pair: QR in app logs or the dashboard
docker compose logs -f app
# — or —
# DASHBOARD_TOKEN=… pnpm dashboard:dev  → http://localhost:3200/pairing
```

Open WhatsApp → **Linked devices** → scan the QR. When the session shows connected, you are done for the default Baileys path.

```bash
curl -sS "http://127.0.0.1:3099/healthz"
```

Local Postgres/Redis only (host-run agent): `make up-dev` — see [examples/docker-compose.override.yml](examples/docker-compose.override.yml).

## Documentation

| Document | Contents |
| -------- | -------- |
| [docs/architecture.md](docs/architecture.md) | Bridge, queue, storage, agent, MCP; provider-adapter rationale |
| [docs/security.md](docs/security.md) | Injection threat model, approval pipeline, ban risk, data locality |
| [SECURITY.md](SECURITY.md) | Responsible disclosure |
| [docs/mcp-clients.md](docs/mcp-clients.md) | Claude Desktop & ChatGPT MCP snippets |
| [docs/providers.md](docs/providers.md) | Baileys vs Meta Cloud API |
| [examples/demo.md](examples/demo.md) | Demo flows, red-team, backup/restore |
| [CHANGELOG.md](CHANGELOG.md) | Release notes |
| [CONTRIBUTING.md](CONTRIBUTING.md) | Dev setup, tests, PR expectations |

## Dashboard

```bash
pnpm dashboard:dev   # http://localhost:3200 — token: DASHBOARD_TOKEN
```

Routes: `/pairing`, `/chats`, `/approvals`, `/health`.

## MCP

| Transport | Command | Auth |
| --------- | ------- | ---- |
| stdio | `pnpm mcp` | Local process (Claude Desktop) |
| HTTP + SSE | App when `MCP_AUTH_TOKEN` is set, or `pnpm mcp:http` | Bearer / `X-MCP-Token` / `?token=` |

Full client setup: [docs/mcp-clients.md](docs/mcp-clients.md).

## Development

```bash
pnpm install && cp .env.example .env
make up-dev && pnpm migrate
pnpm dev
pnpm dashboard:dev

pnpm lint && pnpm typecheck
pnpm test                 # Docker required (testcontainers Postgres)
pnpm test:coverage        # ≥80% on src/safety + src/agent
pnpm redteam              # 10 canned injection payloads
pnpm backup               # Postgres + auth → backups/*.tar.gz
```

CI (`.github/workflows/ci.yml`): lint, typecheck, coverage on Node 22 with Redis; Postgres via testcontainers.

## Configuration

Validated in `src/config.ts` (Zod). Full list: [`.env.example`](.env.example).

| Variable | Purpose |
| -------- | ------- |
| `OPENAI_API_KEY` | Embeddings, summaries, agent, optional classifiers |
| `DATABASE_URL` / `REDIS_URL` | Postgres + Redis |
| `WHATSAPP_PROVIDER` | `baileys` (default) \| `meta` \| `evolution` (reserved) |
| `WHATSAPP_AUTH_DIR` / `MEDIA_DIR` | Baileys auth + inbound media |
| `DASHBOARD_TOKEN` / `MCP_AUTH_TOKEN` | Dashboard / remote MCP secrets |
| `HEALTHZ_PORT` | Aggregated `/healthz` |
| `OWNER_TIMEZONE` / `QUIET_HOURS_*` / `SEND_*` | Auto-send safety |

## License

[MIT](LICENSE) © W Agent contributors