#ai-agents #repo #token #mcp

app repo39

Token-optimized repo explorer for AI agents

1 stable release

Uses new Rust 2024

1.0.1 Apr 16, 2026

#277 in #repo

Apache-2.0

135KB
3.5K SLoC

 ▄▄▄ ▗▞▀▚▖▄▄▄▄   ▄▄▄  ▄▄▄▄ ▄▄▄▄ 
█    ▐▛▀▀▘█   █ █   █    █ █  █ 
█    ▝▚▄▄▖█▄▄▄▀ ▀▄▄▄▀ ▀▀▀█ ▀▀▀█ 
          █           ▄▄▄█ ▄▄▄█ 
          ▀                     

Token-optimized repo explorer for AI agents.

Scans a directory and outputs a compact tree. Designed to minimize tokens so agents can understand repo structure fast and cheap. Single binary: CLI by default, MCP server with repo39 mcp.

Install

cargo install repo39

Quick Reference

repo39 <path> [flags] [commands]

Flags: -s fdhca  -d N  -n N  -g glob  -o nscm  -i smcgt  -u KMG

Commands:
  --identify    --map [--calls]    --deps
  --changes     --summary          --review [ref]
  --search <pat> [--regex] [--context N]
                 [--file-filter glob] [--max-results N]
Flag What Values Default
-s show f=files d=dirs h=hidden c=count a=all fd
-d depth 0=root only, 1..N, 99=unlimited 0
-n limit per subfolder 0=unlimited, 1..N (root always unlimited) 0
-g grep filename glob *.rs, pack*, Cargo.toml -
-o sort n=name s=size m=modified c=created n
-i info to display s=size m=modified c=created g=git t=tokens -
-u size unit K=KB M=MB G=GB K
--identify detect project type(s) with confidence - -
--map extract code symbols (fn, struct, class) uses -d, -n, -g -
--calls show intra-file call graph (with --map) - -
--deps list dependencies from manifest files - -
--changes compact git log (recent file changes) - -
--summary one-shot orientation (identify+deps+map+changes) - -
--search search file contents literal or regex pattern -
--regex treat --search pattern as regex - off
--context context lines around search matches 0..N 0
--file-filter file glob for search *.rs, *.toml -
--max-results max search matches 0=unlimited, N 50
--review symbol-level diff vs git ref git ref (e.g. main, HEAD~3) HEAD~1

Standalone flags (--identify, --map, --deps, --changes, --summary, --search, --review) can be combined. When multiple are used, output is sectioned with [label] headers.

Output Format

name/       directory (trailing /)
name        file (no suffix)
 name       depth 1 (1 space indent per level)
  name      depth 2
...+N       truncated (N hidden entries)
name/ 3     dir with file count (-s c at depth limit)
*name       git dirty file (-i g)
name 1.4K   file with size (-i s)
name 2026-04-10   file with date (-i m or -i c)
name 450     file with token count (-i t)
10:+fn foo   public symbol with line number (--map)
20:fn bar -> baz, qux   call graph (--map --calls)

Agent Workflow

Two interfaces, same output. Use the CLI from a shell or the MCP server from any MCP-compatible agent.

1. Identify the project

repo39 /project --identify
repo39_identify { "path": "/project" }
rust 0.85
markdown 0.39
docs 0.12

71 categories: 22 languages, 37 frameworks, 12 non-code (images, data, docs, devops, etc). Top 5 matches with confidence 0.00-1.00. Framework detection uses dependency analysis (e.g. detects React, Django, Spring from manifests).

2. Read dependencies

repo39 /project --deps
repo39_deps { "path": "/project" }
clap 4
regex 1
tempfile 3 dev

Parses: Cargo.toml, package.json, pyproject.toml, requirements.txt, go.mod, Gemfile, composer.json. Shows dev suffix for dev dependencies.

3. Get the code map

13 languages: Rust, Python, JS, TS, Go, Java/Kotlin, Ruby, PHP, C/C++, Swift, Elixir, Dart, Shell.

Symbols include line numbers and visibility (+ = public):

repo39 /project --map -d 99
repo39_map { "path": "/project", "depth": 99 }
src/main.rs
 1:fn main
src/walk.rs
 5:+struct WalkCtx
 12:+fn walk
 30:fn grep_walk

Show call graph:

repo39 /project --map --calls -d 99
repo39_map { "path": "/project", "depth": 99, "calls": true }
src/walk.rs
 12:+fn walk -> grep_walk
 30:fn grep_walk

Limit symbols per file:

repo39 /project --map -d 99 -n 3
repo39_map { "path": "/project", "depth": 99, "limit": 3 }
src/config.rs
 5:struct Cli
 12:struct ShowFilter
 20:impl ShowFilter
 ...+9

Search for a specific symbol:

repo39 /project --map -d 99 -g "login*"
repo39_map { "path": "/project", "depth": 99, "grep": "login*" }
src/auth.rs
 8:fn login
 15:fn login_handler

4. Check recent activity

