Code intelligence engine that indexes repositories into an in-memory knowledge graph and exposes it via CLI, MCP Server, and web UI.
Built for AI coding agents (Claude Code, Cursor, Codex) — one smart_context call replaces 5-10 file reads, cutting token usage by ~94%.
- Knowledge graph — every file, symbol, import, call chain, and type relationship in one queryable structure
- Multi-repo workspaces — index multiple repositories into a single graph with cross-repo symbol resolution, project grouping, reference tags, and per-repo scoping
- 26 languages — Go, TypeScript, JavaScript, Python, Rust, Java, C#, Kotlin, Swift, Scala, PHP, Ruby, Elixir, C, C++, Dart, Bash, SQL, Protobuf, Markdown, HTML, CSS, YAML, TOML, HCL, Dockerfile
- 44 MCP tools — symbol lookup, call chains, blast radius, community detection, process discovery, contract verification, cycle detection, dead code analysis, scaffolding, multi-repo management, and 6 agent-optimized tools
- Semantic search — hybrid BM25 + vector search with RRF fusion. Built-in GloVe word vectors for offline use, or connect to Ollama/OpenAI for transformer-quality embeddings. Build tags for ONNX, GoMLX, and Hugot offline transformer backends
- Type-aware resolution — infers receiver types from variable declarations, composite literals, and Go constructor conventions to disambiguate same-named methods across types
- On-disk persistence — snapshots the graph on shutdown, restores on startup with incremental re-indexing of only changed files (~200ms vs 3-5s full re-index)
- Bridge Mode — HTTP/JSON API exposing all MCP tools for IDE plugins, CI tools, and web UIs with CORS support and tool discovery endpoint
- 6 MCP resources — lightweight graph context without tool calls
- Two-tier config — global config (
~/.config/gortex/config.yaml) for projects and repo lists, per-repo.gortex.yamlfor guards, excludes, and local overrides - Guard rules — project-specific constraints (co-change, boundary) enforced via
check_guards - Watch mode — surgical graph updates on file change across all tracked repos, live sync with agents
- Web UI — Sigma.js force-directed visualization with node size proportional to importance
- IMPLEMENTS inference — structural interface satisfaction for Go, TypeScript, Java, Rust, C#, Scala, Swift, Protobuf
- PreToolUse hooks — automatic graph context injection on Read and Grep
- Benchmarked — per-language parsing, query engine, indexer benchmarks
- Per-community skills —
gortex skillsauto-generates SKILL.md per detected community with key files, entry points, cross-community connections, and MCP tool invocations for Claude Code auto-discovery - Eval framework — SWE-bench harness for A/B benchmarking tool effectiveness with Docker-based environments and multi-model support
- Zero dependencies — everything runs in-process, in memory, no external services
# Build (requires CGO for tree-sitter C bindings)
go build -o gortex ./cmd/gortex/
# Set up Gortex for a project (creates configs for Claude Code + Kiro IDE)
gortex init /path/to/repo
# Or with codebase analysis for a richer CLAUDE.md
gortex init --analyze /path/to/repo
# Index a repo and print stats
gortex status --index /path/to/repo
# Start MCP server with watch mode and graph caching
gortex serve --index /path/to/repo --watch
# Generate per-community skills for Claude Code
gortex skills /path/to/repo
# Start HTTP bridge API for external integrations
gortex bridge --index /path/to/repo --web --cors-origin '*'
# Multi-repo: track additional repos and set active project
gortex serve --index /path/to/repo --track /path/to/other-repo --project my-project
gortex track /path/to/another-repo
gortex untrack /path/to/another-repoAfter running gortex init, Claude Code automatically starts Gortex via .mcp.json. The agent gets:
- Slash commands:
/gortex-guide,/gortex-explore,/gortex-debug,/gortex-impact,/gortex-refactor - Global skills: installed to
~/.claude/skills/— available across all repos - PreToolUse hook: automatic graph context on Read/Grep calls
- CLAUDE.md instructions: mandatory tool usage table and session workflow
Gortex can index multiple repositories into a single shared graph, enabling cross-repo symbol resolution, impact analysis, and navigation.
Two-tier config hierarchy:
- Global config (
~/.config/gortex/config.yaml) — projects, repo lists, active project, reference tags - Workspace config (
.gortex.yamlper repo) — guards, excludes, local overrides (workspace wins when both define the same setting)
# ~/.config/gortex/config.yaml
active_project: my-saas
repos:
- path: /home/user/projects/gortex
name: gortex
projects:
my-saas:
repos:
- path: /home/user/projects/frontend
name: frontend
ref: work
- path: /home/user/projects/backend
name: backend
ref: work
- path: /home/user/projects/shared-lib
name: shared-lib
ref: opensourcegortex track /path/to/repo # Add a repo to the workspace
gortex untrack /path/to/repo # Remove a repo from the workspace
gortex serve --track /path/to/repo # Track additional repos on startup
gortex serve --project my-saas # Set active project scope
gortex index repo-a/ repo-b/ # Index multiple repos
gortex status # Per-repo and per-project statsAgents can manage repos at runtime without CLI access:
| Tool | Description |
|---|---|
track_repository |
Add a repo, index immediately, persist to config |
untrack_repository |
Remove a repo, evict nodes/edges, persist to config |
set_active_project |
Switch project scope for all subsequent queries |
get_active_project |
Return current project name and repo list |
All query tools (search_symbols, get_symbol, find_usages, get_file_summary, get_call_chain, smart_context) accept optional repo, project, and ref parameters for scoping. When an active project is set, it applies as the default scope.
- Qualified Node IDs — in multi-repo mode, IDs become
<repo_prefix>/<path>::<Symbol>(e.g.,frontend/src/app.ts::App). Single-repo mode keeps the existing<path>::<Symbol>format. - Cross-repo edges — the resolver links symbols across repo boundaries with same-repo preference. Cross-repo edges carry a
cross_repo: trueflag. - Impact analysis —
explain_change_impact,verify_change, andget_test_targetsfollow cross-repo edges automatically, grouping results by repository. - Shared repos — the same repo can appear in multiple projects with different reference tags. It's indexed once and shared across projects.
- Auto-detection — set
workspace.auto_detect: truein.gortex.yamlto auto-discover Git repos in a parent directory.
gortex init also sets up Kiro IDE integration automatically:
- MCP server:
.kiro/settings/mcp.json— all 44 tools auto-approved for zero-friction use - Steering files:
.kiro/steering/gortex-workflow.md(always active) teaches Kiro to prefer graph queries over file reads. Additional manual steering files for explore, debug, impact, and refactor workflows are available via#in chat. - Agent hooks:
gortex-smart-context— on each prompt, assembles task-relevant context from the graph in one callgortex-post-edit— after saving source files, shows blast radius and which tests to rungortex-pre-read— before reading source files, enriches with symbol context from the graph
gortex init [path] Set up Gortex for a project + install global skills
gortex serve [flags] Start the MCP server (--bridge to add HTTP API)
gortex bridge [flags] Start standalone HTTP bridge API
gortex eval-server [flags] Start eval HTTP server for benchmarking
gortex skills [path] Generate per-community SKILL.md files
gortex index [path...] Index one or more repositories and print stats
gortex status [flags] Show index status (per-repo and per-project in multi-repo mode)
gortex track <path> Add a repository to the tracked workspace
gortex untrack <path> Remove a repository from the tracked workspace
gortex query <subcommand> Query the knowledge graph
gortex clean Remove Gortex files from a project
gortex claude-md [flags] Generate CLAUDE.md block
gortex version Print version
gortex query symbol <name> Find symbols matching name
gortex query deps <id> Show dependencies
gortex query dependents <id> Show blast radius
gortex query callers <func-id> Show who calls a function
gortex query calls <func-id> Show what a function calls
gortex query implementations <iface> Show interface implementations
gortex query usages <id> Show all usages
gortex query stats Show graph statistics
All query commands support --format text|json|dot (DOT output for Graphviz visualization).
| Tool | Description |
|---|---|
graph_stats |
Node/edge counts by kind, language, and per-repo stats |
search_symbols |
Find symbols by name (replaces Grep). Accepts repo, project, ref params |
get_symbol |
Symbol location and signature (replaces Read). Accepts repo, project, ref params |
get_file_summary |
All symbols and imports in a file. Accepts repo, project, ref params |
get_editing_context |
Primary pre-edit tool — symbols, signatures, callers, callees |
| Tool | Description |
|---|---|
get_dependencies |
What a symbol depends on |
get_dependents |
What depends on a symbol (blast radius) |
get_call_chain |
Forward call graph |
get_callers |
Reverse call graph |
find_usages |
Every reference to a symbol |
find_implementations |
Types implementing an interface |
get_cluster |
Bidirectional neighborhood |
| Tool | Description |
|---|---|
get_symbol_signature |
Just the signature, no body |
get_symbol_source |
Source code of a single symbol (80% fewer tokens than Read) |
batch_symbols |
Multiple symbols with source/callers/callees in one call |
find_import_path |
Correct import path for a symbol |
explain_change_impact |
Risk-tiered blast radius with affected processes |
get_recent_changes |
Files/symbols changed since timestamp |
| Tool | Description |
|---|---|
smart_context |
Task-aware minimal context — replaces 5-10 exploration calls |
get_edit_plan |
Dependency-ordered edit sequence for multi-file refactors |
get_test_targets |
Maps changed symbols to test files and run commands |
suggest_pattern |
Extracts code pattern from an example — source, registration, tests |
| Tool | Description |
|---|---|
get_communities |
Functional clusters (Louvain community detection) |
get_community |
Members and cohesion for one community |
get_processes |
Discovered execution flows |
get_process |
Step-by-step trace of an execution flow |
detect_changes |
Git diff mapped to affected symbols |
index_repository |
Index or re-index a repository path |
| Tool | Description |
|---|---|
verify_change |
Check proposed signature changes against all callers and interface implementors |
check_guards |
Evaluate project guard rules (.gortex.yaml) against changed symbols |
would_create_cycle |
Check if adding a dependency would create a circular dependency |
| Tool | Description |
|---|---|
find_dead_code |
Symbols with zero incoming edges (excludes entry points, tests, exports) |
find_hotspots |
Symbols ranked by fan-in, fan-out, and community boundary crossings |
find_cycles |
Circular dependency detection via Tarjan's SCC, classified by severity |
index_health |
Health score, parse failures, stale files, language coverage |
get_symbol_history |
Symbols modified this session with counts; flags churning (3+ edits) |
| Tool | Description |
|---|---|
scaffold |
Generate code, registration wiring, and test stubs from an example symbol |
batch_edit |
Apply multiple edits in dependency order, re-index between steps |
diff_context |
Git diff enriched with callers, callees, community, processes, per-file risk |
prefetch_context |
Predict needed symbols from task description and recent activity |
| Tool | Description |
|---|---|
track_repository |
Add a repo at runtime — indexes immediately, persists to global config |
untrack_repository |
Remove a repo — evicts nodes/edges, persists to global config |
set_active_project |
Switch active project scope for all subsequent queries |
get_active_project |
Return current project name and its member repositories |
| Resource | Description |
|---|---|
gortex://stats |
Graph statistics (node/edge counts) |
gortex://schema |
Graph schema reference |
gortex://communities |
Community list with cohesion scores |
gortex://community/{id} |
Single community detail |
gortex://processes |
Execution flow list |
gortex://process/{id} |
Single process trace |
When running gortex serve, a web visualization is available at http://localhost:8765:
- Sigma.js force-directed graph with ForceAtlas2 layout
- Node size proportional to degree (connection count = importance)
- Color-coded by kind (function, type, interface, method, variable, file)
- Real-time updates via SSE when watch mode is active
- Filter by node kind, hide test files, search by name
- Click nodes to highlight neighborhood
The gortex bridge command exposes all MCP tools as an HTTP/JSON API for external integrations:
# Standalone bridge with web UI
gortex bridge --index /path/to/repo --web --port 4747
# Bridge alongside MCP stdio
gortex serve --index /path/to/repo --bridge --port 8765Endpoints:
| Endpoint | Method | Description |
|---|---|---|
/health |
GET | Status, node/edge counts, uptime |
/tools |
GET | List all available tools with descriptions |
/tool/{name} |
POST | Invoke any MCP tool with JSON arguments |
/stats |
GET | Graph statistics by kind and language |
CORS is enabled by default (--cors-origin '*'). The bridge can serve the web UI on the same port with --web.
gortex skills analyzes your codebase, detects functional communities via Louvain clustering, and generates targeted SKILL.md files that Claude Code auto-discovers:
# Generate skills for the current repo
gortex skills .
# Custom settings
gortex skills . --min-size 5 --max-communities 10 --output-dir .claude/skills/generated/Each generated skill includes:
- Community metadata — size, file count, cohesion score
- Key files table — files and their symbols
- Entry points — main functions, handlers, controllers detected via process analysis
- Cross-community connections — which other areas this community interacts with
- MCP tool invocations — pre-written
get_community,smart_context,find_usagescalls
Skills are written to .claude/skills/generated/ and a routing table is inserted into CLAUDE.md between <!-- gortex:skills:start/end --> markers.
Hybrid BM25 + vector search with Reciprocal Rank Fusion (RRF). Multiple embedding tiers:
# Built-in word vectors (always available, zero setup)
gortex serve --index . --embeddings
# Ollama (best quality, local)
ollama pull nomic-embed-text
gortex serve --index . --embeddings-url http://localhost:11434
# OpenAI (best quality, cloud)
gortex serve --index . --embeddings-url https://api.openai.com/v1 \
--embeddings-model text-embedding-3-small| Tier | Flag | Quality | Offline |
|---|---|---|---|
| Built-in | --embeddings |
Basic (GloVe word averaging) | Yes |
| API | --embeddings-url |
Best (transformer model) | No |
| ONNX | --embeddings + build tag |
Best | Yes |
| GoMLX | --embeddings + build tag |
Good | Yes |
| Hugot | --embeddings + build tag |
Good | Yes |
Offline transformer backends via build tags:
go build -tags embeddings_onnx ./cmd/gortex/ # needs: brew install onnxruntime
go build -tags embeddings_gomlx ./cmd/gortex/ # auto-downloads XLA plugin
go build -tags embeddings_hugot ./cmd/gortex/ # auto-downloads XLA pluginGortex snapshots the graph to disk on shutdown and restores it on startup, with incremental re-indexing of only changed files:
# Default cache directory: ~/.cache/gortex/
gortex serve --index /path/to/repo
# Custom cache directory
gortex serve --index /path/to/repo --cache-dir /tmp/gortex-cache
# Disable caching
gortex serve --index /path/to/repo --no-cacheThe persistence layer uses a pluggable backend interface (persistence.Store). The default backend serializes as gob+gzip. Cache is keyed by repo path + git commit hash, with version validation to invalidate on binary upgrades.
gortex binary
CLI (cobra) ──> MultiIndexer ──> In-Memory Graph (shared, per-repo indexed)
MCP Server ──────────────────────> Query Engine (repo/project/ref scoping)
Bridge API ──────────────────────> (HTTP/JSON over MCP tools)
Web Server ──────────────────────> (Nodes + Edges + byRepo index)
MultiWatcher <── filesystem events (fsnotify, per-repo)
CrossRepoResolver ──> cross-repo edge creation (type-aware)
Persistence ──> gob+gzip snapshot (pluggable backend)
Data flow:
- On startup, loads cached graph snapshot if available; otherwise performs full indexing
- MultiIndexer walks each repo directory concurrently, dispatches files to language-specific extractors (tree-sitter)
- Extractors produce nodes (files, functions, types, etc.) and edges (calls, imports, defines, etc.) with type environment metadata
- In multi-repo mode, nodes get
RepoPrefixand IDs become<repo_prefix>/<path>::<Symbol> - Resolver links cross-file references with type-aware method matching; CrossRepoResolver links cross-repo references with same-repo preference
- Query Engine answers traversal queries with optional repo/project/ref scoping
- MultiWatcher detects changes per-repo and surgically patches the graph (debounced per-file), then re-resolves cross-repo edges
- On shutdown, persists graph snapshot for fast restart
Node kinds: file, function, method, type, interface, variable, import, package
Edge kinds: calls, imports, defines, implements, extends, references, member_of, instantiates
Multi-repo fields: Nodes carry repo_prefix (empty in single-repo mode). Edges carry cross_repo (true when connecting nodes in different repos). Node IDs use <repo_prefix>/<path>::<Symbol> format in multi-repo mode.
| Language | Functions | Methods + MemberOf | Types | Interfaces | Imports | Calls | Variables |
|---|---|---|---|---|---|---|---|
| Go | Full | Full (receiver) | Full | Full + Meta["methods"] | Full | Full | Full |
| TypeScript | Full | Full | Full | Full + Meta["methods"] | Full | Full | Full |
| JavaScript | Full | Full | Full | - | Full | Full | Full |
| Python | Full | Full | Full | - | Full | Full | Partial |
| Rust | Full | Full (impl blocks) | Full | Full + Meta["methods"] | Full | Full | Full |
| Java | Full | Full | Full | Full + Meta["methods"] | Full | Full | Fields |
| C# | Full | Full | Full | Full + Meta["methods"] | Full | Full | Fields |
| Kotlin | Full | Full | Full | Full | Full | Full | Properties |
| Scala | Full | Full | Full | Full + Meta["methods"] | Full | Full | - |
| Swift | Full | Full | Full | Full + Meta["methods"] | Full | Full | - |
| PHP | Full | Full | Full | Full | Full | Full | - |
| Ruby | Full | Full | Full | - | Full | Full | Constants |
| Elixir | Full | Full (defmodule) | Modules | - | Full | Full | Attributes |
| C | Full | - | Structs/Enums | - | Full | Full | Globals |
| C++ | Full | Full | Classes/Structs | - | Full | Full | - |
| Dart | Full | Full | Classes/Enums/Mixins/Extensions | Abstract interface | Full | Full | Full |
| Bash | Full | - | - | - | source/. | Full | Exports |
| Language | What it extracts |
|---|---|
| SQL | Tables (with columns), views, functions, indexes, triggers |
| Protobuf | Messages (with fields), services + RPCs, enums, imports |
| Markdown | Headings, local file links, code block languages |
| HTML | Script/link references, element IDs |
| CSS | Class selectors, ID selectors, custom properties, @import |
| YAML | Top-level keys |
| TOML | Tables, key-value pairs |
| HCL | Resource/data/module/variable/output blocks |
| Dockerfile | FROM (base images), ENV/ARG variables |
make build # Build with version from git tags
make test # go test -race ./...
make bench # Run all benchmarks
make lint # golangci-lint
make fmt # gofmt -s
make install # go install with version ldflagsRequires Go 1.21+ and CGO enabled (for tree-sitter C bindings).
See CONTRIBUTING.md for guidelines on adding features, language extractors, and submitting PRs.