Why this exists
If you use more than one coding assistant, you run into the same problem:
Antigravity stores skills in ~/.gemini/config/skills. Claude Code expects them in ~/.claude/skills. Cursor looks in ~/.cursor/skills, Android Studio in ~/.android-studio/skills, GitHub Copilot in ~/.copilot/skills, and Junie in ~/.junie/skills. Claude Desktop stores MCP server commands inside claude_desktop_config.json under Application Support. Projects often have their own .gemini/ or .claude/ folders checked into git.
"If you fix a bug in a skill inside one repo, that fix stays trapped there. If you add an MCP server to Claude, Antigravity does not know about it. Citadel solves this with native symlinks."
You keep one copy of each skill in ~/.citadel/skills, and every tool points back to it.
What is The Armory?
The Armory is your single, canonical source of truth for all AI instructions, prompts, and MCP configurations. It lives at ~/.citadel/skills/.
Instead of manually synchronizing files between editors, The Armory holds the master files. Citadel injects filesystem symbolic links (symlinks) into each tool:
Because these are symlinks, an edit made inside any editor or terminal updates the master file in The Armory instantly with zero sync latency and zero duplicate storage.
Installation
Citadel is written in Swift and compiles to a native Mac binary. It requires macOS Sonoma or later.
Where files go
When you run ctdl sync, Citadel updates these paths on your machine:
| Assistant | Path | How it links |
|---|---|---|
| Antigravity (Global) | ~/.gemini/config/skills/ |
Symlink to ~/.citadel/skills/ |
| Claude Code CLI | ~/.claude/skills/ |
Symlink to ~/.citadel/skills/ |
| Cursor | ~/.cursor/skills/ |
Symlink to ~/.citadel/skills/ |
| Android Studio | ~/.android-studio/skills/ |
Symlink to ~/.citadel/skills/ |
| GitHub Copilot | ~/.copilot/skills/ |
Symlink to ~/.citadel/skills/ |
| Junie | ~/.junie/skills/ |
Symlink to ~/.citadel/skills/ |
| Claude Desktop | ~/Library/Application Support/Claude/claude_desktop_config.json |
Injects into mcpServers |
| Project Workspaces | <repo>/.citadel/skills/ or .gemini/ |
Symlinks selected project skills |
Commands
You can run citadel or the shorthand ctdl:
In-repo skills
When you work in a team repository, you often do not want to commit personal skills to git. In your project folder, run:
Add .gemini/ and .claude/ to your global ~/.gitignore. Both tools can now use your skills inside that project, and any edit you make updates your central copy in ~/.citadel.
Using npm
Citadel uses npm to distribute skills. There is no custom backend to sign up for.
Any npm package with "keywords": ["citadel-skill"] in its package.json can be found with ctdl search and installed with ctdl install:
{
"name": "@developer/citadel-skill-kubernetes",
"version": "1.0.4",
"keywords": ["citadel-skill"],
"files": ["SKILL.md", "scripts/"]
}
When you run ctdl install @developer/citadel-skill-kubernetes, Citadel downloads the archive, puts the files in ~/.citadel/skills/kubernetes, and links them to Antigravity and Claude.
Zero-Knowledge Cloud Sync & Emergency Rollback
Citadel is architected with a strict zero-knowledge policy. There are no Citadel cloud servers or databases. When you configure Cloud Sync:
- Sync communicates directly between your Mac and your own private GitHub/GitLab repository over HTTPS.
- All repository commits are signed with an Ed25519 key generated locally and kept in your macOS Keychain.
- Citadel only creates or accesses your dedicated
citadel-syncrepo; it never reads your other private repositories.
Emergency Rollback / Decoupling ("Eject")
Because your AI assistants depend on symlinks pointing to ~/.citadel/skills/, deleting Citadel without unlinking could cause broken references. Citadel provides two layers of protection:
- Cloud Recovery: Your skills are preserved safely in your personal Git repo, recoverable on any Mac.
- Eject & Materialize: You can click "EJECT & MATERIALIZE" in Settings or run the standalone script at
~/.citadel/rollback.sh. Citadel instantly decouples from all tools by converting symlinks into real, independent folder copies.
API keys
Many MCP servers need tokens like GITHUB_TOKEN. Putting real tokens in JSON files risks committing them to Git.
In Citadel, use ${VAR_NAME} inside MCP JSON definitions:
{
"name": "github",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_TOKEN}"
}
}
Citadel reads $GITHUB_TOKEN from your shell environment or macOS Keychain when generating configs for Claude and Antigravity. The Git repository in ~/.citadel only ever stores the variable name.