Skip to main content
Glama

One line to install on any machine:

# Windows (PowerShell) — runs the installer: install + enable the port + next steps
irm https://raw.githubusercontent.com/Sachitt-AV-08/parley/main/install.ps1 | iex
# macOS / Linux
curl -fsSL https://raw.githubusercontent.com/Sachitt-AV-08/parley/main/install.sh | sh

The installer detects uv → pipx → pip, installs parley-wa (CLI, TUI and MCP extras) from the latest release, enables the local debugging port, and prints the two commands to start.

One line to send from a script on any machine:

pip install 'parley-wa'[mcp]      # or: pip install <release wheel URL>
parley setup            # enable the local debugging port (auto-undoable)
parley send --to Ava --text "ci is green"   # resolves Ava -> live chat -> sends -> confirms it landed

Or in Python:

from parley import Session, parley_connect

wa = parley_connect()            # auto-attaches to the running WhatsApp Desktop
wa.send("Weekend Hikers", "who's bringing the snacks?")
for chat in wa.chats(unread_only=True):
    print(chat)

No WhatsApp account? The entire API runs on a fully scripted simulator:

parley --demo status
parley --demo send --to Ava --text "hi from parley"
parley --demo tui

Why parley exists

The mainstream way to automate WhatsApp is a cloud service — or a library that quietly talks to one. Your chats, your contacts, your fingerprints transit a third party that is not WhatsApp, and a lot of accounts got flagged for it.

parley takes the opposite side:

It never talks to anything but your own machine. You already trusted WhatsApp Desktop with your account — parley attaches to that process over the Chrome DevTools Protocol (a local debugging channel, one setting away from enabled), and drives the very page you're looking at. Everything stays on 127.0.0.1.

The result: no new login, no re-encoding of credentials, no upload, no ban-risk multiplier — automation for your own account, on your own screen, as if a tireless human assistant with hands were sitting at your desk.

  • Windows — WhatsApp Desktop renders WhatsApp Web in WebView2 (Chromium). parley turns on its debugging channel with parley setup and connects.

  • macOS / Linux — same CLI attaches to any Chromium with --remote-debugging-port=9334 pointed at web.whatsapp.com.

  • Remote / containers — PARLEY_CDP_HOST / PARLEY_CDP_PORT point parley at whatever machine exposes the port.

Related MCP server: waxum-mcp

Features

parley status / parley doctor

attach health, login state, endpoint checks, reversible setup

parley chats

conversations, unread counts, pins, last message, last seen

parley chat "Ava"

full history, richest first, JSON-ready

parley send --to X --text …

sends to a contact, group, number, or chat id — parley resolves the recipient first

parley reply --message <id>

quoted replies where WhatsApp supports them

parley react --message <id> --emoji ☕

reactions, not read receipts

parley schedule add …

one-shot and recurring (hourly/daily/weekly) sends, persisted to disk

parley server

local JSON HTTP API — for agents, webhooks, cron, you name it

parley tui

a real terminal chat inside your WhatsApp

--demo

the entire surface, fully scripted, zero WhatsApp needed (also what CI tests live on)

--to knows people and groups: pass an id (15551234567@c.us), a bare number (+1 555 123 4567), a contact name (Ava) or a group subject (Weekend Hikers) — parley finds the exact chat, opens it, verifies the header and only then types. No wrong-chat accidents.

Quick tour

# enable the debugging channel (undo later with: parley setup --undo)
parley setup            # user-level env var, no admin; add --admin for HKLM
parley doctor           # confirm: process running? flag present? endpoint open?

# your real install:
parley chats
parley send --to "Weekend Hikers" --text "who's bringing the snacks?"
parley send --to "+91 98765 43210" --text "sms alternative, but over WhatsApp"
parley chat Ava --json | jq '.[0]'

# scheduled + recurring sends, right from the API:
parley schedule add --to Ava --text "morning standup reminder" \
    --at "2026-10-02T09:00:00" --repeat daily
parley schedule list
parley schedule run --once                # fire anything due, right now

# any HTTP client can use it too — `parley server` issues a token on first
# run and prints it (see `~/.parley/server.token`); pass it as a Bearer token:
export PARLEY_TOKEN="$(cat ~/.parley/server.token)"
curl -X POST localhost:8300/send -H "content-type: application/json" \
     -H "authorization: Bearer $PARLEY_TOKEN" \
     -d '{"to":"Ava","text":"via http"}'

