Self-hosted service
zai-org/Synapse avatar
zai-org/Synapse

The conversation is the runtime, not a chat window

Self-hosted AI workspace with shareable AI teammates, shared conversations, memory, and governed access to plugins, MCP tools, and local devices.

564 stars43 forksTypeScriptApache-2.0

At a glance

What is it?
Synapse is a self-hosted TypeScript workspace that treats a conversation as the boundary where humans, native actors and bridged agents meet, and where every plugin, device, memory space and sandbox is reached through one revocable grants ledger.
Who is it for?
Synapse fits a team that wants agents with durable memory and real machine access without giving them standing access to everything, because the grants ledger and the per-capability device model make every permission visible and revocable in the same thread where the work happens. It does not fit a single user with one assistant, where the conversation-as-runtime design is overhead with no second participant to coordinate.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 106 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on November 14, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • zai-org/Synapse564 ★ · +52
Star history
Repository2026-09-212026-11-14
zai-org/Synapse512564

52 Stars in the last 54 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial analysis

Participants, wakeups and memory are all scoped to the thread

Most assistants put a chat window in front of one bot. Synapse inverts that and makes the thread the runtime boundary, which changes where state lives. A conversation carries participants, transcript visibility, actor sessions, wakeups and memory handoff, and there is no separate API-invoked session sitting beside it. Four kinds of participant share one thread: workspace members, native actors, bridged remote agents, and external chat identities. Wakeups are part of the design rather than an afterthought, since a message from one actor lands as a durable wakeup for another, so a handoff between two agents happens in the open and leaves a record in the same transcript a human can read. Memory lives in permissioned spaces shared through the same grants ledger as everything else, and long conversations are archived verbatim instead of being summarized away, so nothing important disappears quietly as a thread grows.

Sharing a teammate stops at the roster

Teammates are meant to be shareable, and the mechanism is deliberately casual: actors and remote agents can be shared like contacts, through a QR code or a friend ID, with the owner approving. That approval step is where the design gets conservative. Cross-workspace sharing covers discovery and rosters today, which means another workspace can see that your agent exists and add it to a list, while conversations and execution stay inside the workspace that owns the agent. So the share link is a directory entry, not a delegation of authority. A team can advertise the same teammate to partners without any risk that a partner's conversation reaches into your plugins, devices or memory, and equally without a way to grant a partner scoped access to just one capability. If your use case needs a shared agent doing real work inside two organizations at once, this part of the model is the piece to design around.

The daemon pulls, so nothing is pushed to your laptop

The interesting engineering decision is how an agent you already run joins the team. The machine-side daemon in packages/remote-agent-daemon bridges Claude Code and Codex CLI into conversations over an outbound WebSocket, and those agents keep their own runtime, their own tools and their own model accounts. Nothing about your local setup is wrapped or replaced. The direction of traffic is the part worth knowing: the bridged agent fetches messages and posts replies through a per-conversation reverse MCP tool surface, so Synapse never pushes unsolicited content into it. Capabilities are not assumed either, because workspace plugins and runtime capabilities are projected to the remote agent through the same authorization gate native actors pass. When the agent needs input or plan approval, it raises a task card that lands in the conversation, and any eligible participant can answer it. The result is that an offline or busy laptop produces a stalled thread rather than an error, and the stall is visible to everyone in it.

Eight chat transports, one runtime, best-effort delivery

Synapse connects external chats to the same conversation runtime rather than to a parallel bot system, and the list is long enough to be a design statement: Feishu also known as Lark, WeChat, WeCom, DingTalk, QQ, Telegram, the WhatsApp Cloud API, and WhatsApp through the unofficial web protocol. The binding rule is simple and has consequences. An inbound chat maps one to one onto a Synapse conversation, the sender joins as an external participant, and the configured actor is woken, which means a conversation cannot quietly fan out into several threads. Everything else follows from that: actors, grants, memory and automation behave identically in a chat that started in Telegram and one that started in the web client. Two limitations are stated rather than hidden. Voice notes are transcoded on ingest, so an audio message becomes text the actors can read but the original audio is not the record. And delivery status reported by the chat platforms is best-effort, so a message marked sent is not a message an actor has seen.

Devices advertise the command line tools they actually found

Pairing a machine is what turns a teammate into something that can do work rather than discuss it. Desktop, a Linux server or a cloud Docker host can all be paired, and four capabilities are exposed as MCP tools: filesystem, command line, browser through Chrome DevTools, and computer use. Each is granted per capability and per conversation, so the grant that lets an actor read files in one thread is not the grant that lets it read them in another. The transport is outbound only. Devices dial the control plane, every operation travels as a signed envelope over the device's own connection, and nothing is listening on a port inside your network for the control plane to reach into. The detail that makes this usable rather than theoretical is the capability-aware CLI catalog: each device probes the machine it sits on and advertises the command line tools it discovered there, so what an actor can reach is a property of the host rather than a list somebody wrote down and forgot to update.

Sandboxes are off until you name a provider

Isolated compute exists, and it is not on. The sandbox runtime is opt-in through the SANDBOX_PROVIDER setting and ships disabled, which means the default deployment runs actors against whatever host and whatever permissions the grants ledger has handed out, with no workbench in between. When you do turn it on, the shape is session-scoped: an isolated workbench is provisioned when a turn starts and destroyed when the session goes idle. Files are the part that survives. Working sets hydrate from snapshots and commit back at the end of every turn, stored as content-addressed snapshots other actors can pick up, so a torn-down sandbox loses compute and not work. Three providers are on offer and they are chosen per deployment: a local process, a Docker container, or an off-box VM compatible with E2B, named CubeSandbox. That last one is the constraint to plan around, since it requires a self-hosted CubeSandbox endpoint rather than a hosted service you can sign up for.

