Feature-graph code intelligence for AI agents — stop grepping, start graphing
Project description
jcode
Code intelligence for AI agents — without burning your token budget.
If you've ever watched Claude or GPT spend 40 tool calls grepping through your codebase just to answer "where does authentication happen?", you'll get why this exists.
jcode builds a feature graph of your repo — functions, classes, imports, call relationships — stores it locally as a SQLite database, and exposes it as an MCP server. Instead of reading twenty files, your AI agent calls one tool and gets exactly the context it needs.
It's fast, it's local, and it works with Python, TypeScript, JavaScript, Go, and Rust repos right out of the box.
What it actually does
When you run jcode index, it walks your repo with Tree-sitter, extracts every function, class, method, and import, and builds a directed graph of how they relate to each other. That graph lives in a .jcode/ folder at your repo root.
From there, your AI agent has five tools:
| Tool | What it does |
|---|---|
jcode_feature_map |
High-level folder/feature overview — always call this first |
jcode_search |
Semantic + keyword search to find entry points |
jcode_context |
Forward DFS from a node — "show me everything this function touches" |
jcode_blast_radius |
Reverse BFS — "if I change this, what breaks?" |
jcode_index |
Trigger a (re-)index from inside a conversation |
The blast radius tool is the one people find most surprising. Change a function signature, a model field, or a shared utility and instantly see every caller, handler, and dependent that needs to know about it — across the entire codebase, regardless of language.
Language support
jcode uses Tree-sitter under the hood, so it understands the actual structure of your code rather than just searching text.
| Language | Status |
|---|---|
| Python | ✅ Full support — functions, classes, methods, imports, call edges |
| TypeScript | ✅ Supported |
| JavaScript | ✅ Supported |
| Go | ✅ Supported |
| Rust | ✅ Supported |
Mixed-language repos work fine — index once, query across everything.
Install the parsers you need:
pip install jcode[typescript]
pip install jcode[javascript]
pip install jcode[go]
pip install jcode[rust]
pip install jcode[all-langs] # everything at once
Quick start
Step 1 — Install
pip install jcode
Or with uv:
uv add jcode
Verify it worked:
jcode --version
jcode --help
Step 2 — Index your project
jcode index /path/to/your/project
This creates a .jcode/ folder inside your project with the graph database. Works on any supported language — point it at a Python backend, a TypeScript frontend, a Go service, whatever.
Step 3 — Write CLAUDE.md
jcode init /path/to/your/project
This writes a CLAUDE.md at your project root so Claude Code knows to use jcode instead of grepping.
Step 4 — Connect to Claude Code
jcode setup-mcp /path/to/your/project
This prints the exact command you need to run, something like:
claude mcp add jcode -e JCODE_DIR=/path/to/your/project/.jcode -- jcode serve
Copy that and run it. One-time setup per project.
Step 5 — Open Claude Code in your project
cd /path/to/your/project
claude
Claude will read CLAUDE.md on startup and use jcode instead of reading files one by one.
Incremental indexing
Re-indexing only processes files that changed since the last run — content hashed, not timestamp compared. Fast enough to run as a file-watcher or a pre-commit hook.
jcode index /path/to/repo # incremental (default)
jcode index /path/to/repo --full-reindex # wipe and rebuild
Framework plugins
For some frameworks, generic call analysis isn't enough — you need to understand what the framework is doing with your code. jcode has a plugin system for exactly this. Auto-detection is based on your requirements.txt or pyproject.toml, no config needed.
FastAPI — detects Depends(fn) and Security(fn) in route handlers and emits typed depends edges. Blast radius from get_current_user correctly reaches every protected route.
Django — three patterns covered:
path('login/', views.login_view)→routeedge to the view functionForeignKey(User, ...)→referencesedge between models@receiver(post_save, sender=User)→signaledge from handler to model
More plugins are coming. Writing one is about 50 lines — implement handled_names and handle_call, register it in _REGISTRY.
Semantic search
Install sentence-transformers and search upgrades from keyword matching to semantic vector search. Useful when you know what something does but not what it's called.
pip install jcode[embed]
Embeddings are computed once on first index and stored in the graph. Incremental runs only embed new or changed nodes.
How the graph is stored
Everything goes in .jcode/ at your repo root:
graph.db— SQLite database with nodes, edges, FTS5 full-text index, vector embeddings, and a file-hash manifest for incremental indexingobjects/— content-addressable store for raw node data (git-style blobs, keyed by SHA-256)
Add .jcode/ to your .gitignore — it's generated data.
CLI reference
jcode index <repo> Index or re-index a repository
jcode init <repo> Write CLAUDE.md to the repo root
jcode status <repo> Show index stats
jcode setup-mcp <repo> Print the claude mcp add command
jcode serve Start the MCP server (stdio transport)
Project structure
src/jcode/
├── domain/ core models and port interfaces (zero external deps)
├── storage/ SQLite graph DB + content-addressable object store
├── indexer/ Tree-sitter parsers, incremental builder, plugins, embedder
├── graph/ DFS context traversal + BFS blast radius
└── mcp/ FastMCP server exposing the five tools
Known limitations
- Cross-file call resolution is name-based — if two modules have a function with the same name, they're treated as the same target. Rare in practice but worth knowing.
- The semantic search quality depends on your sentence-transformer model. The default (
all-MiniLM-L6-v2) is fast and good enough for most codebases. .jcode/grows with your repo.--full-reindexcleans it up if it feels stale.
License
Personal and non-commercial use only. See LICENSE.
Built because reading source code line by line is a bad use of an AI agent's attention.
Author
Joel Thomas
🌐 codewithjoe.in · LinkedIn · Instagram · 𝕏
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file jcode-0.1.3.tar.gz.
File metadata
- Download URL: jcode-0.1.3.tar.gz
- Upload date:
- Size: 29.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.22 {"installer":{"name":"uv","version":"0.9.22","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3d884520051034c38a6a22b92404464ec8d02ab2a7a93f3863a4e9bb6ff78bdb
|
|
| MD5 |
861f65bdea7c12a7e15ca04f530e016d
|
|
| BLAKE2b-256 |
eb0a5960967f421499eddf707a13672b929d2753e0614a4d8830c125066a8312
|
File details
Details for the file jcode-0.1.3-py3-none-any.whl.
File metadata
- Download URL: jcode-0.1.3-py3-none-any.whl
- Upload date:
- Size: 38.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.22 {"installer":{"name":"uv","version":"0.9.22","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3890f730116717ce2f0495c1ebe8ffe22702c4792252b316b5bc50684ffacbe3
|
|
| MD5 |
5c32481a15e7ee111feaa74e82a9f881
|
|
| BLAKE2b-256 |
bd6ddc6ba4f501b6fab57c219f38494ba5b9f62a028e485f2bcf0e8188fa0d1f
|