ctxkit
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@ctxkitGenerate a context pack for the auth module focusing on token validation."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
ctx-kit
A tool-neutral codebase context kit for AI coding agents — from frontier models to small local LLMs.
One source of project context, served in the form each model tier can actually use: as an MCP server for agentic tools, as a CLI for terminals and CI, and as plain files for everything else.
한국어: README.ko.md · 백서: WHITEPAPER.ko.md · Whitepaper: WHITEPAPER.md
Contents — Usage: install · set up · verify · generate · connect · feed a local model · commands · day-to-day — Background: why · how it works — Reference: CLI · config · MCP tools · profiles · per-environment · local LLMs · cross-repo · results · FAQ · design notes · license
Usage
Install
Requires Node ≥ 20. The package ships dist/ and templates/ only (~21 KB).
npm i -g @seanshin/ctx-kit # global install — the binary is `ctxkit`
npx -y @seanshin/ctx-kit <cmd> # or run without installing anything
npm i -D @seanshin/ctx-kit # or as a project dev dependencyRelated MCP server: ContextAtlas
Step 1: Set up a repository
cd your-project
ctxkit init --auto --hooksCreated | Purpose |
| Rules draft. Build/test commands are auto-detected from |
| Module boundaries (auto-detected from source layout) + consumption profiles |
| Where module docs and generated artifacts live |
| ( |
Existing AGENTS.md / CLAUDE.md files are never overwritten — they are
reported as skipped. Add --ci if you also want a GitHub Actions workflow
(consumes Actions minutes on private repos; --hooks covers the same gate for
free).
Step 2: Verify the two drafts
The only manual step, and the one that decides quality:
AGENTS.md— confirm the detected commands actually run, then add what code cannot tell an agent: architecture decisions, constraints ("never inline discount rates", "don't touchlegacy/"), and a domain glossary. Keep it under 150 lines;ctxkit checkfails past that, because verbose rule files measurably degrade agent performance.context.config.yaml— adjust module boundaries to how your team actually thinks about the codebase, and add noise paths (vendored code, migrations, fixtures) toexclude.
Step 3: Generate the artifacts
ctxkit map # → docs/generated/repomap.md
ctxkit pack --profile light # → docs/generated/packs/all-light.md
ctxkit sync # AGENTS.md → CLAUDE.md, .cursorrules, …
ctxkit check # gate: rules, sync, staleness, secretsStep 4: Connect your AI tools
Agentic tools (Claude Code, Codex CLI, Cursor) — register the MCP server once:
{ "mcpServers": { "ctxkit": { "command": "npx", "args": ["-y", "@seanshin/ctx-kit", "serve"] } } }.mcp.json for Claude Code, mcp_servers in config.toml for Codex CLI.
AGENTS.md (and the CLAUDE.md produced by sync) is picked up natively by
those tools with no configuration at all.
Step 5: Feed a model that has no tools
ctxkit pack --profile light --module risk --stdout > /tmp/ctx.md
ollama run qwen3:14b "$(cat /tmp/ctx.md)
Using only the context above: what is the default retry interval?"Or ctxkit get <query> for just the relevant sections, or simply paste
docs/generated/packs/<module>-light.md into any chat window.
Command summary
Command | What it does | Produces |
| Scaffold a repository |
|
| Rank files by cross-file references, outline their symbols |
|
| Assemble a context pack within a token budget, optionally shaped by a task or a diff |
|
| Distribute rules from the single source |
|
| Gate: rules, sync, staleness, secrets, plus repository health | exit 0/1 |
| Print matching context sections | stdout |
| Measure context profiles against a task file; | results table |
| Run the MCP server (stdio) | 5 tools |
Every command takes --stdout where output is a document, and -C <path> to
run against another repository. Full flag-by-flag detail is in the
CLI reference below.
Day-to-day
When | Run |
Code changed |
|
Rules changed | edit |
Before committing | nothing: the pre-commit hook runs |
Handing work to a weaker model |
|
Reviewing a change |
|
Choosing a profile with evidence |
|
Onboarding another repo |
|
The 10-minute onboarding checklist is docs/onboarding.md.
Background
Why
A repository developed with AI assistance is consumed by models of very different capability, often on the same day:
Consumer | How it reads a codebase | What it needs |
Frontier agent (Claude Code, Codex CLI) | explores with tools, many turns | minimal standing rules + on-demand search |
Mid-size model (32–128K window) | one context load, limited tools | rules + a structural map |
Small local LLM | a single pasted prompt | a pre-cut pack with actual file contents |
A human in a chat window | copy-paste | a readable file |
Most context tooling serves exactly one of these. ctx-kit maintains one source and derives each form from it — and the measurements below show that what decides task success is the context form, not the model grade.
Two further constraints shaped the design:
Verbose rule files actively hurt. A published evaluation across 138 repositories found LLM-generated agent-instruction files reduced task success while raising inference cost by 20%+. So
AGENTS.mdis capped at 150 lines by a gate, andinit --autoonly prefills facts it can read out of the repo's own manifests.No vendor lock-in. AGENTS.md (now under the Linux Foundation; read natively by Claude Code, Codex CLI, Cursor, Aider, Copilot, Gemini CLI, Windsurf) and the Model Context Protocol make a neutral design practical.
How it works
Four tiers of context, ordered by cost and freshness:
Tier | What | Produced by | Refreshed |
0 |
| human | on change |
1 | Repository map — files ranked by cross-file references, with symbol outlines |
| per commit / CI |
2 |
| human + | as needed |
3 | Symbol search (definitions + reference sites) |
| live |
Three interfaces over one core, smartest to simplest:
┌──────────────────────────────────────────────────────────┐
│ A. MCP server ctxkit serve → agentic tools │
├──────────────────────────────────────────────────────────┤
│ B. CLI ctxkit <cmd> → terminals, hooks, CI │
├──────────────────────────────────────────────────────────┤
│ C. Files docs/generated/ → anything else │
└──────────────────────────────────────────────────────────┘Interface C is the floor, not an afterthought: every feature must leave a plain-file artifact, so an environment with neither MCP nor CLI — including a person pasting into a chat window — is still served.
Reference
CLI reference
Global: -C, --dir <path> runs against another repository (default .);
--version, --help.
ctxkit init [--auto] [--hooks] [--ci]
Scaffolds context.config.yaml, AGENTS.md, docs/context/,
docs/generated/packs/. Existing files are skipped, never overwritten.
Flag | Effect |
| Detect commands + module boundaries from manifests and prefill both drafts |
| Install |
| Install |
ctxkit map [-b <tokens>] [--stdout]
Writes the ranked repository map to docs/generated/repomap.md
(default budget 8000 tokens). Ranking: each file scores the number of
cross-file references to the symbols it defines, plus a capped
self-definition weight; test files are demoted ×0.2 so production code
surfaces first. Files past the budget are listed as an omitted count.
ctxkit pack [-p <profile>] [-m <module>] [--repomix] [--stdout]
Assembles a context pack into docs/generated/packs/<module|all>-<profile>.md
and prints its approximate token count. Sections follow the profile's
inject list. Three budget rules keep the pack useful at scale:
The embedded map is capped at ⅓ of the pack budget (max 4000) so it can never starve file contents.
With
--module, the embedded map is scoped to that module rather than the whole repository, plus a paths-only index of the most-referenced files elsewhere. Measured trade-off: a module pack cannot say where an outside symbol is defined (the index carries paths, not outlines) — send those questions tosearch_symbol, or drop--module. In exchange the module's own files get the budget: on a production module, 4 unrelated files left the map and included source files went from 4 to 13.Target files are emitted in reference-rank order, and a file too large to fit is skipped rather than ending the section — one oversized file in the middle of the ranking must not forfeit the budget for the smaller files behind it. Skipped files are reported as a count.
--repomixdelegates to the external Repomix CLI when installed, falling back to the internal packer otherwise.
Shaping the pack. Two flags change which files are chosen, not just how many fit:
ctxkit pack --about "gold tier discount rounding" # rank by task relevance (BM25)
ctxkit pack --diff --staged # center on the change under review
ctxkit pack --about "…" --explain # why each file placed where it did--about scores every file with BM25 over three fields — path (weight 3),
symbol names (2) and body (1) — and adds it to the reference ranking. CJK text
is indexed as character bigrams, so a Korean query survives particle changes
(할인율을 still matches 할인율). English tokens get light suffix folding —
plurals (secrets → secret), gerunds (scanning → scan) and participles
(detected → detect) — so "secret scanning" reaches a file whose code says
Scans/secrets, without requiring the exact inflection. It is conservative
suffix stripping, not a dictionary: tokens under 4 characters are left alone,
and silent-e verbs don't fully meet in the middle (generated/generate,
included/include stem to generat/includ, which under-matches rather
than risking a wrong one); nominalizations (-tion/-sion) are not folded
at all, since session → sess and nation → nat collide with real words
far more often than they help.
--diff takes a git range or --staged. The changed files are seeds: they
are never dropped for budget reasons, and if they alone exceed the budget the
section degrades to a seed path list plus the top-ranked seed's contents.
ctxkit eval [--init] [--dry-run] [--tasks <file>] …
Measures whether a profile actually carries what a task needs. Task files are
YAML (id, question, expect keywords, expect_file); --init writes a
template.
ctxkit eval --init
ctxkit eval --dry-run # free: no model is called
ctxkit eval --profiles mid,light --models haiku,sonnet --out results.md--dry-run reports two inclusion rates per profile, and the distinction
matters: outline_hit is whether the answering file reached the repository
map (enough for "where is X?"), content_hit whether its source reached the
pack (needed for "what is this default value?"). A mid profile scoring
100% outline and 0% content is behaving exactly as designed. Runs that call
models print the planned call count and ask before spending anything.
ctxkit sync [--link] [--force]
Distributes AGENTS.md to per-tool rule files. Targets come from
sync.targets:
Target | File |
|
|
|
|
|
|
|
|
|
|
Generated copies carry a <!-- generated by ctxkit sync … --> header.
A per-tool file that ctx-kit did not generate is reported as
skipped-foreign and the command exits 1 — merge it into AGENTS.md first,
or pass --force. --link creates symlinks instead of copies.
ctxkit check [--max-rule-lines <n>]
The gate. Exits 1 if any check fails.
Check | Level | What it catches |
| fail |
|
| fail / warn | per-tool file differs from |
| warn | a source file is newer than |
| fail | private-key blocks, |
| fail | a rule from |
| warn | the same top-level function defined identically in two files |
| warn | a source file nothing else references (abstains on files with no extractable symbols) |
| warn | a source file belonging to no module |
| warn |
|
| warn | a documented command's runner is not on |
| fail | a module glob matches zero files |
The last seven are the repository-health half: the gate checks the code the
rules describe, not only the rules. Adopt them on an existing codebase with
ctxkit check --update-baseline, which records today's violations so only
new ones fail.
The secret scan targets exactly the files that get pasted into external services. Repomap staleness is a warning because git checkouts do not preserve mtimes.
ctxkit get <query> [-b <tokens>] [-k <n>]
Prints the context sections matching a query to stdout — AGENTS.md,
docs/context/*.md and the repo map are split on ## headings and ranked
(heading hits weigh 5×). Built for pipes:
ctxkit get billing | llm -m local-model "Where is tax computed?"
ctxkit get auth --budget 2000 | pbcopyctxkit serve
Runs the MCP server over stdio. Protocol on stdout, logs on stderr.
Configuration reference
context.config.yaml is the only ctx-kit file that lives in a target repo —
all logic stays in the package.
version: 1 # schema version; mismatches are rejected
modules: # Tier 2 boundaries: name → globs (repo-relative)
risk: ["src/risk/**"]
web: ["web/src/**"]
exclude: # extra ignores, on top of the built-ins
- "**/generated/**"
profiles: # what each model tier receives
frontier: { inject: [agents], budget: 4000 }
mid: { inject: [agents, repomap], budget: 24000 }
light: { inject: [agents-summary, repomap, target-files], budget: 12000 }
light-xl: { inject: [agents-summary, repomap, target-files], budget: 45000 }
sync:
targets: [claude, cursor] # see the sync table aboveinject sections
Section | Contents |
| full |
| first 40 lines, plus a 12-line reminder appended at the end of the pack |
| the ranked map (cached if fresh and within cap, else regenerated) |
| file contents, reference-ranked, truncated at the budget |
The agents-summary + tail-reminder arrangement exists because models recall
the start and end of a long prompt far better than the middle.
Always ignored (no configuration needed): dot-entries (.git, .venv,
.next, …), node_modules, dist, build, out, target, vendor,
__pycache__, venv, .cache, coverage, files over 512 KiB, and binaries.
Languages recognized for symbol extraction: TypeScript/TSX, JavaScript/JSX, Python, Go, Rust, Java, Kotlin, C#, Ruby, PHP, Swift, C/C++.
Token counts are a heuristic: chars/4 for ASCII, and CJK codepoints at a
measured 0.95 tokens/character, because Korean, Japanese and Chinese cost
close to one token each. Plain chars/4 underestimated a Korean-commented
file by 28%; this cuts the error to about 9%, and ASCII counts are unchanged.
For exact counts, install the optional tokenizer and opt in:
npm i -D gpt-tokenizer # MIT; not pulled in by default (~29 MB of BPE tables)
CTXKIT_EXACT_TOKENS=1 ctxkit pack --profile light --module riskOpt-in is explicit rather than "on when installed" so that everyone's counts
match by default and published measurements stay reproducible. The difference
is real: on one Korean-commented module a light pack holds 11 files by the
heuristic and 9 by exact counting — the extra two would have overflowed the
model's actual limit.
MCP tool reference
{ "mcpServers": { "ctxkit": { "command": "npx", "args": ["-y", "@seanshin/ctx-kit", "serve"] } } }Tool | Parameters | Returns |
| — |
|
|
| ranked map with symbol outlines |
|
|
|
|
| definition sites (exact, then substring) + up to 30 reference lines |
|
| writes a pack file, returns its path and token count |
make_pack is the hand-off tool: a frontier agent can prepare context for a
weaker model without leaving its session. search_symbol is outline-based;
for LSP-grade analysis register Serena
alongside ctx-kit — its tool description tells agents to do exactly that.
Profiles: serving each model tier
Profile | Injects | Typical budget | For |
| rules only | 4K | tool-using agents that explore via MCP |
| rules + map | 24K | mid-size models, structure questions |
| rule summary + map + ranked file contents + reminder | 12K | small local LLMs, one-shot prompts |
| same as | 45K | 128K-class local models needing a whole module |
Rule of thumb from the measurements: structure questions ("where is X
defined?") are answered by the map alone, at a fraction of the tokens.
Implementation-detail questions ("what is this default value?") require
file contents on every model tier. Call-graph questions should go to
search_symbol, not the map — see the caution in
eval/findings.md.
Per-environment setup
Environment | Setup |
Claude Code |
|
Codex CLI | same server under |
Cursor / Windsurf | MCP setting + |
aider | file interface: |
Local agent (OpenCode, Ollama-based) | MCP if the model handles tools; otherwise pipe |
Chat window (no tooling) | paste |
CI |
|
Any repo, no install |
|
Working with small local LLMs
ctxkit pack --profile light --module risk --stdout > /tmp/ctx.md
ollama run qwen3:14b "$(cat /tmp/ctx.md)
Using only the context above: what is the default retry interval?"Three things the pack does for you: it puts rules first and repeats them last;
it orders file contents by reference rank so the budget cut lands on the least
important files; and it caps the embedded map so it cannot crowd out the
source you actually need. Set num_ctx on the Ollama side to at least the
pack's reported token count.
You can measure your own repo with the same harness the project uses:
node eval/run.mjs --fixture /path/to/repo --tasks my-tasks.yaml \
--module risk --custom "qwen=ollama run qwen3:14b" --out results.mdTasks are three-field YAML (id, question, expect keywords); model
processes run in an empty temp directory so they cannot read the repo and
cheat.
Cross-repo rollout
Target repositories keep only context.config.yaml plus generated artifacts;
all logic stays in this package, so upgrading everyone is
npm i -g @seanshin/ctx-kit@latest.
for repo in ~/src/*/; do ctxkit -C "$repo" init --auto --hooks; doneMigrating a repo that already has a hand-written CLAUDE.md: move its content
into AGENTS.md, then ctxkit sync --force (plain sync refuses to clobber
files it did not generate).
Measured results
Three tasks × two profiles × two model tiers, run on a synthetic fixture and then on a 308-file production repository. Full data and methodology: eval/findings.md.
small model | larger model | |
| 2/3 | 2/3 |
| 3/3 | 3/3 |
The implementation-detail task failed on both tiers without file contents and passed on both with them: the context profile decided the outcome, not the model. Both models answered "the context does not contain this" rather than hallucinating.
Separately, a live agent session on the same repo — file-reading tools
disabled, ctx-kit MCP only — answered all three questions correctly in 4
turns and 9.3 seconds using just get_rules and one search_symbol call.
That is the frontier profile working as designed, at a fraction of any
pack's token cost.
Onboarding that production repo also caught three defects that the synthetic fixture had hidden (test files dominating the ranking; a cached map starving the file section; alphabetical truncation dropping the wrong files). All three are fixed and covered by tests.
FAQ
Does this replace AGENTS.md? No — it is built on it. ctx-kit keeps
AGENTS.md as the single source and generates the per-tool variants.
Will it overwrite my CLAUDE.md? Never without --force. Files ctx-kit
did not generate are reported and skipped.
Do I need GitHub Actions? No. ctxkit init --hooks runs the same gate at
commit time, locally and free. The workflow is opt-in and labeled.
Why not tree-sitter? The symbol extractor sits behind an interface a tree-sitter adapter can replace; the regex outline keeps the package dependency-light and works offline. Semantic-grade analysis is Serena's job.
Is anything sent anywhere? No. Everything runs locally; ctx-kit makes no network calls.
Repomap looks wrong for my layout. Add noise paths to exclude, then
re-run ctxkit map. Vendored code, migrations and fixtures are the usual
culprits.
Design notes
Adapter boundary as license boundary. External tools are invoked as CLIs, never vendored, so swapping Repomix for code2prompt is a one-file change and the MIT posture stays mechanical.
Reduced-capability core. Everything works with zero external tools installed — important for offline and air-gapped environments.
Files as the contract. Because every command leaves a file, the weakest environment is always supported, and CI can diff artifacts.
Project layout:
src/core/ config, fs walk, tokens, repomap, pack, sync, check, get, detect
src/adapters/ symbols (own), repomix (CLI wrapper), ruler/serena (notes)
src/cli.ts interface B src/mcp.ts interface A
templates/ init scaffolds, pre-commit hook, CI workflow
eval/ measurement harness, fixture, tasks, findings
test/ node --test suiteDevelopment
npm install
npm test # builds, then runs the node --test suite (10 tests)
npm run build # tsc onlyTests cover config defaults and schema rejection, ignore rules, symbol extraction, ranking and test demotion, pack budgeting and module filtering, sync's foreign-file protection and staleness detection, the secret scan, auto-detection, and query retrieval.
License posture
MIT. External tools are integrated by CLI invocation only, never code reuse: Repomix (MIT, optional packer), Serena (MIT, LSP-grade search — registered alongside, not wrapped). The repo-map ranking is an independent implementation inspired by aider's tree-sitter + PageRank approach (Apache-2.0 — algorithm reference only). GPL tools such as universal-ctags were excluded deliberately.
Docs
Changelog — what shipped in each release
Whitepaper · 백서 — design, algorithms, measurements
Onboarding playbook (KO) — 10-minute checklist
Plan v2.3 (KO) — task-shaped context, repository health, and a parallel-execution plan (seams, work streams, merge order)
References (KO) — annotated bibliography: papers, tools, licenses, and what each informs
Context architecture plan (KO) · Package architecture (KO) — v1, with outcomes recorded
Measurements (KO)
MIT © 2026 Hyounmouk Shin
This server cannot be deployed
Maintenance
Related MCP Connectors
Turn a GitHub repo or docs site into agent-ready context: pack it or search it, over MCP.
Search GitHub, npm, PyPI, StackOverflow, ArXiv from one MCP — built for coding agents.
Codebase graphs, caller impact analysis, and recorded project context for AI coding agents.
Your org's AI agents, tasks, runs, search, and brain files as MCP tools and resources.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceProvides AI assistants with a structured, token-efficient map of a codebase's symbols, dependencies, and relationships via MCP tools like overview, query, and impact analysis.8MIT
- AlicenseNot gradedqualityDmaintenanceEnables AI coding agents to retrieve and manage code context with hybrid search, project memory, and observability via MCP tools.29MIT
- AlicenseAqualityAmaintenanceEnables AI coding agents to efficiently explore codebases by providing structural outlines, module digests, symbol bodies, and AST-aware grep via MCP.4201MIT
- AlicenseAqualityCmaintenanceEnables AI coding agents to intelligently index and search codebases with sub-20ms retrieval, 8x memory compression, and cross-encoder reranking via MCP stdio.5MIT