One ledger holds every grant, and an approval is spent once

Actors, plugins, skills, runtime capabilities, memory spaces and event sources are all managed through a single table called workspace_resource_grants, which is the mechanism that makes the governed-access claim concrete rather than aspirational. Every grant is explicit, revocable, and enforced the same way everywhere, so there is no second permission system hiding behind an integration. When a call is blocked, it becomes a one-tap card in the conversation instead of a log line, and among the chat integrations QQ is the one that supports those cards today. The approval model has a sharper edge worth understanding before you build on it: approvals are consume-once. Approving replays the exact original call server-side, so the model never retypes the request and cannot smuggle a different one past the card, and the one-time grant is consumed after that single use. Convenient for a delete or a payment, and a poor fit for anything you want an actor to keep doing. Plugin availability is gated the same way, from the environment rather than the ledger: each optional builtin MCP plugin is only surfaced as installable when its enable flag is set, and the sidecar-backed ones need a matching URL and their own compose profile as well.

bash
MCP_ENABLE_NOTION=
NOTION_MCP_URL=http://notion-mcp:8766/mcp/
XHS_MAX_TENANT_BACKENDS=3
XHS_BACKEND_IDLE_TTL_SECONDS=1800

The Xiaohongshu sidecar shows how carefully those defaults are tuned, since it runs a headless browser backend per tenant, caps concurrent backends at 3 with LRU eviction, tears down an idle backend after 1800 seconds, and keeps a comma-separated allowlist of storage hosts the sidecar may reach for media upload, with an empty list meaning publish-with-media is disabled.

Version 0.28.0, marked private, with no published release

Two version numbers exist and neither is a release you can install from. The root package is named synapse at version 0.28.0 and is marked private, and the repository has no GitHub releases, so there is no tagged artifact and no changelog to diff against in the usual sense, though the tree does carry CHANGELOG.md alongside Chinese and Spanish variants. The README carries a note that sets expectations more honestly than a version number would: Synapse is in an early design and implementation phase, schemas and runtime contracts can still change quickly, and backward compatibility for old data is not guaranteed. The workspace layout shows what a build actually costs. Fifteen workspaces are declared, including six prebuilt device runtime bundles covering linux, darwin and win32 on both x64 and arm64, and the build chain runs a filesystem helper and a computer-use helper shell script before compiling the protocol, shared, device runtime, SDK, API, daemon and web packages in that order.

Editorial conclusion

Synapse fits a team that wants agents with durable memory and real machine access without giving them standing access to everything, because the grants ledger and the per-capability device model make every permission visible and revocable in the same thread where the work happens. It does not fit a single user with one assistant, where the conversation-as-runtime design is overhead with no second participant to coordinate. Before you deploy it, check four things. Whether you can accept its own warning, since the README says schemas and runtime contracts can still change quickly and backward compatibility for old data is not guaranteed. Whether the eight chat transports matter to you, given that voice notes are transcoded on ingest and delivery status is best-effort. Whether you need a sandbox, which is off by default until SANDBOX_PROVIDER names one. And which database and cache you will run, since Postgres with pgvector and Redis are both bound to localhost and both require credentials before the compose file will start.

Frequently asked questions

What is Synapse from zai-org?

It is a self-hosted TypeScript workspace for AI teammates that treats the conversation as the runtime boundary. Humans, native actors, bridged remote agents and external chat identities all work in one thread, and everything they can touch is reached through revocable grants.

Can Synapse connect Claude Code or Codex to a conversation?

Yes. The remote-agent daemon bridges Claude Code and Codex CLI into conversations over an outbound WebSocket, and the agents keep their own runtime, tools and model accounts. The agent pulls messages and posts replies through a per-conversation reverse MCP surface rather than receiving pushed content.

Which chat platforms can Synapse connect to?

Eight transports: Feishu or Lark, WeChat, WeCom, DingTalk, QQ, Telegram, the WhatsApp Cloud API, and WhatsApp through the unofficial web protocol. Voice notes are transcoded on ingest and delivery status reported by the platforms is best-effort.

Are Synapse sandboxes enabled by default?

No. The sandbox runtime is opt-in through the SANDBOX_PROVIDER setting and is off by default. Three providers exist, a local process, a Docker container and an off-box E2B-compatible VM called CubeSandbox, and the off-box provider requires a self-hosted CubeSandbox endpoint.

How does Synapse control access to plugins and MCP tools?

Actors, plugins, skills, runtime capabilities, memory spaces and event sources are all managed through one workspace_resource_grants ledger that is explicit, revocable and enforced uniformly. A blocked call becomes a one-tap card in the conversation, and approving it replays the exact original call server-side before the one-time grant is consumed.

What databases does a Synapse deployment need?

Postgres with the pgvector image at pg16 for the data layer and Redis 7 for the cache, both bound to 127.0.0.1 in the compose file. Both require a password from the environment, and the compose file refuses to start without them and points you at setup.sh first.

Official sources

  1. Issues
  2. License: Apache-2.0
  3. Project website
  4. README
  5. zai-org/Synapse on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/zai-org-synapse.svg)](https://hysenlabs.com/projects/zai-org-synapse)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/zai-org-synapse.svg)](https://hysenlabs.com/projects/zai-org-synapse)

Was this useful?