Skip to main content
Glama
doberkofler

CodeIndex MCP

by doberkofler

CodeIndex MCP

A local, extensible, language-neutral code index exposed through the Model Context Protocol (MCP), a command-line interface, and a loopback management console.

CodeIndex MCP builds an immutable index generation from a workspace, stores it in SQLite, and answers bounded navigation questions without reading the whole repository into an agent's context. It is read-only: tools never modify source files.

What it does

The index stores:

  • authored files with content hashes and line counts;

  • declarations with stable identifiers, qualified names, kinds, and source ranges;

  • definition and reference occurrences, including the enclosing declaration;

  • dependency edges and bindings (authored module imports and canonical external or logical targets);

  • extractor diagnostics;

  • build generations, freshness state, and analytics.

Six read-only MCP tools are exposed:

Tool

Purpose

index_status

Bounded readiness, scope, counts, freshness, and last error; full detail adds build and limitation data

outline

Declarations in one file, in source order

find_symbol

Exact or prefix symbol search

find_references

Occurrences for one symbol ID, or one-call name resolution with file/owner grouping

find_dependencies

Direct target usage or transitive dependency impact

read_symbol

Bounded source for one symbol, rejecting stale files

All results are paginated and byte-bounded. Stale source is rejected rather than returned.

Related MCP server: code-index

Language support

Two extractors ship today:

  • TypeScript / JavaScript, using the TypeScript compiler API.

  • Oracle 19c SQL / PL/SQL, using a pinned ANTLR lexer and a tolerant structural scanner. No Oracle database is needed at runtime.

JavaScript files are indexed when a configured project enables allowJs. Declaration files (.d.ts, .d.mts, .d.cts) and generated output are used for resolution but are not published as authored source.

The Oracle adapter indexes package specifications, package bodies, and standalone procedures/functions from an explicit manifest. Triggers, object types, table lineage, and live catalogue metadata are outside O1 scope. See the Oracle adapter.

ORDS and cross-language edges remain planned; later languages use the same adapter seam.

Architecture

MCP / CLI / console
        │
        ▼
Language-neutral core
  generations · freshness · storage · publication
  pagination · limits · dependency queries · analytics
        │
        ▼
Extractor interface
  files · declarations · occurrences · dependency edges
  diagnostics · source ranges · identity and version
        │
        ▼
TypeScript / JavaScript adapter     Oracle 19c adapter
  TypeScript compiler API              pinned ANTLR lexer + structural scanner

The core does not know about TypeScript, tsconfig.json, npm, Oracle, or any version control system. Compiler objects stay inside the adapter. A new language is added by implementing the extractor interface and selecting it in configuration; storage, publication, MCP envelopes, and analytics do not change.

Installation

The package is consumed directly from GitHub. No npm publication is performed.

pnpm add github:doberkofler/codeindex-mcp#v0.6.0

Pin a released tag. The Git dependency runs its prepare script, which builds:

dist/mcp.mjs
dist/cli.mjs
dist/console.mjs
dist/console/

With pnpm 12, approve the Git dependency build and the oracledb install script in pnpm-workspace.yaml. Use the resolved commit key that pnpm prints:

allowBuilds:
  codeindex-mcp@https://codeload.github.com/doberkofler/codeindex-mcp/tar.gz/<commit-sha>: true
  oracledb: true

See the user guide for the complete sequence. Do not depend on the main branch. Every upgrade requires a new tag, an explicit dependency update, a lockfile update, and verification in the consuming project.

Configuration

Configuration is external to the package. Pass a JSON file with --config or CODE_INDEX_CONFIG:

codeindex-cli status --config ./codeindex.config.json
CODE_INDEX_CONFIG=./codeindex.config.json codeindex-mcp

Paths inside the file resolve relative to the file's directory. Environment overrides resolve relative to the current working directory.

{
	"project": {
		"name": "my-workspace",
		"id": "optional-stable-id",
		"root": "."
	},
	"extractor": {
		"id": "typescript",
		"projects": [
			{ "name": "browser", "project": "tsconfig.json" },
			{ "name": "contracts", "project": "contracts/tsconfig.json" },
			{ "name": "server", "project": "server/tsconfig.json" }
		]
	},
	"storage": {
		"analyticsEnabled": true
	},
	"limits": {
		"maxResultBytes": 32768,
		"maxReadLines": 200
	},
	"diagnostics": {
		"semantic": false
	}
}

