AST analysis is fast and language-broad, but dynamic dispatch and barrel re-exports hide references from any static heuristic. SCIP closes that gap with the compiler's own answer.
You generate a .scip index with a tool you already run, hand jCodeMunch the
file, and reference edges the AST could never see become available to the tools
you already use. jCodeMunch never runs your build, never spawns a language
server, and never leaves your machine.
These are third-party indexers maintained by the SCIP ecosystem, not by us. Invocations change upstream, so treat these as starting points and check each project's own README if a flag has moved.
| Language | Indexer | Typical invocation |
|---|---|---|
| TypeScript / JavaScript | @sourcegraph/scip-typescript |
npx @sourcegraph/scip-typescript index |
| Python | @sourcegraph/scip-python |
npx @sourcegraph/scip-python index . |
| Go | sourcegraph/scip-go |
scip-go from the module root |
| Rust | rust-analyzer |
rust-analyzer scip . |
| Java / Scala / Kotlin | sourcegraph/scip-java |
scip-java index |
| C / C++ | sourcegraph/scip-clang |
needs a compile_commands.json |
Each writes an index.scip in the working directory by default.
TypeScript is the case that pays for itself. Barrel files (export * from './foo') are where AST heuristics lose references, and where the compiler does
not.
jcodemunch-mcp import-scip index.scip.gz is accepted directly. The repo is resolved from the current directory;
pass --repo owner/name to target a different indexed repo.
The command reports what it actually ingested rather than a success banner:
edges_written, unique_edges, reference_edges, implementation_edges,
unmapped with per-reason counts, skipped_local, skipped_import, evicted,
and the tool string the indexer stamped into the file.
Read unmapped before you trust a low edge count. It means the SCIP file
described a symbol jCodeMunch could not place in its own index, which usually
means the two were built from different trees.
Once imported, six tools consume the evidence:
find_referenceslabels agreement asverification: "compiler_verified"and adds the references only the compiler saw assource: "scip"rows.get_blast_radiusandget_call_hierarchyunion compiler edges into the graph.find_implementationsgains a compile-time channel at confidence 1.0.check_edit_safeandcheck_delete_safeweight severity with it.
The marquee case: check_delete_safe flipping from safe to blocked after an
import, because the compiler saw a caller the AST did not.
No new MCP tool. Ingest is CLI-only, deliberately, the same way
import-trace is. Nothing here costs tool-schema budget.
SCIP evidence is a snapshot of one commit. jCodeMunch records the git_head it
was ingested at, and the content hash of every file the edges actually
touch. On each read it checks both.
A moved HEAD is necessary for the evidence to be stale, but not sufficient. If the commits since your import didn't change any file SCIP covers, the evidence still describes the tree and is not flagged. Only a change to a covered file, or its deletion, marks it stale, with a re-import hint.
That refinement matters more than it sounds. Under a HEAD-only comparison a single commit anywhere marked everything stale, and a warning that fires on nearly every read is one people learn to ignore.
The check is deliberately conservative in one direction: the evidence is older, never silently wrong. An index imported before v1.108.200 carries no hash map, and that falls back to the HEAD comparison rather than reporting fresh. Missing provenance is unknown, not clean.
Re-import after any merge you care about. In CI, that means regenerating and re-importing in the same job that indexes, so the two heads always match.
- name: Index for jCodeMunch
run: |
npx @sourcegraph/scip-typescript index
jcodemunch-mcp index .
jcodemunch-mcp import-scip index.scipOrder matters: import-scip resolves SCIP symbols against an existing
jCodeMunch index, so index first, import second. Running the import against a
missing or older index is what produces a high unmapped count.
- Row cap.
scip_edgesandscip_unmappedare capped at 200,000 rows, FIFO-evicted oldest-first. Override withJCODEMUNCH_SCIP_MAX_ROWS; an unparseable value or0falls back to the default. Env-only, not a config key. local Nsymbols and import-role occurrences are skipped and counted separately. Local symbols are not addressable across files, and the import graph already covers imports.- No cross-repo linking yet. SCIP symbols are globally unique, so this is cheap to add and is deliberately demand-gated. Open an issue if you want it.
jCodeMunch does not run your compiler, your tests, or your code. Strong evidence enters through a file you generate, with a tool you chose, on your schedule. That constraint is why this is an import rather than an integration.
If a command here is out of date or a claim doesn't match the source, that's a bug in this document and we'd like the issue.