repo39 /project --changes
repo39_changes { "path": "/project" }
2h src/main.rs +8 -3
5d src/walk.rs +12 -8
1w README.md +95 new

Time-relative (3m, 2h, 1d, 2w, 3M, 1y). Shows insertions/deletions, new/del markers.

Branch diff:

repo39 /project --changes main..HEAD
repo39_changes { "path": "/project", "branch": "main..HEAD" }

5. Search file contents

repo39 /project --search "TODO"
repo39_search { "path": "/project", "pattern": "TODO" }
src/main.rs:42 // TODO: handle error
src/walk.rs:18 // TODO: optimize

With regex and context:

repo39 /project --search "fn\s+test_" --regex --context 1 --file-filter "*.rs"
repo39_search {
  "path": "/project",
  "pattern": "fn\\s+test_",
  "is_regex": true,
  "context": 1,
  "file_glob": "*.rs"
}
src/walk.rs
17-
18:fn test_walk() {
19-    let ctx = WalkCtx::new();

Max 50 results by default. Use --max-results 0 / "max_results": 0 for unlimited.

6. Review symbol-level changes

repo39 /project --review
repo39_review { "path": "/project" }
src/main.rs
 +45:fn new_feature
 ~1:fn main
src/old.rs
 -fn deprecated

Compares against HEAD~1 by default. Specify a ref:

repo39 /project --review main
repo39_review { "path": "/project", "ref_spec": "main" }

Symbols: + = added, - = removed, ~ = modified. Max 20 changed files.

7. Full picture in one command

repo39 /project --summary
repo39_summary { "path": "/project" }
[identify]
rust 0.85
markdown 0.39

[deps]
clap 4
regex 1

[map]
src/main.rs
 1:fn main
src/walk.rs
 5:+struct WalkCtx
 ...+3

[changes]
2h src/main.rs +8 -3
5d src/walk.rs +12 -8

Combines identify + deps + map (depth 99, 1 symbol/file) + changes. Equivalent to --identify --deps --map -d 99 -n 1 --changes.

8. Explore structure

repo39 /project -d 1 -n 3
repo39_tree { "path": "/project", "depth": 1, "limit": 3 }
Cargo.toml
README.md
src/
 main.rs
 walk.rs
 config.rs
 ...+4

One level deep, max 3 items per subfolder.

9. Find specific files

repo39 /project -g "*.json" -s a
repo39_tree { "path": "/project", "grep": "*.json", "show": "a" }
.mcp.json
config/
 settings.json

Full depth search. Only matching files + ancestor dirs shown.

10. Check sizes and dates

repo39 /project -d 1 -i sm
repo39_tree { "path": "/project", "depth": 1, "info": "sm" }
Cargo.lock 51K 2026-04-10
src/
 main.rs 22K 2026-04-10

11. Git dirty files

repo39 /project -d 99 -i g
repo39_tree { "path": "/project", "depth": 99, "info": "g" }
src/
 *main.rs
README.md

Dirty files prefixed with *. Warns on non-git folders.

Auto-skipped Directories

.git, node_modules, target, __pycache__, .venv, venv, dist, .next

Note: --identify does NOT skip these — their presence is a detection signal.

MCP Server

repo39 mcp starts the MCP server over stdio. Configure via .mcp.json:

{
  "mcpServers": {
    "repo39": {
      "command": "repo39",
      "args": ["mcp"]
    }
  }
}

Tools

Tool Description Extra params vs CLI
repo39_tree directory tree listing -
repo39_identify project type detection -
repo39_map code symbol extraction calls (bool)
repo39_deps dependency parsing -
repo39_changes git change log branch (e.g. main..HEAD)
repo39_search content search file_glob, is_regex, context, max_results
repo39_review symbol-level diff ref_spec
repo39_summary one-shot repo orientation (identify + deps + map + changes) -

All tools take a required path parameter. Tree/map tools accept depth, limit, grep as in the CLI.

Benchmark: repo39 vs standard tools

repo39 /project --summary vs the equivalent shell commands (ls, find, cat, grep -rn, git log --stat) to get the same repo orientation.

Results

Calls ~Tokens Output size Savings
express (~240 files)
standard 5 ~1,727 24 KB
repo39 1 ~479 4 KB 72% tokens, 81% size
fastapi (~3k files)
standard 5 ~26,640 643 KB
repo39 1 ~3,281 49 KB 87% tokens, 92% size

Where the savings come from

fastapi standard breakdown:

                        Calls   Lines Words(≈tok)      Bytes
identify (ls + find)        2      28           47        301
deps (cat manifests)        1     340          928      10497
map (grep definitions)      1    4381        13345     447513
changes (git log --stat)    1    2986        12320     184850

The biggest win is symbol extraction: grep -rn outputs full matching lines while repo39 outputs compact line:name format — 99% byte reduction on map alone.

Reproduce

benchmark.sh is included in the repo. Run it against any project:

./benchmark.sh /path/to/repo

Cross-platform

Works on Linux, macOS, and Windows. Output always uses / path separators.

License

Apache-2.0

Dependencies

~12–18MB
~243K SLoC