Every extractor.projects[].project must stay inside project.root. The single extractor.project form remains supported. The Oracle extractor requires an explicit manifest path; it never guesses a project filename. Storage paths must stay outside the indexed workspace.

Oracle manifest

{
	"schemaVersion": 1,
	"dialect": "19c",
	"defaultSchema": "APP",
	"extensions": [".pks", ".pkg", ".pkb", ".prc", ".fnc"],
	"include": ["database/**/*.pks", "database/**/*.pkb"],
	"exclude": ["**/generated/**"]
}

extensions is optional and replaces the default .pks, .pkg, .pkb, .prc, .fnc set. Add .sql or .pls only when those files should be published.

All project contexts build into one atomic generation. Each declaration and occurrence records the contexts that produced it; find_symbol and find_references accept an optional context filter.

Environment overrides

Variable

Effect

CODE_INDEX_CONFIG

Configuration file path

CODE_INDEX_ROOT

Indexed workspace root

CODE_INDEX_EXTRACTOR

Extractor identifier

CODE_INDEX_PROJECT_FILE

Single extractor project file override

CODE_INDEX_DATABASE

SQLite index path

CODE_INDEX_ANALYTICS

0 or false disables analytics writes

CODE_INDEX_ANALYTICS_PATH

Analytics JSONL path

CODE_INDEX_MAX_RESULT_BYTES

MCP response byte bound

CODE_INDEX_MAX_READ_LINES

read_symbol line bound

CODE_INDEX_SEMANTIC_DIAGNOSTICS

1 or true enables semantic diagnostics

CODE_INDEX_PROJECT_ID

Stable project identifier

CODE_INDEX_LOG_LEVEL

debug, info, warn, error

CODE_INDEX_LOG remains an alias for the analytics path.

Executables

codeindex-mcp

Stdio MCP server. Stdout belongs exclusively to the MCP transport; diagnostics and the version banner use stderr.

{
	"mcp": {
		"servers": {
			"codeindex": {
				"type": "local",
				"command": ["codeindex-mcp", "--config", "./codeindex.config.json"]
			}
		}
	}
}

Some clients require a launcher script to inject configuration. In that case point the command at the launcher, keep stdout clean, and let the launcher import the installed codeindex-mcp/mcp entry.

codeindex-cli

codeindex-cli update     # build only when source or configuration changed
codeindex-cli rebuild    # force a new generation
codeindex-cli status     # generation, counts, freshness, scope
codeindex-cli verify     # SQLite integrity and stored counts
codeindex-cli analytics  # offline analytics report (text, json, html)
codeindex-cli benchmark  # cold/warm build, edit-to-fresh, resources, deep cursors
codeindex-cli benchmark-suite    # run a declarative benchmark suite
codeindex-cli benchmark-prepare  # clone and install pinned public projects
codeindex-cli qualify --extractor typescript  # language-service reference cross-check
codeindex-cli qualify --extractor oracle --identifiers ... --dependencies ...
codeindex-cli publication-report --output report.json  # report-only Phase 2 measurements
codeindex-cli clean      # remove project index databases (dry run by default)

Index-backed commands accept --config, --root, --extractor, --project-file, and --database. publication-report is report-only: it accepts the first four and never opens or writes an index database. The benchmark command also accepts a generated corpus profile or a disposable database path. With --baseline, it writes an evaluation sidecar and fails only for failure gates; warnings remain successful. --summary writes Markdown. --reference accepts a previous benchmark report or a stored reference. See the maintainer guide.

Repeated benchmark runs are orchestrated by a suite manifest. Each generated run starts from a pristine corpus, every step executes in a fresh process, and the evidence directory records identity, reports, gates, checksums, and a Markdown summary:

pnpm benchmark:typescript:generated -- --output ~/codeindex-evidence/typescript-generated
pnpm benchmark:typescript:public:prepare
pnpm benchmark:typescript:public -- --output ~/codeindex-evidence/typescript-public
pnpm benchmark:oracle:corpus -- --output ~/codeindex-evidence/oracle

