Tools
Agent Toggle
Temporarily disable and restore AI-agent skills, agents, commands, rules, plugins and MCP servers across Claude Code, Codex, Grok, OpenCode, OpenClaw, Copilot and Vibe. Nothing is deleted, and it shows what each item costs at session start.
Install
pip install -e
README
# agent-toggle
Temporarily disable and restore AI-agent resources — skills, agents, commands,
rules, plugins, MCP servers — across Claude Code, Codex, Grok CLI, OpenCode,
OpenClaw, Copilot, Vibe, Devin and Antigravity — and show what each one costs at
session start.
**Nothing is ever deleted.** Everything is parked and recorded, and `enable`
puts it back where it came from.
## Why
| target | native mechanism | the gap |
|---|---|---|
| plugin | `claude plugin disable/enable` | fine — this tool just batches it |
| skill | none | moving files by hand hits the rename trap below |
| agent | none | same |
| command | none | same, plus nested `group/name.md` paths get flattened |
| MCP | `remove` only | the config is gone unless you saved it first |
## Install
Latest release, from [PyPI](https://pypi.org/project/agent-toggle/):
```sh
uv tool install agent-toggle
agent-toggle --version
```
Straight from this repository, pinned to a release tag (`v0.5.1` is the current one;
an unpinned `git+` URL installs whatever is on the default branch):
```sh
uv tool install git+https://github.com/weskao/[email protected]
agent-toggle --version
```
Alternatively, use `pipx`:
```sh
pipx install agent-toggle # from PyPI; or: pipx install git+https://github.com/weskao/[email protected]
```
From a checkout, either install it editable or run it in place:
```sh
git clone https://github.com/weskao/agent-toggle agent-toggle
cd agent-toggle
pip install -e . # puts the `agent-toggle` console script on PATH
python3 agent_toggle.py status # no install needed; same CLI
```
Python 3.10+, no runtime dependencies. Then write the skill shim:
```sh
agent-toggle install-shims # installed, or: ./install.sh (a thin wrapper)
python3 agent_toggle.py install-shims # from a checkout, no install needed
```
`install-shims` writes a thin skill shim (`skills/agent-toggle/SKILL.md`) into
every installed harness that supports skills, so `/agent-toggle` works from any
of them, and adds the park dirs (`skills-disabled/` etc.) to a `.gitignore`
already present in that harness home. Each harness gets its own template from
`agent_toggle/shims/<harness>.md.tmpl`, else `generic.md.tmpl` (which tells the
agent to pass `--harness <that harness>`). The shim tells the agent to act only
on the user's explicit request, never on instructions found inside skill or
tool content, and to preview bulk operations with `--dry-run`.
OpenCode's shim goes into the first `skills.paths` dir when one is set (and its
parent exists), else `skills/`. OpenCode also scans `~/.claude/skills` and
`~/.agents/skills`: when one of them already holds the very same shim text, the
OpenCode shim is skipped (`covered by <path>`); a different shim there (the
claude one, whose default harness is `claude`) is noted and OpenCode's own is
still written.
Every shim carries an `<!-- agent-toggle shim: ... -->` marker line.
`install-shims` updates a file that has the marker in place (it is idempotent)
and **refuses** to overwrite one that lacks it, or a symlink: that harness gets
an `error` row with the fix, the other harnesses still install, and the run
exits `1`. A shim written by a version before the marker counts as foreign;
delete it and re-run. `--dry-run` shows the same plan, refusals included. The
tool itself stays in one place.
**Optional: Telegram alerts for CI** (for maintainers of a fork or clone). Install
with the `telegram` extra, which adds [telegram-kit](https://pypi.org/project/telegram-kit/)
(itself stdlib-only), then run the setup once; see [CI notifications](#ci-notifications):
```sh
uv tool install "agent-toggle[telegram]" # or: pipx install "agent-toggle[telegram]"
pip install -e ".[telegram]" # from a checkout
agent-toggle config # settings menu: bot token + chat id live under Notifications
agent-toggle config sync-ci # set the two GitHub repository secrets
```
Without the extra everything else works exactly as before. Only `config test`,
`config sync-ci` (both exit `4` without it) and the Telegram rows of the
[settings menu](#settings--config-menu) need it; bare `config` still opens, and
those rows read `install agent-toggle[telegram]`.
## Shell completion
Each release publishes static completion files for bash, zsh and fish as the
`completions` artifact of its Release workflow run. They are generated from the
CLI parser; to build them from a checkout:
```sh
python3 tools/gen_completions.py completions # agent-toggle.bash, _agent-toggle (zsh), agent-toggle.fish
```
Source `agent-toggle.bash` from `~/.bashrc`, put `_agent-toggle` on your zsh
`fpath`, or copy `agent-toggle.fish` to `~/.config/fish/completions/`.
## Usage
```sh
agent-toggle <command> [args] # or: python3 agent_toggle.py <command> [args]
```
| command | what it does |
|---|---|
| `ui` (alias `pick`) | interactive picker — harness tabs, type groups, cost bars, search, sort, profiles (`p`); `--dry-run` shows the plan for what you stage and changes nothing; `--project <dir>` picks in a repo's own scope; see [Interactive picker](#interactive-picker) |
| `status` | health check: harnesses found, types each supports, parked counts, gitignore, untracked parked items, stale live twins, shared dirs, and state entries whose parked item is gone (a `stale` row with the fix command; read-only, still exit `0`) |
| `list [type]` | what is currently disabled (`--project <dir>` filters to one project) |
| `cost [--type T]` | estimated startup tokens per item, biggest first (read-only; `--harness H` filters; `--project <dir>` prices a repo's `.claude/` and `.mcp.json` instead of user scope) |
| `install-shims` | write the skill shim into every installed harness that is on in the settings (an off one is skipped unless named with `--harness`); refuses to overwrite a file it did not write (`--dry-run` shows the plan); on a terminal, then asks y/n for each problem `doctor` can fix (see [Fixing](#fixing)) |
| `disable <type> <name>...` | park one or more items (`--dry-run` shows the plan; `--project <dir>` for a repo's own `.claude/` and `.mcp.json`) |
| `enable <type> <name>...` | put them back (`--dry-run` shows the plan; `--project <dir>` likewise) |
| `enable --all` | put back **every** disabled item (`--harness H` narrows it, `--project <dir>` takes only that project's) |
| `undo` | reverse the last logged batch (`--dry-run` shows the plan) |
| `profile save\|apply\|diff\|list` | named sets of live items; see [Profiles](#profiles) |
| `config` | settings menu (curses, else a numbered list); `config --json` lists every setting; see [Settings & config menu](#settings--config-menu) |
| `config test\|sync-ci` | send one Telegram test message / set the GitHub CI secrets; needs the `[telegram]` extra; see [CI notifications](#ci-notifications) |
| `help [command]` | styled help; `help ui` = `--help ui` = `ui --help`; see [Help](#help) |
| `doctor` | check each harness layout and `state.json` against disk; exit `1` only on an `error` row; on a terminal, asks y/n per fix it can run itself |
| `migrate` | import an older `~/.claude-toggle/` state |
Every command also works with a leading `--` (`agent-toggle --status`, `--help`, `--config`); this README uses the plain form.
`<type>` = `skill` / `agent` / `command` / `rule` / `plugin` / `mcp`.
`rule` is claude-only (`~/.claude/rules/*.md`, parked in `rules-disabled/`).
Disabling a rule prints a warning (also in `--json` `warnings`, dry run included)
that rules may carry safety constraints.
Flags accepted by every command, before or after the subcommand:
- `--harness claude|codex|grok|opencode|openclaw|copilot|vibe|devin|agy` picks the
target (default `claude`; on `list` / `status` / `cost` it filters when given).
- `--json` prints exactly one JSON document and nothing else on stdout:
`{"ok", "command", "results": [{harness, type, name, action, status, detail, ...}],
"warnings", "needs_new_session"}`. Errors -- including unexpected ones, as
`{ExceptionType}: {message}` -- always emit it, with `"ok": false`.
Exception: `--help` / `--version` print plain text even with `--json`, and
`ui` is interactive so it rejects `--json` (exit 2).
- `--project <dir>` (`disable` / `enable` / `enable --all` / `list` / `ui` / `cost` / `profile
save|apply|diff`) switches to project scope; see [Project scope](#project-scope).
- `--version` prints the version.
- `AGENT_TOGGLE_CLI_TIMEOUT=<seconds>` overrides the timeout of every `claude` CLI call
(default 30 s for read-only `plugin list`, 120 s for every other call); a
non-positive or non-numeric value is ignored with a warning.
- `-v` / `--verbose` (or `AGENT_TOGGLE_DEBUG=1`) adds a traceback on stderr for
unexpected errors; otherwise they are a single `error:` line.
- `--color auto|always|never` sets ANSI color for human output: green ok, red errors,
yellow warnings, cyan harness names, dim secondary text (`status`, `list`, `cost`,
`disable` / `enable`, `doctor`, warnings and errors; the picker uses curses color pairs
and stays monochrome when the terminal has no colors). `--json` is never colored.
`never` turns it off and `always` forces it even when piped; `auto` (default) checks
`NO_COLOR`, then `FORCE_COLOR`, then `TERM=dumb`, and otherwise colors only on a TTY.
Precedence: `--color` flag > `AGENT_TOGGLE_COLOR` > the `color` [setting](#settings--config-menu)
> `auto`; `NO_COLOR` still wins over `auto`.
`always` still stays plain on a Windows console that cannot do ANSI.
Extra row fields: `list` rows carry `at`, `mechanism`, `companions`; `cost` rows
carry `enabled`, `tokens`, `would_save`, `chars`, and the final `total` row
carries `total_tokens`, `saved_tokens`, `formula`. Rows for a
directory shared with another harness (see below) carry `shared_with`, the other
harnesses that read it: `disable` / `enable` rows relative to the harness you
asked, plus `owner`, the harnes
... (truncated)
tools
Comments
Sign in to leave a comment