Skip to main content
Glama

LLMScribe

Turn any local code repository into clean, structured context for AI coding agents.

One core, four surfaces — an MCP server, a CLI, a desktop GUI and a Python API. All of them read your project from disk, and the same input always produces the same bytes.

No AI. No embeddings. No hidden ranking.

Apache-2.0, and it runs entirely on your machine — no network, no account.

Works with Cursor, Claude Code, Claude Desktop, Codex, VS Code, Windsurf, Zed, Cline, Continue, JetBrains and LM Studio — any MCP client — plus pip install and a standalone Windows EXE.


The problem

Your agent does not have an intelligence problem. It has a retrieval problem — and no model upgrade fixes a context window filled with the wrong files.

On a 1.4-million-line codebase, one benchmark agent burned 6,000 seconds and produced nothing — no analysis, no output, zero score.

The same model, given structured code search instead of free-form file reading, finished the same task in 89 seconds and scored 0.90.

Across another benchmark, Codex CLI completed its entire turn sequence without ever reaching the file that would have solved the task in 27–29% of runs.

Handed the right context up front, its score nearly doubled.

The bottleneck is not the model. It is what goes into the context window.

What users keep reporting:

  • The agent explores 200 files to change one line, and admits it is "looking at unnecessary files"

  • Nine searches and fourteen files to find one constant, because the search itself is not ranked

  • The same files re-read in a loop, with no reasoning between the reads

  • Stale fixtures, mock data and outdated comments read as current truth

  • Search reporting "no matches found" when a plain grep finds the text immediately

  • Truncation that hides itself, and build output filling the window with noise

Related MCP server: MCPort

What LLMScribe does about it

The failure

What LLMScribe does

Reads 200 files to change one line

project_map returns the whole tree with contents excluded, before a single file is read

Re-reads the same files in a loop

Same input, same bytes, every run

Misses the file that actually mattered

project_dependencies resolves local, stdlib, external and unresolved imports, plus reverse dependencies

Search returns nothing when the text exists

search returns path, line, matched text and match type, or a stable error code — never a silent empty

Stale fixtures read as current truth

Nothing is inferred, embedded or ranked; you get the files as they are, plus a Git diff

Build output and binaries fill the context

Real .gitignore semantics; binaries and oversized files are skipped

Context silently truncated

Every cut is reported: truncated, truncation_note, omitted_files

The file an agent needs next is usually the one structurally related to the file it is already looking at — a dependent, a sibling module, a test fixture. That is a graph question, not a similarity question, which is why LLMScribe ships dependency analysis and a real tree instead of embeddings.


Feature Overview

Core Tools

Feature

Description

Map

Generate a clean directory tree without dumping file contents

Search

Search file paths, file names, file contents, and individual lines

Read

Safely retrieve a specific file

More

Feature

Description

Read Many

Retrieve multiple files in a single operation

Dependencies

See what a file depends on and what depends on it

Diff

Inspect Git status and unified diffs

Overview

Export the complete structure and supported file contents


Quick Start

Install LLMScribe from PyPI:

pip install llmscribe

Then point it at any project directory on your machine. No API key, no network access, no account.

The project_map(...), search(...), read(...) snippets below show MCP tool calls. The same operations are available from the CLI (local directories) and from Python through llmscribe.core (see Python API).

Map

Generate a clean directory tree without file contents. This is the best first step when exploring an unfamiliar repository.

project_map()

CLI

llmscribe map
llmscribe map --json

MCP

project_map

Output:

src/
├── api/
│   ├── routes.py
│   └── auth.py
├── models/
│   └── user.py
└── main.py

Search across file paths, file names, file contents, and individual lines.

Search is intentionally literal: LLMScribe does not try to guess what you meant.

search(query="authentication")

CLI

llmscribe search "authentication"
llmscribe search "authentication" --json

MCP

search

Each match includes the file path, line number, the matching line, the matched text and the match type (filename or content).

