lynx-mcp

lynx-mcp

A 100% local MCP server for semantic and lexical search over your code, library docs, and PDFs, featuring hybrid BM25 and dense retrieval, syntax aware chunking, and an optional code knowledge graph. It also ships a Coral integration, so you can expose your code search as SQL and join it with live data, all without anything leaving your machine.

Category
访问服务器

README

Lynx

A 100% local MCP server for semantic code search — AST-aware chunking, hybrid BM25 + dense retrieval, and an optional code knowledge graph. Works with any MCP client (Claude Code, Cursor, Windsurf, Antigravity, ...).

Tests License: Apache 2.0 Python 3.10+ Glama score

Your AI assistant greps file names and guesses. Lynx gives it real retrieval over your code, your library docs, and your PDFs — without a single byte leaving your machine.

  • AST-aware indexing — tree-sitter parses 13+ languages and indexes whole functions/classes, not arbitrary text windows.
  • Hybrid retrieval — dense embeddings + code-tokenized BM25, fused with RRF; optional cross-encoder reranker.
  • Code knowledge graph (opt-in) — who-calls-what, inheritance, imports: ask "what breaks if I change this?" and get the actual blast radius.
  • Multi-source — index codebases, public docs sites (fetched once, on demand; JS-rendered SPAs supported via optional headless Chromium), and PDFs side by side.
  • Live index — a file watcher re-indexes saves in ~2s. No manual rebuild ritual.
  • Web manager UIlynx manager ui gives you guided setup, a query playground, diagnostics, and client config snippets.

(Named after Lynceus, the Argonaut whose sharp eyes could find anything hidden.)

Quickstart

# 1. Install the CLI (isolated, no venv ritual)
pipx install lynx-mcp
#    or: uv tool install lynx-mcp

# 2. Create a config pointing at your project
lynx manager init

# 3. Build the index (downloads the ~130MB embedding model on first run)
lynx build

Then register Lynx in your MCP client (Claude Code shown; see the full guide for Cursor, Antigravity, and generic stdio clients — or let lynx manager ui generate the snippet for you):

{
  "mcpServers": {
    "lynx": {
      "command": "lynx",
      "args": ["serve", "--config", "/absolute/path/to/config.json"]
    }
  }
}

Prefer zero terminal? There are double-click installers for macOS and Windows.

The tools your AI gets

The tool set is fixed — it does not grow with the number of sources, so your client's tool list (and context window) stays small. Tools take a source argument where relevant.

Tool What it answers
search(query, source?) Primary hybrid search. Omit source to search every source at once (RRF-fused).
deep_search(queries, source?) Escalation: tries multiple query phrasings until one passes a quality threshold.
graph_query(operation, symbol?) callers, callees, subclasses, superclasses, imports, neighbors, shortest_path, overview, surprising_connections, status.
find_definition(symbol) Where is X defined? (AST-precise when the graph is on, BM25 fallback otherwise.)
find_usages(symbol) Every use of X — calls and non-call references (generics, decorators, docs).
find_tests_for(symbol) Are there tests for X?
find_similar(snippet) Does code like this already exist?
search_diff(query, base?) Search only the files changed vs a base branch — built for code review.
feedback(trying_to_do, tried, stuck) The agent files a report when the index couldn't answer — stored 100% locally, your signal for tuning sources.
list_sources / get_rag_status / update_source_index Introspection and maintenance.

