warden

warden

A single MCP server that fronts many downstream MCP servers and Skills, exposing only four tools (search, call_tool, use_skill, admin) so that an agent's context window only ever sees search results on demand.

Category
Visit Server

README

warden

CI License: MIT Python 3.10+

warden is one MCP server. It gives an agent access to many other MCP servers and Skills. The agent sees only 5 tools:

  • search(query, limit=5) — This tool does a regex or keyword search. It looks in the name, the description, and the arguments of each tool. It also looks in the name and the description of each Skill. No other data goes to the agent.
  • call_tool(server, name, arguments) — This tool sends a call to the MCP server that has the tool. Use a search result to find the server and the tool.
  • use_skill(name) — This tool returns the full instructions for a Skill. Use a search result to find the Skill.
  • admin(action, params) — This tool controls the registry. It can also move MCP servers and Skills out of Claude Code. The changes are immediate, and you do not restart the server. Refer to The admin tool.
  • route(task, context=None, mode=None) — This tool selects the best tool or Skill for a task. It ranks the candidates and returns the best one. It does not run the tool. Refer to Routing.

At start, warden connects one time to each MCP server in the configuration and gets its tools with list_tools. It also reads each Skill directory and finds the SKILL.md files. warden keeps this catalog on the server. The model does not get these definitions. The model gets only search results, and only when it asks.

How to use

The goal is to move your MCP servers and Skills behind warden. Then the Claude context has only the 5 tools. warden supplies the other data only when the agent asks for it.

  1. Install.

    pip install -r requirements.txt        # or: pip install .  (for the warden command)
    
  2. Test first (the safe method). The dry run shows each change. Then apply the migration to a temporary Claude home. warden does not change your real ~/.claude.

    warden migrate --all                                   # dry run: shows each change
    warden migrate --all --apply --home /tmp/fake-claude   # apply to a temporary home
    warden restore --id <printed-id> --home /tmp/fake-claude
    
  3. Do the real migration. Remove --home to change your real Claude configuration. warden adds the items to the registry. warden also disables the items in Claude.

    warden migrate --all --apply     # or select items: --plugins X --skills Y --mcp Z
    warden list                      # look at the registry
    

    To move only some items, add them one at a time. Use warden add-mcp <name> --command <cmd> [--args ...] or warden add-skill <path>.

  4. Set warden as the only MCP server in Claude. Refer to the JSON in Setup. Then restart Claude Code. Claude Code reads the disabled items at start. warden does not need a restart, because its catalog updates immediately.

  5. Tell the agent to use warden (one command). warden does not start hidden skills automatically. Run warden init. It writes a short capability block into your agent-instruction file. The block tells the agent to call route or search first. The command asks for the scope and the file, and it does not change anything until you confirm.

    warden init                       # asks the scope and the file, then writes
    

    Refer to Limitation for the full text and the manual method.

  6. Use warden. Give Claude a usual instruction. When Claude needs a tool, it calls route or search. Then it calls call_tool or use_skill. To add or move more items later, an agent calls the admin tool, or you use the CLI. To reverse a migration, use warden restore --id <id>.

Each section below gives more data: CLI, The admin tool, Migration from Claude Code.

Setup

pip install -r requirements.txt

warden reads its catalog from a registry file. The registry file has the same structure as config.example.json:

{
  "mcp_servers": {
    "github": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-github"], "env": {} }
  },
  "skill_dirs": ["./skills"]
}

You do not have to write the registry manually. The commands warden add-mcp, add-skill, and migrate make the registry and change it. An empty registry is also correct. Then warden starts with an empty catalog and prints one line to stderr. An agent can then fill the registry with the admin tool.

Config location

warden finds the registry in this sequence:

  1. WARDEN_CONFIG — the full path to the config.json file.
  2. WARDEN_HOME — a directory. The registry is <home>/config.json.
  3. The default: ~/.config/warden/config.json (XDG).

All writes go to WARDEN_CONFIG, WARDEN_HOME, or the XDG default. The commands add-mcp, add-skill, migrate, and the admin tool make these writes. The writes do not go to the current directory. Therefore the registry stays available in all sessions and from all directories. For reads, if none of these are present, warden uses ./warden.config.json.

To start the server, use one of these commands:

python3 -m warden          # or: warden  (the installed console command)

Each command is the same as warden serve.

Set warden as the only MCP server in your MCP client. Example clients are Claude Desktop, Claude Code, Copilot CLI, and Cursor. For example:

{
  "mcpServers": {
    "warden": {
      "command": "python3",
      "args": ["-m", "warden"],
      "cwd": "/path/to/warden"
    }
  }
}

CLI

The same registry operations are available to you as subcommands. The default subcommand is serve.

Command Function
warden serve Runs the MCP server. This is the default.
warden init [--scope user|project|local] [--file CLAUDE.md|AGENTS.md|GEMINI.md] [--remove] [--print] [--yes] Writes the warden capability block into your agent-instruction file, so the agent calls route first. It asks for the scope and the file. Add --yes for a non-interactive run.
warden add-mcp <name> --command <cmd> [--args ...] [--env K=V ...] Adds an MCP server to the registry.
warden add-skill <path> Adds a Skill directory to the registry. warden reads its SKILL.md files.
warden list Prints the registry as JSON. It shows the MCP servers, the skill directories, and the migration ids.
warden migrate [--all] [--mcp ...] [--plugins ...] [--skills ...] [--apply] [--home <dir>] Moves MCP servers and Skills out of Claude Code. This is a dry run. Add --apply to make the changes. Add --home <dir> to use a different Claude home for a test.
warden restore --id <migration-id> [--home <dir>] Reverses a migration. It puts back the changes in Claude. Add --home <dir> for a test home.
warden routing show Prints the routing configuration as JSON.
warden routing set-mode <auto|ask> Sets the default routing mode.
warden routing prefer <name...> Adds names to priority_order.
warden routing exclude <name...> Adds names to exclude.
warden routing add-rule --ext <e...> | --glob <g> [--prefer <n...>] [--exclude <n...>] Adds a per-file routing rule.
warden auto-start list Prints the Skills that load at every session start.
warden auto-start add <name...> Marks Skills to load at every session start. Restart the client to apply.
warden auto-start remove <name...> Stops the Skills from loading at every session start.
warden add-mcp github --command npx --args -y @modelcontextprotocol/server-github
warden add-skill ~/my-skills
warden list

The admin tool

The admin(action, params) tool gives the registry operations to an agent through MCP. The agent can set up warden or change it, and the agent does not restart the server. After each change, warden makes the internal catalog again. Therefore search shows the change immediately. The actions are:

  • list — returns {mcp_servers, skill_dirs, migrations}.
  • register_mcpparams: {name, command, args?, env?}.
  • register_skillparams: {path}.
  • unregisterparams: {kind: "mcp"|"skill", name}.
  • migrateparams: {targets: {mcp, plugins, personal_skills}, apply?}. This is a dry run and returns the plan. Set apply to true to make the changes. Each target is an array of names or keys, or the text "all".
  • restoreparams: {id}.
  • get_routing — returns the routing configuration.
  • set_routingparams: {mode?, priority_order?, exclude?, rules?}. It changes the routing configuration. Refer to Routing.
  • set_auto_startparams: {name, enabled?}. It marks a Skill to load at every session start, or it removes the mark. Refer to Always-on Skills.

Routing

The route tool selects the best tool or Skill for a task. It ranks the candidates and returns the best one. It does not run the tool. The agent then calls call_tool or use_skill on the result.

route(task, context=None, mode=None):

  • task — a description of what you want to do.
  • context — optional and light. It is {"file_path"?, "extension"?, "project_markers"?}. It holds references only, not file content. If you omit it, warden still ranks from the configuration.
  • mode"auto" returns the single best pick. "ask" returns a ranked list. The default comes from the configuration. If only one tool is a candidate, warden returns it directly and does not rank.

The result is {"mode", "single_option", "chosen", "candidates"}. Each candidate has a name, a score, and reasons.

Routing rules live in the configuration (the routing block). warden reads them at each call, so a change takes effect immediately.

  • priority_order — a list of names. An earlier name gets a higher rank and wins a tie.
  • exclude — a list of names. warden never routes to these.
  • rules — per-file rules. Each rule is {"when": {"extension"?: [...], "path_glob"?: "..."}, "prefer"?: [...], "exclude"?: [...]}. A rule matches the passed context. If you omit the context, warden skips the context rules and uses priority_order and exclude only.

Set the rules with the CLI or the admin set_routing action:

warden routing set-mode ask
warden routing prefer ts-tools code-reviewer
warden routing exclude legacy-linter
warden routing add-rule --ext tsx --prefer ts-tools
warden routing show

Always-on Skills (auto_start)