Semantic qualification is separate from performance benchmarking:

pnpm qualify:typescript
CODE_INDEX_ROOT=/path/to/oracle/workspace \
CODE_INDEX_PROJECT_FILE=/path/to/oracle/workspace/oracle-index.json \
CODE_INDEX_ORACLE_IDENTIFIERS=/path/to/user-identifiers.csv \
CODE_INDEX_ORACLE_DEPENDENCIES=/path/to/user-dependencies.csv \
pnpm qualify:oracle

codeindex-console

Loopback-only management console.

codeindex-console --config ./codeindex.config.json --open

It binds to 127.0.0.1, requires a per-run bearer token, and serves a bundled frontend. It reports status, freshness, analytics, and runs update, rebuild, verify, benchmark, and qualification operations.

Freshness and indexing semantics

  • Queries read exactly one published generation. building rows are never exposed.

  • A generation is published only after extraction, insertion, and integrity verification succeed. A failed build leaves the previous generation serving.

  • The scanner is authoritative. Filesystem events are hints; the coordinator always performs a deterministic scan.

  • Exactly one process owns the build lease. Other processes remain readers and observe the externally published generation.

  • Rebuilds run in a worker thread so the MCP transport stays responsive.

  • read_symbol verifies the file hash and rejects dirty paths with stale_file.

  • Persisted paths are workspace-relative POSIX paths.

Data storage and privacy

  • Default storage: ~/.local/share/codeindex-mcp/<projectId>/.

  • The database contains source content so read_symbol never trusts a changed file. It stays local.

  • Analytics are local, versioned, bounded, and disabled with CODE_INDEX_ANALYTICS=false. They contain tool names, durations, counts, and freshness state — never source text, prompts, queries, symbol names, credentials, or absolute paths.

  • Version-control provenance is optional. Git and SVN are detected when present; an unversioned workspace indexes normally.

Documentation

Development

pnpm install
pnpm verify              # typecheck, Oxlint, Knip, Oxfmt, complete Vitest suite
pnpm verify:pr           # single PR gate: one build, verify, fixture qualification
pnpm test:fast           # module, adapter, core, and fake-index MCP classes
pnpm test:typescript     # TypeScript adapter and reference-corpus classes
pnpm test:mcp            # MCP protocol class
pnpm test:system         # built-process deterministic system class
pnpm test:oracle         # Oracle adapter tests
pnpm qualify:typescript:fixture  # self-contained TypeScript language-service gate
pnpm build

Requires Node.js 26 or newer. Formatting is owned by Oxfmt; semantic analysis by Oxlint. Focused workflows and verify:pr fail when they exceed their budget. Do not weaken a check to make it pass. Nightly and stable/release checks are recorded in Verification workflows.

Current limitations

  • TypeScript files must be reachable from a configured project file; JavaScript requires allowJs.

  • Oracle O1 indexes static source only: no live database, triggers, object types, table/column lineage, synonyms, database links, wrapped source, or conditional compilation branch evaluation.

  • ORDS and cross-language edges are planned but not shipped.

  • No embeddings, fuzzy search, or full-text search.

  • No incremental delta storage; reuse is generation-granular.

  • Console and MCP trust the local loopback boundary.

License

MIT. See LICENSE.

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    A
    maintenance
    Indexes codebases into a SQLite database to provide metadata, exports, dependency graphs, and change tracking for JS/TS projects. It enables users to search for symbols, map internal dependencies, and monitor file changes through MCP tools and a web dashboard.
    6
    297 npm
    5
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    A local, SQLite-backed code index for Claude Code, exposed over MCP, enabling targeted code retrieval without external APIs.
    91 PyPI
    1
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables AI clients to perform local code search, indexing, and analysis across Java, JavaScript/TypeScript, .NET/C#, and Python projects through the MCP protocol.
    1
    Apache 2.0
  • F
    license
    Not graded
    quality
    D
    maintenance
    Provides code intelligence by indexing source code into SQLite and offering MCP tools for symbol search, flow tracing, and context retrieval to assist with code navigation and understanding.
    -