spannercg
v0.1.5
Published
Code intelligence and knowledge graph for any codebase, served from Google Cloud Spanner — shared, compiler-accurate code context for AI agents over MCP.
Maintainers
Readme
spannercg
One shared code graph for your whole team, served from Google Cloud Spanner. The platform team indexes each repo once and publishes its graph to a shared Spanner instance. Every engineer's AI agent then reads that same graph: no local indexing, no per-repo setup. Ask how something works and get the exact source, the call paths, and the blast radius in one call, for repos you cloned and repos you never did.
Table of contents
The two roles
SpannerCG serves one shared code graph to a whole team. Which commands you run depends on which side of that graph you're on:
| | Platform team: runs the graph | Individual engineer: uses the graph |
|---|---|---|
| Goal | Onboard repos and keep their graphs fresh on the shared instance. | Get accurate answers in your agent about any onboarded repo. |
| One-time setup | spannercg setup provisions or verifies the instance. | spannercg connect saves the connection settings and configures your agents. |
| Per repo | census, then index to publish; sync to keep fresh. | Nothing. Open the repo; your agent attaches automatically. |
| Indexing | Yes, with a SCIP artifact for compiler-verified references. | Never. Reads the published graph. |
| What's committed | A small spannercg.json: the repo ID and exclude patterns, never cloud coordinates. | Nothing. You clone what the platform team set up. |
| Main commands | setup, census, index, sync, repos, status --dashboard, drop-repo | connect, then repos to browse. Your agent does the rest. |
Get started
Every step is one command plus what you should see.
Install the CLI (everyone)
SpannerCG runs on Node.js 22.5 through 24. Node.js 25 is not supported.
Check your Node.js version:
node --versionIf the version is below 22.5, or is 25 or later, install Node.js 22 LTS:
nvm install 22 && nvm use 22With Homebrew, run
brew install node@22 && brew link --overwrite --force node@22instead.Install the CLI:
npm i -g spannercgConfirm that it resolves:
spannercg --version
Connect as an individual engineer
Your platform team has onboarded the repos. Your whole setup is one command.
Sign in to Google Cloud, then connect this machine. Get the project, instance, and registry database names from your platform team, who also grants you the
roles/spanner.databaseReaderrole on the instance:gcloud auth application-default login spannercg connectThe output is similar to the following. Your answers follow the
│marks:┌ Connect this machine to your team's remote codebase knowledge │ ◆ Google Cloud project id │ acme-prod │ ◆ Spanner instance id │ spanner-code-knowledge │ ◆ Registry database name │ spannercg-reg │ ◇ Checking Google Cloud credentials… ◇ Checking access to the remote codebase knowledge… │ ● Connected — 12 repositories are served from this instance. ● Saved to ~/.config/spannercg/config.json. Repos that commit a "repoId" now attach automatically. │ ◆ Add the spannercg server to your coding agents now? │ Yes │ └ Done — open any onboarded repo in your agent and just ask.Open an onboarded repo in your coding agent's workspace (Claude Code, Cursor, and others), and ask:
"How does a payment request reach the database?"
The answer quotes the relevant source, the call paths between the symbols, and what depends on them. In a repo that isn't onboarded, the agent falls back to its built-in tools.
Ask about repos you haven't cloned. List what the instance serves:
spannercg reposThe output is similar to the following:
Repos on instance spanner-code-knowledge: acme/payments-service · 6787b7c5 · java, python acme/checkout-web · 9f8e7d6c · typescript acme/inventory · 55aa01b2 · goName any of them in your question:
"In
acme/inventory, how does a stock reservation get released when an order is cancelled?"You get the same kind of answer, for a repo you never checked out. If your agent uses its generic tools instead, say "use spannercg" once.
Note: That's the whole engineer setup. For agent configuration details, questions across repos, code search in the dashboard, and troubleshooting, see the detailed guide: Use SpannerCG with your AI agent.
Onboard repos as the platform team
Provision the shared instance once. SpannerCG runs on a Spanner Enterprise edition instance that autoscales between 1 and 3 nodes:
gcloud auth application-default login spannercg setupThe output is similar to the following. Your answers follow the
│marks:┌ spannercg setup │ ◆ What do you want to do? │ Provision or manage the shared instance │ ◇ Checking gcloud credentials… ● Signed in as [email protected] │ ◆ GCP project │ acme-prod │ ◆ Spanner instance │ Create "spanner-code-knowledge" (Enterprise · autoscales 1–3 nodes · recommended) │ ◆ Region config │ regional-us-central1 │ ◆ Create "spanner-code-knowledge" in acme-prod (regional-us-central1)? │ Yes │ ◇ Creating "spanner-code-knowledge"… ● Created "spanner-code-knowledge" ✓ │ ◆ Configuration complete — Saved to ~/.config/spannercg/config.json │ └ Ready. Onboard a repo: cd <repo> && spannercg census then spannercg index --scip <artifact>Scope the corpus before you index.
censusclassifies the repo's files and excludes the test fixtures that would degrade answer accuracy:cd your-project spannercg censusThe output is similar to the following:
Backend: instance spanner-code-knowledge (machine config from setup) Census — ~/code/payments-service 1,482 indexable files · 1,210 code · 214 fixtures · 58 generated language files SCIP java 861 ████████░░░░ → scip-java python 621 █████░░░░░░░ → scip-python Recommended excludes (written to spannercg.json) **/__fixtures__/ −214 test fixtures — snippet/data files that poison name resolution To be indexed — 1,268 files across these directories (top 3) src 1,102 scripts 108 tools 58 ✓ Added 1 exclude pattern to spannercg.jsonBuild the graph and publish it. Use SCIP indexes from your CI build; they make symbol references compiler-exact. Pass one
--scipper compiler toolchain:spannercg index --scip ci-artifacts/scip-java.scip --scip ci-artifacts/scip-python.scipThe output is similar to the following:
ℹ Backend: instance spanner-code-knowledge · project acme-prod (machine config from setup) ◆ Publish this repo's codebase knowledge as "acme/payments-service" (database cg-acme-payments-service)? │ Yes │ ● Bound — repoId written to spannercg.json (commit it; corpus settings kept, no cloud coordinates stored) ℹ Corpus: excludes from spannercg.json (**/__fixtures__/) ┌ Building codebase knowledge │ ◆ Indexed 1,268 files │ ● 18,450 symbols, 61,204 relationships in 24s │ ◆ Remote codebase knowledge: updated 1,268 files (0 unchanged) in 41s │ ◆ Symbol catalog: recorded 1,268 files (0 unchanged) in 6s │ └ DoneNote:
spannercg indexalso works without--scip; symbol references then resolve by best-effort name matching until you add an artifact. To produce the artifacts, see SCIP build recipes.Commit the repo ID that
indexwrote. The committed ID is how engineers get access: when they ask questions in a clone, their coding agent reads it to find the repo's knowledge on the shared instance. The file carries only the repo's name and your corpus settings, never a project, instance, or database name:git add spannercg.json && git commit -m "spannercg: onboard to shared graph"Repeat
censusandindexfor each repo. They all share the one instance, and engineers reach any of them by name.Keep it fresh. After changes merge, sync transfers only the changed files:
spannercg syncThe output is similar to the following:
┌ Syncing codebase knowledge │ ◆ Synced 3 changed files │ ● 3 modified — 41 symbols updated in 1.2s │ └ DoneSee the instance. List what's indexed:
spannercg reposThe output is similar to the following:
Repos on instance spanner-code-knowledge: acme/payments-service · 6787b7c5 · java, python acme/checkout-web · 9f8e7d6c · typescript acme/inventory · 55aa01b2 · goTo watch it live instead, start the dashboard:
spannercg status --dashboardThe output is
SpannerCG status dashboard is live at http://127.0.0.1:7317/. The page refreshes itself:Remove a repo when its graph is no longer needed:
spannercg drop-repo acme/payments-serviceThe command shows what it will delete and asks you to type the repo ID to confirm. Pass
--yesin scripts. The output is similar to the following:┌ Deleting the remote codebase knowledge for "acme/payments-service" │ ◇ This deletes ────────────────────────────────────────────────╮ │ │ │ graph database cg-acme-payments-service │ │ registry rows 1,268 files · 18,450 defs · 61,204 refs │ │ last indexed 6787b7c5fb4b │ │ local spannercg.json keeps its repoId and excludes — │ │ a re-index reuses them │ │ │ │ Attached readers lose access until the repo is re-indexed. │ │ │ ├───────────────────────────────────────────────────────────────╯ │ ● registry: repo record removed │ ● graph: database cg-acme-payments-service dropped │ ◆ Kept your corpus settings (1 exclude pattern) — a re-index will use them. │ └ Re-index anytime: spannercg index
Note: These six steps cover one repo's happy path. For syncing from CI, dropping and re-adding repos, monitoring, and troubleshooting, see the detailed guide: Manage repos on the shared instance.
Configure your agents
spannercg connect offers this step at the end. To run it separately:
spannercg installThe installer lists the detected agents — Claude Code, Cursor, Codex CLI, opencode, Hermes Agent, Gemini CLI, Antigravity, and Kiro — and marks each one configured. Restart your agent session afterward; agents read MCP configuration at session start.
To confirm that it works, ask your agent a "how does X work?" question and check that it calls spannercg_explore. One call should answer it.
To remove the server from every agent it was installed into:
spannercg uninstallProject graphs and your machine configuration are left untouched. To remove the CLI itself, run npm uninstall -g spannercg.
Documentation
The quick start above covers the main path. The guides cover the rest:
- Manage repos on the shared instance: onboarding many repos, syncing from CI, dropping and re-adding a repo, the live dashboard, and troubleshooting. For the platform team.
- Use SpannerCG with your AI agent: agent configuration, questions across repos, code search in the dashboard, and troubleshooting. For every engineer.
- SCIP build recipes: how to build compiler-exact index artifacts in CI for each language.
Language support
Every supported language gets the same treatment: full structural extraction and cross-file resolution into one graph, with no per-language setup.
TypeScript · JavaScript · ArkTS · Python · Go · Rust · Java · C# · VB.NET · PHP · Ruby · C · C++ · CUDA · Objective-C · Metal · Swift · Kotlin · Scala · Dart · Lua · Luau · R · Nix · Erlang · CFML · COBOL · Solidity · Terraform/OpenTofu · Svelte · Vue · Astro · Liquid · Pascal/Delphi
Compiler-verified accuracy through --scip is available for TypeScript/JavaScript, Python, Java, Kotlin, C#, Go, Rust, Ruby, and C/C++. Every other language indexes with best-effort reference resolution.
Multi-language repos index into one graph across all their languages. Pass a separate SCIP artifact per language, such as spannercg index --scip scip-java.scip --scip scip-python.scip, so each language gets compiler-verified accuracy.
License
Licensed under the Apache License 2.0.
SpannerCG is based on and derived from CodeGraph by Colby Mchenry, originally released under the MIT License. That original license is retained in the NOTICE file.