Most Skills stay hidden until search surfaces them. This keeps the context small. Some Skills only work when they are always active, though. A "think before you code" ruleset, for example, must sit in the context before the agent writes anything; it cannot wait for a search. auto_start is the opt-in for that case.

A Skill flagged auto_start has its full text folded into warden's MCP server instructions. The MCP client reads those instructions one time, at the start of each session, so the Skill is always active. warden still stays one MCP server, and your other Skills stay on demand.

warden add-skill ~/skills/ponytail   # register the skill dir first
warden auto-start add ponytail       # mark it always-on (by skill name)
warden auto-start list
warden auto-start remove ponytail

An agent can do the same with the admin set_auto_start action.

Keep this set small. Each always-on Skill spends context in every session, which is the cost warden otherwise removes. Note these limits:

  • It needs a client restart. The MCP client reads the instructions only at start. So a new or removed auto_start Skill takes effect at the next restart. The on-demand catalog still updates immediately.
  • The client must inject server instructions. Claude Code does. Not every MCP client does.
  • warden caps the size. If the always-on text gets too long, warden truncates it and prints a warning. Flag fewer Skills.

Migration from Claude Code

Claude Code loads each MCP tool and Skill into the context at start. The migrate command moves them behind warden. The command does these tasks:

  • MCP servers — warden copies the server into the registry. warden removes the server from ~/.claude.json (the user scope or the project scope).
  • Plugins — warden adds the Skills directory of the plugin to the registry. warden disables the plugin in ~/.claude/settings.json. This action disables all the functions of that plugin. Look at the dry run first.
  • Personal skills — warden moves the directory ~/.claude/skills/<name> into a warden directory. warden adds that directory to the registry.

Before each change, warden makes a backup of the file. warden also writes a manifest that permits a reverse. Therefore restore --id <id> (or admin restore) puts back all the changes.

warden migrate --all                 # dry run: shows each change
warden migrate --all --apply         # apply the changes and print the migration id
warden restore --id <id>             # reverse the migration

Safe test. By default, migrate and restore change your real ~/.claude. Add --home <dir> to use a different Claude home. Then you can do a full test of a migration and its restore. Your real configuration does not change.

warden migrate --all --apply --home /tmp/fake-claude
warden restore --id <id> --home /tmp/fake-claude

Restart Claude Code. Claude Code reads ~/.claude.json and ~/.claude/settings.json at start. Therefore the changes to the MCP servers and the plugins take effect only after a restart. The warden catalog updates immediately.

Limitation: warden does not start skills automatically

You get skills behind warden only through route or search. Claude Code cannot start these skills automatically from their description. This is the cost to keep them out of the context until you need them. To help, tell the model to use warden first.

For a Skill that must be active in every session (for example, a "think before you code" ruleset), use auto_start. That is the opt-in override to this limitation, for the few Skills that need it.

The easy way. Run warden init. It writes the capability block below into your agent-instruction file (CLAUDE.md, AGENTS.md, or GEMINI.md). It asks for the scope (user, project, or local) and for the file, and it writes only after you confirm. A second run replaces the block in place. warden init --remove strips it again.

warden init                 # interactive: asks the scope and the file
warden init --print         # show the block without writing
warden init --remove        # remove the block

The manual way. Copy this text into your agent-instruction file:

## Capabilities via warden

warden keeps many tools and Skills out of your context. Before you decide
that a capability is not available, use warden first:

1. Call `route` with a short description of the task. Add the current file
   path if you have one. `route` returns the best tool or Skill to use.
2. Or call `search` to find a capability by keyword.
3. Then call `call_tool` or `use_skill` on the result.

Tests

python3 -m unittest discover -s tests -v

tests.test_search and tests.test_config are self-contained and need no other software. tests.test_integration runs the full server through stdio MCP. It uses a test MCP server and a test skill, and it needs mcp. If mcp is not installed, this test skips automatically.

Design notes

  • The search is one function. It does regex scoring and keyword scoring together, and it uses only the standard re module. Refer to warden/search.py.
  • The call_tool tool opens a new connection to the MCP server for each call. It does not keep a pool of connections. Refer to warden/downstream.py. This design is simple and correct. It is sufficient, unless the start time of the subprocess becomes a measured problem.
  • The configuration is plain JSON. It does not need a YAML dependency for two keys.

Support

If warden is useful to you, add a star to the repository. A star helps other people find the project. It is optional. It is not a condition to use warden or to contribute.

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured