Take cat away from your agent. Guard hooks block cat, raw grep, and full-file reads and rewrite each into a token-budgeted ccx call for an outline, a symbol with its callers, or a diff.
/plugin marketplace add yasyf/cc-skills
/plugin install cc-context@skills
The plugin arrives wired together: the ccx binary self-provisions (a shim downloads the pinned release on first use and caches it in ${CLAUDE_PLUGIN_DATA}), the MCP server auto-registers its mcp__cc-context__ccx_* tools plus BashToon, the guard hooks turn on, and the ccx skill teaches the reach-for-ccx-first workflow. It needs uv on PATH — the hooks run through uvx capt-hook, and semantic search shells out to semble via uvx.
Driving with an agent? Paste this:
/plugin marketplace add yasyf/cc-skills
/plugin install cc-context@skills
Using ccx outside Claude Code? Install the standalone CLI
The Homebrew formula pulls in ast-grep and uv:
brew install yasyf/tap/ccxWithout the plugin, register the MCP server by hand:
claude mcp add --scope user --transport stdio cc-context -- ccx mcpCold-starting in a codebase you've never seen burns the first few thousand tokens on ls and cat wandering. One command replaces the tour:
ccx repo overview[tilth] Go project — 75 source files, 10 directories
dirs: cli/ backend/ astgrep/ vcs/ render/ toon/ outline/ mcpserver/ querykind/ locate/
deps: asm, cobra, encoding, go-sdk, jsonschema-go, mousetrap, oauth2, pflag, sys, toon-go
hot (× = importers): bench/ccxbench/types.py ×7, bench/ccxbench/config.py ×4, plugin/hooks/common.py ×4
git: branch main, clean
manifest: go.mod (github.com/yasyf/cc-context)Structure, dependencies, the hottest files by importer count, and VCS state — a few hundred tokens instead of a directory crawl.
Understanding one function shouldn't cost a whole-file read plus a grep for its call sites. Ask for the symbol:
ccx code symbol NewRootCmd# grok: NewRootCmd [internal/cli/root.go:11]
## signature
func NewRootCmd() *cobra.Command
## doc
// NewRootCmd builds the root command and registers its subcommands.
## body
…
## callees (4 internal, 5 extern)
…
## callers (5 of 6)
internal/cli/cli_test.go
[30] in TestRootHelpListsAllOps()
…Definition, doc, body, callees, and callers in one budgeted response — the agent edits code it never paged through.
gh --json and kubectl -o json dump verbose, nested JSON that floods the context window. Run the command through ccx toon and its JSON or NDJSON stdout comes back as TOON, a compact tabular encoding (or compact JSON when that is smaller):
ccx toon -- gh release list --limit 3 --json tagName,publishedAt,isLatest[3]{isLatest,publishedAt,tagName}:
true,"2026-06-26T01:05:28Z",v0.2.1
false,"2026-06-23T07:52:46Z",v0.2.0
false,"2026-06-21T09:21:47Z",v0.1.1That's less than half the bytes of the raw JSON, and typically 40–60% fewer tokens on tabular data. Non-JSON output passes through verbatim, stderr streams live, the exit code is propagated, and it doubles as a pipe filter (… | ccx toon). The MCP BashToon tool is the same wrapper in tool form.
A budgeted command only helps if the agent reaches for it. The bundled capt-hook guard pack makes that the path of least resistance: its PreToolUse/PostToolUse hooks block the token-heavy primitives — cat, raw grep, an unbounded full-file Read, a git diff through a pager — and point the agent at the ccx equivalent instead. Reach for the raw tool and the hook turns you back; reach for ccx and you stay inside the budget by default.
The pack also watches for JSON. A command flagged for JSON output (--json, -o json) gets rewritten to run through ccx toon, and the pack learns which commands emit JSON so it can nudge you to wrap them next time.
Each command is a token-bounded stand-in for a primitive an agent would otherwise reach for. Structural output is capped at --budget tokens, cut on a line boundary, with an explicit marker saying how much was dropped:
| Command | What it does |
|---|---|
ccx repo overview |
Repository structure and entry points; start here |
ccx code search <query> [path] |
Search routed by query kind: natural language runs semantic, an ast-grep pattern ($A, $$$) runs structural |
ccx code replace <pattern> <rewrite> [paths...] |
Structural find-replace; previews a diff, writes only with --apply |
ccx code related <file:line> |
Code semantically related to a location |
ccx code symbol <name> (alias grok) |
Definition, doc, body, callers, callees, siblings, tests |
ccx code outline <file-or-dir> |
Token-budgeted structural outline of a file or directory |
ccx code read <file> --section A-B |
Read a line range, a ## Heading, or the whole file with --full |
ccx code deps <file> |
Symbols a file uses, and what uses it back |
ccx code grep <text> --glob G |
Literal text search, optionally globbed and budgeted |
ccx repo find <glob> |
List files matching a glob, with per-file token counts |
ccx repo locate <name> |
Resolve a sibling repo, Go module, or Python package to its on-disk path; exits 3 when unresolved |
ccx vcs diff [uncommitted|staged|<ref>] |
VCS-aware structural diff; defaults to uncommitted |
ccx vcs show [ref] |
Commit message plus a structural per-file diff of one commit; defaults to the last commit |
ccx vcs history <path> [-n N] |
Per-commit summary of a file's changed symbols; replaces git log -p |
ccx vcs ship [-m <msg>] |
Commit, push, and watch CI in one call: jj-aware commit, push, gh run watch --exit-status |
ccx toon [-- <cmd>] |
Re-encode a command's JSON/NDJSON output as TOON, or filter a pipe |
Run ccx <command> --help for the full flag set, and ccx --version for the build version. Three engines sit behind the one surface — semble for semantic search, ast-grep for structural search and rewrites, tilth for the rest — and ccx routes each command for you.
ccx reads no config file; behavior is tuned through environment variables:
Licensed under PolyForm Noncommercial 1.0.0.


