aicsync
AI client config sync — back up and migrate your Claude Code and Cursor configuration (MCP servers, skills, plugins, commands, agents, rules, extensions) across machines.
Pure Python standard library. Zero dependencies, zero build step. python3 -m aicsync or the aicsync command.
Why
You've accumulated a personal config across Claude Code and Cursor — MCP servers, skills, plugins, custom commands, Cursor rules, extensions. When you switch machines or reinstall, these are scattered across ~/.claude.json, ~/.claude/, ~/.cursor/ and can't be carried over in one shot. Manual copying is error-prone and risks leaking plaintext API tokens elsewhere.
Existing tools (Smithery, community mcp-sync) only handle installing MCP servers from scratch. There's nothing that packages your whole setup and restores it on a new machine. aicsync fills that gap.
Install
Requires Python 3.10+ (standard library only).
From PyPI (remote) — recommended via pipx (Homebrew/system Python is PEP 668 externally-managed and blocks plain pip):
brew install pipx # macOS, once
pipx install aicsync # or: pipx install aicsync==0.1.3
aicsync --version # installed command is `aicsync`
Without pipx, use a venv:
python3 -m venv ~/.venvs/aicsync && source ~/.venvs/aicsync/bin/activate
pip install aicsync
aicsync --version
From source:
git clone <your-repo> aicsync && cd aicsync
pipx install -e . # editable: pipx install -e .
The PyPI distribution name is
aicsync; the installed command isaicsync. Upgrade later withpipx upgrade aicsync.
Global options
-V, --version print version
-v, --verbose verbose logging to stderr
-q, --quiet suppress progress logs
-h, --help show help
Results go to stdout, logs/errors to stderr — safe for pipes. Exit codes: 0 success, 1 failure, 130 interrupt. Override the target home with AICS_HOME (for testing / sandboxes).
Interactive mode
aicsync is a CLI with an interactive layer (not a full-screen TUI). In a TTY it activates automatically; under a pipe / agent it stays plain text:
aicsyncwith no args: in a TTY opens a numbered menu (status/export/list/diff/install/convert/quit) and prompts for arguments; non-TTY prints help.- Color: when stdout is a TTY, status/diff/list are colored (headers cyan,
==green,+bundle/+localyellow, redacted red). SetNO_COLORor pipe → plain text. - Install confirm gate: in a TTY without
--yes, prints a colored diff, thenApply these changes? [y/N]. Answeringnaborts (no backup, no changes);ybacks up and applies. Non-TTY /--yesskips the gate for automation.
Commands
status — what's on this machine
aicsync status # both clients
aicsync status --client claude
Prints a markdown inventory: install commands for every MCP server, claude plugin install lines for plugins, lists of skills/commands/agents, and Cursor extensions. Secrets are redacted by default.
export — pack a bundle
aicsync export -o ./my-bundle # redact secrets by default
aicsync export -o ./my-bundle --tar # also produce a tar.gz
aicsync export -o ./my-bundle --include-secrets # keep plaintext secrets
Bundle layout:
my-bundle/
├── INSTALL.md # agent-readable install guide (with per-item commands)
├── manifest.json # machine-readable index (counts / redacted / assets)
├── claude_mcp.json # MCP servers + settings + plugins manifest
├── cursor_config.json # MCP + settings + extensions manifest
└── assets/
├── claude/{skills,commands,agents}/ # plain-text assets, copied as-is
└── cursor/rules/ # .mdc rule files
list — bundle contents
aicsync list ./my-bundle
diff — bundle vs local
aicsync diff ./my-bundle
Item-by-item comparison of MCP/plugins/skills/extensions counts.
install — apply to this machine
aicsync install ./my-bundle # file ops applied; network ops only printed
aicsync install ./my-bundle --client claude
aicsync install ./my-bundle --force # overwrite existing items
aicsync install ./my-bundle --yes # also run network installs (plugins/extensions)
Behavior:
- Before applying, the current config is backed up to
~/.aicsync/backup/<timestamp>/. - File ops (MCP JSON merge, skills/commands/agents/rules copy, settings merge) run directly and are idempotent (existing items skipped;
--forceoverwrites). - Network ops (
claude plugin install,cursor --install-extension) only print commands by default;--yesruns them. - Secrets: redacted fields stay empty and prompt you to fill them manually — values are never guessed.
convert — Claude skill → Cursor rule
aicsync convert --skill ~/.claude/skills/foo/SKILL.md --out foo.mdc
Translates a SKILL.md's frontmatter into a Cursor .mdc rule; trigger semantics that can't be expressed get a <!-- TODO -->.
Two usage paths
flowchart LR
A["aicsync export"] --> B["bundle + INSTALL.md"]
B --> C{who installs?}
C -->|let the CLI do it| D["aicsync install bundle --yes"]
C -->|hand to an agent| E["agent reads INSTALL.md\nruns each command"]
B -.->|secrets| F["redacted list\nfill manually"]
Agent usage
Non-TTY → no color, no confirm gate, no menu. stdout carries parseable results; stderr carries progress logs. Exit codes: 0 / 1 / 130.
Minimum three steps:
aicsync export -o b # pack (secrets redacted by default; produces b/INSTALL.md + manifest.json)
aicsync install b --yes # apply (non-interactive; --yes also runs network installs; idempotent)
aicsync diff b # verify (all == means fully restored)
Notes:
aicsync statusstdout is markdown; eachclaude mcp add .../claude plugin install ...line is directly executable.- Secrets are
nullin the bundle — the agent never guesses values; surfacemanifest.json'sredactedlist for the user to fill. - Sandbox test:
AICS_HOME=/tmp/sb aicsync install b --yes— doesn't touch your real home. installis idempotent; re-running skips existing items.
Design: why plugins are "reinstalled", not "copied"
The plugin cache in ~/.claude/plugins/cache/ holds platform-specific compiled artifacts (darwin-x64 binaries), git working-tree state, and absolute paths — and all of it is reproducible from installed_plugins.json's name@marketplace + git SHA. So aicsync only exports the install manifest and runs claude plugin install <name>@<marketplace> on install, rebuilding by SHA. We migrate the intent to install, not the cache corpse.
skills/commands/agents/rules are plain text — copied directly, no reinstall needed.
Security model
- Redact by default: any JSON value whose key matches
token|key|secret|password|auth|credentialis nulled on export/status and recorded inmanifest.redacted. --include-secretsis an explicit opt-in to keep plaintext.installnever guesses secret values — it prompts you to fill them.installalways backs up the existing config first.
Client adapters
Currently supports Claude Code + Cursor. Adding a client means writing one scan function and one apply function.
Module layout
aicsync/
├── __main__.py # python3 -m aicsync entry
├── cli.py # arg parsing + command dispatch + version/help + exit codes
├── config.py # path constants + env (AICS_HOME)
├── log.py # leveled logging -> stderr (verbose/quiet)
├── errors.py # AicsError + exit codes
├── scan.py # Claude/Cursor config scanners
├── sanitize.py # secret redaction
├── render.py # markdown rendering (status + install guide)
├── bundle.py # export / list / diff / tar
├── installer.py # install / backup / merge
└── convert.py # skill -> cursor rule
License
MIT
Metadata
Release files for aicsync 0.1.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| aicsync-0.1.3.tar.gz | 14.0 kB | Without provenance | Details for aicsync-0.1.3.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| aicsync-0.1.3-py3-none-any.whl | Python 3 | none | any | Details for aicsync-0.1.3-py3-none-any.whl |
Total release size: 32.4 kB
Release files / aicsync-0.1.3.tar.gz
| Download URL | aicsync-0.1.3.tar.gz |
|---|---|
| Size | 14.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
cddfbe24fa192bb4c913376d49f59995be3141d3d36638bfa34299b6fe1fb738
|
|
BLAKE2b-256 checksum How to use checksums |
ec91b7ac3947afa02c83ed7459e72668cade7c5ab7ad28e21da5dc6e6ee4e5e7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.7
|
Release files / aicsync-0.1.3-py3-none-any.whl
| Download URL | aicsync-0.1.3-py3-none-any.whl |
|---|---|
| Size | 18.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b121611a57a7855df0cd5dcd12267ef6da9cb0c06a7c5d7816caf98f6f475edc
|
|
BLAKE2b-256 checksum How to use checksums |
983450530b99a8b063c5bbe305817aa96fcdc8897d895471783d6f90b549c9e7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.7
|
Security for aicsync 0.1.3
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.