CAM: Claude Agent Manager
A terminal UI for managing your Claude Code skills and agents. Browse, search, preview, install, and uninstall from your own library — no AI tokens spent. Pure bash + fzf, one-line install.
Published May 16, 2026
CAM: Claude Agent Manager
TL;DR. CAM is a tiny terminal UI for managing the Claude Code skills and agents you've written. It lives in your shell, browses your personal vault, and installs items into ~/.claude/ one keystroke at a time — so your context window only carries what the task actually needs. No AI tokens spent on the management itself. Pure bash and fzf. One-line install. Source at github.com/edwincapel/CAM.
The Problem: Every Skill Costs Tokens, Every Session
Claude Code skills and agents are powerful, but they have a quiet cost: every skill you install gets loaded into the model's context window on every session, even the ones irrelevant to what you're doing right now. Each skill carries its name, description, and any always-on instructions. Multiply that by twenty skills, and you're paying for twenty system-prompt entries whether you're shipping a feature, fixing a typo, or asking a one-line question.
The pattern I kept running into: I'd write a skill for a specific workflow — reviewing a PR, debugging Cloudflare Worker logs, helping with my keybindings — use it heavily for a week, then forget about it. Three weeks later it was still in ~/.claude/skills/, still loading on every session, eating tokens I wasn't getting any value from.
So the file layout that Claude Code expects (everything-installed-everywhere-always) is fundamentally at odds with how I actually use these things. I want a curated set per task. I want to bring in the PR-review skill when I'm reviewing a PR and pull it back out when I'm done.
The Other Problem: Curating Is Annoying
Even when you know which skills you want, the management workflow is friction-heavy. You're either:
- Writing them in your editor and remembering to drop the file into the exact right path under
~/.claude/skills/<name>/SKILL.mdor~/.claude/agents/<name>/AGENT.md - Maintaining them in a personal vault (mine lives in Obsidian, with wiki-link metadata at the top) and copy-pasting them into the right place when you want them active
- Asking Claude to install one for you, which works, but burns tokens on a task that doesn't need an LLM at all
The third option always felt the most wrong. Why am I spending model calls to do filesystem operations? A skill file is just a markdown file. Moving it should be a keystroke, not a conversation.
That's the gap CAM fills.
My Angle: A Curation Layer, Not a Marketplace
There are plenty of "browse community skills" ideas floating around the Claude Code ecosystem. CAM is intentionally not that. It manages your own library — a vault of skills and agents you've written, cloned, or kept around — and gives you a friction-free way to install the few you actually need for today's session.
The design follows three rules:
- Zero AI tokens for the management itself. Browsing, searching, previewing, installing, uninstalling — all deterministic. The whole point is to spend tokens on the work, not on the tools you use to do the work.
- Your vault, your rules. CAM doesn't care where your library lives. Point it at any folder that contains
Skills/andAgents/subdirectories. Mine is an Obsidian vault. Yours could be a git repo, a Dropbox folder, anything readable. - Respect Claude Code's file layout, don't fight it. CAM installs into the exact paths Claude Code expects (
~/.claude/skills/<name>/SKILL.md,~/.claude/agents/<name>/AGENT.md). It's an installer, not a parallel runtime.
What CAM Looks Like
You launch it by typing cam in your terminal. You get a small dashboard that counts what's in your vault and what's already installed:
Four options: browse skills, browse agents, manage what's installed, settings. Pick one and you drop into an fzf browser with a live preview on the right.
Type to fuzzy-search. The preview pane updates in real time, so you can see what a skill actually does before installing it. No more "what does this one do again?" round-trips through the LLM.
Hit Enter and the skill is installed. Open Claude Code, it's there. Done.
Browsing agents is the same flow with a different list:
When you're done with a task and want to clean up, the "manage installed" view shows everything currently active under ~/.claude/ so you can uninstall in the same UI you used to install:
The whole loop — open a terminal, pull in the three skills you need for the next hour, work, pull them back out — takes under thirty seconds at either end. It's faster than typing the name of one skill into a chat box.
Architecture
There isn't a lot of code, by design. The whole thing is shell scripts.
Click to expand
The entry point is cam.sh, which sources six small library files in lib/:
| File | Responsibility |
|---|---|
config.sh | Resolves the vault path (env var → config file → first-run dialog → --vault flag) |
scan.sh | Walks ~/.claude/skills/ and ~/.claude/agents/ to inventory what's installed |
install.sh | Copies a vault file into Claude Code's expected layout, stripping Obsidian metadata |
skills.sh | The browse/search/preview/install loop for skills |
agents.sh | Same shape, for agents |
manage.sh | The "what's installed right now" view, including uninstall |
Every interactive surface is fzf. There's no curses library, no React-for-terminal, no ncurses bindings. fzf does the list, the search filter, and the preview pane out of the box, which keeps the codebase to a few hundred lines.
The preview pane is the trick that makes the whole UX feel snappy. CAM shells out to a preview.sh script as fzf's --preview command, which reads the selected markdown file and renders its frontmatter and body. The fuzzy filter and the preview update on every keystroke without CAM doing anything — fzf handles all of it.
How Installation Works
A skill in my vault looks like this:
~/MyVault/Skills/pr-review.md
~/MyVault/Skills/cloudflare-debug.md
~/MyVault/Agents/release-notes.md
Each file has YAML frontmatter (name, description, optional tools and model) and a markdown body. Some have Obsidian wiki-link metadata above the frontmatter, because that's how Obsidian organizes notes.
When you install pr-review, CAM does exactly two things:
- Strip pre-frontmatter content.
sed -n '/^---$/,$p' "$src"keeps everything from the first---onward and drops whatever lived above it. That cleans out Obsidian's link headers without touching the actual skill. - Write to Claude Code's expected path. Skills go to
~/.claude/skills/<name>/SKILL.md. Agents go to~/.claude/agents/<name>/AGENT.md. Parent directories are created withmkdir -p.
That's the entire install function. No state, no database, no symlinks to chase. The "installed" state is just the file exists at the path Claude Code expects. Uninstalling is rm on that file. scan.sh walks the directory tree to figure out what's currently active.
This is the part I'm most happy with. The whole system is stateless — there's nothing CAM stores about what it did. If you delete CAM tomorrow, every skill it installed keeps working. If you install a skill by hand, CAM picks it up the next time you open the manage view. The vault is the source of truth; ~/.claude/ is the runtime; CAM is just a fast way to move files between them.
Configuration Without a Config Format
CAM resolves the vault path through a four-step fallback:
--vault <path>on the command line wins- Otherwise,
$CAM_VAULTfrom the environment - Otherwise,
~/.config/cam/config(a one-line file) - Otherwise, prompt the user on first run
The config "file" is one line of shell variable assignment. There's no YAML, no TOML, no schema. The settings menu just rewrites that one line when you change vaults. Anything beyond this would be over-engineered for a tool whose entire surface area is "where do my markdown files live."
Installation and Footprint
curl -fsSL https://raw.githubusercontent.com/edwincapel/CAM/main/install.sh | bash
That clones the repo into ~/.local/share/cam, symlinks the binary at ~/.local/bin/cam, and appends the ~/.local/bin directory to your shell rc if it's not already on PATH. The installer is itself a shell script, sentinel-guarded so re-running it acts as an update.
Dependencies are deliberately minimal:
| Tool | Why |
|---|---|
bash 3.2+ | macOS still ships 3.2 by default; CAM works against it |
fzf | The whole UI |
git | Cloning and updating CAM itself |
curl | The one-line installer |
No Node, no Python, no Homebrew package, no compile step. On a fresh macOS box, the only thing you typically need to install yourself is fzf (brew install fzf), and CAM tells you exactly that if it's missing.
The lesson here, if there is one: the cheapest tools to build are often the ones that just respect the file layout the system already wants. CAM doesn't reinvent Claude Code's skill format. It doesn't run a process in the background. It doesn't even keep state. It's a few hundred lines of bash wrapped around fzf, and it makes a real problem (token bloat in long-running sessions) disappear by giving me a thirty-second curation step at the start and end of each task.
If you write your own Claude Code skills and you've felt the same friction, give it a try. It installs in one command and uninstalls almost as cleanly.