Results are ordered by path then line, and limited to 1,000 matches. Binary and oversized files are skipped.

Output (--json, data.matches):

[
  {
    "file_path": "src/auth/service.py",
    "line_number": 12,
    "line_content": "def authenticate(user, password):",
    "match_type": "content",
    "matched_text": "authenticate"
  }
]

Read

Safely retrieve the contents of a specific file. LLMScribe validates paths and prevents path traversal outside the project.

read(file_path="src/auth/service.py")

CLI

llmscribe read src/auth/service.py

MCP

read

Power Your Agent

Instead of throwing an entire repository into a context window, an agent can progressively retrieve exactly what it needs:

1. project_map()
      ↓
2. search("authentication")
      ↓
3. read("src/auth/service.py")
      ↓
4. project_dependencies("src/auth/service.py")
      ↓
5. read_many([...])

MCP

LLMScribe is a standard Model Context Protocol server that runs locally over stdio.

Any MCP-compatible client can use it against a project directory on your machine.

Config — put this in your client (see the per-app setup below):

{
  "mcpServers": {
    "llmscribe": {
      "command": "llmscribe-mcp"
    }
  }
}

If llmscribe-mcp is not on your PATH, point the client at the module:

{
  "mcpServers": {
    "llmscribe": {
      "command": "python",
      "args": ["-m", "llmscribe.mcp"]
    }
  }
}

Per-app setup

Each client reads a different configuration file. The blocks below were checked against each tool's official documentation.

Edit claude_desktop_config.json (in the app: Settings → Developer → Edit Config):

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json

  • Windows: %APPDATA%\Claude\claude_desktop_config.json

{
  "mcpServers": {
    "llmscribe": {
      "command": "llmscribe-mcp"
    }
  }
}

Fully quit and reopen Claude Desktop after saving.

claude mcp add llmscribe -- llmscribe-mcp

Confirm with claude mcp list.

Add --scope user to make it available in every project, or --scope project to share it with your team via .mcp.json.

Create .cursor/mcp.json in your project (or ~/.cursor/mcp.json for all projects):

{
  "mcpServers": {
    "llmscribe": {
      "command": "llmscribe-mcp"
    }
  }
}

Restart Cursor, then check Customize → MCPs.

Create .vscode/mcp.json in your workspace. Note that VS Code uses servers, not mcpServers:

{
  "servers": {
    "llmscribe": {
      "type": "stdio",
      "command": "llmscribe-mcp"
    }
  }
}

Then open Copilot Chat in Agent mode and click the tools icon to start the server.

Edit ~/.codeium/mcp_config.json (in the app: Windsurf Settings → Cascade → MCP → View Raw Config):

{
  "mcpServers": {
    "llmscribe": {
      "command": "llmscribe-mcp"
    }
  }
}

Press the refresh button after saving.

Open the Cline panel → MCP Servers → Configure → Configure MCP Servers, then add:

{
  "mcpServers": {
    "llmscribe": {
      "command": "llmscribe-mcp"
    }
  }
}

Edit the global mcp_settings.json (Edit Global MCP), or create .roo/mcp.json in your project (Edit Project MCP):

{
  "mcpServers": {
    "llmscribe": {
      "command": "llmscribe-mcp"
    }
  }
}

In the app: Program tab → Install → Edit mcp.json.

The file is ~/.lmstudio/mcp.json on macOS/Linux, %USERPROFILE%\.lmstudio\mcp.json on Windows:

{
  "mcpServers": {
    "llmscribe": {
      "command": "llmscribe-mcp"
    }
  }
}

LM Studio follows Cursor's mcp.json notation.

Add to your Zed settings (in the app: Settings → AI → MCP Servers → Add Server, or zed: open settings file):

{
  "context_servers": {
    "llmscribe": {
      "command": "llmscribe-mcp",
      "args": [],
      "env": {}
    }
  }
}