Every command supports --json for piping into scripts, agents and cron. Scheduled entries live in ~/.parley/schedules.json (override with PARLEY_DATA_DIR), and parley server watches the queue in the background — a scheduled blast obeys the same pacing and budget as a manual send.

How it actually works

            ┌─────────────────────────── your machine ───────────────────────────┐
            │                                                                     │
  CLI/TUI   │   ┌──────────┐   ┌──────────────────┐   ┌───────────────────────┐  │
  HTTP API  │   │  parley  │──▶│   Session (paced,│──▶│ Backend (CDP attach)  │  │
  agents    │   │  Session │   │   retried)       │   │ playwright over CDP   │  │
            │   └──────────┘   └──────────────────┘   └──────────┬────────────┘  │
            │                                                     │  CDP over    │
            │   ┌──────────────────────────┐      ┌──────────────┐ │  ws://       │
            │   │ WhatsApp Desktop (WinUI3) │◀────▶│  WebView2    │◀────── localhost│
            │   │  …already logged in…       │      │  (Chromium)  │               │
            │   └──────────────────────────┘      └──────────────┘               │
            └──────────────────────────────────────────────────────────────────────┘
  1. parley setup opens the WebView2 debugging channel (user env var by default, machine-wide HKLM policy with --admin; --undo removes both) — exactly how you'd debug any WebView2 app.

  2. WebViewBackend attaches over CDP and finds the WhatsApp page target.

  3. Reads prefer WhatsApp's internal Store (WAWebCollections, or a webpack registry scan) — structured, fast, no screen-scraping. A DOM fallback kicks in when the store's internal name changes between builds.

  4. Writes go through the Store's message API (sendTextMsg / chat.sendMessage with several strategy fallbacks) and, when the build exposes none, the DOM path drives the visible UI: search (name and number candidates) → click the exact row by title → verify the conversation header switched → type → Enter → poll until the text visibly appears in the conversation before reporting success.

  5. HumanPacing guards every send so an account never looks like a spam bot.

  6. SchedulerThread (in parley server) fires due entries through the same paced session.

DemoBackend implements the same backend protocol entirely in memory — that's what powers --demo, the unit tests and the CI.

Give your AI agent hands on WhatsApp

parley ships a Model Context Protocol (MCP) server, so any MCP client — Claude Desktop, Claude Code, Cursor, Copilot, or any agent framework — can read chats and send/reply/react/schedule on your real WhatsApp, locally.

pip install 'parley-wa[mcp]'     # install with the MCP extra
parley mcp                       # serve an MCP stdio server on your live account

Point your client at it. Claude Desktop-style config (the command must honor the --demo global flag placement — it goes before the subcommand):

{
  "mcpServers": {
    "parley": { "command": "parley", "args": ["mcp"] }
  }
}

For Claude Code, one command installs the bundled agent skill into ~/.claude/skills — the skill teaches the agent the tool set, pacing and guardrails:

parley skill install

Exposed tools: status, list_chats, read_messages, send_message, reply_message, react_message, schedule_message, list_schedules, cancel_schedule, run_due_schedules. Everything stays on 127.0.0.1 and runs through the same paced, verified session as the CLI.

Reliability, with receipts

Automating a store you don't own is only as good as the verifier. parley treats "send" as three confirmed steps, each independently checked:

  1. Resolve — resolve_recipient(needle) returns a (chat_id, display_name) you can inspect, or raises cleanly. Name, number, id and group all work.

  2. Open — the DOM path only clicks a row whose title matches, then re-checks the conversation header really switched before allowing typing.

  3. Landed — after Enter, parley polls #main until the exact normalized text appears in the conversation bubble stream. Only then is ok: true returned. Failed confirmation raises instead of silently pretending.

Measured on the author's Windows 11 box (one-time cold vs warm):

path

cost

CDP attach + login check

~0.8 s

recipient resolution

~0.1 s

open an already-open chat + send + confirm

~5 s

full cold path (search → open → type → confirm)

~9 s

Every number is paced down further by HumanPacing before it touches the wire.

parley vs the status quo

parley

WhatsApp Cloud API

web-scraping "bots"

"tools-in-the-cloud" platforms

where data lives

your machine

Meta

random VPS

their cloud

new login / QR needed

