One source of truth for every AI coding agent on your machine.
Define your MCP servers, memory, skills, and marketplace plugins once in
~/.agentsync/. Run agentsync apply. They land — correctly translated — in
Claude Code, OpenCode, and Codex CLI (with Cursor planned).
Quickstart · Install · Docs site → agentsync.cc · User guide · Known limits
Status: beta. v1.0 ships Claude Code + OpenCode end-to-end. The tool is functional and tested under
just test-release; package-manager distribution and a few documented trade-offs are still being finalized.
If you use more than one AI coding agent, you keep re-entering the same config in each one's native format, you forget to install a plugin everywhere, and your configs quietly drift apart. agentsync fixes the fan-out:
- Edit once, apply everywhere. Add an MCP server or install a plugin a single time; it's projected into each agent's native config — fully where the agent has the concept, lossily-but-reported where it doesn't, skipped (never silently) where it can't.
- Bidirectional, chezmoi-style. When an agent edits its own config, agentsync detects the drift and offers a merge: adopt the edit into your source, or re-impose the source. Nothing is overwritten behind your back.
- Secrets stay secret. Reference
${secret:github.token}; agentsync resolves it at apply time from an age-encrypted vault and never writes the cleartext back into your (committable) source.
New here? The User guide takes you 0→100.
agentsync init
agentsync agent add claude
agentsync agent add opencode
agentsync mcp add github --command npx --args "-y,@modelcontextprotocol/server-github"
agentsync apply --dry-run # preview translation report before writing
agentsync apply
The full docs are published with search and rendered diagrams at
agentsync.cc (source in website/). The
canonical markdown also lives in docs/:
| Doc | What it covers |
|---|---|
| User guide | Install → first sync → daily loop → secrets → plugins → project config. |
| Concepts & glossary | The three-state model, drift, reconcile — every term in one page. |
| Capability matrix | Exactly what each agent supports, and what's lossy or deferred. |
| Architecture | The apply/capture pipelines, drift classifier, and secret invariants. |
| Component map | The codebase, package by package. |
| CONTRIBUTING · SECURITY · CHANGELOG | Contributing, threat model, release history. |
| Agent | Status | Component coverage |
|---|---|---|
| Claude Code | ✓ full adapter | All seven components, incl. LSP. |
| OpenCode | ✓ adapter | MCP, memory, skills, subagents, commands. Hooks + LSP skipped. |
| Codex CLI | ✓ adapter | MCP (TOML config.toml), memory, skills, subagents (◐), slash commands (◐, global-only), hooks (◐) + plugin import. No LSP concept. |
| Cursor | planned | No-op today; will project skills + subagents (.cursor/skills/, .cursor/agents/) and project-scope rules. |
Full ✓/◐/✗ breakdown per component: capability matrix.
Pre-release: the package-manager channels below are wired in
.goreleaser.yamlbut are published starting with the first tagged release. Until then, build from source:go install github.com/spxrogers/agentsync/cmd/agentsync@latestor clone and
go build ./cmd/agentsync.
brew tap spxrogers/tap
brew install agentsync
scoop bucket add spxrogers https://github.com/spxrogers/scoop-bucket
scoop install agentsync
choco install agentsync
Pick the package for your architecture (amd64 or arm64).
Debian/Ubuntu:
curl -fsSL https://github.com/spxrogers/agentsync/releases/latest/download/agentsync_linux_amd64.deb -o agentsync.deb
sudo dpkg -i agentsync.deb
RPM:
sudo rpm -i https://github.com/spxrogers/agentsync/releases/latest/download/agentsync_linux_amd64.rpm
Arch (AUR):
yay -S agentsync-bin
agentsync is single-machine. To sync ~/.agentsync/ across machines, use chezmoi (or any dotfile manager):
chezmoi add ~/.agentsync
If you lose your age private key, you lose access to all encrypted secrets. Recommended: store the key in a 1Password Secure Note or your machine-setup repo. agentsync does not back up the key for you.
agentsync secrets set accepts the value three ways:
agentsync secrets set github.token --stdin # value from stdin (best for scripts / 1Password CLI)
agentsync secrets set github.token # prompt with echo off
agentsync secrets set github.token=ghp_… # back-compat; warns — argv is visible to ps(1) and shell history
agentsync diff redacts every resolved ${secret:…} value before printing, so a piped diff doesn't leak credentials to logs.
- OpenCode hooks: OpenCode hooks are JS/TS plugins, not declarative shell commands. agentsync v1 does NOT auto-translate Claude hooks to OpenCode. Hand-author a small JS/TS plugin if you need a hook on OpenCode.
- Codex projections are lossy where Codex differs: subagents project to Codex's TOML agent format (the
tools/colorfrontmatter has no target and is dropped, reported in the apply report); slash commands map to Codex custom prompts which are global-only, so a project-scope command is skipped; hooks mirror Claude's declarative hook schema as inline[hooks.*]tables in~/.codex/config.tomlbut only for the events Codex recognizes (Claude'sSessionEnd/Notificationdrop). All of these are surfaced in the translation report — nothing is dropped silently. - Cursor adapter: not implemented in v1 — registers as a no-op adapter (planned), and
agent add cursoris rejected unlessAGENTSYNC_ALLOW_UNIMPLEMENTED=1. Cursor's planned coverage includes skills and subagents (which it stores on the filesystem under.cursor/skills/and.cursor/agents/), but its user-level rules live in app-local storage (not the filesystem), so the adapter will manage rules at project scope only. - LSP projection beyond Claude: OpenCode/Cursor LSP support is deferred (Codex has no LSP concept at all). Claude plugins that include LSP servers install correctly on Claude itself; on other agents you'll see
lsp server X skippedin the apply translation report. - cursor agent registration:
agent add cursoris rejected in v1.0 because its adapter is a noop. SetAGENTSYNC_ALLOW_UNIMPLEMENTED=1to register anyway (apply will silently emit zero ops for it). - TOML / JSONC comment preservation: comments in
~/.agentsync/mcp/*.toml, in agent-sideopencode.json, and in Codex's~/.codex/config.tomlare NOT preserved across reconcile[w]rite-back or import / apply. Hand-edited comments survive in unrelated sections; the rewritten section will be re-emitted without comments. Deferred to v1.x. - Hand-edits to agentsync-owned keys in shared agent files (e.g. an MCP server entry in
~/.claude.jsonthat agentsync owns): the nextapplyoverwrites them with NO foreign-collision backup, because agentsync considers them its own. Useagentsync reconcile(the drift classifier catches the edit and offers[w]rite-back) BEFORE the next apply if you want to keep them. - Plain-http / git:// plugin sources are rejected by default to prevent MITM swap. Set
AGENTSYNC_ALLOW_INSECURE_URLS=1for internal mirrors. - Symlinked destinations (e.g.
~/.claude.jsonis a chezmoi symlink into your dotfiles repo) are rejected by default — a rename onto the path would replace the symlink with a regular file and strand your linked source. SetAGENTSYNC_ALLOW_SYMLINK_DEST=1to write through the symlink instead (the underlying file is updated in place; the link survives). - Continue, Gemini CLI, Aider: not on the v1.x roadmap.
| Env var | Purpose |
|---|---|
AGENTSYNC_HOME |
Override ~/.agentsync/ location (absolute path). |
AGENTSYNC_TARGET_ROOT |
Redirect $HOME for testing (used by the hermetic test container). |
AGENTSYNC_ALLOW_SYMLINK_DEST=1 |
Permit writes to symlinked destination files (resolves the link first). |
AGENTSYNC_ALLOW_INSECURE_URLS=1 |
Accept http:// and git:// plugin / marketplace sources. |
AGENTSYNC_ALLOW_UNIMPLEMENTED=1 |
Accept agent add cursor despite the noop adapter. |
AGENTSYNC_ALLOW_PLUGIN_DRIFT=1 |
Bypass the plugin-cache manifest-SHA check (after hand-editing). |
AGENTSYNC_ALLOW_OFFLINE_VERIFY=1 |
Skip ${secret:…} resolution in agentsync verify (CI without an age key). |
AGENTSYNC_AGE_SKIP_PERM_CHECK=1 |
Skip the 0600 mode check on the age identity file (ACL'd NFS). |
AGENTSYNC_MAX_TARBALL_MB=<N> |
Override the per-tarball decompressed-bytes cap (default 512). 0 disables. |
AGENTSYNC_TEST_IN_CONTAINER=1 |
Bypass the host test guard (use only with go test -run for a single case). |
- First apply on a populated machine: agentsync sees pre-existing native config files and triggers
foreign-collision. The original is backed up to~/.agentsync/.state/backups/<ts>/before the new content lands. Recommendagentsync apply --dry-runfirst to preview the translation report. - One-time backup churn after upgrading: state keys are now stored
${HOME}-relative (portable across machines) instead of with absolute paths. If you ran a pre-portability build, the firstapplyafter upgrading will not recognize the old absolute-path entries, so every managed destination is treated as aforeign-collisiononce: the current content is backed up to~/.agentsync/.state/backups/<ts>/and then re-owned. This is expected, non-destructive (nothing is lost — it's backed up), and self-heals after that single apply. Runagentsync apply --dry-runfirst if you want to see which files will be backed up. agentsync updatefails to fetch a marketplace: verify the marketplace URL withgit ls-remote. agentsync usesgo-gitand falls back to systemgitfor sparse clones if needed.${secret:foo}not resolving: runagentsync secrets get footo verify the key exists in the decrypted file. age library errors will surface here.
Every just test* recipe runs inside a hermetic container (podman first,
docker fallback) — except the two explicit on-host opt-ins (test-fast and
test-live) called out below. The repo is mounted read-only, the network
is off, and every test's HOME is a fresh tmpdir — the suite cannot touch
your real ~/.claude.json, ~/.config/opencode/, or ~/.agentsync/.
| Layer | Question it answers | Command |
|---|---|---|
Unit + integration (internal/*/*_test.go) |
Did I break an internal contract? | just test |
Lifecycle e2e (test/e2e, build tag e2e) |
Does the binary survive the v1 happy path? | just test-e2e |
BDD Gherkin lock (test/bdd, tag bdd) |
Are the spec's north-star behaviours intact? | just test-bdd |
| All layers in one container run | Can I safely cut a release right now? | just test-release |
If just test-release is green, ship.
For fast in-place iteration without spinning up the container, just test-fast
runs the unit/integration layer directly on the host. The existing tests
already redirect HOME via AGENTSYNC_TARGET_ROOT, so they are still safe;
the container is the release gate.
If you reach for the obvious go test ./..., the filesystem-touching
packages refuse to run on the host and print a long banner pointing you
at the recipes above. To bypass the guard manually (e.g. for go test -run
on a single test), set AGENTSYNC_TEST_IN_CONTAINER=1:
AGENTSYNC_TEST_IN_CONTAINER=1 go test ./internal/cli/ -run TestApply_FirstRun
just test-live runs the live cohort (build tag live) — currently the
obra/superpowers projection check, which clones the real upstream plugin
to verify agentsync's projector keeps working as the upstream evolves. It
runs on host because it needs network access; it is opt-in and NOT part
of test-release, so the release gate stays hermetic and offline.
MIT.