Add to ~/.continue/config.yaml (or a standalone file under .continue/mcpServers/):

name: LLMScribe
version: 1.0.0
schema: v1
mcpServers:
  - name: LLMScribe
    command: llmscribe-mcp

Continue also picks up Cursor/Claude/Cline JSON configs dropped into .continue/mcpServers/.

Settings → Tools → AI Assistant → Model Context Protocol (MCP) → Add → As JSON:

{
  "mcpServers": {
    "llmscribe": {
      "command": "llmscribe-mcp"
    }
  }
}

You can also click Import from Claude to reuse an existing Claude Desktop configuration.

Add an extension to ~/.config/goose/config.yaml:

extensions:
  llmscribe:
    name: llmscribe
    enabled: true
    type: stdio
    cmd: llmscribe-mcp
    args: []
    timeout: 300

Add to ~/.codex/config.toml:

[mcp_servers.llmscribe]
command = "llmscribe-mcp"

Available tools

project_map
project_overview
search
read
read_many
project_dependencies
project_diff

More Tools

Read Many

Retrieve multiple files in a single operation. Partial success is supported, so one problematic file does not invalidate the entire request.

read_many([
    "src/auth/service.py",
    "src/auth/models.py",
    "src/api/login.py"
])
llmscribe read-many src/auth/service.py src/api/login.py

Dependencies

Inspect the dependency relationships around a file.

LLMScribe identifies local dependencies, external dependencies, unresolved dependencies, and the files that depend on this file.

project_dependencies("src/auth/service.py")
llmscribe dependencies src/auth/service.py --json

Output:

src/auth/service.py
│
├── depends on
│   ├── auth/models.py
│   ├── auth/config.py
│   └── auth/utils.py
│
└── used by
    ├── api/login.py
    └── tests/test_auth.py

This is particularly useful when determining the potential impact of modifying a file.

Diff

Inspect repository changes using Git. Supports Git status, unstaged changes, staged changes, specific commits, and unified diffs.

llmscribe diff

This lets applications and agents understand not only the current repository, but also what changed.

Overview

Generate a complete project snapshot containing the directory structure, supported text file contents, and structured project information.

llmscribe overview

Best for small and medium-sized projects. For large repositories, use the recommended workflow instead:

map → search → read

CLI

Every command can return machine-readable JSON with --json (-j), which makes the CLI a building block for scripts, automation, and developer tools.

llmscribe map
llmscribe overview
llmscribe search "authentication"
llmscribe read src/auth/service.py
llmscribe read-many src/auth/service.py src/api/login.py
llmscribe dependencies src/auth/service.py
llmscribe diff

# machine-readable output
llmscribe map --json
llmscribe search "auth" --json
llmscribe dependencies src/auth/service.py --json

Paths are flexible. Every command takes an optional directory, so --path is never required:

llmscribe .                       # map the current directory
llmscribe ./src                   # map a specific directory
llmscribe map ./src               # the same thing, spelled out
llmscribe search "auth" ./src     # search inside a directory

Aliases for the verbs you already type:

Alias

Command

ls

map

tree

overview

grep, find

search

cat

read

deps

dependencies

read accepts several files and switches to a batch read automatically:

llmscribe cat src/main.py src/util.py

llmscribe -V prints the version.


Configuration

LLMScribe runs entirely on your machine and needs no configuration.

Two optional environment variables restrict which directories the MCP server may read:

Variable

Description

Default

MCP_ALLOWED_ROOTS

Directories (separated by : on POSIX, ; on Windows) the tools may read

all paths

MCP_ALLOW_LOCAL_PATHS

0 disables local path access entirely

enabled


Python API

from pathlib import Path
from llmscribe.core import project_map, search_project, read_file, read_files, analyze_dependencies, get_git_diff, LLMScribeError

root = Path(".")
print(project_map(root).tree)
print(search_project("auth", root).to_dict())
print(read_files(["README.md", "missing.py"], root).to_dict())   # per-file errors, never raises
try:
    analyze_dependencies("src/app.py", root)