All retrieval tools carry MCP readOnlyHint annotations (clients can auto-approve them), and the server ships its usage playbook in the MCP handshake (instructions + a lynx://guide resource) — your agent knows how to query well without any rules-file setup.

How it works

your code ──► tree-sitter AST chunker ──► bge-small embeddings ──► ChromaDB
                                     └──► code-tokenized BM25 ─┐
query ───────────────────────────────────► RRF fusion ◄────────┘ ──► (optional reranker) ──► results

Everything runs locally: HuggingFace models are downloaded once, then Lynx switches to offline mode. No telemetry, no cloud index, no code upload. The only network access is the model download and the explicit webdoc fetch step you trigger yourself.

Why not just let the agent grep?

Grep is great when you know the identifier. It fails when you (or the agent) know the behavior: "where do we clamp the camera zoom?" matches nothing literal. Agentic grep also burns tokens — every wrong file the agent opens is context spent. Lynx answers behavioral queries in one tool call with file + line + symbol citations, and the graph layer answers structural questions (callers, inheritance) that grep fundamentally cannot — polymorphic dispatch leaves no textual trace.

Honest counterpoint: on a small repo that fits in the agent's context, built-in tools are fine. Lynx pays off on large codebases, on framework docs your model's training data has gone stale on, and on repeated sessions where re-exploring from scratch is waste.

Benchmarks (reproducible)

<img src="https://raw.githubusercontent.com/lorenzo-cambiaghi/LynxMCP/main/benchmarks/chart.svg" alt="Lynx vs agentic grep: -58% tokens to answer; 4 vs 101 tool calls to map a class hierarchy" width="980">

On the django/ package of Django 5.2 (883 files, ~158k lines), 20 behavioral questions with known ground-truth files — full methodology, per-task results, and an intentionally strong grep baseline in benchmarks/RESULTS.md:

Agentic grep Lynx
median tokens to answer (tool output + required follow-up read) 4,150 1,725
tool round-trips before the code is in context 2+ 1 (chunks included, with symbol + file:line + score)
hit@1 / MRR 45% / 0.64 55% / 0.67
"what inherits from Field?" — full descendant tree (100 classes) 101 grep rounds 4 graph calls, same recall, file:line per edge

The ranking quality is comparable (Django's docstring-rich code is grep's best case — we say so in the report). The structural difference is not: every tool round-trip is a full model inference over the growing context, and class-relation questions force grep into one round per discovered class while graph_query reads resolved inheritance edges.

# reproduce
git clone --depth 1 --branch 5.2 https://github.com/django/django.git benchmarks/_target/django
python benchmarks/run_benchmark.py && python benchmarks/structural_demo.py

Lynx + Coral: code search as a SQL data source

Coral is a local SQL engine over your live tools (GitHub, Sentry, Linear, …). Point it at Lynx's source spec and your semantic code search becomes a SQL table: you ask a question as a string and get back structured rows — file, symbol, line range, score, and the code content — that you can filter, sort, and join with live data. Everything stays local; only the live-data side touches an API. Setup in docs/CORAL.md.

-- semantic search, then keep only the C# hits, ranked:
SELECT file, symbol, score
FROM lynx.search(q => 'where the camera zoom is clamped')
WHERE language = 'c_sharp'
ORDER BY score DESC
LIMIT 5;

Because the results are just a SQL table, you can correlate them with anything else Coral exposes — for example, line up a code search against the repo's open PRs:

SELECT s.file, s.symbol, s.score, p.html_url, p.state
FROM lynx.search(q => 'retry logic for payment webhooks') s
CROSS JOIN github.pulls p
WHERE p.owner = 'your-org' AND p.repo = 'your-repo' AND p.state = 'open'
ORDER BY s.score DESC
LIMIT 5;

One query turns a behavioral question into ranked code locations an agent can cite precisely — and, when useful, alongside live context. The search string is a literal you provide (Coral resolves table-function arguments at plan time), so this is code search as a queryable, joinable source, not a per-row enrichment of other tables. lynx.sources lists your indexed sources; lynx.search(q => '…') is the ranked search function (source => '…', top_k => N to narrow it). More in docs/CORAL.md.

Documentation

Full guide Configuration, all source types (codebase / webdoc / PDF), retrieval internals, troubleshooting
Manager UI Guided setup, playground, diagnostics
Use Lynx from Coral SQL over your code search: SELECT ... FROM lynx.search joined with live GitHub/Sentry data
config.example.json Annotated example configuration

Status

Actively developed by one author; APIs may still move before 1.x stabilizes. Issues and PRs welcome — the test suite runs with pytest and CI must stay green.

License

Apache 2.0

<!-- MCP Registry ownership marker — must stay in the README published on PyPI so registry.modelcontextprotocol.io can verify the package. mcp-name: io.github.lorenzo-cambiaghi/lynx -->

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选