Extract compact structural maps from source code — designed to reduce LLM context usage.
When working with an LLM on a large codebase, dumping entire source files into the context is expensive and slow. shortcode generates a .meta file for each source file — a one-line-per-symbol summary that tells the LLM where everything lives without wasting tokens on implementation details.
Workflow:
- Run
shortcode ./srconce to generate.metafiles - Feed the LLM the relevant
.metafiles (tiny) - Ask it to read only the specific functions it needs
- The LLM reads targeted line ranges from the originals
Given auth.py:
class TokenManager:
def __init__(self, secret): ...
def generate(self, user_id): ...
def verify(self, token): ...shortcode produces auth.py.meta:
[py] src/auth.py
IMPORT flask,jwt,datetime
CLASS TokenManager:4-52
__init__:5-9
generate:11-24
verify:26-38
FN hash_password:54-61
FN check_password:63-70
~15 tokens instead of ~400. The LLM asks to see lines 11-24 when it needs generate.
| Language | Extensions |
|---|---|
| Python | .py |
| JavaScript | .js .mjs .cjs |
| TypeScript | .ts .tsx |
| Java | .java |
| C# | .cs |
| C / C++ | .cpp .cc .cxx .hpp .h |
| Go | .go |
| Rust | .rs |
| Ruby | .rb |
| PHP | .php |
Powered by tree-sitter — real AST parsing, no regex heuristics.
pip install shortcode
# or
uv add shortcodeNo Python? Download the pre-built Windows executable from Releases.
# Scan a folder — writes .meta next to each source file
shortcode ./src
# Write all .meta files to a separate directory
shortcode ./src --output-dir ./meta
# Only process specific extensions
shortcode ./src --ext py ts java
# Top-level only (no subdirectories)
shortcode ./src --no-recursiveDouble-clicking the .exe opens an interactive prompt asking for the folder path.
from shortcode import parse_file
from pathlib import Path
meta = parse_file(Path("src/auth.py"))
print(meta.language) # "py"
print(meta.imports) # ["flask", "jwt", "datetime"]
for cls in meta.classes:
print(cls.name, cls.line_start, cls.line_end)
for method in cls.methods:
print(" ", method.name, method.line_start)
for fn in meta.functions:
print(fn.name, fn.line_start)shortcode ships an MCP server so Claude Code (and any MCP-compatible agent) can call it as a tool directly — no manual .meta file management needed.
pip install "shortcode[mcp]"
# or
uv add "shortcode[mcp]"Edit your Claude Code config file:
- macOS/Linux:
~/.claude.json - Windows:
C:\Users\<YourName>\.claude.json
Add the mcpServers block:
{
"mcpServers": {
"shortcode": {
"command": "shortcode-mcp"
}
}
}Or with uvx — no separate install needed, just requires uv:
{
"mcpServers": {
"shortcode": {
"command": "uvx",
"args": ["--from", "shortcode[mcp]", "shortcode-mcp"]
}
}
}Restart Claude Code after editing the config. Run /mcp to confirm the server is connected.
Add a CLAUDE.md file to your project root:
## Code navigation
A shortcode MCP server is available. Before reading any source file, call
`compact_file(path)` to get its structure and line ranges. Then read only
the specific lines you need using offset + limit.This instructs Claude to use shortcode at the start of every session instead of reading full files.
| Tool | Description |
|---|---|
compact_file(path) |
Return a token-efficient view of a source file |
compact_file automatically picks the most token-efficient response:
[COMPACT]— returned when the structural map is significantly smaller than the source. Shows imports, classes, methods, and functions with line ranges. Claude then reads only the specific lines it needs.[FULL]— returned when the file is too small to benefit from compaction (compact map would save less than 30%). Claude gets the full content in one call with no second round trip needed.
You: show me the generate method in src/auth.py
Claude: [calls compact_file("src/auth.py")]
[COMPACT]
[py] src/auth.py
IMPORT flask,jwt,datetime
CLASS TokenManager:12-87
__init__:13-18
generate:20-35
verify:37-52
[reads src/auth.py lines 20-35]
You: what does src/config.py do?
Claude: [calls compact_file("src/config.py")]
[FULL]
DEBUG = True
DATABASE_URL = "sqlite:///db.sqlite3"
SECRET_KEY = "abc123"
Other MCP clients: The same
shortcode-mcpserver works with Cursor, Windsurf, and any agent that supports the Model Context Protocol.
See CONTRIBUTING.md. Adding support for a new language takes about 10 lines.
MIT © Ahmet Bekcan