ECC
The agent harness performance optimization system. Skills, instincts, memory, security, and research-first development for Claude Code, Codex, Opencode, Cursor and beyond.
npx ecc-install --profile fullThe agent harness performance optimization system. Skills, instincts, memory, security, and research-first development for Claude Code, Codex, Opencode, Cursor and beyond.
npx ecc-install --profile fullFair-code workflow automation platform with native AI capabilities. Combine visual building with custom code, self-host or cloud, 400+ integrations.
npx n8nAn open-source AI agent that brings the power of Gemini directly into your terminal.
npx @google/gemini-cliSupports Claude Code, Codex, Cursor, Windsurf, Mcp
Shows active maintenance signals
Carries strong trust indicators from repository metadata
1995 GitHub stars recorded
Settings are controlled by a JSONC config file (config.jsonc) with env var fallbacks for backward compatibility. Defaults are chosen so that a fresh install works without any configuration.
jcodemunch-mcp config --init # create ~/.code-index/config.jsonc from template
jcodemunch-mcp config # show effective configuration
jcodemunch-mcp config --check # validate config + verify prerequisites
--check validates that your config file is well-formed, your AI provider package is installed, your index storage path is writable, and HTTP transport packages are present. Exits non-zero on any failure — useful for CI/CD or first-run scripts.
| Layer | Path | Purpose |
|---|---|---|
| Global | ~/.code-index/config.jsonc | Server-wide defaults |
| Project | {project_root}/.jcodemunch.jsonc | Per-project overrides |
Project config merges over global config — closest to the work wins.
| Config key | What it controls | Typical savings |
|---|---|---|
tool_profile | "core" (16 tools), "standard" (51), "full" (62, default) | ~5-6k tokens (core) |
compact_schemas | Strip rarely-used advanced params from schemas | ~1-2k tokens |
disabled_tools | Remove individual tools from schema entirely | ~100–400 tokens/tool |
languages | Shrink language enum + gate features | ~2–86 tokens/turn |
meta_fields | Filter _meta response fields | ~50–150 tokens/call |
descriptions | Control description verbosity | ~0–600 tokens/turn |
Recommended for context-conscious setups: "tool_profile": "core", "compact_schemas": true reduces the schema footprint from ~11.5k tokens to ~4k tokens.
See the full template for all available keys. Run jcodemunch-mcp config --init to generate one.
jcodemunch-mcp exposes 60+ tools. On request-capped plans, having all of them visible to small models causes primitive-preference bias (many search → read → search → read cycles instead of one get_context_bundle). The server mitigates this by narrowing the exposed tool list per the running model.
Three tiers ship with sensible defaults, fully editable in config.jsonc:
core (16 tools): indexing, search, retrieval. Recommended for Haiku / small local models.standard (51 tools): core + analytics / architecture / quality. Recommended for Sonnet / GPT-4o class.full (all 62 tools): no filter. Recommended for Opus / o1 / frontier models.Edit tool_tier_bundles.core / tool_tier_bundles.standard in your config.jsonc to add or remove tools from each tier.
Runtime tier switching is off by default. To enable it, set in config.jsonc:
"adaptive_tiering": true
When on, plan_turn — already the opening-move tool — accepts an optional model parameter that switches the session tier as a side effect, with no extra MCP request:
plan_turn(repo="...", query="...", model="claude-haiku-4-5")
The server resolves the model to a tier via model_tier_map in config (fuzzy matching: normalizes the id, then exact → glob → substring → * → full fallback). Subsequent tools/list calls return only the narrowed set.
When adaptive_tiering is false, plan_turn(model=...) and announce_model(...) accept their arguments but do not switch the tier — the static tool_profile continues to drive the exposed tools. set_tool_tier(tier=...) remains honored either way because it's an explicit user call, not automatic behavior.
tool_surface)tool_surface goes further than tiering: it collapses the resident tool list to a three-tool front door that fronts the entire catalog without losing any capability. Every turn the host serializes each resident tool's schema into context; the front door shrinks that fixed per-turn cost (≈21.6k → ≈0.9k tokens, ~24×) and removes the "pick one of N" dispatch dilution.
New installs default to counter so a first-time user gets maximal token savings out of the box, with every tool one menu() / route() call away. This default is applied only to a genuinely first-ever install: an existing install keeps its surface across upgrades — if you never set tool_surface, a package update leaves you on full exactly as before, never silently collapsing your tool list. Set it explicitly any time:
"tool_surface": "counter"
order(action, args) — dispatch any catalog action by name. Read-only by default at the boundary: actions that change index/session state require allow_state_change=true, and execution/file-write verbs are refused outright (the front door is a charter checkpoint, never a mutation path).menu(query?) — search/browse the action catalog (compact rows: action, summary, required args, state_changing), so the full set of schemas needn't stay resident in context.route(task, repo?, execute?) — map a natural-language task to the best action(s); with execute=true, dispatch the top recommendation in the same call. Recommends assemble_task_context / plan_turn for context-gathering intents.counter keeps the always-present controls (set_tool_tier, announce_model, jcodemunch_guide) alongside the front door. Setting full advertises every tool schema (the pre-counter behavior). The two mechanisms compose: under counter, order / route still reach every action regardless of the active core / standard / full tier. Seeing only three tools in your client's tool list is expected under counter — call menu() to list the full catalog.
disabled_tools precedencedisabled_tools applies after tier filtering. A tool listed in both a tier bundle and disabled_tools will not be exposed. The server logs a WARNING on startup and jcodemunch-mcp config --check prints a WARN: row if this happens.
architecture.layers)Place a .jcodemunch.jsonc file at your project root to declare the layers your architecture must respect. get_layer_violations will then enforce that imports only flow in the declared direction.
// .jcodemunch.jsonc — example for a layered Python project
{
"architecture": {
"layers": [
{ "name": "api", "paths": ["src/routes", "src/controllers"] },
{ "name": "service", "paths": ["src/services"] },
{ "name": "repo", "paths": ["src/repositories"] },
{ "name": "db", "paths": ["src/models", "src/migrations"] }
],
"rules": [
{ "layer": "api", "may_not_import": ["db"] },
{ "layer": "service", "may_not_import": ["api"] },
{ "layer": "repo", "may_not_import": ["api", "service"] }
]
}
}
Call get_layer_violations(rules=[...]) directly to pass rules inline — the config file is optional and used as a fallback. When no config is present, get_layer_violations infers layers from top-level directory structure.
The following env vars still work but are deprecated. Config file values take priority:
| Variable | Config key | Default |
|---|---|---|
JCODEMUNCH_USE_AI_SUMMARIES | use_ai_summaries | true |
JCODEMUNCH_TRUSTED_FOLDERS | trusted_folders | [] |
JCODEMUNCH_MAX_FOLDER_FILES | max_folder_files | 2000 |
JCODEMUNCH_MAX_INDEX_FILES | max_index_files | 10000 |
JCODEMUNCH_STALENESS_DAYS | staleness_days | 7 |
JCODEMUNCH_MAX_RESULTS | max_results | 500 |
JCODEMUNCH_EXTRA_IGNORE_PATTERNS | extra_ignore_patterns | [] |
JCODEMUNCH_CONTEXT_PROVIDERS |
AI provider keys (ANTHROPIC_API_KEY, GOOGLE_API_KEY, OPENAI_API_BASE, MINIMAX_API_KEY, ZHIPUAI_API_KEY, etc.), JCODEMUNCH_SUMMARIZER_PROVIDER, and CODE_INDEX_PATH are always read from env vars — they are never placed in config files.
AI provider priority in auto-detect mode: Anthropic → Gemini → OpenAI-compatible (OPENAI_API_BASE) → MiniMax → GLM-5 → signature fallback. Set JCODEMUNCH_SUMMARIZER_PROVIDER to force anthropic, gemini, openai, minimax, glm, or none. jcodemunch-mcp config shows which provider is active.
allow_remote_summarizer only affects OpenAI-compatible HTTP endpoints. When false, jcodemunch accepts only localhost-style endpoints such as Ollama or LM Studio on 127.0.0.1 and rejects remote hosts like api.minimax.io. When a remote endpoint is rejected, AI summarization falls back to docstrings or signatures instead of sending source code to that provider. Set allow_remote_summarizer: true in config.jsonc if you intentionally want to use a hosted OpenAI-compatible provider such as MiniMax or GLM-5.
openai_extra_body (config key, or JCODEMUNCH_OPENAI_EXTRA_BODY env var as a JSON object) is merged into every OpenAI-compatible /chat/completions and /responses summarizer request. Use it for provider knobs the standard payload doesn't expose — most commonly to turn off a local thinking model's reasoning so the output budget isn't spent on reasoning tokens (which silently degrades summaries to generic signatures). For llama.cpp / Qwen: JCODEMUNCH_OPENAI_EXTRA_BODY='{"chat_template_kwargs":{"enable_thinking":false}}'. When a summarization run produces mostly generic fallbacks despite successful responses, jcodemunch now logs a degradation warning pointing at this setting (issue #323).
jCodeMunch indexes local folders or GitHub repos, parses source with tree-sitter, extracts symbols, and stores structured metadata alongside raw file content in a local index. Each symbol includes enough information to be found cheaply and retrieved precisely later.
That includes metadata like:
So when the agent wants a symbol, jCodeMunch can fetch the exact source directly instead of loading and rescanning the full file.
context_providers |
true |
JCODEMUNCH_REDACT_SOURCE_ROOT | redact_source_root | false |
JCODEMUNCH_STATS_FILE_INTERVAL | stats_file_interval | 3 |
JCODEMUNCH_SHARE_SAVINGS | share_savings | true |
JCODEMUNCH_TELEMETRY_URL | (none) | community meter URL |
JCODEMUNCH_SUMMARIZER_CONCURRENCY | summarizer_concurrency | 4 |
JCODEMUNCH_ALLOW_REMOTE_SUMMARIZER | allow_remote_summarizer | false |
JCODEMUNCH_RATE_LIMIT | rate_limit | 0 |
JCODEMUNCH_TRANSPORT | transport | stdio |
JCODEMUNCH_HOST | host | 127.0.0.1 |
JCODEMUNCH_PORT | port | 8901 |
JCODEMUNCH_LOG_LEVEL | log_level | WARNING |
Want semantic search? Install the local embedding extra for zero-config semantic search — no API keys, no internet after first download:
pip install "jcodemunch-mcp[local-embed]" # bundled ONNX encoder (recommended) jcodemunch-mcp download-model # fetch model (~23 MB, one-time)Want AI-generated summaries? Install the extra for your provider:
pip install "jcodemunch-mcp[anthropic]" # Claude pip install "jcodemunch-mcp[gemini]" # Gemini pip install "jcodemunch-mcp[openai]" # OpenAI-compatible pip install "jcodemunch-mcp[all]" # all providers + local embeddingsWithout an extra, summaries fall back to signatures (which still works — you just get shorter descriptions). Run
jcodemunch-mcp config --checkto verify your provider is installed and working.
Most extras are pure-Python and self-contained. A few pull libraries that touch system surfaces worth noting for managed-endpoint and SOC 2 / HIPAA-adjacent deployments. For the base package alone, none of these surfaces are introduced.
| Extra | Transitive dependencies of note | System surfaces |
|---|---|---|
| (base, no extra) | none | none |
[local-embed] | onnxruntime | local CPU inference (no network after model download); model fetched on first run |
[anthropic] | anthropic SDK | outbound HTTPS to api.anthropic.com when AI summaries are enabled |
[gemini] | google-generativeai | outbound HTTPS to Google AI endpoints when AI summaries are enabled |
[openai] | openai SDK | outbound HTTPS to api.openai.com (or OPENAI_API_BASE) when AI summaries are enabled |
[groq] | openai SDK | outbound HTTPS to Groq endpoints; used by the gcm CLI and speedreview Action |
[groq-voice] | sounddevice, numpy | microphone access — sounddevice.InputStream opens the system audio device when the voice path is invoked |
[groq-explain] | Pillow | image decode / re-encode of attached screenshots |
[all] | union of all the above | union of all surfaces above, including microphone ([groq-voice]) and image libraries ([groq-explain]) |
For managed-endpoint deployments where microphone access on developer machines
is policy-restricted (HIPAA, SOC 2, finance), pin to the base package or to the
specific provider extras you need. The voice and explain paths are opt-in
features, not part of the core MCP server functionality, and [all] is the
only extra that bundles them together.
Upgrade through whatever installed it, then restart your editor / MCP client so it relaunches the server on the new version:
pip install -U jcodemunch-mcp # pip
pipx upgrade jcodemunch-mcp # pipx
uv tool upgrade jcodemunch-mcp # uv tool
uvx jcodemunch-mcp@latest --help # uvx (forces a cache refresh)
Check what you're running with jcodemunch-mcp --version.
Prefer not to touch the command line? jMunch Console (free, MIT, opt-in) makes upgrades one click — it shows an "update available" badge when a newer release exists and runs the install for you in a visible terminal (uv / pipx / pip, whichever you have), so you never copy a command.
If you’re using Claude Code, pick whichever matches what you installed in step 1.
Pip install (simplest, what most people do):
claude mcp add -s user jcodemunch jcodemunch-mcp
The -s user flag registers it at user scope so it's available in every
project. Without it, the registration is project-local and you'll see it
missing the next time you cd elsewhere. If jcodemunch-mcp isn't found
on PATH (common on Windows where pip install --user installs to
AppData\Roaming\Python\PythonXYZ\Scripts\), use the absolute path:
# Windows
claude mcp add -s user jcodemunch "C:\Users\YOU\AppData\Roaming\Python\Python312\Scripts\jcodemunch-mcp.exe"
# macOS/Linux — check `which jcodemunch-mcp` first
claude mcp add -s user jcodemunch "$(which jcodemunch-mcp)"
uvx (no pip install required, but uv must be on PATH):
claude mcp add -s user jcodemunch uvx jcodemunch-mcp
'uvx' is not recognized(Windows / Cursor / any client)?uvxships with uv. Install it withpowershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex", then fully restart your editor so it picks up the new PATH. To skip uv entirely:python -m pip installthe package and launch withcommand: "python",args: ["-m", "jcodemunch_mcp"]instead.
If /mcp reports failed with no reason, run claude --mcp-debug or
check %USERPROFILE%\AppData\Roaming\Claude\logs\mcp*.log — the /mcp
summary hides the actual error.
If you’re using Paperclip (the multi-agent orchestration platform), add a .mcp.json to your workspace root:
{
"mcpServers": {
"jcodemunch": {
"type": "stdio",
"command": "uvx",
"args": ["jcodemunch-mcp"]
},
"jdocmunch": {
"type": "stdio",
"command": "uvx",
"args": ["jdocmunch-mcp"]
}
}
}
Paperclip’s Claude Code agents auto-detect .mcp.json at startup. Add both servers to give your agents symbol search + doc navigation without blowing the token budget.
This matters more than people think.
Installing jCodeMunch makes the tools available. It does not guarantee the agent will stop its bad habit of brute-reading files unless you instruct it to prefer symbol search, outlines, and targeted retrieval. The changelog specifically calls out improved onboarding around this because it is a real source of confusion for first-time users.
A simple instruction like this helps:
Use jcodemunch-mcp for code lookup whenever available. Prefer symbol search, outlines, and targeted retrieval over reading full files.
Note:
jcodemunch-mcp inithandles steps 2 and 3 automatically. For a comprehensive guide on enforcing these rules through agent hooks and prompt policies, see AGENT_HOOKS.md.
| dbt, Git, and custom context provider docs |
| TROUBLESHOOTING.md | Common issues and fixes |
| AGENT_INSTALL_UNIVERSAL.md | Paste-and-go prompt for installing jCodemunch guidance into agent/IDE clients without a first-class jcm install target (Codex CLI, Cline, JetBrains AI, Aider, etc.). For Claude Code, Cursor, Windsurf, Continue — use jcm install <client> instead. |