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 aics or the aics 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.2
aics --version # installed command is `aics`
Without pipx, use a venv:
python3 -m venv ~/.venvs/aicsync && source ~/.venvs/aicsync/bin/activate
pip install aicsync
aics --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 isaics. 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:
aicswith 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
aics status # both clients
aics 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
aics export -o ./my-bundle # redact secrets by default
aics export -o ./my-bundle --tar # also produce a tar.gz
aics 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
aics list ./my-bundle
diff — bundle vs local
aics diff ./my-bundle
Item-by-item comparison of MCP/plugins/skills/extensions counts.
install — apply to this machine
aics install ./my-bundle # file ops applied; network ops only printed
aics install ./my-bundle --client claude
aics install ./my-bundle --force # overwrite existing items
aics install ./my-bundle --yes # also run network installs (plugins/extensions)
Behavior:
- Before applying, the current config is backed up to
~/.aics/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
aics 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["aics export"] --> B["bundle + INSTALL.md"]
B --> C{who installs?}
C -->|let the CLI do it| D["aics 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:
aics export -o b # pack (secrets redacted by default; produces b/INSTALL.md + manifest.json)
aics install b --yes # apply (non-interactive; --yes also runs network installs; idempotent)
aics diff b # verify (all == means fully restored)
Notes:
aics 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 aics 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
aics/
├── __main__.py # python3 -m aics 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
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file aicsync-0.1.2.tar.gz.
File metadata
- Download URL: aicsync-0.1.2.tar.gz
- Upload date:
- Size: 14.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5ad02b6c02b9791e9cfdc4fb813712a3497996d6d1edd2a416cac197390a4bf7
|
|
| MD5 |
bfc3baf8cd27fa3c649eedcd222cca75
|
|
| BLAKE2b-256 |
03911ea48a9ef8ef0cf2860c0300373eb90696e109b1a4aa66e0df367c94880f
|
File details
Details for the file aicsync-0.1.2-py3-none-any.whl.
File metadata
- Download URL: aicsync-0.1.2-py3-none-any.whl
- Upload date:
- Size: 18.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
12e7f6b8236c7f9c23684e08019c9c41f750bb9347b686acf9ba80c6acc58ee4
|
|
| MD5 |
ee997d9890ab41e81ab3d4f578081f1d
|
|
| BLAKE2b-256 |
378f65c1ab84c32129721dcbf40da77cba18a4dbeb13b9a6a0409d3ceb72e886
|