except LLMScribeError as err:      # err.code is a stable machine-readable code
    print(err.code, err.message)

Behavior reference

Ignore rules

Defaults (.git, node_modules, venv, dist, build, .env, *.log, …), the root .gitignore and nested .gitignore files are applied with real Git semantics: wildcards, directories, ! negation, and root-anchored patterns.

Hidden files are included unless ignored.

Symlinks are never followed or listed.

Supported text files

Known source, config and doc extensions, plus names such as Dockerfile, Makefile, LICENSE and .gitignore.

Other files appear in the tree, but cannot be read or searched.

Limits

One source of truth: llmscribe.core.limits.

  • 400,000 content characters per project_overview / read_many

  • 50 files per read_many

  • 1,000 search matches

  • 20,000 map entries

  • 2 MiB per file

  • 200,000 diff characters

  • 100,000 scanned entries

Anything cut is reported: truncated, truncation_note, omitted_files.

Errors

Every failure has a stable, machine-readable code:

invalid_argument · invalid_path · file_not_found · unsupported_file_type · binary_file · file_too_large · read_error · not_a_repository · git_unavailable · unsupported_operation · internal_error

JSON errors look like this:

{"ok": false, "tool": "...", "error": {"code": "...", "message": "..."}}

Dependencies

Supported languages: Python, JavaScript/TypeScript, Java, Go, Rust, and C/C++.

Each reference is classified as one of:

  • local — resolved to a file or directory inside the project

  • stdlib — part of the language's standard library

  • external — not in the project, assumed third-party

  • unresolved — a relative or local-looking reference that matches nothing

used_by lists the reverse dependencies.

Git diff

Runs git with an argument list, a 30 s timeout, a minimal environment, and without external diff/textconv drivers.

Migration notes

  • Legacy tool names (project_get_file, project_get_files, project_search, project_list_files) are gone; use read, read_many, search.

  • Error code path_traversal is now invalid_path; not_text_file is unsupported_file_type.

  • project_dependencies results: all_local_files/all_external_deps/all_unresolved were replaced by used_by and per-category lists (stdlib_dependencies added).

  • llmscribe.core functions raise LLMScribeError (not FileNotFoundError) for a bad root.

  • 1.3.0: the online GitHub source was removed — LLMScribe is now local-only. The repo and ref arguments, the in-memory snapshot cache, the llmscribe.github package, and the hosted HTTP transport are gone. Point the tools at a local path.


Architecture

All interfaces share one core engine, so behavior stays consistent everywhere.

                         Repository
                             │
                             ▼
                        Local Project
                             │
                             ▼
                     LLMScribe Core
                             │
       ┌─────────────────────┼─────────────────────┐
       │                     │                     │
       ▼                     ▼                     ▼
      CLI                   MCP                   GUI
       │                     │
       └──────────────┬──────┘
                      ▼
              Structured Output
                   / JSON

Philosophy

LLMScribe intentionally stays simple. The goal is not to make the repository "smarter." The goal is to make the repository accessible to software.

One consequence is worth stating precisely: LLMScribe is deterministic — the same input produces the same bytes on every run. An agent can rely on what it learned last turn, and you can diff two runs of the same command and see only what actually changed.

We provide

  • Repository extraction

  • Literal search

  • Structured project data

  • File retrieval

  • Dependency information

  • Git information

  • Multiple interfaces

We don't provide

  • ❌ AI-generated answers

  • ❌ Embedding-based search

  • ❌ Semantic ranking

  • ❌ Autonomous coding

  • ❌ An AI coding agent

  • ❌ A generic Git client


Use Cases

  • AI coding agents

  • MCP applications

  • Developer tools

  • Code search interfaces

  • Repository explorers

  • Documentation systems

  • Code analysis pipelines

  • Automation scripts

  • Local LLM applications

  • Exploring unfamiliar open-source projects


