Parley
Allows using Matrix (Synapse) as a backend for messaging, enabling integration with Matrix rooms for human and agent communication via the Matrix Client-Server API.
Allows using Redis streams as a backend for message delivery, supporting event-driven push with XREAD BLOCK and durable message ordering.
Allows using SQLite as a backend for storing and retrieving messages, enabling persistent message history and catch-up via local database.
Allows using XMPP (Prosody) as a backend for messaging, supporting MUC live messages and MAM-based history via stanza IDs.
This server does not currently have a deployable release on Glama. Follow the repository's setup instructions to install and configure it for your MCP client, including any required credentials and local dependencies.
Parley
Plan a task in your Claude chat, hand it to a Claude Code session that catches up on the shared thread and does the work, then read the result back in a chat app you already keep open.
Parley is an MCP server — the standard way Claude connects to outside tools — that turns your Claude chat, your Claude Code sessions, and you into one shared, durable thread over a messaging backend you choose.
Put plainly, it lets you share context between Claude chat and Claude Code, hand off a task to a coding agent and get the result back, and keep humans and agents in the same chat room — running on a self-hosted message bus for AI agents that you operate.
Contents: The loop · Two ways in · Quickstart A — local, 5 min · Quickstart B — chat→Code, 15 min · Today vs. preview · How it works · Backends · Tools · Configuration · Remote / chat mode · Compare · Status · Docs
The loop
Your Claude chat and your Claude Code sessions can't talk to each other. Right now you are the cable: you copy a plan out of one window, paste it into the other, wait, then ferry the answer back. Parley is the shared thread that lets them confer over a durable backend while you watch from an ordinary chat app.
Keep Matrix open on your phone, run a Claude Code session on your acme project, and wire a Claude chat to the same topic — project-acme:
In your Claude chat, post a self-contained brief to
project-acme: "Add retry-with-backoff to the S3 upload path inuploader.ts; cap at 5 attempts; add a unit test." (Under the hood:parley_post.)You copy nothing. Go back to what you were doing.
A Claude Code session on
acmestarts (asclaude-code-acme) and, on start, callsparley_fetch_recentonproject-acme— catch-up-on-start over the durable backend, not a live push — reading your brief as if it had been in the room the whole time, though it wasn't running when you posted. (The chat-handoff skill is what wires this fetch to fire automatically on session start.)It does the work — edits
uploader.ts, adds the test, runs it — then posts the result back into the same topic (threaded viain_reply_to): "Done — addedwithBackoff(), capped at 5, testretries on 503passing."You read the answer where you asked it — the whole plan → hand-off → result thread lands in your ordinary Matrix app. No terminal, no copy-paste.
Related MCP server: agent-bus-mcp
Two ways in
The full chat→Code loop above needs remote mode: a Claude chat lives in Anthropic's cloud and can't reach a stdio server on your laptop, so chat joins the thread over an HTTP connector, not a local file. Two on-ramps — price the gap before you start:
Kick the tires in 5 minutes — no accounts, no domain, no server; Node ≥ 22. A local taste on one SQLite file, Code↔Code. It proves the whole shared-thread spine end to end; the only thing left off is the chat seat.
The real hand-off — needs a public HTTPS URL + a claude.ai connector; ~15 min. chat→Code over remote/OAuth mode. The maintainer runs this remote-mode hand-off in production, in a hardened Keycloak/OIDC + Zulip variant (see Remote / chat mode); Quickstart B is the lighter built-in-OAuth + SQLite on-ramp to the same mode.
About the phone. The hero's "read it back in a chat app you already keep open" is the full loop — remote mode plus a chat backend — so it's Quickstart B with one swap, not the 5-minute path. Today the honest, live-proven phone pick is Matrix (or XMPP with a MAM server); the consumer apps most people keep open are still fake-conformance (details). Quickstart B lands chat→Code and reads back in Claude chat; its Land it on your phone step swaps SQLite for Matrix to also drop the thread onto your phone.
Quickstart A: the local taste (5 min, zero infra)
The deliberate local taste — two Claude Code sessions, two directories, one SQLite file — the shared-thread spine with the chat seat left off (that's Quickstart B). No broker, no server, no flags.
Prereqs: Node ≥ 22, two Claude Code sessions, ~5 min — no accounts, no domain, no server.
Give each session its own directory so their configs and .mcp.json don't collide; both point at the same db_path, which is the bus.
1. Install core plus the SQLite backend (in each directory):
npm install @sharptrick/parley-core @sharptrick/parley-sqlite2. Write a parley.config.yaml in each directory — identical except the handle:
# planner/parley.config.yaml (coder/ is identical but handle: "coder")
# The backend is chosen by which binary you run (parley-sqlite, below) — not by config.
identity:
handle: "planner" # session B uses "coder"
topics:
- "ctx-demo"
backend_config:
db_path: "../parley-demo.db" # BOTH sessions point at this one file — it is the busDefaults are catch-up-only and safe: no live push. The rest of the knobs are in Configuration; you need none of them for the aha.
3. Point a .mcp.json in each directory at the stdio server:
{
"mcpServers": {
"parley": {
"command": "npx",
"args": ["parley-sqlite", "--config", "parley.config.yaml"]
}
}
}
parley-sqliteis the bin shipped by@sharptrick/parley-sqlite;npxresolves it from your local install. Every backend package ships one —parley-redis,parley-matrix,parley-postgres, and so on — and which one you run is how you choose a backend.
4. Run the hand-off. Open two Claude Code sessions, one per directory (planner and coder), both resolving to the same parley-demo.db:
In
planner: "postplan: add retry-with-backoff to uploader.ts, cap at 5to ctx-demo" → it runsparley_post.In
coder: "fetch recent on ctx-demo, then reply with a result" → it runsparley_fetch_recent, readsplanner's brief even though it wasn't running when planner posted, and replies withparley_post+in_reply_to.Back in
planner: "fetch recent on ctx-demo" → the coder's threaded reply is right there.
Here you trigger each fetch by hand to watch it work; in a wired session the on-start catch-up from The loop fires automatically.
That's the round-trip. parley_fetch_recent hands back the message plus the bookmark that makes catch-up durable:
{
"messages": [
{
"topic": "ctx-demo",
"senderHandle": "planner",
"content": "plan: add retry-with-backoff to uploader.ts, cap at 5",
"backendMsgId": "1",
"cursor": "1",
"mentions": [],
"timestamp": "2026-07-12T18:03:11.204Z"
}
],
"nextCursor": "1"
}nextCursor is the whole trick: persist it, pass it back as since, and the next catch-up returns only messages newer than it — never re-sending one you already read. Kill coder mid-hand-off and start it again: it catches up from its bookmark, re-reads the thread, and loses nothing. Then run parley-redis / parley-nats / parley-matrix instead of parley-sqlite and the same participants run across machines with zero code changes — correctness lives in the seam, not in any one host. The mechanics (cursor, backendMsgId) are spelled out in How it works.
Quickstart B: the chat-to-Code hand-off (remote mode, ~15 min)
The loop the hero promised — a Claude chat plans, a Claude Code session does the work — over the built-in OAuth front door. No external identity provider for this light path.
Prereqs: a public HTTPS URL (a one-command tunnel works) and a claude.ai connector, ~15 min. Node ≥ 22 for the server; no external IdP on this light path.
Run the self-host-remote reference server as an HTTP server (same seam, a local SQLite backend, just spoken over HTTP). Set
PARLEY_OWNER_PASSPHRASElocally and start it on127.0.0.1:3000.Put it behind HTTPS. Claude requires a public HTTPS endpoint. The fastest way is one tunnel command (install
cloudflaredfirst):cloudflared tunnel --url http://127.0.0.1:3000Set
PARLEY_ISSUER_URLto thehttps://…trycloudflare.comURL it prints. That URL is ephemeral — for a stable one, front the server with Caddy/nginx instead (there's a ready Caddyfile in the self-host README).Add a claude.ai connector pointed at
https://parley.example.com/mcp(your HTTPS URL +/mcp). Claude runs discovery → dynamic client registration → PKCE; on the consent page, enter your owner passphrase to authorize. Backend creds never leave the server — Claude holds only a consented token.Hand off. In your Claude chat,
parley_posta brief toproject-acme. A Claude Code session on that project catches up on start withparley_fetch_recentand does the work — so the brief is waiting whether or not any session was live when you posted.
Step 4 is the real, in-production shape: chat→Code lands over the durable catch-up path. The other half — an already-running session reacting the instant you post — is the live-push preview (below), not needed here. Full recipe + connector gotchas + the optional Keycloak/OIDC front door: examples/self-host-remote/README.md.
Optional — land it on your phone. Quickstart B reads back in Claude chat. To get the hero's phone experience, swap the SQLite backend for Matrix — the live-proven phone pick (backends): install
@sharptrick/parley-matrix, runparley-matrixinstead ofparley-sqlite, swapbackend_configfor your homeserver's, and keep the same topics. The plan → hand-off → result thread then also shows up in an ordinary Matrix app on your phone. Same seam, zero participant-code changes; config is in thebridge-matrixREADME.Give the Matrix instance its own
instance_id(or delete the old read-state file it names). Read-state is keyed per instance, and cursors are backend-specific — replaying a SQLite cursor into Matrix is an error, though a clearly-worded one.
What runs today, and what's still preview
Two delivery paths — one is the product, one is a preview. Stated once, here:
Tier 1 — durable catch-up (the product, works today). parley_post + parley_fetch_recent over standard MCP: a session catches up on start from the backend's own store, with ordering and dedup from the cursor + backendMsgId, never timestamps. Live-tested on 6 of 10 backends against real implementations — SQLite as a real on-disk file, plus real Redis/NATS/Postgres servers and live Matrix/XMPP homeservers — with no subscription, no flag, and on the SQLite path no server at all. This is what buys restart-survival, a swappable backend, and a human reading in a real chat app — and it's what the remote hand-off in Quickstart B rides.
Tier 2 — live <channel> push (research preview). Proactive events into an already-running Code session, riding Claude Code's native claude/channel capability. Verified headless-only — an InMemoryTransport harness plus a human manual checklist — and not yet demonstrated in a real interactive Claude Code session. It needs Claude Code v2.1.80+, a claude.ai subscription or a Console API key (not Bedrock, Vertex, or Foundry), and the --dangerously-load-development-channels flag against the fakechat loopback (--channels plugin:fakechat@claude-plugins-official). It rides Anthropic's research preview and may break on any Claude Code release — treat it as experimental, never load-bearing: a dropped or duplicated push is reconciled by the next parley_fetch_recent, and Tier 1 stands on its own.
Reading on your phone. Of the 6 live backends, Matrix is a mainstream chat app with clients on every phone — the honest end-to-end pick right now (XMPP is the other, given a MAM-enabled server). The consumer apps most people already keep open — Zulip, Slack, Discord, Telegram — are fake-conformance today (see the table below; Zulip is additionally the maintainer's operator-run production backend). So for the loop end-to-end on live-proven code, reach for Matrix.
How it works
Three numbers: 10 backends, each implementing the same 6 seam methods (plus one optional mention feed, which Zulip offers); Claude itself calls just 5 MCP tools.
The seam is that one small interface every backend implements. All the hard, backend-independent logic — live push, catch-up, dedup, ordering, reply fan-out, OAuth mode — is written once above it in @sharptrick/parley-core. Dependencies point one way: a plugin depends on core, never the reverse.
Messaging backend SQLite · Redis · Postgres · Matrix · XMPP · NATS · Zulip · Discord · Slack · Telegram
│ backend-native protocol
Backend plugin implements the seam (the six methods below)
│ normalized Message (topic · sender · content · backendMsgId · cursor · mentions)
@sharptrick/parley-core reactive tools (post · fetchRecent) + proactive push (<channel> events)
│ dedup + ordering via cursor · reply fan-out · topic allowlist · OAuth mode
┌────┴───────────────────────────┐
Claude Code Claude chat · you, in a normal chat client
catch-up + live push (preview) post + fetchRecentThe whole product is these six seam methods, plus one optional one:
interface BackendPlugin {
connect(config): Promise<void>;
disconnect(): Promise<void>;
subscribe(topic, handler): Promise<void>; // live path (push) — lossy, see below
post(topic, identity, content, opts?): Promise<BackendMsgId>; // the single durable write
fetchRecent({ topic, since?, limit? }): Promise<{ messages, nextCursor }>; // catch-up
resolveIdentity(handle): Promise<BackendIdentity>;
subscribeMentions?(handle, handler): Promise<void>; // OPTIONAL: mentions from any topic (Zulip)
}Four requirements make a backend correct. Two are about the message: a stable, unique backendMsgId (the dedup key — how core throws away a message it has already seen) and a monotonic cursor (an opaque, ever-advancing per-topic position). Two are about the live path: what subscribe delivers is a subset of the post-subscribe tail and no more, and it must actually deliver — a subscriber does not fall behind a topic written a message at a time. A backend satisfying only the first two is not conformant: one with no live listener at all, which meets both, fails 10 of the suite's cases. Catch-up is exclusive on since: it returns only messages newer than the cursor you pass, never re-sending it (ordering is the plugin's job; core never orders or parses a cursor, but it does compare two for byte equality as a no-progress brake, so a cursor naming a position has to be byte-stable across calls). The one absent-topic escape hatch is NoSuchTopicError; every other rejection is a real failure and propagates.
The two paths owe different things, and this is deliberate. fetchRecent is complete — every message above since comes back, page by page. subscribe is lossy: what it delivers is a subset of the post-subscribe tail, in cursor order, never twice, never anything from before the subscribe; what it leaves out is returned by the next fetchRecent. That is what keeps a backend from having to rebuild its transport's own gaps client-side — a Matrix burst wider than the 100 timeline events the plugin's own /sync filter asks for, or a SQLite row a peer commits during start-up, is left to catch-up rather than reconstructed by hand. A live path that delivers nothing is still non-conformant, and the shared suite grades both bounds.
Adding every backend after SQLite changed zero lines of @sharptrick/parley-core — check the git log — and one shared conformance suite proves each against the same contract.
Add a backend. Implement the six methods, point the shared conformance suite (
@sharptrick/parley-conformance) at your plugin, and ship it as its own package — core never has to know it exists. The Redis backend is a complete, conformant example in one small file:post=XADD,fetchRecent=XRANGE(stream id as the cursor),subscribe= a blockingXREADloop. Every transport maps its native position onto the cursor (SQLiterowid, Redis stream id, PostgresBIGSERIAL, … — full mapping in the table below). →packages/bridge-redis/src/index.ts
Backends
Ten backends — six live-tested against real implementations, four proven against in-process API fakes of the vendor protocol. The Verified column tells you which is which, so "10 backends" never reads as "10 live-tested backends."
This is what backend-agnostic MCP messaging buys: the same six-method seam gives you
agent-to-agent messaging over Matrix/NATS or plain SQLite, and moving between them changes a
binary and a backend_config block, not a line of participant code.
Backend | Transport / mechanism | Cursor | Verified |
SQLite | local file, polling-only (WAL, no broker) |
|
|
Redis | Redis Streams, blocking | stream id |
|
Postgres | table + |
|
|
Matrix | hand-rolled Client-Server HTTP + |
|
|
XMPP | MUC + MAM archive (server must enable MAM) | MAM id |
|
NATS | JetStream (persistent streams) | stream sequence |
|
Zulip | event-queue long-poll (raw | message id |
|
Discord | gateway websocket (raw | snowflake (Discord's time-sortable id) |
|
Slack | Socket Mode websocket (raw |
|
|
Telegram | Bot API | local observation sequence, qualified by the store file ( |
|
live— exercised against real implementations in CI/dev: SQLite on a real on-disk file, real Redis/NATS binaries, live Synapse/Prosody homeservers, and Postgres 16 (SQLite, Redis, Matrix, NATS, XMPP, Postgres — 6 of 10).fake-conformance— the same shared suite run against in-process fakes of the vendor API, not live vendor accounts: Zulip, Discord, Slack, Telegram (4 of 10). Zulip is additionally operator-run (the maintainer's own instance, below) and ships an env-gated real-credential suite (PARLEY_ZULIP_URL/_EMAIL/_API_KEY) that runs the identical seam suite against a live Zulip server. Telegram's Bot API has no pre-join history endpoint, so that backend documents the gap rather than faking backfill.
Every backend clears the identical seam contract — cursor monotonicity, exclusive-since catch-up, subset-but-never-duplicated live push, and double-delivery dedup — plus multi-process write safety wherever the transport allows concurrent writers (Telegram is single-writer by design: one bridge per bot token, since a second getUpdates poller gets HTTP 409, so that one conformance case is deliberately skipped). No vendor SDKs: Matrix is a hand-rolled HTTP client (not matrix-js-sdk), Discord and Slack use raw ws, Telegram and Zulip use raw fetch.
The five MCP tools
Distinct from the six seam methods a backend implements, these are the 5 tools Claude actually calls:
parley_fetch_recent— catch a topic up from the durable backend.{topic, since?, limit?, block_ms?, from?}→{messages, nextCursor}.from: "recent"asks for the backend's newest page instead of resuming from where this instance last read, without moving that position.block_mslong-polls where the backend's own read primitive takes a wait, and is refused by name where it cannot — see Waiting for a reply below.parley_post— publish or hand off into a topic (thread with optionalin_reply_to).{topic, content, in_reply_to?, read_through?, force?}→{posted: true, backendMsgId}. Read before you speak: if the topic has messages the author has not been handed, nothing is written and they come back as{posted: false, unread, nextCursor}; send it again once read.@handlein the content pushes it to that handle; a backend's own address syntax (Zulip's@**handle**) also keeps it from every follower it does not name.parley_whoami— who this instance is and what its bridge can do: handle, followed and post-only topics, version, whether live push and mention push are on, and the operator'sdirectoryof how to reach the others.parley_live_status— ask whether the live<channel>path is actually delivering, per topic, rather than reading a quiet topic as good news.{}→ per-topicdelivering/not-delivering/no-traffic, or a refusal naming why this deployment cannot tell.parley_reply— reply into the topic an inbound<channel>event arrived from. Likeparley_post, it's written durably to the backend — the live channel is only the fast inbound hop, so a reply survives restart and shows up in the next catch-up.
Waiting for a reply (block_ms)
A session that hands off work usually wants the answer. Without help that means polling
parley_fetch_recent on a timer and burning a tool call per tick, most of them empty.
block_ms is on the schema everywhere, and served where the backend's own read primitive takes a
caller's wait — today Redis (XREAD BLOCK) and NATS (a JetStream pull expiry). There, pass it and
the call blocks server-side until a message newer than since arrives, or the budget expires —
whichever comes first:
{ "topic": "ctx-demo", "since": "<nextCursor from the last call>", "block_ms": 30000 }It returns the moment a message lands, so the cost is one call per message rather than one
per interval. Keep block_ms comfortably under your client's tool timeout — a blocked call that
outlives the timeout looks like a hang. Core clamps it to catchup.block_max_ms (default 60s)
before it ever reaches a plugin, so a caller cannot exceed the server's own ceiling.
On the other eight — discord, telegram, matrix, slack, xmpp, postgres, zulip and sqlite — there
is no read primitive to park a budget on, so fetchRecent fails fast: it rejects with
BlockingFetchUnsupportedError naming the backend, and the tool hands that error back rather than a
page. That is the point of refusing rather than ignoring — an empty page is exactly what a long-poll
that timed out looks like, so an agent handed one goes on polling in the belief that it is parked.
Retry without block_ms and poll on your own cadence, or run under Claude Code with
live_push.enabled and be pushed a <channel> event as well — push is a latency shortcut over
catch-up, never a replacement for it. The
chat-hand-off skill shows both loops.
The refusal lives entirely in the plugin: the seam carries blockMs and nothing else, so a backend
that cannot serve a wait costs zero changes to any other package.
Configuration
Full reference in DESIGN.md §11. The knobs worth knowing before you run this against
a real account:
Key | Default | Why you'd touch it |
| (required) | This instance's logical name; what peers |
|
| Read-state namespace. Two sessions sharing a handle clobber each other's read position — give each its own. Also give a new one when repointing an instance at a different backend, since cursors are backend-specific. |
|
| Where that cursor file lives. Core writes three siblings beside it: |
| (required) | Subscribe + catch-up list. This is the allowlist. Capped at 64 topics: each one is an allowlist entry every |
|
| Extra topics allowed for post/fetch only, as anchored regexes. Never subscribed or caught up on. Patterns are screened for catastrophic backtracking at load, capped at 64 patterns (every post/fetch matches its topic against all of them), and matched only against topics of at most 64 characters — a longer topic must be listed in |
|
| At startup, read forward to the topic's live boundary and mark those ids seen, so the live push cannot re-deliver them. Nothing is emitted and nothing is consumed: your read position does not move, and |
|
| Page size per |
|
| Server-side ceiling on |
|
| How often core re-drives |
|
| Claude Code only — push |
|
|
|
| — | How an agent reaches the other participants in this deployment, e.g. |
|
| Opaque to core, passed verbatim to the plugin. Secrets live here — never committed. |
There is no backend key: the backend is whichever parley-<name> binary you run. A config
carrying one is rejected at load with the binary to run instead, rather than silently ignored.
Every other key outside backend_config is checked too: an unrecognised one (live_push: enable:,
presense:) is a load error naming it, not a silently dropped line that leaves you with a bridge
quietly doing nothing. backend_config stays open — it is opaque to core.
Remote / chat mode
The same codebase runs as a public HTTP MCP server so a Claude chat connector can reach it directly — the mechanism behind Quickstart B. It sits behind a standards-compliant built-in OAuth 2.1 + PKCE front door (dynamic client registration; standards-based discovery (RFC 9728) and audience binding (RFC 8707) — details in the docs), or delegates to an external IdP in OIDC mode (Keycloak is the tested target). It's single-tenant: backend credentials stay server-side, and Claude only ever holds a consented, audience-bound token.
For a hardened setup, the maintainer runs Parley as their own single-tenant instance behind a Keycloak/OIDC front door (issuer at auth.example.com) fronting a self-hosted Zulip backend (zulip.example.com), TLS terminated at a reverse proxy and reachable over a private tailnet — shipped infrastructure, not a roadmap slide. That's optional hardening; the built-in OAuth front door in Quickstart B is the light path.
Security posture: secrets live in backend_config / .env, never in core and never committed. A client-side topic allowlist plus anchored post_topics regexes bound each instance (e.g. general + project-.*). Inbound messages are treated as untrusted data, never as privileged instructions. SQLite uses WAL for safe concurrent multi-process writes, and retention_days pruning is opt-in on SQLite/Redis/NATS.
How it compares
vs. localhost agent buses (xats, claude-peers-mcp, AgentBus): the one thing they fundamentally can't do is put a human reading and replying in an ordinary chat app — on their phone, off the machine. Those buses are localhost-only and agents-only. Parley is the same primitives — topics, durable history,
claude/channelpush — but off one machine and carrying a human plus a Claude chat too. Should you switch from xats today? Not for live push: xats rides the same experimentalclaude/channelcapability, and Parley's is still preview-grade (above) — concede that. Switch when you want a human in a real chat app, cross-host sessions, or a durable backend you can swap: the same participants run on a local SQLite file today and Redis / NATS / Matrix / Zulip across machines tomorrow with zero participant-code changes.vs. a plain MCP server: Parley is dual-role. A request/response server can answer
post/fetch_recent; it can't proactively push a<channel>event into a session that's already running. Parley does both (the push half is the research preview above).What it isn't: not an agent framework (A2A, AutoGen, MindRoom) — deliberately just the seam. No built-in chat UI.
Project status & maintenance
Single maintainer, MIT, no hosted service. It runs on infrastructure you operate — no lock-in, deliberately just the seam.
Pre-1.0, actively developed. See the GitHub Releases for cadence; the last-commit badge up top is the live pulse. Per project convention, early breaking changes land as
feat:until 1.0 is deliberately cut.The one risk to price in. The product (Tier 1 durable catch-up) stands alone and depends on nothing unstable — six methods, ten backends, and zero core changes are the evidence the seam is stable. The only experimental dependency is Tier 2 live push, which rides Anthropic's
claude/channelresearch preview and may break on any Claude Code release — scoped above, never load-bearing.Releases are automated. A merge to
mainis a release: CI runs the test gate, thensemantic-releasepicks the version bump from the PR title and publishes every package to npm in lockstep with provenance (OIDC — no tokens). SeeCONTRIBUTING.md.Contributing. Dev setup, running the shared conformance suite, and the pre-PR checklist are in
CONTRIBUTING.md; extending Parley with a new backend is the Add a backend callout above.Support: open a GitHub issue; report vulnerabilities via
SECURITY.md.
Docs & license
DESIGN.md— the source of truth for the seam, cursors, delivery paths, and security model.docs/CONVENTIONS.md— catch-up-on-start and the hand-off conventions.docs/keycloak-integration.md— OIDC / Keycloak remote-mode setup.docs/1.0-readiness.md— the evidence for cutting 1.0, what it would and wouldn't promise, and the per-backend verification matrix.skills/chat-handoff/SKILL.md— the chat-handoff skill (the full, runnable chat→code walkthrough).docs/REVIEW_PROTOCOL.md— the adversarial review protocol (ten lenses, computed convergence), anddocs/findings/critical-review/— what we've measured about the review process itself.examples/fakechat-loopback/MANUAL-CHECKLIST.md— the headless live-push loopback and its manual checklist.examples/self-host-remote/README.md— the public remote-MCP reference deployment (the ~15-minute recipe behind Quickstart B).examples/dev-compose/docker-compose.yml— throwaway backends for testing (point at upstream canonical Docker setups for production).Per-backend details live in each
packages/*/README.md.
A parley is a conference between parties to reach an understanding — which is all Parley is: one durable thread where your Claude chat, your Claude Code sessions, and you confer.
MIT licensed.
This server cannot be deployed
Maintenance
Related MCP Connectors
Shared memory and mail for your AI agents. Verified with Claude Code; other MCP clients in testing.
Real-time chat for AI agents. Claude Code, Cursor, Cline and Codex join channels over MCP.
Real-time chat hub for AI agents — Claude Code, Cursor, Cline, Codex over MCP or REST.
Share one project context across ChatGPT, Claude, Telegram and any MCP client.
Related MCP Servers
- AlicenseNot gradedqualityFmaintenanceThe self-hosted MCP bridge between Claude Chat and Claude Code.46AGPL 3.0
- AlicenseNot gradedqualityCmaintenanceA local MCP server that connects AI coding agents (Claude Code, Codex, Cursor, etc.) on the same machine via a shared message bus, enabling them to chat, delegate tasks, and collaborate privately without cloud or internet.58 npmMIT
- AlicenseNot gradedqualityDmaintenanceAn MCP server for inter-session communication between Claude Code instances. Built on NATS JetStream, it provides room-based messaging, direct agent communication, presence tracking, and message history.Apache 2.0
- AlicenseNot gradedqualityBmaintenanceA message bus that enables AI assistants (Claude, ChatGPT, Gemini, Perplexity) to communicate via shared channels using MCP or REST APIs.19MIT