Connects to your local codebase via tree-sitter AST parsing and exposes precise retrieval tools: fetch individual functions, classes, or methods by name instead of reading entire files. Supports 25+ languages and cuts token usage by 95%+ in retrieval-heavy workflows because your agent stops scanning thousands of irrelevant lines. Index once with stdio transport, then query symbols, outlines, references, and scoped context bundles with byte-level precision. Ships with a compact wire format (MUNCH) that shrinks responses by another 45% median. Reach for this when your agent burns tokens opening giant files just to find one implementation, or when you need structured code navigation without the brute-force tax.
claude mcp add jcodemunch-mcp -- uvx jcodemunch-mcpRun in your terminal. Replace YOUR_* placeholders with real values; add --scope user to install for every project.
Review the command, arguments, and environment values before installing — MCP servers run with your local permissions.
Verified live against the running server on Jun 10, 2026.
index_repoIndex a GitHub repository's source code. Fetches files, parses ASTs, extracts symbols, and saves to local storage. Set JCODEMUNCH_USE_AI_SUMMARIES=false to disable AI summaries globally.4 paramsIndex a GitHub repository's source code. Fetches files, parses ASTs, extracts symbols, and saves to local storage. Set JCODEMUNCH_USE_AI_SUMMARIES=false to disable AI summaries globally.
url*stringincrementalbooleanuse_ai_summariesbooleanextra_ignore_patternsarrayindex_folderIndex a local folder of source code. Response surfaces `discovery_skip_counts` and `no_symbols_files` for diagnosing missing files.7 paramsIndex a local folder of source code. Response surfaces `discovery_skip_counts` and `no_symbols_files` for diagnosing missing files.
path*stringpathsarrayincrementalbooleanidentity_modestringconfig · local · gitdefault: configfollow_symlinksbooleanuse_ai_summariesbooleanextra_ignore_patternsarraysummarize_repoRe-run AI summarization on all symbols in an existing index. Use this when index_folder completed but AI summaries are missing — e.g., the background summarization thread was interrupted, AI was disabled at index time, or the summarizer provider wasn't configured yet. With for...2 paramsRe-run AI summarization on all symbols in an existing index. Use this when index_folder completed but AI summaries are missing — e.g., the background summarization thread was interrupted, AI was disabled at index time, or the summarizer provider wasn't configured yet. With for...
repo*stringforcebooleanindex_fileIndex a single file within an existing index. Surgical update after edits. The file must be under an already-indexed folder's source_root. Can also add new files.3 paramsIndex a single file within an existing index. Surgical update after edits. The file must be under an already-indexed folder's source_root. Can also add new files.
path*stringuse_ai_summariesbooleancontext_providersbooleanimport_runtime_signalIngest a runtime trace file into the runtime_* tables for the target repo. source='otel' takes OTel JSON / JSON-Lines / .gz and maps spans via (file_path, line_no, function_name); source='sql_log' takes pg_stat_statements CSV or a generic SQL JSON-Lines log and maps queries vi...4 paramsIngest a runtime trace file into the runtime_* tables for the target repo. source='otel' takes OTel JSON / JSON-Lines / .gz and maps spans via (file_path, line_no, function_name); source='sql_log' takes pg_stat_statements CSV or a generic SQL JSON-Lines log and maps queries vi...
path*stringrepostringsourcestringotel · sql_log · stack_log · apmdefault: otelredact_enabledbooleanget_runtime_coverageRuntime coverage histogram for a repo or a single file: count of indexed symbols with vs without runtime evidence, plus the diagnostic list of unmapped runtime spans (likely reflective dispatch the AST missed). Pairs with Phase 2's per-result _runtime_confidence stamping. Retu...3 paramsRuntime coverage histogram for a repo or a single file: count of indexed symbols with vs without runtime evidence, plus the diagnostic list of unmapped runtime spans (likely reflective dispatch the AST missed). Pairs with Phase 2's per-result _runtime_confidence stamping. Retu...
repo*stringfile_pathstringunmapped_limitintegerfind_hot_pathsTop-N symbols ranked by total runtime hit count across ingested traces, with per-symbol p50/p95 latency, sources contributing, and last_seen. Optionally filtered by a name substring. Pairs with get_blast_radius to answer 'is this PR touching code that runs 4M times/day?' Retur...3 paramsTop-N symbols ranked by total runtime hit count across ingested traces, with per-symbol p50/p95 latency, sources contributing, and last_seen. Optionally filtered by a name substring. Pairs with get_blast_radius to answer 'is this PR touching code that runs 4M times/day?' Retur...
repo*stringquerystringtop_nintegerfind_unused_pathsSymbols with zero (or stale) runtime hits over the look-back window. Distinct from find_dead_code: this surfaces code that's reachable on paper but never executed — only possible to detect with runtime data. Excludes test files and entry-point filenames by default. Returns an...5 paramsSymbols with zero (or stale) runtime hits over the look-back window. Distinct from find_dead_code: this surfaces code that's reachable on paper but never executed — only possible to detect with runtime data. Excludes test files and entry-point filenames by default. Returns an...
repo*stringsince_daysintegermax_resultsintegerinclude_testsbooleaninclude_entry_pointsbooleanget_redaction_logPer-pattern PII redaction counts from runtime_redaction_log. Operators run this to verify the redaction chokepoint is firing on production traffic — covers the OTel / SQL / stack ingest paths (file-based or HTTP live-ingest, Phase 6). Returns {patterns: [{source, pattern, coun...3 paramsPer-pattern PII redaction counts from runtime_redaction_log. Operators run this to verify the redaction chokepoint is firing on production traffic — covers the OTel / SQL / stack ingest paths (file-based or HTTP live-ingest, Phase 6). Returns {patterns: [{source, pattern, coun...
repo*stringsourcestringotel · sql_log · stack_log · apmsince_daysintegerlist_reposList all indexed repositories. START HERE before using Grep/Read/search tools — check if the project is already indexed, then use search_symbols / get_symbol_source instead of native file reads. If jcodemunch tools appear as deferred in your tool list, call ToolSearch to load...List all indexed repositories. START HERE before using Grep/Read/search tools — check if the project is already indexed, then use search_symbols / get_symbol_source instead of native file reads. If jcodemunch tools appear as deferred in your tool list, call ToolSearch to load...
No parameters — call it with no arguments.
get_watch_statusReport watch-all daemon coverage: every locally-indexed repo, each repo's staleness / reindex-in-progress state, and the OS-level service status. Call before relying on index freshness when you suspect files may have changed since the last index.Report watch-all daemon coverage: every locally-indexed repo, each repo's staleness / reindex-in-progress state, and the OS-level service status. Call before relying on index freshness when you suspect files may have changed since the last index.
No parameters — call it with no arguments.
resolve_repoResolve a filesystem path to its indexed repo identifier. O(1) lookup — faster than list_repos for finding a single repo. Accepts repo root, worktree, subdirectory, or file path.1 paramsResolve a filesystem path to its indexed repo identifier. O(1) lookup — faster than list_repos for finding a single repo. Accepts repo root, worktree, subdirectory, or file path.
path*stringget_file_treeGet the file tree of an indexed repository, optionally filtered by path prefix. Results are capped at max_files (default 500) to prevent token overflow; use path_prefix to scope large trees.4 paramsGet the file tree of an indexed repository, optionally filtered by path prefix. Results are capped at max_files (default 500) to prevent token overflow; use path_prefix to scope large trees.
repo*stringmax_filesintegerpath_prefixstringinclude_summariesbooleanget_file_outlineGet all symbols (functions, classes, methods) in a file with full signatures (including parameter names) and summaries. Use signatures to review naming at parameter granularity without reading the full file. Pass repo and file_path (e.g. 'src/main.py').3 paramsGet all symbols (functions, classes, methods) in a file with full signatures (including parameter names) and summaries. Use signatures to review naming at parameter granularity without reading the full file. Pass repo and file_path (e.g. 'src/main.py').
repo*stringfile_pathstringfile_pathsarrayget_symbol_sourceGet full source of one symbol (symbol_id → flat object) or many (symbol_ids[] → {symbols, errors}). Supports verify, context_lines, and fqn (PHP FQN via PSR-4).6 paramsGet full source of one symbol (symbol_id → flat object) or many (symbol_ids[] → {symbols, errors}). Supports verify, context_lines, and fqn (PHP FQN via PSR-4).
fqnstringrepo*stringverifybooleansymbol_idstringsymbol_idsarraycontext_linesintegerget_file_contentGet cached source for a file, optionally sliced to a line range.4 paramsGet cached source for a file, optionally sliced to a line range.
repo*stringend_lineintegerfile_path*stringstart_lineintegersearch_symbolsSearch for symbols matching a query across the entire indexed repository. Returns matches with signatures and summaries.19 paramsSearch for symbols matching a query across the entire indexed repository. Returns matches with signatures and summaries.
fqnstringkindstringfunction · class · method · constant · type · templaterepo*stringdebugbooleanfuzzybooleanquery*stringfusionbooleansort_bystringrelevance · centrality · combineddefault: relevancelanguagestringada · al · ansible · apex · arduino · asmsemanticbooleandecoratorstringmax_resultsintegerdetail_levelstringcompact · standard · fulldefault: standardfile_patternstringtoken_budgetintegersemantic_onlybooleanfuzzy_thresholdnumbersemantic_weightnumbermax_edit_distanceintegerinvalidate_cacheDelete the index and cached files for a repository. Forces a full re-index on next index_repo or index_folder call.1 paramsDelete the index and cached files for a repository. Forces a full re-index on next index_repo or index_folder call.
repo*stringsearch_textFull-text search across indexed file contents. Useful when symbol search misses (e.g., string literals, comments, config values). Supports regex (is_regex=true) and context lines around matches (context_lines=N, like grep -C).6 paramsFull-text search across indexed file contents. Useful when symbol search misses (e.g., string literals, comments, config values). Supports regex (is_regex=true) and context lines around matches (context_lines=N, like grep -C).
repo*stringquery*stringis_regexbooleanmax_resultsintegerfile_patternstringcontext_linesintegerget_repo_outlineGet a high-level overview of an indexed repository: directories, file counts, language breakdown, symbol counts. Lighter than get_file_tree.1 paramsGet a high-level overview of an indexed repository: directories, file counts, language breakdown, symbol counts. Lighter than get_file_tree.
repo*stringfind_importersFind all files that import a given file. Answers 'what uses this file?'. has_importers=false on a result means that importer is itself unreachable (dead code chain). Supports dbt {{ ref() }} edges. Use file_paths for batch queries. Set cross_repo=true to also find importers in...5 paramsFind all files that import a given file. Answers 'what uses this file?'. has_importers=false on a result means that importer is itself unreachable (dead code chain). Supports dbt {{ ref() }} edges. Use file_paths for batch queries. Set cross_repo=true to also find importers in...
repo*stringfile_pathstringcross_repobooleanfile_pathsarraymax_resultsintegerfind_referencesFind all files that import or reference an identifier via the import graph. Answers 'where is this imported / re-exported?'. SCOPE: import sites + dbt `{{ ref() }}` edges + (when `include_call_chain=true`) symbols whose bodies textually mention the identifier. Does NOT exhaust...5 paramsFind all files that import or reference an identifier via the import graph. Answers 'where is this imported / re-exported?'. SCOPE: import sites + dbt `{{ ref() }}` edges + (when `include_call_chain=true`) symbols whose bodies textually mention the identifier. Does NOT exhaust...
repo*stringidentifierstringidentifiersarraymax_resultsintegerinclude_call_chainbooleancheck_referencesCheck if an identifier is referenced anywhere: imports + file content. Combines find_references and search_text into one call. Returns is_referenced (bool) for quick dead-code detection. Accepts multiple identifiers in one call via identifiers param.5 paramsCheck if an identifier is referenced anywhere: imports + file content. Combines find_references and search_text into one call. Returns is_referenced (bool) for quick dead-code detection. Accepts multiple identifiers in one call via identifiers param.
repo*stringidentifierstringidentifiersarraysearch_contentbooleanmax_content_resultsintegersearch_columnsSearch column metadata across indexed models. Works with any ecosystem provider that emits column data (dbt, SQLMesh, database catalogs, etc.). Returns model name, file path, column name, and description. Use instead of grep/search_text for column discovery — 77% fewer tokens.4 paramsSearch column metadata across indexed models. Works with any ecosystem provider that emits column data (dbt, SQLMesh, database catalogs, etc.). Returns model name, file path, column name, and description. Use instead of grep/search_text for column discovery — 77% fewer tokens.
repo*stringquery*stringmax_resultsintegermodel_patternstringget_context_bundleGet full source + imports for one or more symbols in one call. Multi-symbol bundles deduplicate shared imports. Set token_budget to cap response size; use budget_strategy to control what's kept. Supports fqn (PHP FQN via PSR-4) as alternative to symbol_id.9 paramsGet full source + imports for one or more symbols in one call. Multi-symbol bundles deduplicate shared imports. Set token_budget to cap response size; use budget_strategy to control what's kept. Supports fqn (PHP FQN via PSR-4) as alternative to symbol_id.
fqnstringrepo*stringsymbol_idstringsymbol_idsarraytoken_budgetintegeroutput_formatstringjson · markdowndefault: jsonbudget_strategystringmost_relevant · core_first · compactdefault: most_relevantinclude_callersbooleaninclude_budget_reportbooleanget_session_statsGet token savings stats for the current MCP session. Returns tokens saved and cost avoided (this session and all-time), per-tool breakdown, session duration, and cumulative totals. Use to see how much jCodeMunch has saved you.Get token savings stats for the current MCP session. Returns tokens saved and cost avoided (this session and all-time), per-tool breakdown, session duration, and cumulative totals. Use to see how much jCodeMunch has saved you.
No parameters — call it with no arguments.
analyze_perfPer-tool latency telemetry: p50/p95/max in ms, error rate, plus cache hit-rate by tool. Defaults to the in-memory session ring; pass window=1h|24h|7d|all to query persisted telemetry.db (requires perf_telemetry_enabled). Useful for finding slow tools, cold caches, and regressi...5 paramsPer-tool latency telemetry: p50/p95/max in ms, error rate, plus cache hit-rate by tool. Defaults to the in-memory session ring; pass window=1h|24h|7d|all to query persisted telemetry.db (requires perf_telemetry_enabled). Useful for finding slow tools, cold caches, and regressi...
topintegertoolstringledgerbooleanwindowstringsession · 1h · 24h · 7d · alldefault: sessioncompare_releasestringcheck_embedding_driftPin (or re-check) a 16-string canary against the active embedding provider. On first run with capture=True (or force=True), embeds CANARY_STRINGS and persists the vectors to ~/.code-index/embed_canary.json. Subsequent calls re-embed those strings and report cosine drift; alarm...3 paramsPin (or re-check) a 16-string canary against the active embedding provider. On first run with capture=True (or force=True), embeds CANARY_STRINGS and persists the vectors to ~/.code-index/embed_canary.json. Subsequent calls re-embed those strings and report cosine drift; alarm...
forcebooleancapturebooleanthresholdnumbertune_weightsLearn per-repo retrieval weights from the v1.78.0 ranking ledger. Computes confidence correlations for the semantic and identity-match channels and writes overrides to ~/.code-index/tuning.jsonc. search_symbols reads those overrides at query time when the caller doesn't pass a...4 paramsLearn per-repo retrieval weights from the v1.78.0 ranking ledger. Computes confidence correlations for the semantic and identity-match channels and writes overrides to ~/.code-index/tuning.jsonc. search_symbols reads those overrides at query time when the caller doesn't pass a...
repostringdry_runbooleanexplainbooleanmin_eventsintegerget_session_contextGet the current session context — files accessed, searches performed, and edits registered during this MCP session. Use to avoid re-reading the same files.2 paramsGet the current session context — files accessed, searches performed, and edits registered during this MCP session. Use to avoid re-reading the same files.
max_filesintegermax_queriesintegerget_session_snapshotGet a compact session snapshot for context continuity. Returns a ~200 token markdown summary of files explored, edits made, searches performed, and dead ends. Designed for injection after context compaction to restore session orientation.4 paramsGet a compact session snapshot for context continuity. Returns a ~200 token markdown summary of files explored, edits made, searches performed, and dead ends. Designed for injection after context compaction to restore session orientation.
max_editsintegermax_filesintegermax_searchesintegerinclude_negative_evidencebooleanget_file_riskPer-symbol composite risk for one file. For each function or method, returns a 0-100 composite score (higher = healthier; lower = riskier) plus per-axis sub-scores (complexity, exposure, churn, test_gap). Powers the VS Code risk-density gutter. complexity is per-symbol (cyclom...2 paramsPer-symbol composite risk for one file. For each function or method, returns a 0-100 composite score (higher = healthier; lower = riskier) plus per-axis sub-scores (complexity, exposure, churn, test_gap). Powers the VS Code risk-density gutter. complexity is per-symbol (cyclom...
repo*stringfile_path*stringdiff_health_radarCompare two health-radar payloads (from get_repo_health.radar) and return axis-by-axis deltas, composite delta, grade movement, and a one-line verdict. Pure data transform — no index access, no I/O. Designed for PR-time diff-grade reports: run get_repo_health on the base branc...2 paramsCompare two health-radar payloads (from get_repo_health.radar) and return axis-by-axis deltas, composite delta, grade movement, and a one-line verdict. Pure data transform — no index access, no I/O. Designed for PR-time diff-grade reports: run get_repo_health on the base branc...
current*objectbaseline*objectdigestAgent stand-up briefing for a repo. Returns a tight (~200 token) markdown digest of (a) what changed since the agent's last session (by tracking git HEAD between calls), (b) the current risk surface (top hotspots by complexity × churn), and (c) dead-code candidates. Each item...5 paramsAgent stand-up briefing for a repo. Returns a tight (~200 token) markdown digest of (a) what changed since the agent's last session (by tracking git HEAD between calls), (b) the current risk surface (top hotspots by complexity × churn), and (c) dead-code candidates. Each item...
repo*stringsince_shastringmax_hotspotsintegermax_dead_codeintegermax_changed_filesintegerplan_turnPlan the next turn by analyzing query against the codebase. Returns confidence level (high/medium/low), recommended symbols/files, and guidance. Use as opening move for any task.4 paramsPlan the next turn by analyzing query against the codebase. Returns confidence level (high/medium/low), recommended symbols/files, and guidance. Use as opening move for any task.
repo*stringmodelstringquery*stringmax_recommendedintegerregister_editRegister file edits to invalidate caches. Call after editing files to clear BM25 cache and search result cache for the repo.3 paramsRegister file edits to invalidate caches. Call after editing files to clear BM25 cache and search result cache for the repo.
repo*stringreindexbooleanfile_paths*arrayaudit_agent_configAudit agent configuration files (CLAUDE.md, .cursorrules, copilot-instructions.md, etc.) for token waste. Reports per-file token cost, stale symbol references, dead file paths, redundancy between global and project configs, bloat patterns, and scope leaks. Cross-references aga...2 paramsAudit agent configuration files (CLAUDE.md, .cursorrules, copilot-instructions.md, etc.) for token waste. Reports per-file token cost, stale symbol references, dead file paths, redundancy between global and project configs, bloat patterns, and scope leaks. Cross-references aga...
repostringproject_pathstringget_dependency_graphGet the file-level dependency graph for a given file. Traverses import relationships up to 3 hops. Use to understand what a file depends on ('imports'), what depends on it ('importers'), or both. Prerequisite for blast radius analysis. Set cross_repo=true to include cross-repo...5 paramsGet the file-level dependency graph for a given file. Traverses import relationships up to 3 hops. Use to understand what a file depends on ('imports'), what depends on it ('importers'), or both. Prerequisite for blast radius analysis. Set cross_repo=true to include cross-repo...
file*stringrepo*stringdepthintegerdirectionstringimports · importers · bothdefault: importscross_repobooleanget_symbol_diffDiff symbol sets between two indexed snapshots. Shows added, removed, and changed symbols. Branch workflow: index branch A as repo-main, index branch B as repo-feature, then diff.2 paramsDiff symbol sets between two indexed snapshots. Shows added, removed, and changed symbols. Branch workflow: index branch A as repo-main, index branch B as repo-feature, then diff.
repo_a*stringrepo_b*stringget_class_hierarchyGet the full inheritance hierarchy for a class: ancestors (base classes via extends/implements) and descendants (subclasses/implementors). Works across Python, Java, TypeScript, C#, and any language where class signatures contain 'extends' or 'implements'.2 paramsGet the full inheritance hierarchy for a class: ancestors (base classes via extends/implements) and descendants (subclasses/implementors). Works across Python, Java, TypeScript, C#, and any language where class signatures contain 'extends' or 'implements'.
repo*stringclass_name*stringget_related_symbolsFind symbols related to a given symbol using heuristic clustering: same-file co-location (weight 3), shared importers (weight 1.5), and name-token overlap (weight 0.5/token). Useful for discovering what else to read when exploring an unfamiliar codebase.3 paramsFind symbols related to a given symbol using heuristic clustering: same-file co-location (weight 3), shared importers (weight 1.5), and name-token overlap (weight 0.5/token). Useful for discovering what else to read when exploring an unfamiliar codebase.
repo*stringsymbol_id*stringmax_resultsintegersuggest_queriesSuggest search queries, entry-point files, and index stats. Good first call on an unfamiliar repo — surfaces most-imported files, top keywords, and ready-to-run example queries.1 paramsSuggest search queries, entry-point files, and index stats. Good first call on an unfamiliar repo — surfaces most-imported files, top keywords, and ready-to-run example queries.
repo*stringget_blast_radiusFind all files affected by changing a symbol. Returns confirmed files (import + name match) and potential files (import only, e.g. wildcard). Use before renaming or deleting a symbol. Set cross_repo=true to also find consumers in other indexed repos. Set include_source=true to...10 paramsFind all files affected by changing a symbol. Returns confirmed files (import + name match) and potential files (import only, e.g. wildcard). Use before renaming or deleting a symbol. Set cross_repo=true to also find consumers in other indexed repos. Set include_source=true to...
fqnstringrepo*stringdepthintegersymbol*stringcall_depthintegercross_repobooleansource_budgetintegerinclude_sourcebooleandecorator_filterstringinclude_depth_scoresbooleanget_call_hierarchyReturn incoming callers and outgoing callees for a symbol, N levels deep. Uses AST-derived call detection: callers = symbols in importing files that mention this name; callees = imported symbols mentioned in this symbol's body. Useful for understanding how a symbol fits into t...4 paramsReturn incoming callers and outgoing callees for a symbol, N levels deep. Uses AST-derived call detection: callers = symbols in importing files that mention this name; callees = imported symbols mentioned in this symbol's body. Useful for understanding how a symbol fits into t...
repo*stringdepthintegerdirectionstringcallers · callees · bothdefault: bothsymbol_id*stringget_impact_previewShow what breaks if a symbol is removed or renamed. Walks the call graph transitively to find every symbol that calls this one, returning affected symbols grouped by file with call-chain paths. Use this before deleting or renaming a symbol to understand full impact. For a stru...2 paramsShow what breaks if a symbol is removed or renamed. Walks the call graph transitively to find every symbol that calls this one, returning affected symbols grouped by file with call-chain paths. Use this before deleting or renaming a symbol to understand full impact. For a stru...
repo*stringsymbol_id*stringget_symbol_provenanceTrace the complete authorship lineage and evolution narrative of a symbol through git history. Returns every commit that touched the symbol (or its file), classified into semantic categories (creation, bugfix, refactor, feature, perf, rename, revert, etc.) with extracted commi...3 paramsTrace the complete authorship lineage and evolution narrative of a symbol through git history. Returns every commit that touched the symbol (or its file), classified into semantic categories (creation, bugfix, refactor, feature, perf, rename, revert, etc.) with extracted commi...
repo*stringsymbol*stringmax_commitsintegerget_pr_risk_profileProduce a unified risk assessment for all changes between two git refs (branch, PR, or SHA range). Fuses five signals — blast radius, complexity, churn, test gaps, and change volume — into a single composite risk_score (0.0–1.0) with actionable recommendations. Returns the top...4 paramsProduce a unified risk assessment for all changes between two git refs (branch, PR, or SHA range). Fuses five signals — blast radius, complexity, churn, test gaps, and change volume — into a single composite risk_score (0.0–1.0) with actionable recommendations. Returns the top...
daysintegerrepo*stringbase_refstringhead_refstringget_dependency_cyclesDetect circular import chains in a repository. Returns every strongly-connected component (set of files that mutually import each other, directly or transitively). Run this to identify architectural problems before a refactor, or to understand why a module is hard to test in i...1 paramsDetect circular import chains in a repository. Returns every strongly-connected component (set of files that mutually import each other, directly or transitively). Run this to identify architectural problems before a refactor, or to understand why a module is hard to test in i...
repo*stringget_coupling_metricsReturn afferent coupling (Ca), efferent coupling (Ce), and instability score for a file/module. Ca = files that import this module (dependents). Ce = files this module imports (dependencies). Instability I = Ce/(Ca+Ce): 0 = stable, 1 = unstable. Use to identify fragile modules...2 paramsReturn afferent coupling (Ca), efferent coupling (Ce), and instability score for a file/module. Ca = files that import this module (dependents). Ce = files this module imports (dependencies). Instability I = Ce/(Ca+Ce): 0 = stable, 1 = unstable. Use to identify fragile modules...
repo*stringmodule_path*stringget_layer_violationsCheck whether imports respect declared architectural layer boundaries. Reports every import that crosses a forbidden layer boundary. Layer rules can be passed directly or defined in .jcodemunch.jsonc under 'architecture.layers'. Use to enforce clean architecture and detect dep...2 paramsCheck whether imports respect declared architectural layer boundaries. Reports every import that crosses a forbidden layer boundary. Layer rules can be passed directly or defined in .jcodemunch.jsonc under 'architecture.layers'. Use to enforce clean architecture and detect dep...
repo*stringrulesarraycheck_rename_safeCheck whether renaming a symbol to a new name would cause name collisions. Scans the symbol's own file and every file that imports it, looking for an existing symbol with the proposed new name. Returns safe=true when no collisions are found. Run this before any rename/refactor...3 paramsCheck whether renaming a symbol to a new name would cause name collisions. Scans the symbol's own file and every file that imports it, looking for an existing symbol with the proposed new name. Returns safe=true when no collisions are found. Run this before any rename/refactor...
repo*stringnew_name*stringsymbol_id*stringcheck_delete_safeComposite preflight: can this symbol be deleted safely? Combines find_importers (cross-repo), check_references, find_dead_code confidence, runtime evidence (Phase 7 traces when available), and entry-point heuristics into a single verdict + one-line recommended_action. Verdict...4 paramsComposite preflight: can this symbol be deleted safely? Combines find_importers (cross-repo), check_references, find_dead_code confidence, runtime evidence (Phase 7 traces when available), and entry-point heuristics into a single verdict + one-line recommended_action. Verdict...
repo*stringsymbol*stringcross_repobooleaninclude_runtimebooleanfind_implementationsFind concrete implementations of an interface, abstract class, or method. Multi-source resolution with confidence scoring: LSP dispatch (1.0), AST class hierarchy (0.85), duck-typed name match (0.65), decorator handler (0.45). Classifies each impl (subclass_override / interfac...8 paramsFind concrete implementations of an interface, abstract class, or method. Multi-source resolution with confidence scoring: LSP dispatch (1.0), AST class hierarchy (0.85), duck-typed name match (0.65), decorator handler (0.45). Classifies each impl (subclass_override / interfac...
repo*stringsymbol*stringcross_repobooleanmax_resultsintegertoken_budgetintegerinclude_subclassesbooleanrank_by_importancebooleanrelationship_kindsarrayplan_refactoringGenerate edit-ready refactoring instructions for renaming, moving, extracting, or changing the signature of a symbol. Returns {old_text, new_text} blocks for every affected file — directly compatible with Edit tool. Handles import rewrites, collision detection, new file genera...7 paramsGenerate edit-ready refactoring instructions for renaming, moving, extracting, or changing the signature of a symbol. Returns {old_text, new_text} blocks for every affected file — directly compatible with Edit tool. Handles import rewrites, collision detection, new file genera...
repo*stringdepthintegersymbol*stringnew_filestringnew_namestringnew_signaturestringrefactor_type*stringrename · move · extract · signatureget_dead_code_v2Find likely-dead functions and methods using three independent evidence signals: (1) the symbol's file is not reachable from any entry point via the import graph (filename heuristic + package.json main/module/exports/bin), (2) no indexed symbol calls this symbol in the call gr...5 paramsFind likely-dead functions and methods using three independent evidence signals: (1) the symbol's file is not reachable from any entry point via the import graph (filename heuristic + package.json main/module/exports/bin), (2) no indexed symbol calls this symbol in the call gr...
repo*stringmax_resultsintegerfile_patternstringinclude_testsbooleanmin_confidencenumberget_extraction_candidatesIdentify functions in a file that are good candidates for extraction to a shared module. A candidate must have high cyclomatic complexity (doing a lot) AND be called from multiple other files (already implicitly shared). Results are ranked by score = complexity × caller_file_c...4 paramsIdentify functions in a file that are good candidates for extraction to a shared module. A candidate must have high cyclomatic complexity (doing a lot) AND be called from multiple other files (already implicitly shared). Results are ranked by score = complexity × caller_file_c...
repo*stringfile_path*stringmin_callersintegermin_complexityintegerget_symbol_complexityReturn cyclomatic complexity, nesting depth, and parameter count for a single symbol. Complexity data is stored at index time (requires jcodemunch-mcp >= 1.16 / INDEX_VERSION 7). assessment field: 'low' (1-4), 'medium' (5-10), 'high' (11+). Re-index the repo if all metrics sho...2 paramsReturn cyclomatic complexity, nesting depth, and parameter count for a single symbol. Complexity data is stored at index time (requires jcodemunch-mcp >= 1.16 / INDEX_VERSION 7). assessment field: 'low' (1-4), 'medium' (5-10), 'high' (11+). Re-index the repo if all metrics sho...
repo*stringsymbol_id*stringget_churn_rateReturn git churn metrics for a file or symbol: commit count, unique authors, first_seen date, last_modified date, and churn_per_week over a configurable window. assessment: 'stable' (<=1/week), 'active' (<=3/week), 'volatile' (>3/week). Requires a locally indexed repo (index_f...3 paramsReturn git churn metrics for a file or symbol: commit count, unique authors, first_seen date, last_modified date, and churn_per_week over a configurable window. assessment: 'stable' (<=1/week), 'active' (<=3/week), 'volatile' (>3/week). Requires a locally indexed repo (index_f...
daysintegerrepo*stringtarget*stringget_hotspotsReturn the top-N highest-risk symbols ranked by hotspot score = cyclomatic_complexity x log(1 + commits_last_N_days). Identifies code that is both complex and frequently changed — the highest bug-introduction risk in the codebase. Methodology matches CodeScene/Adam Tornhill. R...4 paramsReturn the top-N highest-risk symbols ranked by hotspot score = cyclomatic_complexity x log(1 + commits_last_N_days). Identifies code that is both complex and frequently changed — the highest bug-introduction risk in the codebase. Methodology matches CodeScene/Adam Tornhill. R...
daysintegerrepo*stringtop_nintegermin_complexityintegerget_repo_healthReturn a one-call triage snapshot of the entire repository: symbol counts, dead code %, average cyclomatic complexity, top 5 hotspots, dependency cycle count, and unstable module count. Designed to be the first tool called in any new session — one call gives a complete picture...2 paramsReturn a one-call triage snapshot of the entire repository: symbol counts, dead code %, average cyclomatic complexity, top 5 hotspots, dependency cycle count, and unstable module count. Designed to be the first tool called in any new session — one call gives a complete picture...
daysintegerrepo*stringget_untested_symbolsFind functions and methods with no evidence of being exercised by any test file. Uses import-graph reachability + name matching (AST call_references when available, word-boundary text heuristic as fallback). Returns symbols classified as 'unreached' (no test file imports the s...4 paramsFind functions and methods with no evidence of being exercised by any test file. Uses import-graph reachability + name matching (AST call_references when available, word-boundary text heuristic as fallback). Returns symbols classified as 'unreached' (no test file imports the s...
repo*stringmax_resultsintegerfile_patternstringmin_confidencenumbersearch_astCross-language AST pattern matching. Finds structural code patterns across all 70+ indexed languages using a single query — no need to know language-specific AST node types. Two modes: (1) preset anti-patterns (empty_catch, bare_except, deeply_nested, nested_loops, god_functio...6 paramsCross-language AST pattern matching. Finds structural code patterns across all 70+ indexed languages using a single query — no need to know language-specific AST node types. Two modes: (1) preset anti-patterns (empty_catch, bare_except, deeply_nested, nested_loops, god_functio...
repo*stringpatternstringcategorystringlanguagestringmax_resultsintegerfile_patternstringget_symbol_importanceReturn the most architecturally important symbols in a repo, ranked by PageRank or in-degree centrality on the import graph. Useful for orientation: surfaces the symbols that most of the codebase depends on. New tool: use after indexing to understand repo architecture at a gla...4 paramsReturn the most architecturally important symbols in a repo, ranked by PageRank or in-degree centrality on the import graph. Useful for orientation: surfaces the symbols that most of the codebase depends on. New tool: use after indexing to understand repo architecture at a gla...
repo*stringscopestringtop_nintegeralgorithmstringpagerank · degreedefault: pagerankfind_similar_symbolsFind clusters of similar functions/methods/classes — consolidation candidates. Blends three signals: semantic (embedding cosine when embed_repo has run), structural (signature-token Jaccard + size ratio), and behavioral (callee-set Jaccard). Runs union-find clustering, classif...9 paramsFind clusters of similar functions/methods/classes — consolidation candidates. Blends three signals: semantic (embedding cosine when embed_repo has run), structural (signature-token Jaccard + size ratio), and behavioral (callee-set Jaccard). Runs union-find clustering, classif...
repo*stringscopestringmin_sizeintegerthresholdnumbermax_clustersintegertoken_budgetintegerinclude_kindsarrayinclude_testsbooleansemantic_weightnumberget_repo_mapQuery-less, token-budgeted, signature-level overview of a repository. Groups symbols by file, ranks files by PageRank on the import graph, and greedy-packs signatures (not bodies) under token_budget. Designed for cold-start orientation — 'I just cloned this repo, what matters...5 paramsQuery-less, token-budgeted, signature-level overview of a repository. Groups symbols by file, ranks files by PageRank on the import graph, and greedy-packs signatures (not bodies) under token_budget. Designed for cold-start orientation — 'I just cloned this repo, what matters...
repo*stringscopestringmax_per_fileintegertoken_budgetintegerinclude_kindsarrayfind_dead_codeFind dead code — files and symbols with zero importers and no entry-point role. Uses the import graph to identify unreachable code. Returns confidence scores (1.0 = provably unreachable, 0.7 = all importers are themselves dead). Set granularity='file' for file-level results only.5 paramsFind dead code — files and symbols with zero importers and no entry-point role. Uses the import graph to identify unreachable code. Returns confidence scores (1.0 = provably unreachable, 0.7 = all importers are themselves dead). Set granularity='file' for file-level results only.
repo*stringgranularitystringsymbol · filedefault: symbolinclude_testsbooleanmin_confidencenumberentry_point_patternsarrayget_ranked_contextAssemble the best-fit context for a query within a token budget. Ranks all symbols by relevance (BM25) and/or centrality (PageRank), loads source for the top candidates, and packs greedily until token_budget is exhausted. Use when you want 'the best N tokens of context for thi...7 paramsAssemble the best-fit context for a query within a token budget. Ranks all symbols by relevance (BM25) and/or centrality (PageRank), loads source for the top candidates, and packs greedily until token_budget is exhausted. Use when you want 'the best N tokens of context for thi...
repo*stringquery*stringscopestringfusionbooleanstrategystringcombined · bm25 · centralitydefault: combinedtoken_budgetintegerinclude_kindsarrayassemble_task_contextTask-aware single-call orchestrator. Auto-classifies task into explore/debug/refactor/extend/audit/review intent, runs the right sub-tools, returns one source-attributed capsule under token_budget.7 paramsTask-aware single-call orchestrator. Auto-classifies task into explore/debug/refactor/extend/audit/review intent, runs the right sub-tools, returns one source-attributed capsule under token_budget.
repo*stringtask*stringintentstringexplore · debug · refactor · extend · audit · reviewincludearraysymbolsarraycross_repobooleantoken_budgetintegerget_changed_symbolsMap a git diff to affected symbols: given two commits, returns which symbols were added, removed, modified, or renamed. Useful after merging a PR to answer 'what actually changed?' for code review or regression triage. Requires a locally indexed repo (index_folder). Defaults t...5 paramsMap a git diff to affected symbols: given two commits, returns which symbols were added, removed, modified, or renamed. Useful after merging a PR to answer 'what actually changed?' for code review or regression triage. Requires a locally indexed repo (index_folder). Defaults t...
repo*stringsince_shastringuntil_shastringmax_blast_depthintegerinclude_blast_radiusbooleanembed_repoPrecompute and cache symbol embeddings for semantic search. Optional warm-up: search_symbols with semantic=true lazily embeds missing symbols on first use, but embed_repo warms the cache upfront so the first semantic query returns immediately. Requires an embedding provider (J...3 paramsPrecompute and cache symbol embeddings for semantic search. Optional warm-up: search_symbols with semantic=true lazily embeds missing symbols on first use, but embed_repo warms the cache upfront so the first semantic query returns immediately. Requires an embedding provider (J...
repo*stringforcebooleanbatch_sizeintegerget_cross_repo_mapReturn which indexed repos depend on which other indexed repos at the package level. Shows the full cross-repository dependency map based on package names extracted from manifest files (pyproject.toml, package.json, go.mod, Cargo.toml, etc.). Use to visualize how your indexed...1 paramsReturn which indexed repos depend on which other indexed repos at the package level. Shows the full cross-repository dependency map based on package names extracted from manifest files (pyproject.toml, package.json, go.mod, Cargo.toml, etc.). Use to visualize how your indexed...
repostringget_group_contractsSurface the de-facto API contracts across a group of indexed repos. Walks each member's named imports, resolves them to symbols in other members via the package registry, and classifies each shared symbol into one of four verdict tiers: 'de_facto_api' (used by ≥min_importers e...8 paramsSurface the de-facto API contracts across a group of indexed repos. Walks each member's named imports, resolves them to symbols in other members via the package registry, and classifies each shared symbol into one of four verdict tiers: 'de_facto_api' (used by ≥min_importers e...
repos*arrayclassifybooleanchurn_daysintegertoken_budgetintegermax_contractsintegermin_importersintegerinclude_internalbooleaninclude_dead_contractsbooleanget_tectonic_mapDiscover the logical module topology of a codebase by fusing three coupling signals: structural (import edges), behavioral (shared symbol references), and temporal (git co-churn). Returns tectonic plates (auto-detected file clusters), each with an anchor file, cohesion score,...3 paramsDiscover the logical module topology of a codebase by fusing three coupling signals: structural (import edges), behavioral (shared symbol references), and temporal (git co-churn). Returns tectonic plates (auto-detected file clusters), each with an anchor file, cohesion score,...
daysintegerrepo*stringmin_plate_sizeintegerget_signal_chainsDiscover how external signals (HTTP requests, CLI commands, scheduled tasks, events) propagate through the codebase via the call graph. Each signal chain traces a path from a gateway (entry point) through its callees to leaf symbols. Two modes: (1) Discovery — omit symbol to m...5 paramsDiscover how external signals (HTTP requests, CLI commands, scheduled tasks, events) propagate through the codebase via the call graph. Each signal chain traces a path from a gateway (entry point) through its callees to leaf symbols. Two modes: (1) Discovery — omit symbol to m...
kindstringhttp · cli · event · task · main · testrepo*stringsymbolstringmax_depthintegerinclude_testsbooleanrender_diagramRender any graph-producing tool's output as rich, annotated Mermaid markup. Pass the raw output dict from get_call_hierarchy, get_signal_chains, get_tectonic_map, get_dependency_cycles, get_impact_preview, get_blast_radius, or get_dependency_graph. Auto-detects the source tool...3 paramsRender any graph-producing tool's output as rich, annotated Mermaid markup. Pass the raw output dict from get_call_hierarchy, get_signal_chains, get_tectonic_map, get_dependency_cycles, get_impact_preview, get_blast_radius, or get_dependency_graph. Auto-detects the source tool...
themestringflow · risk · minimaldefault: flowsource*objectmax_nodesintegerget_project_intelAuto-discover and parse non-code knowledge files (Dockerfiles, CI configs, docker-compose, K8s manifests, .env templates, Makefiles, package.json scripts) and cross-reference them to indexed code symbols. Returns structured intelligence grouped by category: infra, ci, config,...3 paramsAuto-discover and parse non-code knowledge files (Dockerfiles, CI configs, docker-compose, K8s manifests, .env templates, Makefiles, package.json scripts) and cross-reference them to indexed code symbols. Returns structured intelligence grouped by category: infra, ci, config,...
repo*stringcategorystringall · infra · ci · config · deps · apidefault: allscope_pathstringlist_workspacesEnumerate monorepo workspace members for an indexed repo. Detects pnpm (pnpm-workspace.yaml), yarn/npm (package.json workspaces), turborepo (turbo.json), lerna (lerna.json), rush (rush.json), Go (go.work), and Cargo ([workspace] members). Returns [{path, package_name, manager}...1 paramsEnumerate monorepo workspace members for an indexed repo. Detects pnpm (pnpm-workspace.yaml), yarn/npm (package.json workspaces), turborepo (turbo.json), lerna (lerna.json), rush (rush.json), Go (go.work), and Cargo ([workspace] members). Returns [{path, package_name, manager}...
repo*stringwinnow_symbolsRun a multi-axis constraint query against the index in a single round trip. Accepts an ordered list of criteria (AND) intersecting signals no other tool composes: kind, language, name (regex), file glob, cyclomatic complexity, decorator, direct call references, summary/docstri...5 paramsRun a multi-axis constraint query against the index in a single round trip. Accepts an ordered list of criteria (AND) intersecting signals no other tool composes: kind, language, name (regex), file glob, cyclomatic complexity, decorator, direct call references, summary/docstri...
repo*stringorderstringasc · descdefault: descrank_bystringimportance · complexity · churn · namedefault: importancecriteria*arraymax_resultsintegerset_tool_tierExplicit tier override for the current session. Narrows or widens the exposed tool list to 'core' / 'standard' / 'full'. Prefer plan_turn(model=...) for routine per-task use; use set_tool_tier only when you need an explicit override (e.g. escalate mid-task to 'full' after a ca...1 paramsExplicit tier override for the current session. Narrows or widens the exposed tool list to 'core' / 'standard' / 'full'. Prefer plan_turn(model=...) for routine per-task use; use set_tool_tier only when you need an explicit override (e.g. escalate mid-task to 'full' after a ca...
tier*stringcore · standard · fullannounce_modelAgent self-reports its active model identifier. Server resolves to a tier via model_tier_map (fuzzy: normalize → exact → glob → substring → '*' → 'full') and narrows the exposed tool list accordingly. Idempotent: a second call with the same model is a cheap no-op. Prefer calli...1 paramsAgent self-reports its active model identifier. Server resolves to a tier via model_tier_map (fuzzy: normalize → exact → glob → substring → '*' → 'full') and narrows the exposed tool list accordingly. Idempotent: a second call with the same model is a cheap no-op. Prefer calli...
model*stringThe leading, most token-efficient MCP server for precise GitHub source code retrieval via tree-sitter AST parsing. Cut AI token costs 95%+ on code exploration — stop burning your context window reading entire files.
Real results, live from production 313B+ tokens saved · 45,000+ developers · $1.58M+ in AI spend avoided · 37,500+ kg CO₂ prevented Live telemetry at jcodemunch.com — benchmark: 95% average token reduction (15 tasks / 3 repos, 99.8% peak).
Works with Claude Code, Cursor, VS Code, Codex CLI, Continue, Windsurf, and any MCP-compatible client.
Prefer the command line?
pip install jcodemunch-mcp
uvx jcodemunch-mcp
For pinned/B2B deployments that want a version-stable install channel independent of PyPI, install straight from the repo (requires git, builds from source):
pip install git+https://github.com/jgravelle/jcodemunch-mcp.git
uvx --from git+https://github.com/jgravelle/jcodemunch-mcp.git jcodemunch-mcp
Quickstart - https://github.com/jgravelle/jcodemunch-mcp/blob/main/QUICKSTART.md
A crapload of detailed info: http://jcodemunch.com/
Live OSS code-health observatory — weekly six-axis health snapshots of Express, FastAPI, Gin, Pydantic, Django, Flask, NestJS, Cobra, and this very repo: https://jgravelle.github.io/jcodemunch-observatory/
Token Cost Radar — daily intelligence on AI token costs, minimization strategies, and budget trends for teams running Claude Code / Cursor / MCP: https://jcodemunch.com/radar/
Use it to make money, and Uncle J. gets a taste. Fair enough? details
Our guarantee: If jCodeMunch doesn't pay for itself, you don't pay for jCodeMunch!
Most AI agents explore repositories the expensive way:
open entire files → skim thousands of irrelevant lines → repeat.
That is not “a little inefficient.” That is a token incinerator.
jCodeMunch indexes a codebase once and lets agents retrieve only the exact code they need: functions, classes, methods, constants, outlines, and tightly scoped context bundles, with byte-level precision.
In retrieval-heavy workflows, that routinely cuts code-reading token usage by 95%+ because the agent stops brute-reading giant files just to find one useful implementation.
| Task | Traditional approach | With jCodeMunch |
|---|---|---|
| Find a function | Open and scan large files | Search symbol → fetch exact implementation |
| Understand a module | Read broad file regions | Pull only relevant symbols and imports |
| Explore repo structure | Traverse file after file | Query outlines, trees, and targeted bundles |
Index once. Query cheaply. Keep moving. Precision context beats brute-force context.
| Doc | What it covers |
|---|---|
| QUICKSTART.md | Zero-to-indexed in three steps |
| USER_GUIDE.md | Full tool reference, workflows, and best practices |
| AGENT_HOOKS.md | Agent hooks and prompt policies |
| CONFIGURATION.md | JSONC config file reference, migration from env vars |
| GROQ.md | Groq Remote MCP integration, deployment, gcm CLI |
| HEADLESS.md | Using jCodeMunch with claude -p (and the jragmunch CLI) |
| ARCHITECTURE.md | Internal design, storage model, and extension points |
| LANGUAGE_SUPPORT.md | Supported languages and parsing details |
| CONTEXT_PROVIDERS.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. |
Retrieval decides what to send. MUNCH decides how to pack it.
Every tool response can be emitted in a purpose-built compact wire format instead of verbose JSON. Path prefixes are interned to short handles, homogeneous lists of dicts pack into single-character-tagged CSV rows, and per-column types are preserved so the decode is lossless.
# any tool call accepts format=
find_references(identifier="get_user", format="auto")
# auto — emit compact if savings ≥ 15%, otherwise JSON
# compact — always compact
# json — never compact (back-compat passthrough)
Benchmark (v1.56.0): median 45.5% bytes saved across 6 representative tools, peaks at 55.4% on graph and outline responses. Full spec in SPEC_MUNCH.md; numbers and harness in TOKEN_SAVINGS.md.
Encoding savings stack on top of retrieval savings — every byte off the wire is a byte the agent doesn't pay to read.
Commercial licenses
jCodeMunch-MCP is free for non-commercial use.
Commercial use requires a paid license.
jCodeMunch-only licenses
- Builder — $79 — 1 developer
- Studio — $349 — up to 5 developers
- Platform — $1,999 — org-wide internal deployment
Want the full jMunch suite (code + docs + data)?
Stop paying your model to read the whole damn file.
jCodeMunch turns repo exploration into structured retrieval.
Instead of forcing an agent to open giant files, wade through imports, boilerplate, comments, helpers, and unrelated code, jCodeMunch lets it navigate by what the code is and retrieve only what matters.
That means:
It indexes your codebase once using tree-sitter, stores structured symbol metadata plus byte offsets into the original source, and retrieves exact implementations on demand instead of re-reading entire files over and over.
Recent releases have made that retrieval workflow sharper and more useful in real engineering work, with BM25-based symbol search, fuzzy matching, semantic/hybrid search (opt-in, zero mandatory dependencies), query-driven token-budgeted context assembly (get_ranked_context), dead code detection (find_dead_code), untested symbol detection (get_untested_symbols), git-diff-to-symbol mapping (get_changed_symbols), architectural centrality ranking (get_symbol_importance, PageRank), cold-start orientation maps (get_repo_map — query-less, token-budgeted, signature-only repo overview ranked by PageRank), consolidation candidate detection (find_similar_symbols — multi-signal duplicate finder blending semantic embeddings, structural signature, and behavioral callee Jaccard; union-find clustering with verdict tiers and PageRank-based canonical-pick), cross-repo API contract surfacing (get_group_contracts — group of indexed repos in, ranked shared-symbol contracts out, each classified as de_facto_api / leaky_internal / dead_contract / version_skew with stability + breaking-change history + runtime hits), concrete-implementation discovery (find_implementations — multi-source resolution across LSP dispatch / class hierarchy / duck-typed / decorator-handler with confidence scoring), deletion preflight (check_delete_safe — composite verdict from importers + references + dead-code + runtime evidence + entry-point heuristics, with ranked blockers and recommended action), edit-safety preflight (check_edit_safe — the companion that answers "can I modify this," fusing signature impact, cyclomatic complexity, test-coverage presence, and runtime traffic into a verdict + recommended action), task-aware single-call context orchestration (assemble_task_context — natural-language task in, source-attributed context capsule out; auto-classifies into one of six intents with explainable keyword matching, auto-extracts anchor symbols from the task, runs the intent-appropriate sub-tool sequence end-to-end under one token budget), blast-radius depth scoring with source snippets, context bundles with token budgets, AST-derived call graphs and call hierarchy traversal, decorator-aware search and filtering, hotspot detection (complexity x churn), dependency cycles and coupling metrics, session-aware routing (plan_turn, turn budgets, negative evidence), agent config auditing, complexity-based model routing (Agent Selector), enforcement hooks (PreToolUse/PostToolUse/PreCompact), dependency graphs, class hierarchy traversal, multi-symbol bundles, live watch-based reindexing, automatic Claude Code worktree discovery (watch-claude), registry-wide auto-reindexing with one-command login-service install (watch-all + watch-install / watch-uninstall / watch-status; also exposed as MCP tool get_watch_status), auto-watch on demand (when watch: true in config, the server automatically indexes and watches any repo a tool is called against — ensuring fresh results from the first call), trusted-folder access controls, edit-ready refactoring plans (plan_refactoring) for rename, move, extract, and signature change operations, symbol provenance archaeology (get_symbol_provenance — full git lineage, semantic commit classification, evolution narrative), unified PR risk profiling (get_pr_risk_profile — composite risk score fusing blast radius, complexity, churn, test gaps, and volume), automatic response secret redaction (AWS/GCP/Azure/JWT/GitHub tokens scrubbed before reaching the LLM context window), and cross-language AST pattern matching (search_ast — 10 preset anti-pattern detectors + custom mini-DSL for structural queries like call:*.unwrap, string:/password/i, nesting:5+; works across all 70+ languages with universal node-type mapping).
Measured with tiktoken cl100k_base across three public repos. Workflow: search_symbols (top 5) + get_symbol_source × 3 per query. Baseline: all source files concatenated (minimum cost for an agent that reads everything). Full methodology and harness →
| Repository | Files | Symbols | Baseline tokens | jCodeMunch tokens | Reduction |
|---|---|---|---|---|---|
| expressjs/express | 34 | 117 | 73,838 | ~1,300 avg | 98.4% |
| fastapi/fastapi | 156 | 1,359 | 214,312 | ~15,600 avg | 92.7% |
| gin-gonic/gin | 40 | 805 | 84,892 | ~1,730 avg | 98.0% |
| Grand total (15 task-runs) | 1,865,210 | 92,515 | 95.0% |
Per-query results range from 79.7% (dense FastAPI router query) to 99.8% (sparse context-bind query on Express). The 95% figure is the aggregate. Run python benchmarks/harness/run_benchmark.py to reproduce.
Independent 50-iteration A/B test on a real Vue 3 + Firebase production codebase — JCodeMunch vs native tools (Grep/Glob/Read), Claude Sonnet 4.6, fresh session per iteration:
| Metric | Native | JCodeMunch |
|---|---|---|
| Success rate | 72% | 80% |
| Timeout rate | 40% | 32% |
| Mean cost/iteration | $0.783 | $0.738 |
| Mean cache creation | 104,135 | 93,178 (−10.5%) |
Tool-layer savings isolated from fixed overhead: 15–25%. One finding category appeared exclusively in the JCodeMunch variant: orphaned file detection via find_importers — a structural query native tools cannot answer without scripting.
Full report: benchmarks/ab-test-naming-audit-2026-03-18.md
Most agents still inspect codebases like tourists trapped in an airport gift shop:
jCodeMunch fixes that by giving them a structured way to:
plan_turn — confidence-guided routing before the first readassemble_task_context — intent-classified, multi-tool, single token budgetAgents do not need bigger and bigger context windows.
They need better aim.
Find and fetch functions, classes, methods, constants, and more without opening entire files.
Inspect repository structure and file outlines before asking for source.
Send the model the code it needs, not 1,500 lines of collateral damage.
The retrieval primitives below are not a disconnected bag of tools the agent has to wire together by hand. Two composition tools drive the rest:
assemble_task_context takes a natural-language task and returns a single source-attributed context capsule under a token budget. It auto-classifies the task into one of six intents (explore / debug / refactor / extend / audit / review), auto-extracts the anchor symbols, and runs the intent-appropriate sequence of the tools below end-to-end — so the agent gets the whole context for a task in one request instead of chaining five. Every entry is tagged with its stage and source_tool, so the provenance is auditable.plan_turn is the opening move: it analyzes the query against the index and returns a confidence-guided route — which tools to call, on which symbols, under a turn budget — before the first read. Low confidence means "this probably doesn't exist," so the agent stops instead of burning a budget hunting for a feature that isn't there.get_ranked_context packs the most relevant symbols for a query into a fixed token budget (BM25 + PageRank), when you want a ranked context pack rather than a full intent sequence.The point: jCodeMunch is structured retrieval with an orchestration layer over it, not a pile of primitives. The composition tools run the right sub-tools, in the right order, under one budget, in one call.
find_importers tells you what imports a file. get_blast_radius tells you what breaks if you change a symbol, with depth-weighted risk scores and optional source snippets. get_class_hierarchy traverses inheritance chains. get_call_hierarchy traces callers and callees N levels deep using AST-derived call graphs, with optional LSP-enriched dispatch resolution for interface/trait method calls. find_dead_code finds symbols and files unreachable from any entry point. get_untested_symbols finds functions with no evidence of test-file reachability — the intersection of import-graph analysis and test-file detection. get_changed_symbols maps a git diff to the exact symbols that were added, modified, or removed. get_symbol_importance ranks your codebase by architectural centrality using PageRank on the import graph. get_hotspots surfaces the riskiest code by combining complexity with git churn. get_dependency_cycles detects circular imports. get_coupling_metrics measures module coupling and instability. get_tectonic_map discovers the logical module topology by fusing three coupling signals (imports, shared references, git co-churn) — revealing hidden module boundaries, misplaced files, and god-module risk without any configuration. get_signal_chains traces how external signals (HTTP requests, CLI commands, scheduled tasks, events) propagate through the codebase via the call graph — discovery mode maps all entry-point-to-leaf pathways and reports orphan symbols, lookup mode tells you which user-facing chains a specific symbol participates in (e.g. "validate_email sits on POST /api/users and cli:import-users"). These are not "faster grep" — they are questions grep cannot answer at all.
audit_agent_config scans your CLAUDE.md, .cursorrules, copilot-instructions.md, and other agent config files for token waste: per-file token cost, stale symbol references (cross-referenced against the index — catches renamed or deleted functions), dead file paths, redundancy between global and project configs, bloat, and scope leaks. No other tool can tell you "line 15 references a function that was renamed three weeks ago."
get_symbol_provenance is git archaeology: given a symbol, it traces every commit that touched it, classifies each into semantic categories (creation, bugfix, refactor, feature, perf, rename, revert), extracts commit intent, and generates a human-readable narrative explaining who created it, why, and how it evolved. get_pr_risk_profile produces a unified risk assessment for a branch or PR — one call fuses blast radius, complexity, churn, test gaps, and change volume into a composite risk score (0.0–1.0) with actionable recommendations. get_delivery_metrics quantifies durable-change delivery over a window: of the non-merge commits in the last N days, how many landed and stuck versus were reverted or re-touched (churn-back) within a short horizon — with churn-hub files (CHANGELOG, version, a monolithic dispatch module) excluded from the rework signal so a shared ledger can't masquerade as rework. The durable count is the honest numerator for a cost-per-outcome ratio: pair it with AI spend (the delivery CLI takes --cost) to show how much got done for how little, instead of rewarding raw activity. All responses are automatically scanned for leaked credentials (AWS keys, JWTs, GCP service accounts, etc.) and redacted before reaching the LLM.
search_ast brings structural code analysis to every language jCodeMunch indexes — write one query, match across all 70+ languages. Preset anti-patterns detect common problems without any configuration: empty_catch (silently swallowed errors), bare_except (catch-all handlers), deeply_nested (5+ control-flow levels), nested_loops (O(n³)+ performance risk), god_function (100+ line functions), eval_exec (injection-risk dynamic execution), hardcoded_secret (credential patterns in strings), todo_fixme (unfinished work markers), magic_number (unexplained numeric constants), and reassigned_param (overwritten function parameters). Run category='all' for a full sweep, or focus on security, error_handling, complexity, performance, or maintenance. Custom queries use a mini-DSL: call:*.unwrap (find method calls by glob), string:/password/i (regex over string literals), comment:/TODO/i (regex in comments), nesting:5+, loops:3+, lines:80+ (threshold queries). Every match is attributed to its enclosing indexed symbol with complexity metadata — so you can see not just where the problem is, but how bad the surrounding function already is.
winnow_symbols composes signals that every other tool exposes separately — kind, complexity, decorator, direct call references, file glob, name regex, git churn, and PageRank importance — into a single AND-intersected query. Agents stop making four or five calls and merging results by hand: "functions that call db.Exec, cyclomatic > 10, churned in the last 30 days, ranked by importance" resolves in one round trip. Supported axes expose their own operator set (eq, in, matches, contains, numeric comparisons); the window for churn-based filters is per-criterion. Results include per-symbol importance, complexity, and churn scores so the agent can explain why each survivor made the cut.
Useful for onboarding, debugging, refactoring, impact analysis, and exploring unfamiliar repos without brute-force file reading.
plan_refactoring generates exact edit-ready instructions for rename, move, extract, and
signature change operations. Returns {old_text, new_text} blocks compatible with any editor's
find-and-replace, plus import rewrites, collision detection, new file generation, and multi-file coordination.
Every retrieval result now ships with three machine-readable health signals so agents can stop guessing whether to trust the response:
_meta.confidence — calibrated 0–1 score combining top-1/top-2 score gap, top-1 strength, identity-match presence, and freshness. Lets an agent gate follow-up get_symbol_source calls on a single number._freshness ∈ {fresh, edited_uncommitted, stale_index} on every result entry, plus a _meta.freshness summary. Derived from index SHA vs git rev-parse HEAD and per-file mtime checks.p50/p95/max/error_rate) exposed via get_session_stats.latency_per_tool and the analyze_perf tool. Optional SQLite sink (~/.code-index/telemetry.db) for cross-session analysis.The tune_weights tool reads the persistent ranking ledger and learns per-repo retrieval weights (saved to ~/.code-index/tuning.jsonc). check_embedding_drift pins a 16-string canary to detect silent provider model changes. benchmarks/replay/ provides a CI-friendly retrieval-quality regression gate (nDCG/MRR/Recall) that every release runs against.
The suggest_corrections tool (and the reflect CLI) close the loop: they mine the same ranking ledger for retrieval regret — where retrieval failed and the agent had to re-ask — and return a prioritized, explainable set of suggested fixes (a CLAUDE.md routing or glossary line as a unified-diff preview, an index-freshness hint, a stale-config finding, a dry-run weight proposal). It is read-only by design: it suggests a patch and shows you the diff; applying it is your keystroke, never the server's. Requires perf_telemetry_enabled (it has a ledger to read only then) and returns an honest hint when off.
Indexes are stored locally for fast repeated access.
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.
Everything jCodeMunch does beyond answering a tool call is listed here. All of it is visible, opt-in or opt-out, and reversible.
watch / watch-all / watch-claude commands (and watch: true in config) re-index files when they change. Watching runs inside a process you started and stops when that process exits. Nothing monitors your filesystem unless a jCodeMunch process you launched is running.jcodemunch-mcp watch-install registers watch-all as a login service (Windows Task Scheduler / macOS launchd / Linux systemd) so indexes stay fresh across reboots. This happens only when you run watch-install yourself; init, install, and normal server use never register a service. Inspect it with watch-status; remove it with watch-uninstall.share_savings: false in config.jsonc or JCODEMUNCH_SHARE_SAVINGS=0; redirect the endpoint with JCODEMUNCH_TELEMETRY_URL.init / install can write hook entries (auto-reindex on edit, read-interception nudges) into your MCP client's settings. They're offered during the interactive flow, shown before writing, and fully removed by uninstall.~/.code-index/ (override with CODE_INDEX_PATH). Delete the directory and every trace of indexing is gone._session_live.json in ~/.code-index/ recording the files and searches the agent touched this session (paths and query strings only, no file contents). It exists so the out-of-process PreCompact hook can restore session orientation after context compaction. Throttled, atomically written, overwritten in place; disable with JCODEMUNCH_LIVE_JOURNAL=0.The base package makes no other network calls and leaves no other persistent processes. AI-summary extras call their configured provider's API only when you enable them — see the extras matrix under Start fast.
Ubuntu 24.04+ / Debian 12+: System Python is externally managed (PEP 668). Use
pipx install jcodemunch-mcporuv tool install jcodemunch-mcpinstead of barepip install.
pip install jcodemunch-mcp
jcodemunch-mcp init
init auto-detects your MCP clients (Claude Code, Claude Desktop, Cursor, Windsurf, Continue), writes their config entries, installs the CLAUDE.md prompt policy so your agent actually uses jCodeMunch, optionally installs enforcement hooks (PreToolUse read guard + PostToolUse auto-reindex + PreCompact session snapshot), optionally indexes your project, and audits your agent config files for token waste. Run jcodemunch-mcp init --help for all flags.
Prefer a one-line CLAUDE.md? From v1.71.0 the server exposes a
jcodemunch_guidetool that returns the same policy snippetclaude-md --generateprints — with the running version embedded. Keep this single line in your CLAUDE.md / AGENT.md and the guide always matches the installed server:Call the jcodemunch_guide tool and strictly follow its instructions.The tool is force-included, so it can't be hidden by
disabled_toolsor tier filtering.
For non-interactive CI or scripting:
jcodemunch-mcp init --yes --claude-md global --hooks --index --audit
pip install jcodemunch-mcp
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.
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.
Pre-built indexes for popular frameworks and libraries. Skip the initial indexing step — install a pack and start querying immediately.
# List available packs
jcodemunch-mcp install-pack --list
# Install a free pack
jcodemunch-mcp install-pack fastapi
# Install a licensed pack
jcodemunch-mcp install-pack express --license YOUR-KEY
Free packs require no license. Licensed packs require a jCodeMunch license. Use --force to re-download an already-installed pack.
Use jCodeMunch as a remote MCP tool with Groq's ultra-fast inference — answer codebase questions in seconds with zero local setup.
from openai import OpenAI
client = OpenAI(api_key="YOUR_GROQ_KEY", base_url="https://api.groq.com/openai/v1")
response = client.responses.create(
model="llama-3.3-70b-versatile",
input="What does parse_file do in jgravelle/jcodemunch-mcp?",
tools=[{
"type": "mcp",
"server_label": "jcodemunch",
"server_url": "https://YOUR_JCODEMUNCH_URL",
"headers": {"Authorization": "Bearer YOUR_TOKEN"},
"server_description": "Code intelligence via tree-sitter AST parsing.",
"require_approval": "never",
}],
)
Groq handles MCP tool discovery and execution server-side — one API call, no orchestration needed.
Self-host with Docker + Caddy for auto-TLS:
DOMAIN=mcp.example.com JCODEMUNCH_HTTP_TOKEN=secret docker compose up -d
See GROQ.md for the full tutorial: allowed-tools presets, model recommendations, deployment options, and validation scripts.
Get a structured PR review in under 5 seconds:
# .github/workflows/speedreview.yml
- uses: jgravelle/jcodemunch-mcp/speedreview@v1.108.52
with:
groq_api_key: ${{ secrets.GROQ_API_KEY }}
For stricter supply-chain hygiene, pin to the tag's commit SHA instead of the
tag itself (git ls-remote https://github.com/jgravelle/jcodemunch-mcp refs/tags/v1.108.52).
The action installs pinned package versions by default and exposes
jcodemunch_version / openai_version inputs for override.
See speedreview/README.md for full setup and configuration.
Ask any question about any codebase. Get an answer in under 3 seconds.
pip install jcodemunch-mcp[groq]
export GROQ_API_KEY=gsk_...
# Ask about a GitHub repo (auto-indexes on first use)
gcm "how does authentication work?" --repo pallets/flask
# Ask about the current directory
gcm "where are the API routes defined?"
# Interactive chat mode
gcm --chat --repo facebook/react
# Use the fast 8B model
gcm "what does parse_file do?" --fast
Combines jCodeMunch's token-efficient retrieval (BM25 + PageRank) with Groq's 280+ tok/s inference for near-instant answers. See gcm --help for all options.
Speak a question, hear the answer. Full audio loop: Whisper STT → retrieval → LLM → Orpheus TTS.
pip install jcodemunch-mcp[groq-voice]
# Voice conversation with a codebase
gcm --voice --repo pallets/flask
# Press Enter to start recording, Enter again to stop
# Or type a question directly as text fallback
Push-to-talk via Enter key. Caps answers to ~100 words for natural spoken delivery. Requires a microphone.
Generate a narrated explainer video for any codebase in a single command.
pip install jcodemunch-mcp[groq-explain]
# Generate a 60-second narrated explainer
gcm explain --repo pallets/flask -o flask-explainer.mp4
# With verbose timing
gcm explain --repo facebook/react -v
Pipeline: repo structure → LLM narration script → Orpheus TTS → Pillow slides → FFmpeg MP4. Requires FFmpeg on PATH.
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)For the most token-sensitive setups, 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 and removes the "pick one of N" dispatch dilution.
Set it in config.jsonc (or the JCODEMUNCH_TOOL_SURFACE env var, which wins):
"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. Any other value (default full) leaves the existing behavior unchanged — the front-door tools stay hidden (still callable), so upgrading changes nothing until you opt in. The two mechanisms compose: under counter, order / route still reach every action regardless of the active core / standard / full tier.
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 | 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 |
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).
A common question: does this only help during exploration, or also when the agent is prompted to read a file before editing?
It helps most when editing a specific function. The "read before edit" constraint doesn't require reading the whole file — it requires reading the code. get_symbol_source gives you exactly the function body you're about to touch, nothing else. Instead of reading 700 lines to edit one method, you read those 30 lines.
| Scenario | Native tool | jCodemunch | Savings |
|---|---|---|---|
| Edit one function (700-line file) | Read → 700 lines | get_symbol_source → 30 lines | ~95% |
| Understand a file's structure | Read → full content | get_file_outline → names + signatures | ~80% |
| Find which file to edit | Grep many files | search_symbols → exact match | comparable |
| Edit requires whole-file context | Read → full content | get_file_content → full content | ~0% |
| "What breaks if I change X?" | not possible | get_blast_radius | unique capability |
The cases where it doesn't help: edits that genuinely require understanding the entire file (restructuring file-level state, reordering logic that spans hundreds of lines). For those, get_file_content is roughly equivalent to Read. The cases where it helps most are targeted edits — one function, one method, one class — which is the majority of real editing work.
Start with QUICKSTART.md for the fastest setup path.
Then index a repo, ask your agent what it has indexed, and have it retrieve code by symbol instead of reading entire files. That is where the savings start.
jCodeMunch is an MCP server — it plugs into every major agent and IDE that speaks MCP:
Claude Code · Claude Desktop · Cursor · Windsurf · Codex CLI · Continue · Cline · Roo Code · Zed · Goose · Hermes Agent · Paperclip — and more.
Tested configurations:
| Platform | Config |
|---|---|
| Claude Code / Claude Desktop | jcodemunch-mcp init (auto-detects and patches config) |
| Cursor / Windsurf / Continue | jcodemunch-mcp init or manual mcp.json |
| OpenAI Codex CLI | Add [mcp_servers.jcodemunch] block to ~/.codex/config.toml (see below) |
| Cline / Roo Code | Add via the MCP marketplace UI or paste command: uvx, args: ["jcodemunch-mcp"] |
| Zed | Add to settings.json under context_servers |
| Goose (Block) | goose configure → Add Extension → command uvx jcodemunch-mcp |
| Hermes Agent | Add to ~/.hermes/config.yaml — see skill |
| Paperclip | .mcp.json at workspace root (auto-detected) |
| Any other MCP client | stdio: jcodemunch-mcp, HTTP: jcodemunch-mcp serve --transport sse |
| VS Code (any MCP client) | Install the jCodeMunch VS Code extension for on-save auto-reindex under Copilot Chat / Continue / Cline — closes the staleness gap when the host doesn't fire PostToolUse hooks |
| GitHub Copilot CLI / cloud agent | jcodemunch-mcp init --copilot-hooks writes .github/hooks/hooks.json with a postToolUse rule for auto-reindex |
| Odysseus (self-hosted AI workspace) | SSE transport: run jcodemunch-mcp serve --transport sse on the host (token unset), register the URL in the MCP Registry (see below) — community-tested |
Recommended (pre-installed binary, no uvx). Codex's rmcp transport
is strict about the first JSON-RPC frame on stdout. uvx's install
chatter on first run can poison the handshake, which historically
manifests as a silent multi-hour hang. Install the package into a
project venv and point Codex at the resolved binary directly:
python3 -m venv .venv
.venv/bin/pip install -U jcodemunch-mcp
.venv/bin/jcodemunch-mcp --help # confirm the binary resolves
# ~/.codex/config.toml
[mcp_servers.jcodemunch]
command = "/absolute/path/to/.venv/bin/jcodemunch-mcp"
# (no args required)
If the handshake still doesn't complete, set
JCODEMUNCH_HANDSHAKE_TIMEOUT=5 (the default) and watch stderr — v1.82.1+
emits a one-line hint when the client doesn't call any handler within
the window.
Note for codex review --background and other non-interactive runs.
Codex's MCP elicitation/approval system can silently decline tool
calls to unrecognised servers in non-interactive mode (visible in
~/.codex/logs_2.sqlite as ResolveElicitation { decision: Decline }
with no chatter on the server side). This is a Codex-side concern, not
a jcodemunch one — track upstream
here for the right per-server
auto-approve key. Interactive codex runs are unaffected.
Legacy uvx config (kept for reference; works on tolerant clients,
not recommended for Codex):
[mcp_servers.jcodemunch]
command = "uvx"
args = ["jcodemunch-mcp"]
# ~/.hermes/config.yaml
mcp_servers:
jcodemunch:
command: "uvx"
args: ["jcodemunch-mcp"]
Odysseus runs in Docker and indexes nothing itself; jCodeMunch indexes your code on the host. Run jCodeMunch as an SSE server on the host and register its URL in Odysseus. Its SSE client connects by URL only (no auth header), so leave the token unset and secure the endpoint by network binding instead.
1. Start jCodeMunch on the host (no token):
jcodemunch-mcp index .
jcodemunch-mcp serve --transport sse --host 0.0.0.0 --port 8848
Leave JCODEMUNCH_HTTP_TOKEN unset — Odysseus's SSE client sends no
Authorization header, so a token returns 401 on connect.
2. In Odysseus → Settings → MCP Registry → Add server:
http://host.docker.internal:8848/sse
(Linux: add extra_hosts: ["host.docker.internal:host-gateway"] to the
Odysseus service in docker-compose.yml)3. Secure by network, not token. Because the SSE path is unauthenticated,
bind jCodeMunch so only the Odysseus container can reach it (host-gateway
interface / firewall), not a public interface. JCODEMUNCH_RATE_LIMIT adds a
throttle.
4. Restart Odysseus. All jCodeMunch tools appear in chat + agents. Keep the
index fresh with jcodemunch-mcp watch .; use Odysseus's per-server
disabled_tools to trim the surface.
jCodeMunch is read-only by charter, and its get_* / search_* / find_* /
check_* tool naming satisfies Odysseus's plan-mode read-only gate, so the
suite stays usable in plan mode.
Community-tested: the MCP protocol round-trip (SSE connect + tool discovery) is verified; the container-to-host network dial depends on your Docker setup.
How much can I save on Claude / Opus tokens? In retrieval-heavy workflows, code-reading tokens typically drop 95%+ because the agent fetches exact symbols instead of brute-reading whole files — benchmarked at a 95% average reduction across 15 tasks / 3 repositories, with peaks of 99.8% on large repos. Compact MUNCH encoding then trims another ~45% off the wire. Full methodology and harness: TOKEN_SAVINGS.md and benchmarks/.
Does it work with large monorepos? Yes. It indexes incrementally, detects workspace members (pnpm / yarn / npm / Turborepo / Cargo / Go workspaces), and scopes queries to subpaths, so retrieval stays cheap as the repo grows. A file watcher keeps the index fresh.
What languages are supported? 70+ languages, including Python, JavaScript/TypeScript, Go, Rust, Java, C/C++, C#, PHP, Ruby, Swift, and Kotlin via tree-sitter AST parsing. Full matrix: LANGUAGE_SUPPORT.md.
Which agents and IDEs does it work with? Any MCP client — Claude Code, Cursor, VS Code, Codex CLI, Continue, Windsurf, and more. One-click and CLI installs are at the top of this README and in the Works With section.
Is it free for personal use? Yes — free for personal use; commercial use needs a license. See Commercial Licenses. The guarantee: if jCodeMunch doesn't pay for itself, you don't pay for it.
How is this different from RAG or grep-based tools? jCodeMunch retrieves at the symbol level with byte-level precision — functions, classes, importers, blast radius, class hierarchies — rather than returning fuzzy chunks (RAG) or raw line matches (grep) that the agent still has to read and reason over. Index once, query exactly what you need.