no

yes (business mgr)

sometimes

yes

cost

free, open source

usage-metered

blocked fast

subscriptions

ban profile

low (your own desktop)

official but gated

high

high

offline dev / CI

yes (--demo)

no

no

no

self-hostable

yes

no

makeshift

no

Human by default

Blasting is how accounts get flagged. parley's HumanPacing:

  • types for ~90 ms/character (bounded), jittered;

  • sleeps a variable "network" beat before each sent;

  • keeps a rolling burst budget (18 messages / 60 s by default).

Every value is overridable per command and per API call, because you are the responsible party for your own account.

Safety notes

  • parley never sees, stores or transmits your credentials, chats, contacts or session state. All traffic stays on 127.0.0.1.

  • Sends are paced and budgeted by design. Read operations never write.

  • Treaty: use your own account, your own device, your own automation — comply with local law and WhatsApp's ToS. The issues tracker is open for questions.

  • If you expose the HTTP server beyond loopback, set --token and use TLS in front — and honestly, don't; keep it on 127.0.0.1.

Status

Area

State

Simulator (--demo)

stable, unit-tested, CI

Live attach (Windows WhatsApp Desktop)

verified — real messages sent & content-confirmed in the UI

Recipient resolution (contact, group, number, id)

stable, unit-tested

Scheduler (one-shot + hourly/daily/weekly, JSON store)

stable, unit-tested

CDP attach + status + login detect

implemented

Store read path (chats/messages/contacts)

implemented, version-tolerant

DOM fallback reads + DOM send

implemented, verified

HTTP API (incl. /schedule*)

implemented, unit-tested

TUI

functional, rides the simulator too

Cross-platform (any Chromium + web.whatsapp.com)

supported

Tests / CI

40+ green on Windows + Ubuntu, Python 3.10–3.13

The live-store APIs are inherently version-sensitive (they call WhatsApp's own internal module surface). parley degrades gracefully — a build bump only ever softens a feature, never crashes the process.

Roadmap

  • PyPI release of parley-wa (one token away — uv tool install parley-wa)

  • First-class Python SDK docs and a docs/ site

  • Media sends (images, voice notes) and message download

  • Webhooks → parley server push channels

  • A parley as a service mode for containers (still local-first)

  • Contributions welcome — see CONTRIBUTING

Contributing

uv venv && uv pip install -e '.[dev]'
uv run pytest          # green, offline, fast
uv run parley --demo chats

Issues, PRs and "it works on this build" reports are all gold. Read CONTRIBUTING and the code of conduct first.

Contributors

License

MIT © Sachitt. Made for people who automate their own machines — not for harvesting other people's. See LICENSE.

Related MCP Connectors

  • Drive WhatsApp from any MCP client: pair devices, send text and media, manage contacts and groups.

  • Your own WhatsApp as an MCP server: read, search and send from any MCP client.

  • Hosted MCP server for your own WhatsApp accounts: messages, contacts, groups, channels, calls.

  • WhatsMCP connects Claude and other MCP-compatible AI agents directly to WhatsApp. Send and receive text, images, documents, and voice notes; manage groups (create, add/remove members, promote admins); look up contacts and profiles; follow channels; and read call and message history — all through a standard MCP interface. For voice use cases, WhatsMCP offers SIP-based calling plans (inbound-only, or full inbound/outbound) so AI voice agents can answer and place WhatsApp calls, plus low-latency WebSocket integrations with voice agent providers like ElevenLabs. Multiple WhatsApp accounts can be paired and managed per workspace, with webhook support for real-time inbound message delivery to your own infrastructure.

Related MCP Servers

  • F
    license
    Not graded
    quality
    C
    maintenance
    MCP server for WhatsApp that exposes send, read, and media management tools through the waxum REST API gateway, enabling any MCP client to interact with WhatsApp chats and media over stdio.
    1
    -
  • A
    license
    Not graded
    quality
    B
    maintenance
    MCP server that controls WhatsApp Desktop via Chrome DevTools Protocol using the user's real session, enabling tools to list chats, read messages, search contacts, and send messages with simulated typing and rate limiting.
    31 npm
    1
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    MCP server that turns WhatsApp into agent-callable tools, enabling search contacts, send/receive messages, read chats, handle media, and monitor calls via the WhatsApp Web multi-device protocol.
    2 npm
    MIT