Keep your AI skills and MCP servers in one place.

Claude, Antigravity, and Cursor expect configs in conflicting directories. Citadel maintains your skills centrally in ~/.citadel and symlinks them into every tool with zero overhead.

Filesystem mapping APFS Symlinks
~/.citadel/skills/hallmark/
// Linked directly to:
  ↳ ~/.gemini/config/skills/hallmark
  ↳ ~/.claude/skills/hallmark
  ↳ ~/Projects/my-app/.gemini/skills/hallmark
  ↳ ~/Projects/my-app/.claude/skills/hallmark
6
AI assistants supported
0 ms
APFS symlink sync latency
0 bytes
duplicate storage overhead
100%
zero-knowledge private sync

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:

Architecture APFS Symlinks
~/.citadel/skills/my-skill     # Master Canonical Copy
// Pointed to by zero-overhead symlinks:
  ├── ~/.gemini/skills/my-skill         (Antigravity)
  ├── ~/.claude/skills/my-skill         (Claude Code)
  ├── ~/.cursor/skills/my-skill         (Cursor)
  ├── ~/.android-studio/skills/my-skill (Android Studio)
  ├── ~/.copilot/skills/my-skill        (GitHub Copilot)
  └── ~/.junie/skills/my-skill          (Junie)

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.

Terminal zsh
$git clone https://github.com/kartikarora/citadel.git
$cd citadel && make install
installed /usr/local/bin/citadel
installed /usr/local/bin/ctdl
$ctdl init
initialized ~/.citadel (git enabled)

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:

Terminal ctdl
ctdl list                # List skills, MCPs, and linked repos
ctdl sync                # Re-apply symlinks and commit changes
ctdl add skill <path>    # Copy a skill folder into ~/.citadel
ctdl add mcp <name>      # Register an MCP server
ctdl portal .            # Symlink skills into current repo
ctdl search <query>      # Search npm for community skills
ctdl install <pkg>       # Download and unpack an npm skill
ctdl push / pull         # Sync ~/.citadel with your private Git remote

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:

Terminal Workspace
$cd ~/Projects/my-app
$ctdl portal .
Linked: my-app/.gemini/skills/hallmark -> ~/.citadel/skills/hallmark
Linked: my-app/.claude/skills/hallmark -> ~/.citadel/skills/hallmark

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:

package.json Skill author
{
  "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-sync repo; 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:

  1. Cloud Recovery: Your skills are preserved safely in your personal Git repo, recoverable on any Mac.
  2. 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:

~/.citadel/mcps/github.json JSON
{
  "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.