lens-mcp
Deterministic navigation maps over code AND markdown — for AI agents. OneMCP server, two lenses: tree-sitter for source (TypeScript / JavaScript /Python) and a markdown lens for docs. It answers "where is X and what's theshape of this project?" in one cheap call — so an agent spends context onthinking, not on browsing files.
Speaks the Model Context Protocol; workswith any MCP client — Claude Code, Cursor, Codex, or your own agent.
Why
An agent orienting in an unfamiliar repo otherwise burns tokens ls-ing,grep-ing, and Reading whole files to find the one function or the rightdoc. lens returns the map instead of the territory:
function_bodyreads one function — often ~99% less context than Readingthe file it lives in.headingreads one doc section — the referenced heading and itssubsections, nothing else.mapreturns the whole project's surface — every code file's structureand every doc's outline — in a single call.
Every output is deterministic (real parsing, not a model summarizing), cappedwith an honest truncated flag, and framed by one contract:
lens is a navigation map. Use it to locate, then Read the realsource/section before judging or modifying it. A signature is not the body;an outline is not the section.
Tools (11)
Orientation
| Tool | What it does |
|---|---|
map |
Whole-tree surface in one call: per code file → structure; per doc → title + outline. Both families, one response. |
info |
Version, sandbox root, supported languages/extensions, tool list, every output cap, and the lens contract. |
Code (tree-sitter — .ts .tsx .mts .cts .js .jsx .mjs .cjs .py)
| Tool | What it does |
|---|---|
overview |
One file's imports, exports, classes (+ methods), top-level functions, with line ranges. |
functions |
Every function incl. nested — signatures, params/types, parent scope, kind. |
function_body |
Verbatim source of ONE function — the focused read. |
comments |
Comments + TODO/FIXME/BUG/HACK/… markers (markersOnly for the debt list). |
find |
Locate a function/method/class definition by name across a directory. |
Docs (markdown — .md .markdown .mdx)
| Tool | What it does |
|---|---|
outline |
Full heading hierarchy (the TOC) with line numbers. |
heading |
Read ONE section by heading text / slug / line number. |
links |
Extract inline / image / wikilink / autolink / reference links. |
search |
Case-insensitive full-text search across docs (heading hits ranked first). |
Call a code tool on a .md (or a doc tool on a .ts) and it fails with ahelpful pointer to the right tool — no silent confusion.
Honest by construction
- Never silent data loss — a file with syntax errors returns
hasErrors+parseErrors, still extracting what it can; unparseable files inmap/findappear with an inlineerror, never vanish. - Caps everywhere — every list is bounded (see
info.limits) and every capis reported with the true total. A context-saving tool with unbounded outputis self-refuting. - Path sandbox — only files under the server's working directory arereadable; escaping symlinks are rejected.
inforeports the root. - Errors name the fix —
{error, path, hint}, withisErrorset.
Install
One line clones, installs, and writes a ready-to-paste MCP config with thisinstall's absolute path:
git clone https://github.com/segentic-lab/lens-mcp && cd lens-mcp && ./install.sh
No system packages and no native build — tree-sitter runs as WebAssembly, so itworks anywhere Node 18+ runs (Linux, macOS, Windows via WSL/Git Bash). Theinstaller checks Node, runs npm ci, builds (tsc → dist/), self-tests the fullsuite (135 tests), and generates mcp-config.json.
Register it with your client — the generated mcp-config.json looks like:
{
"mcpServers": {
"lens": { "command": "node", "args": ["/abs/path/lens-mcp/dist/index.js"] }
}
}
- Claude Code:
claude mcp add lens -- node /abs/path/lens-mcp/dist/index.js(or copymcp-config.jsoninto a project as.mcp.json) - Cursor / Windsurf: merge
mcp-config.jsoninto~/.cursor/mcp.json - Codex CLI: add
[mcp_servers.lens]with the same command/args to~/.codex/config.toml
lens reads files under its working directory — the project your clientlaunches it in. Point it at a project and call map("."). Nothing outside theworking directory is readable.
Update later, in place:
./update.sh # git pull --ff-only + reinstall + self-test
Prefer to do it by hand? npm install && npm run build && npm test, thenrun node dist/index.js.
Lineage
lens-mcp supersedes the earlier split servers codelens-mcp (code) anddocslens-mcp (docs) — same engines, one server, one pipeline. Sibling ofperiscope-mcp (web-app QA);built to the same standard: honest errors, caps + truncated flags everywhere,docs == behavior, tests before release.
Built by Segentic Lab. AGPL-3.0.