# Backup and Restore of AI Agent Assets (Skills, MCP, Plugins) ## 1. Context and Motivation `ai-memory` coordinates memory and context across AI coding agents (Claude Code, OpenAI Codex, Antigravity CLI, Gemini CLI, Cursor, OpenCode, Devin, Grok, Kiro, etc.). Before these commands were added: - **Server Backup:** `ai-memory backup` takes a snapshot of the server's SQLite database (`memory.sqlite`), git wiki (`wiki/`), and `config.toml` via `POST /admin/backup`. - **Client Configuration Knowledge:** `ai-memory` installers (`install_mcp.rs`, `install_skills.rs`, `install_hooks.rs`, `uninstall.rs`) already have detailed definitions of where each supported AI harness stores MCP servers, skills, plugins, and project instructions. - **Gap:** There was no command to snapshot, export, backup, or restore host agent configurations (MCP servers, agent skills, plugins, instructions). Moving to a new machine required reconfiguring every agent manually. --- ## 2. Target Matrix by Agent Harness | Harness | MCP Configuration | Skills (Global / Project) | Plugins / Extensions | Instructions / Rules | | :--- | :--- | :--- | :--- | :--- | | **Claude Code / Desktop** | `~/.claude.json`
`~/.claude/settings.json`
`claude_desktop_config.json` | `~/.claude/skills/`
`.claude/skills/` | `~/.claude/plugins/`
`Claude Extensions/` | `CLAUDE.md` | | **OpenAI Codex CLI** | `~/.codex/config.toml`
`~/.codex/mcp.json` | `~/.agents/skills/`
`.agents/skills/`
`~/.codex/skills/` | `~/.codex/plugins/` | `AGENTS.md` | | **Antigravity CLI (`agy`) / Gemini** | `~/.gemini/settings.json`
`~/.gemini/config/mcp_config.json`
`antigravity-cli/mcp_config.json` | `~/.gemini/antigravity-cli/skills/`
`~/.gemini/skills/`
`.gemini/skills/` | `antigravity-cli/plugins/`
`~/.gemini/plugins/` | `GEMINI.md`
`AGENTS.md`
`rules/` | | **Cursor IDE** | `~/.cursor/mcp.json`
`.cursor/mcp.json` | — | VS Code / Cursor extensions | `.cursorrules`
`.cursor/rules/` | | **OpenCode (v1 / v2)** | `opencode.json`
`opencode.jsonc`
`~/.config/opencode/opencode.json` | `~/.config/opencode/skills/` | `~/.config/opencode/plugins/` | `AGENTS.md` | | **Devin CLI** | `~/.devin/config.json` | `~/.devin/skills/` | — | Devin instructions | | **Grok Build CLI** | `~/.grok/config.toml` | `~/.grok/skills/` | — | Grok instructions | | **Kiro CLI (AWS)** | `~/.kiro/settings/mcp.json` | `~/.kiro/agents/*.json` | — | — | | **OpenClaw** | `~/.openclaw/config.json` | — | `~/.openclaw/extensions/` | — | | **VS Code Copilot** | `.vscode/mcp.json` | — | Extensions | Copilot instructions | Claude Desktop config paths use the same platform-aware resolver as `install-mcp`, including packaged Windows installs. OpenCode uses `%USERPROFILE%\.config\opencode` on Windows too, as its [official troubleshooting guide](https://dev.opencode.ai/docs/troubleshooting/) documents. --- ## 3. Architecture & CLI Design ### Dedicated Host CLI Subcommands: `backup-agents` and `restore-agents` Host configurations live on the client filesystem, independent of whether the `ai-memory serve` daemon is running. Therefore, backup and restore of agent assets execute as client-side commands. #### CLI Command Specification ```bash # Backup all detected agents into an archive ai-memory backup-agents -o agent-assets.tar.gz # Filter specific agents or scopes ai-memory backup-agents --agents claude,codex,antigravity --scope both -o backup.tar.gz # Include raw MCP-config secrets (warns loudly; every archive is 0600 on Unix) ai-memory backup-agents -o backup.tar.gz --include-secrets # Dry-run inspection of an archive before restoring ai-memory restore-agents -i backup.tar.gz # Apply the reviewed restoration plan ai-memory restore-agents -i backup.tar.gz --apply ``` --- ## 4. Archive Manifest Schema (`manifest.json`) Stored in the root of the generated tarball: ```json { "$schema": "https://ai-memory.dev/schemas/agent-backup-v1.json", "version": 1, "created_at": "2026-09-28T14:30:00Z", "host": { "os": "macos", "arch": "aarch64", "home_dir": null }, "sanitized": true, "entries": [ { "agent": "claude-code", "asset_kind": "mcp-config", "scope": "global", "archive_path": "agents/claude-code/settings.json", "target_relative": ".claude/settings.json" }, { "agent": "claude-code", "asset_kind": "skill", "scope": "global", "archive_path": "agents/claude-code/skills/custom-skill/SKILL.md", "target_relative": ".claude/skills/custom-skill/SKILL.md" }, { "agent": "codex", "asset_kind": "mcp-config", "scope": "global", "archive_path": "agents/codex/config.toml", "target_relative": ".codex/config.toml" } ] } ``` --- ## 5. Security & Invariants 1. **Secret Redaction:** - By default, known tokens, bearer headers, and environment keys (`*_TOKEN`, `*_KEY`, `*_SECRET`) in UTF-8 MCP config files are sanitized using `ai-memory-hooks::sanitizer`. - Skills, plugins, and instruction files are copied verbatim and may contain secrets. - Passing `--include-secrets` bypasses MCP redaction. Every archive is set to mode `0600` on Unix because verbatim instructions and plugins may also contain credentials. Other platforms rely on their native ACLs. 2. **Symlink Safety:** - Archives do not traverse or include external symlinks (`follow_symlinks(false)`). - Restore rejects a symlink at the target or in any archive-controlled descendant below the approved home/project/config root. 3. **Path Traversal Protection:** - Restoring rejects traversal and permits only allowlisted agent destinations. Claude Desktop uses the same platform-specific path resolver as `install-mcp`. - Archive entries are regular UTF-8 paths only, and entry count, manifest, per-file, and total expanded sizes are bounded before content is staged. - Every manifest entry must have exactly one body and a well-formed SHA-256; duplicate paths/destinations, missing bodies, unmanifested bodies, and checksum mismatches are refused. Checksums detect corruption or internal inconsistency; they do not authenticate an archive's author. 4. **Atomic Restores:** - The output archive is completed and synced in a private sibling tempfile before it replaces the requested destination. - Target files use temporary file + rename + sync (`ai_memory_wiki::write_atomic`). If a later write fails, earlier writes are rolled back; timestamped copies of overwritten files remain available. - Non-managed custom files are never overwritten without explicit `--force`. - Portable Unix execute/read/write bits are restored; set-id and sticky bits are never accepted from a manifest. 5. **Active Content:** - Skills, plugins, and instruction files can contain executable code or model-visible instructions. Restore is dry-run by default and prints this warning; only use `--apply` for an archive whose source and listed paths you trust. SHA-256 consistency is not a signature. --- ## 6. Implementation Map 1. **`crates/ai-memory-core`**: - Add `agent_backup` module containing `AgentAssetKind`, `AgentAssetScope`, `AgentBackupEntry`, and `AgentBackupManifest`. 2. **`crates/ai-memory-cli`**: - `src/cli.rs`: Register `BackupAgents(BackupAgentsArgs)` and `RestoreAgents(RestoreAgentsArgs)`. - `src/commands/backup_agents.rs`: Scan host configs, package archive. - `src/commands/restore_agents.rs`: Validate manifest, present diffs, write files. 3. **Tests**: - Roundtrip tests: archive -> verify manifest -> extract into temporary directory -> assert equality. - Sanitization tests: ensure keys are redacted unless requested otherwise. - Security tests: reject path traversal payloads (`../../etc/passwd`).