Open Source

LLMScribe is open source under the Apache License 2.0. Inspect the source, modify it, and build your own integrations.

There is no hosted service and no telemetry. It reads your files, and nothing leaves your machine.


Resources


Contributing

Contributions are welcome — whether that is repository extraction, search, dependency analysis, interfaces, integrations or documentation.

Start with the vision, which sets out what is in scope and what deliberately is not, then the contributing guide.

  • A first response within about 7 days — this is a part-time project, and pinging a quiet thread is welcome.

  • Issues labelled good first issue are scoped to be self-contained.

  • Questions are best asked in an issue, so the next person can find the answer.

  • LLMScribe is maintained by @AMRITO-KUNDU; GOVERNANCE.md describes how decisions are made.


License

LLMScribe is licensed under the Apache License 2.0.

See the LICENSE file for details.

Repository data, structured.

↑ Back to top

Available Tools

7 tools
project_dependenciesB

Imports of one file (local, standard-library, external, unresolved) and the files that import it.

Supports Python, JavaScript/TypeScript, Java, Go, Rust and C/C++.

Inputs: file_path (required), path, format. Returns: result

project_diffA

Git status and unified diff of the working tree (vs HEAD, vs 'commit', or staged only).

Inputs: path, commit, format, staged. Returns: result

project_mapB

Directory tree and the list of supported text files, without file contents.

Respects default ignores and .gitignore files. Symlinks are not followed.

Inputs: path, format. Returns: result

project_overviewB

Directory tree plus the contents of supported text files.

Output is capped at 400,000 characters of file content; when capped, the result says so and lists the omitted files.

Inputs: path, format. Returns: result

readA

Read one text file. Paths cannot leave the root; binary and oversized files are rejected.

Inputs: file_path (required), path, format. Returns: result

read_manyB

Read several text files in one call. A bad path yields an error entry; other files are still read.

Inputs: file_paths (required), path, format. Returns: result

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.6/5.0

    Scored across 7 tools

    Disambiguation4/5

    Most tools are cleanly separated by purpose: search vs read vs read_many vs project_diff are unambiguous. The one soft overlap is project_map vs project_overview, which both return a directory tree, though the descriptions make the contents-vs-no-contents distinction explicit. project_dependencies is clearly distinct in output shape.

    Naming Consistency3/5

    All names are snake_case, but the convention is applied unevenly: some carry a project_ prefix (project_map, project_overview, project_dependencies, project_diff) while the core file operations are bare verbs (search, read, read_many). Readable, but an agent can't infer the prefix rule predictably.

    Tool Count5/5

    Seven tools is well within the ideal range and each one earns its place: three discovery tools, two read tools, a dependency tool, and a diff tool. No redundant or filler entries.

    Completeness4/5

    The read-only exploration lifecycle is largely covered: map, bulk overview, search, single/bulk read, dependency graph, and git diff. Minor gaps remain, such as no line-range or offset read for large files and no pattern/glob filtering when listing files, all of which agents can work around with search.

    Maintenance

    ActivityActive
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      B
      maintenance
      Enables AI clients to safely read, search, understand, and edit local project code and files, with Git inspection, code indexing, and controlled command execution within permissioned workspaces.
      4 npm
      6
      MIT
    • A
      license
      Not graded
      quality
      B
      maintenance
      Enables language models to explore and analyze source code repositories through read-only tools for listing directories, reading files, searching code, finding symbols, and inspecting git history, with strict sandboxing and security controls.
      MIT
    • A
      license
      Not graded
      quality
      C
      maintenance
      Enables AI coding assistants to inspect local and remote repositories through sandboxed tools that surface project overviews, structure, dependency audits, Git churn hotspots, and a heuristic health score. It also supports safe GitHub issue searching and creation with built-in duplicate preflight checks, while blocking sensitive files, binary content, and path traversal attacks.
      22 npm
      MIT