jDocmunch MCP

io.github.jgravelle由 GitHub 账号 jgravelle 发布v1.151.0更新于 Nov 5, 2026

Section-level doc search for .md, .rst, .adoc, .org, .ipynb, .html, .yaml, .json, and OpenAPI specs.

已验证STDIO仅桌面知识与记忆开发者工具

概览

AI 生成的概览

按标题层级索引文档集,让助手按章节搜索、导航并只取回所需章节,而不是整份文件。

可以做什么
  • 索引本地文档文件夹或 GitHub 仓库,并列出、查看生成的索引
  • 按关键词或混合语义排序搜索章节,并按标题匹配
  • 导航结构:目录、大纲、面包屑、子章节与相邻章节
  • 读取单个章节、批量章节、片段预览,或带上下文的章节
  • 文档体检:失效链接、孤立页面、过期页面、反向链接、标签与角色清单、代码示例
  • 查看会话与各工具的性能统计,并生成最终的 Markdown 交接文档
适用场景
适合助手需要在较大文档库中工作、只取回相关章节而非整份文件的场景,也适合对文档做结构或健康检查,例如失效链接、孤立页面和过期页面。
运行要求
本地 Python 3.10+ 进程,从 PyPI 安装(uv tool、uvx、pipx 或 pip)并注册到 MCP 客户端。可选扩展提供 Office 格式与 OCR。语义检索可选,需要 GOOGLE_API_KEY 或 OPENAI_API_KEY 等提供方密钥,或本地模型;OCR 需要 JDOCMUNCH_OCR=1 以及机器上已安装的引擎。
安装前请注意
商业用途需购买一次性付费许可,个人及非商业用途免费。基础包默认发送匿名节省量统计,可用 JDOCMUNCH_SHARE_SAVINGS=0 关闭。启用嵌入或摘要提供方会把数据发送给所配置的服务,本地模型会从 HuggingFace 下载。OCR 会让扫描件(包括敏感表单)对任何可查询该索引的助手可读。delete_index 删除索引后无法撤销。

安装

在 SourceWeft 中

  1. 打开 控制台中的 jDocmunch MCP,将其添加到工作区。
  2. 为需要使用其工具的对话启用该服务。

Desktop only,通过 STDIO。 STDIO 服务会启动本地进程,因此需要 SourceWeft 桌面宿主。

其他 MCP 客户端

参照 仓库 中的启动说明。

README

jDocMunch MCP

jDocMunch is an MCP server for coding agents that retrieves the exact documentation section a task needs, without loading whole files into the context window.

Index a documentation set once by heading hierarchy, then fetch a single section, a heading subtree, or a ranked search result — extracted byte-precisely from the original file.

Install · Quickstart · Benchmarks · Commercial licensing

[PyPI version] [PyPI - Python Version] [License] [MCP] [Local-first] [DOI]

Free for personal use. Commercial use requires a paid license — terms below.


Why jDocMunch?

The problem. An agent asked "how do I configure authentication?" opens a documentation file, skims hundreds of paragraphs it does not need, opens another, and repeats. Large context windows do not fix this. They just make the waste affordable enough to ignore until the bill arrives, and they crowd out the context the model actually needed.

The mechanism. jDocMunch parses a documentation set into a section tree keyed by heading hierarchy, stores each section's byte offsets into the original file, and exposes retrieval over MCP. Sections keep durable identities across re-indexing as long as path, heading text, and heading level are unchanged.

The outcome. The unit of access changes from file to section. An agent retrieves the installation section, one configuration block, or a specific heading subtree — and nothing else.


What makes it different

Section-first retrieval

Search and retrieve documentation by section, not just file path or keyword match.

Byte-precise extraction

Full content is pulled on demand from exact byte offsets into the original file.

Stable section IDs

Sections retain durable identities across re-indexing when path, heading text, and heading level remain unchanged.


Evidence

Four benchmarks against public documentation corpora, each with the corpus, date, and per-query results recorded in benchmarks/.

CorpusScaleIndexed inResult
Kubernetes (kubernetes/website, 2026-03-04)1,569 .md files, 4,355 sections, 16 MB3,352 ms27,285 tokens saved on a single node-affinity query; 100 ms latency
SciPy10,402 sections, ~855,000 corpus tokens2,247 ms135–152 ms per query across sparse-solver, FFT, and optimization lookups
LangChain (MDX)5,973 sections5,204 msMDX-aware sectioning found 754% more sections than the naive pass
Wiki7,449-token corpus—Search returns ranked metadata in ~190 tokens against a 7,449-token whole-corpus read

Read these as per-corpus results, not as a single headline multiple. Savings depend on how large the containing file is relative to the section you needed: a small file with one heading saves almost nothing, and the Kubernetes corpus saves a great deal. The benchmark files record the queries that did poorly alongside the ones that did well.

A separate, measured result from the v1.121.0 projection work, on this repository's own docs at max_results=10: a search row went 1,989 chars → 319 with compact=true (−84%), or 431 with snippet_bytes=200 (−78%) while removing the follow-up get_section call entirely.

Retrieval quality is gated, not assumed. Every release runs a replay fixture over a frozen golden set and fails below nDCG 0.95. That gate has failed builds and blocked releases; it is not decorative.


Install

Requirements: Python 3.10+, any MCP-compatible client.

bash
uv tool install jdocmunch-mcpjdocmunch-mcp init

No virtualenv to manage, nothing written into system Python, and it works as-is on PEP 668 distros (Ubuntu 24.04+, Debian 12+) where bare pip install is refused. Don't have uv yet?

init detects your MCP clients, writes their config entries, installs the doc-exploration prompt policy so your agent actually reaches for the tools, and optionally installs hooks and indexes your docs.

Other install paths
CommandUse it when
uvx jdocmunch-mcpZero install. Runs from an ephemeral environment — nothing lands on disk permanently. The client entries init writes already invoke the server this way, so for most setups this is all that ever runs. ⚠ Hooks are the exception: they're spawned by a minimal-PATH subshell and resolve the executable by name, so they need uv tool install (or pipx/pip) to work.
pipx install jdocmunch-mcpYou already standardise on pipx
pip install jdocmunch-mcpInside a virtualenv you manage yourself

Verify:

bash
jdocmunch-mcp --version

Manual Claude Code setup:

bash
claude mcp add -s user jdocmunch -- uvx jdocmunch-mcp

No install step — uvx fetches and runs the server on demand. Prefer it on your PATH (and required for hooks)? uv tool install jdocmunch-mcp, then claude mcp add -s user jdocmunch jdocmunch-mcp.

Installing the server makes the tools available; it does not break an agent's habit of brute-reading files. One line in your CLAUDE.md does that:

markdown
Call the jdocmunch_guide tool and strictly follow its instructions.

Quickstart

Assumes: jDocMunch installed and registered with your client, and a folder of documentation.

Index a local documentation folder:

bash
jdocmunch-mcp index-local --path ./docs

It prints JSON naming the corpus and what it found:

json
{  "success": true,  "repo": "local/docs",  "file_count": 1,  "section_count": 4,  "doc_types": { ".md": 1 },  "semantic_search": false}

section_count greater than file_count is the whole point: the index addresses headings, not files.

Then, inside your agent:

Using jdocmunch, search the docs for "authentication configuration" and show me that section.

The agent should call search_sections, then get_section on the top hit — returning one section rather than a file. _meta.tokens_saved on the get_section response is a modeled saving: the containing document's size minus the section served (_meta.savings_basis: "modeled"). search_sections itself earns no credit.

Next step: get_toc_tree for a structural view of the whole corpus, or index_repo to index documentation straight from a GitHub repository.

Very large folders

An MCP client stops waiting on a tool call after a fixed time. Indexing a folder with tens of thousands of files can take longer than that. On one Windows machine, a full index of 10,000 files (271,585 sections) took 67 s without embeddings, and sentence-transformers embeddings added about 3 minutes.

If a folder is that large, or an index_local call times out, index it from a shell:

bash
jdocmunch-mcp index-local --path /path/to/folder

The CLI runs the same indexing with no tool timeout. It writes to the same store as the MCP server, so the server uses the index once the command finishes. If you set DOC_INDEX_PATH in your client's MCP config, set it in the shell too.

  • Custom names. If the folder was indexed under a custom name, pass the same --name. Without it, the CLI uses the folder name and writes a second index.
  • The file cap. A folder is capped at 10,000 files, newest first. Raise it with --max-files N (the CLI form of the MCP tool's max_files). When a call hits the cap, its warning prints the command with the folder's discovered count.
  • Narrowing a folder. Exclude what you don't need with --extra-ignore-pattern (repeatable, the CLI form of extra_ignore_patterns), or index only listed files with --paths-from FILE (the CLI form of paths).
  • Embeddings. --no-embeddings builds a lexical index first. Run the command again later with --rebuild to add embeddings.

Scanned PDFs

A scanned PDF is a picture of text, with no text layer to index. The optional [ocr] extra reads them with an OCR engine already on your machine. jDocMunch never installs or downloads an engine, a language pack or a model.

bash
pip install "jdocmunch-mcp[ocr]"

Engines. jDocMunch looks for one in this order and uses the first that answers:

  1. JDOCMUNCH_TESSERACT_PATH, if you set it.
  2. tesseract on PATH.
  3. Tesseract's default install folders: C:\Program Files\Tesseract-OCR, the per-user folder under %LOCALAPPDATA%\Programs, /opt/homebrew/bin, /usr/local/bin and /usr/bin.
  4. On Windows, the built-in Windows OCR, if an English OCR language is installed (it is on English-language Windows).

JDOCMUNCH_OCR_ENGINE=tesseract or windows picks one. JDOCMUNCH_OCR_LANG passes Tesseract languages that are already installed (default eng).

OCR needs two keys. It runs only when both are set:

  • You set JDOCMUNCH_OCR=1 in your MCP client's env block (or your shell, for the CLI).
  • The call asks for it: index_local(ocr=true), or index-local --ocr on the CLI.

So an agent can't turn OCR on by itself. The choice is stored with the index, and later refreshes and the watcher reuse it; ocr=false or --no-ocr turns it off. Every response that ran with OCR requested has an ocr block saying whether it was enabled in config, whether it was used, how much it read and with which engine.

What you get. Each scanned image becomes a ## Page N section. Every section from OCR is marked text_source: "ocr", with ocr_engine, ocr_pages and (Tesseract only) ocr_confidence. The document opens with a visible note that its text came from OCR, and the response warns about it. Any part of a PDF with its own text layer keeps it. OCR sections earn no token-savings credit.

How good it is. On 6 real public-domain scans of printed prose (Encyclopaedia Britannica 1911 and The American Printer), Tesseract 5.4 found 97.4% of the words with a 2.0% character error rate, and Windows OCR 97.1% and 2.0%. The limits:

  • Tables and forms may come out scrambled. The words are mostly there, so a search can find them, but columns and fields lose their layout. On two scanned forms, Tesseract found 25% to 80% of the words.
  • Decorative and black-letter (Gothic) type isn't read. Neither engine reads it.
  • Handwriting isn't read.

Speed. Tesseract took 3.4 s per image here (Windows OCR 0.3 s): a 20-image scan took 69 s with Tesseract and 6 s with Windows OCR. An MCP call gives OCR a 60-second budget (ocr_budget_seconds), so with Tesseract, a scan of 20 images or more may not finish in one call. It's skipped as ocr_budget_exhausted. What was already read is cached, and the next call carries on. For a folder of scans, run the CLI, which has no budget:

bash
JDOCMUNCH_OCR=1 jdocmunch-mcp index-local --path /path/to/scans --ocr

The first 50 scanned images of a document are read (ocr_max_pages, --ocr-max-pages); the rest are reported as ocr_pages_capped.

Privacy. OCR runs on your machine. Tesseract is a local program, and Windows OCR is an on-device Windows API; no page leaves the machine. But OCR turns scans into searchable text. If you OCR tax forms, pay stubs, IDs or medical records, their contents (names, SSNs, account numbers) become readable to any agent that can query this index, and they're stored in the index's text cache on disk. jDocMunch's secret-file rules match file names, not contents, so they won't catch a scanned W-2. Keep such files out of indexed folders, or exclude them with extra_ignore_patterns.


What you can do

  • Retrieve one section instead of a document. get_section and get_sections pull byte-precise content from the original file; get_section_excerpt narrows further.
  • Search by meaning, not just keywords. search_sections fuses BM25 with semantic cosine when an embedding provider is configured. compact=true, fields=[...], and snippet_bytes=N cut the response further.
  • Navigate structure. get_toc, get_toc_tree, get_section_path, get_section_descendants, and section_neighbors traverse the heading tree without reading content.
  • Find what documentation is missing or rotting. get_doc_coverage, get_undocumented_symbols, get_stale_pages, get_orphan_sections, get_broken_links, and doc_health_radar.
  • Work across API specs. find_endpoint, list_endpoints_by_tag, find_operations_using_schema, and get_schema_graph treat OpenAPI documents as first-class.
  • Preflight documentation changes. check_section_delete_safe and get_section_blast_radius before you remove or restructure.
  • Know when an answer is stale. Content reads disclose _meta.freshness, _meta.verdict, and which source layer answered.

64 tools in total. The full reference is in USER_GUIDE.md.


How it works

Everything runs locally. Indexes live under your home directory; no hosted service is required for indexing or retrieval.

text
docs/ ──► parser (per format) ──► section tree ──► local index                                                      │                          MCP client ◄── retrieval ◄──┘
  • Parsing is per format, one module each: Markdown/MDX, reStructuredText, AsciiDoc, Org-mode, Jupyter notebooks, HTML, plain text, OpenAPI (YAML), JSON/JSONC, XML/SVG/XHTML, Godot scenes, and — via the optional [office] extra — PDF, DOCX, PPTX, and EPUB.
  • Storage is a versioned local index (INDEX_VERSION = 3) that auto-migrates on first load. A 1.x release never forces a reindex.
  • Retrieval is lexical BM25 by default, hybrid when embeddings are available.
  • Embeddings are optional and provider-agnostic — Gemini, OpenAI, an OpenAI-compatible endpoint, or a local offline model through either FastEmbed (ONNX) or sentence-transformers (torch). Without one, search stays lexical and entirely offline.

Deeper detail: ARCHITECTURE.md and SPEC.md.

Memory in long-running processes

A parsed index takes about 2.5 to 3 times its file's size in memory (measured on five real indexes, 0.5 MB to 112 MB). Two settings keep long-running processes bounded:

  • JDOCMUNCH_INDEX_CACHE_MAX_BYTES caps the indexes the server keeps parsed between calls. The default is 512 MiB, estimated as 3 times each index file's size. Past it, the least recently used index is dropped and re-read when it's next needed. A single index larger than the cap is still kept. 0 or less turns the byte cap off; the 8-index cap stays either way.
  • JDOCMUNCH_WATCH_INPROCESS=1 makes the watcher re-index in its own process instead of a child per batch (see below).

Security and privacy

Local-first by design. Your documentation is parsed and stored on your machine, and the base package's only default network behavior is an anonymous savings counter — a random ID plus aggregate token counts, no content, no paths, no PII.

Opt out completely:

bash
JDOCMUNCH_SHARE_SAVINGS=0

Embedding and summarizer providers call their configured API only when you enable them, and never by default. watch-install registers a login service only when you run it yourself.

Background behavior, fully disclosed

A model download, the first time a local embedding provider runs. Both offline providers fetch their model from HuggingFace on first use and cache it on disk. Nothing downloads until you enable embeddings, and a lexical-only install never contacts the hub. Startup warmup is skipped when the model is not already cached, so a first run defers the download to your first search rather than stalling the MCP handshake behind it (#110).

A package install and a model download, only if you say yes to init. jdocmunch-mcp init checks whether an embedding provider is available. If none is, it asks once whether to turn semantic search on. The default answer is no. On a yes it does two things and prints both before doing them:

  • runs python -m pip install "fastembed>=0.8.0" in the Python environment jdocmunch is running in (about 160 MB installed; pulls onnxruntime, not torch);
  • downloads one model file, all-MiniLM-L6-v2 in ONNX form, from huggingface.co (87 MB, once).

After that, embedding runs on your machine. No text from your documents is sent anywhere. --yes does not answer this question for you: it accepts config edits, not a download. A scripted install opts in with --with-embeddings. --dry-run prints the command and the sizes and touches nothing. If pip is not usable (a uv tool or pipx install has none) or the install fails, init prints the manual command for your install style and carries on with word matching. The MCP server itself never installs or downloads anything unasked.

Why init asks at all: on a public benchmark of 492 real user questions over 6 documentation sets, semantic (hybrid) search put a direct answer in the top 5 results for 47% of questions, against 34% for word matching alone. Method, data and the negative result that came with it: jdoc-rerank-bench. Measured on one CPU-only machine, embedding added about 7 seconds per 1,000 sections to a first index. doc_list_repos reports has_embeddings per index, so you can see which ones are still words-only.

FastEmbed as the offline provider. pip install jdocmunch-mcp[fastembed] runs the same all-MiniLM-L6-v2 model through onnxruntime instead of torch, which is a much smaller install. When both offline providers are present FastEmbed is preferred; JDOCMUNCH_EMBEDDING_PROVIDER=sentence-transformers selects the other one. On the shared model the two write the same vector store, so switching runtimes does not re-embed your corpus. Point FastEmbed at a different model with JDOCMUNCH_FASTEMBED_MODEL and it keeps its own vectors instead, because vectors from two models are not interchangeable (#126).

Where the FastEmbed model lives, and repairing it. FastEmbed's own default folder is <temp dir>/fastembed_cache, and OS cleanup can empty it. When the model can't load, index_local says so in embedding_provider_error and a warning, and search is word matching until it is fixed. init checks the model from local files only, without a download. If the model is missing or damaged, it offers a repair, and the repair asks for the same consent as the install: a yes at the prompt, or --with-embeddings. The repair downloads the model (87 MB, once) into ~/.cache/jdocmunch-mcp/fastembed, outside the temp directory. The server loads from that folder once the model is there; an install whose temp-dir copy works keeps using it and is never re-downloaded. JDOCMUNCH_FASTEMBED_CACHE names a different folder, and FastEmbed's own FASTEMBED_CACHE_PATH still takes precedence over both.

A local OCR program, only if you turn OCR on. With the [ocr] extra, JDOCMUNCH_OCR=1 in config and ocr=true on the call (or --ocr), jDocMunch runs Tesseract as a short-lived child process once per scanned page, or calls Windows' on-device OCR. Neither opens a network connection. The text is cached under your doc-index directory (.office_cache/ocr). Nothing runs in the background and nothing is installed. See Scanned PDFs for what OCR'd text exposes.

A child process per watcher batch. The watcher (jdocmunch-mcp watch, or the jdocmunch-watch login service) re-indexes each batch of changed files in a short-lived child, python -m jdocmunch_mcp.watch_batch. A re-index rewrites the whole index file, and memory used for that doesn't return to the system in a long-running process, so the watcher's memory used to climb toward its limit (#189). The child returns it when it exits. It:

  • runs once per batch, and exits when the batch is done;
  • opens no network connection of its own; it calls only what indexing already calls, such as your embedding or summary provider if you set one;
  • starts its embedding provider fresh each time. On one Windows PC, a one-file batch took 0.3 s in-process, 0.55 s in a child, and 1.7 s in a child with FastEmbed on (the model loads each time). sentence-transformers wasn't measured and loads more slowly;
  • on Windows, opens no console window.

JDOCMUNCH_WATCH_INPROCESS=1 restores the previous in-process re-index.

A child process, when local embeddings are in use. When the sentence-transformers provider is active, jDocMunch runs the embedding model in a child process (python -m jdocmunch_mcp.embeddings.worker) instead of inside the server. It:

  • starts when something first needs an embedding — at startup if the model is already in your local HuggingFace cache, otherwise on the first search or index that uses it. A lexical-only install never spawns it;
  • opens no network connection and speaks only to its parent, over a private pipe;
  • exits when the server exits, and is killed if it stops responding;
  • is not a login service, is not registered anywhere, and survives nothing.

This exists because importing the embedding stack inside the server process can deadlock in the Windows loader (#118), hanging every tool call for as long as the server runs. Disable it with JDOCMUNCH_EMBED_WORKER=0, which restores the previous in-process import.

A login service, only if you install one. jdocmunch-mcp watch-install registers the doc watcher to start at login (systemd user unit, launchd agent, or a Task Scheduler task named jdocmunch-watch). Nothing installs it for you. Once installed it:

  • re-indexes every locally-indexed doc repo when a doc file on disk changes;
  • runs exactly jdocmunch-mcp watch with the flags you passed to watch-install — --no-ai-summaries to keep the summarizer out of it, --quiet to suppress its per-change log lines;
  • writes to watch.log and watch.err under your doc-index directory;
  • is removed by jdocmunch-mcp watch-uninstall.

⚠ Re-running watch-install rewrites the service definition, so a hand-edited one is replaced. It now prints what it replaced; pass the flags to watch-install itself so an upgrade keeps them (#120).

Path traversal prevention, symlink escape protection, secret exclusion, file-size limits, binary detection, and encoding safety are documented in SECURITY.md, along with how to report a vulnerability.


Limitations

  • Section retrieval helps least on small files. If a document has one heading and 40 lines, retrieving the section and reading the file cost about the same.
  • Semantic search requires an embedding provider. Without one, search is lexical only — good for identifiers and exact phrasing, weaker for paraphrased questions.
  • Office formats need the optional [office] extra and are supported for local indexing only. A scanned (image-only) PDF has no text layer, so without OCR it is not indexed. The response names it under skipped_paths.no_extractable_text, adds a warning, and reports coverage_complete: false.
  • OCR is optional, off by default, and modest. With the [ocr] extra, an engine already on your machine and both keys set, scanned pages are read (see Scanned PDFs). Printed prose reads well. Tables and forms may come out scrambled, and decorative, black-letter and handwritten text isn't read.
  • Freshness is disclosed, not guaranteed. A section whose source cannot be checked is reported as unknown rather than assumed current.
  • jDocMunch does not parse code. Symbols, signatures, and call graphs belong to jcodemunch-mcp; tabular data belongs to jdatamunch-mcp.

Documentation

DocWhat it covers
USER_GUIDE.mdFull tool reference, workflows, and best practices
ARCHITECTURE.mdStorage model, parsing pipeline, extension points
SPEC.mdResponse contracts and reason-code vocabulary
SECURITY.mdSecurity controls and vulnerability reporting
TOKEN_SAVINGS.mdHow savings are counted and reported
CONTRIBUTING.mdDevelopment setup and the CLA requirement
CHANGELOG.md · ROADMAP.mdRelease history and what's next

Licensing and commercial use

Released under the jDocMunch-MCP Dual-Use License (full terms). Free for non-commercial use. Commercial use requires a paid license, one-time, sold by jMunch LLC.

jDocMunch only: Builder, $29 (1 developer) · Studio, $99 (up to 5) · Platform, $499 (org-wide internal deployment)

Full jMunch suite (code + docs + data): Trio Builder, $99 · Trio Studio, $449 · Trio Platform, $2,499

Personal and other non-commercial use is free. Work use at a for-profit company, or for client or paid work, needs a license, paid once.

1.x compatibility commitment

Every 1.x license entitles you to every future 1.x release. We will never ship a 1.x version that:

  • removes or renames an MCP tool (deprecated tool names keep their aliases),
  • drops a Section field from the response shape,
  • forces a reindex without auto-migrating your existing index on first load,
  • changes the JSON wire format of any tool response in a way that breaks an existing consumer,
  • or makes a previously-default behavior raise.

Anything that would require breaking these promises is reserved for a future major version (2.x). The full machine-checked contract is enforced via tests/test_server.py (tool-name and required-field invariants) and the replay-fixture gate that runs on every release.


Support and project status

Actively maintained. Issues and bug reports: GitHub Issues. Security reports: see SECURITY.md. Commercial licensing questions go through jcodemunch.com.

Part of the jMunch suite alongside jcodemunch-mcp (code symbols) and jdatamunch-mcp (tabular data). All three implement jMRI, the open retrieval interface spec.

来源:README.md,提交 c0b9a41

工具

64

index_local

Index a local folder containing documentation files (.md, .txt, .rst; plus .pdf/.docx/.pptx/.epub when the optional [office] extra is installed — converted to Markdown locally). Parses by heading hierarchy into sections for efficient retrieval. An already-indexed source is recognized before storage is chosen: the established handle is reused (or refreshed), an explicit conflicting name returns a conflict instead of creating a duplicate index, and multiple equivalent legacy indexes return bounded ambiguity. Embeddings auto-enable when a provider is configured (GOOGLE_API_KEY, OPENAI_API_KEY, openai-compatible + JDOCMUNCH_OPENAI_COMPAT_URL + JDOCMUNCH_OPENAI_COMPAT_MODEL, or sentence-transformers). For a folder of tens of thousands of files, which can outlast a client's tool timeout, run `jdocmunch-mcp index-local --path <dir>` from a shell instead; this server reads the index it writes. Coverage: `coverage_complete` answers 'did I get everything', with `skip_counts` / `skipped_paths` naming what was dropped and why; `truncated` answers ONLY the max_files cap and is false when a file was dropped for any other reason. Files over the per-file size cap (5MB default, JDOCMUNCH_MAX_FILE_SIZE) are reported under skip_counts.oversize. Response includes a `changes` list with one {doc_path, status: new|changed|deleted, mtime} entry per file, sorted newest first and capped at 50 entries, useful for a 'recently edited' map at session start. `changes_total` is the uncapped count and `changes_truncated` is true when entries were dropped. Deleted files sort last, so the cap drops them first: the `new`/`changed`/`deleted` count fields are the authority, not the length of `changes`. v1.147+ — a response that indexes the folder or finds nothing to change returns `duplicate_anchors` (empty when none; at most 20 entries, each with `section_ids` and `titles` capped at 20 and `section_ids_truncated`), `duplicate_anchors_total` (uncapped), `duplicate_anchors_truncated` and `duplicate_ancho

输入参数ocrnamepath必填pathssort_byautotunemax_filesincrementalocr_max_pagesworktree_modeuse_embeddingsfollow_symlinks另有 5 个

doc_index_repo

Index a GitHub repository's documentation. Fetches .md/.txt files, parses sections, and saves to local storage. Embeddings auto-enable when a provider is configured (GOOGLE_API_KEY, OPENAI_API_KEY, openai-compatible + JDOCMUNCH_OPENAI_COMPAT_URL + JDOCMUNCH_OPENAI_COMPAT_MODEL, or sentence-transformers). Indexes .md and .txt only; every other file in the repo is ignored. Returns `changes` on every success path (at most 50 entries, newest first) with `changes_total` and `changes_truncated` beside it; the new/changed/deleted counts are the authority, not len(changes). Each entry's `mtime` is the head COMMIT date, offset-aware (e.g. 2026-09-20T13:15:39+00:00), because a repository has no per-file modification time. index_local's `mtime` is naive local time instead, so read the offset before comparing times across the two. v1.147+ — every success response returns `duplicate_anchors` (empty when none; at most 20 entries, each with `section_ids` and `titles` capped at 20 and `section_ids_truncated`), `duplicate_anchors_total` (uncapped), `duplicate_anchors_truncated` and `duplicate_anchor_warning` for explicit `{#id}` headings written twice in one document.

输入参数refurl必填nameincrementaluse_embeddingsuse_ai_summaries

doc_list_repos

List every indexed documentation repo with its identifier and storage location. Call it first to find out whether the docs you need are already indexed, and to get the repo id every other tool needs. Lists only indexes under the active storage_path, so an empty list means nothing is indexed there. Each row has has_embeddings: false means that index matches words only.

无需输入参数。

get_index_overview

v1.56+ — single-call repo snapshot: doc_count, section_count, total_byte_size, format_breakdown, top_tags, top_roles, indexed_at. Composition of v1.46/v1.50/v1.55 aggregations. Use for 'what is this repo at a glance?'. Counts come from the index, so they are only as fresh as the last index run.

输入参数repo必填top_n

get_doc

v1.58+ — single-doc detail view. Pairs with list_docs (cross-doc inventory). Returns section list (handles), role_distribution, tag_distribution, byte_size, format, indexed_at for one doc. No content reads.

输入参数repo必填doc_path必填

list_docs

v1.55+ — flat per-doc inventory of an indexed repo: doc_path, section_count, format, byte_size for each indexed document. Lighter than get_toc_tree (which returns full section trees per doc). Sorted by doc_path. Inventory only; it returns no section titles and no content. Each doc also carries `mtime` when one is known — as of the last indexing pass, omitted when unknown rather than null — and `_meta.docs_with_mtime` says how many have one, so a partially filled or pre-1.144 index is distinguishable from a complete one.

输入参数repo必填limitoffsetpath_glob

get_toc

Get a flat table of contents for all sections in a repo, sorted by document order. Content is excluded — use get_section to retrieve content. Scope with path_glob; for a SINGLE document use get_document_outline (this tool has no doc_path parameter).

输入参数repo必填limitoffsetpath_glob

get_toc_tree

Get a nested table of contents tree per document. Shows parent/child heading relationships. Content is excluded.

输入参数repo必填limitoffsetpath_glob

get_document_outline

Get the section hierarchy for a single document file, without content. Headings only, no content. Read a section with get_section.

输入参数repo必填doc_path必填

search_sections

Search sections by relevance. Hybrid (BM25 lexical + semantic embedding) fusion when the index was built with use_embeddings=true; falls back to lexical-only otherwise. Returns summaries only — use get_section for full content. Results with text_source="ocr" came from a scanned page via OCR and may contain errors.

输入参数reporoletagsquery必填rolesdedupefieldscompactprofiledoc_pathsemanticmax_level另有 13 个

count_sections

v1.59+ — count sections matching the same filter set as search_sections (path_glob, role/roles/exclude_roles, tags/exclude_tags, min/max_level, min/max_byte_length) but skip ranking. Use for UI counters or 'does anything match?' probes. Returns the count only, never the matching sections.

输入参数repo必填roletagsrolesdoc_pathmax_levelmin_levelpath_globexclude_tagsexclude_rolesmax_byte_lengthmin_byte_length

search_titles

v1.57+ — fast title-only token-overlap match. Different from search_sections (full hybrid retrieval). Use for navigation: 'find the section whose heading text matches X'. Handle-only output ({id, title, level, doc_path, _score}); no content reads, no embeddings.

输入参数repo必填query必填max_results

get_section

Retrieve the full content of a specific section using byte-range reads. Use after identifying section IDs via search_sections or get_toc. Returns this section's own bytes; nested child sections are not included. A section with text_source="ocr" was read from a scanned page by OCR: its text may contain errors, and tables or forms in it may be scrambled.

输入参数repo必填verifysection_id必填compress_codestrip_boilerplate

get_sections

Batch content retrieval for multiple sections in one call. Content only for the ids you pass; unknown ids come back as per-id errors, not a failed call.

输入参数repo必填verifysection_ids必填compress_codestrip_boilerplate

get_section_context

Retrieve a section with its full hierarchy context: ancestor headings (root → parent) for orientation, the target section's content, and immediate child summaries. Prevents 'section too thin' without falling back to whole-file reads.

输入参数repo必填max_tokenssection_id必填include_relatedinclude_childrenstrip_boilerplate

describe_section

v1.54+ — consolidated handle bundle: full metadata + ancestor breadcrumb + prev/next/parent/first_child neighbors for one section in a single call. Saves three round-trips vs calling get_section_summary + get_section_path + section_neighbors separately. No content reads.

输入参数repo必填section_id必填

section_neighbors

v1.37+ — return prev/next siblings (in document order), parent, and first child for a section. Handles only (id, title, level, doc_path) — no content. Use for fast sequential navigation without re-querying search_sections.

输入参数repo必填section_id必填

get_recent_changes

v1.47+ — list sections that have drifted from index state (edited_uncommitted or stale_index buckets via the v1.16 FreshnessProbe). By default compares the index against the cached raw-content mirror, NOT live workspace files; pass live_source=true to read the live files under the index's source_root. _meta.drift_layer reports which layer ran. Pre-flight check before deciding whether to re-index. Handle-only — no content reads.

输入参数repo必填live_sourceinclude_staleinclude_edited

get_all_roles

v1.50+ — list every distinct role classification across the repo with per-role section counts and id samples. Companion to v1.46 get_all_tags. Sections without metadata.role are bucketed under 'unknown'. Use to discover what roles exist before constructing a `role=` or `profile=` query.

输入参数repo必填sample_size

get_all_tags

v1.46+ — list every unique #hashtag across the repo with per-tag section counts. Companion to the v1.45 `tags` filter on search_sections — use this to discover what tag namespaces exist before constructing a tag-filtered query. Lowercase-normalized. Aggregates the tags the index stored on each section, so a tag added since the last index is missing.

输入参数repo必填min_section_count

get_section_descendants

v1.43+ — return every descendant of a section (BFS over parent_id) in document order with depth offset. Pairs with get_section_path (ancestors). Optional max_depth caps the walk; max_depth=1 returns immediate children only. Handles only — no content.

输入参数repo必填max_depthsection_id必填

get_section_excerpts

v1.49+ — batch counterpart to get_section_excerpt. Resolves N previews in one call against a single index load. Per-id errors reported in-line. _meta.tokens_saved aggregates byte savings across the batch. Previews are truncated by design; read full content with get_sections.

输入参数repo必填max_bytessection_ids必填

get_section_excerpt

v1.41+ — return a short content preview (default 500 bytes) for one section. Trimmed to last newline before the cap so it ends on a paragraph boundary. Use to peek at content before paying for a full get_section read. _meta.tokens_saved reports the byte-savings vs full content.

输入参数repo必填max_bytessection_id必填

get_section_path

v1.40+ — return the breadcrumb chain (root → ... → target) for a section_id. Walks parent_id upward; cycle-protected. Handles only ({id, title, level, doc_path}) per step plus depth.

输入参数repo必填section_id必填

get_orphan_sections

v1.39+ — list sections whose doc_path receives zero inbound references from any other doc. Companion to get_broken_links and get_stale_pages: documentation that exists but nobody links to. Inbound links are counted across indexed docs only, so a link from code or an external site does not rescue a section.

输入参数repo必填include_same_doc

get_section_summary

v1.38+ — return full indexed metadata (title, summary, role, tags, metadata, parent_id, children, content_hash, byte_start/end, byte_length) for one section without fetching content. Use to inspect role/tags before deciding whether to read the content via get_section.

输入参数repo必填section_id必填

get_section_summaries

v1.48+ — batch version of get_section_summary. Resolve metadata for many ids in one call against a single index load. Per-id errors are reported in-line on the corresponding result entry rather than aborting the batch.

输入参数repo必填section_ids必填

delete_index

Remove a repo index and its cached raw files. Deletes the index and its cached files, never your source documents. There is no undo; re-index to restore.

输入参数repo必填

get_doc_coverage

Check which jcodemunch symbols have matching documentation in this doc index. Given a list of jcodemunch symbol IDs, reports which symbols are mentioned in section titles (documented) vs absent (undocumented). Bridges jcodemunch <-> jdocmunch. symbol_ids capped at 200. Output: {documented, undocumented, coverage_pct}.

输入参数repo必填symbol_ids必填

get_stale_pages

Find wiki pages whose declared sources have been modified on disk. Convention: wiki pages include YAML frontmatter with a 'sources' list of relative paths to raw source files. This tool checks whether those source files have changed since the page was last indexed. Output: list of {doc_path, title, stale_sources} where each stale source has a reason: 'modified', 'missing', or 'untracked'.

输入参数repo必填sources_dir

get_wiki_stats

Wiki health dashboard. Returns: orphan pages (zero inbound internal links), most-linked pages (top 10), tag distribution, total internal link count, and sections-per-doc min/max/avg. Use for periodic wiki lint checks.

输入参数repo必填

analyze_perf

Per-tool latency analysis. window='session' reads the in-memory ring (last 512 calls per tool — always available); window='1h'|'24h'|'7d'|'all' reads the persistent SQLite sink at ~/.doc-index/telemetry.db (opt-in via JDOCMUNCH_PERF_TELEMETRY=1). Returns {window, telemetry_enabled, source, per_tool:{tool:{count,p50_ms,p95_ms,max_ms,errors,error_rate}}}.

输入参数window

get_session_stats

Session self-monitor: returns {latency_per_tool, total_tokens_saved (modeled: file bytes avoided minus bytes served; searches earn none)}. Lightweight; reads the in-memory latency ring + persistent savings counter. For windowed analysis use analyze_perf. The latency ring lives in memory, so a server restart clears it.

无需输入参数。

get_watch_status

Doc-watcher coverage + login-service state. Reports whether the `jdocmunch-watch` background service is active and, per locally-indexed doc repo, whether its source_root still exists on disk (watchable). Returns {service, watchable_repo_count, local_repo_count, repos[], hint}. Run `jdocmunch-mcp watch` (foreground) or `watch-install` (login service) to keep indexes fresh on any on-disk doc change. Covers locally-indexed repos only; a GitHub-indexed repo has no source_root to watch.

无需输入参数。

finalize_handoff

Finalize one canonical Markdown handoff for a completed documentation audit/analysis (jdocmunch.handoff/v1; suite parity with jCodeMunch). The server assembles YOUR sections deterministically, validates every evidence_refs entry against what this session actually retrieved (section ids or doc paths served by search_sections / search_titles / get_section / get_sections — unknown refs fail closed), persists the result session-scoped, and returns a compact receipt {handoff_id, resource_uri, sha256, length, canonical:true}. Read the immutable body via the munch://handoff/<id> resource; repeated reads are byte-identical. Appendices are included exactly once; no character limit; never writes to the documentation corpus.

输入参数repo必填task必填profilesections必填appendicesevidence_refs必填

find_code_examples

Search fenced code blocks across the indexed docs by BM25 over the block content. Returns one row per block with {block_id, section_id, doc_path, title, lang, byte_start, byte_end, snippet, _score}. Optional lang filter (e.g. 'python', 'bash') and doc_path/path_glob scope filters (applied before scoring, same contract as search_sections). Use after index_local; requires INDEX_VERSION>=3.

输入参数langrepo必填query必填doc_pathpath_globmax_results

doc_resolve_repo

Resolve a filesystem path (index root, subfolder, or file) to its indexed documentation repo handle via stored source_root metadata — O(1)-sized response, use instead of doc_list_repos when the path is known. Exact root match wins, then the most specific containing root; equally-specific duplicates return ambiguous:true with a bounded candidates list (max 5) plus total_matches. GitHub-indexed corpora (no source_root) never match. Read-only: never creates, refreshes, or deletes an index. Prefer absolute paths; relative paths resolve against the server CWD (echoed as _meta.resolved_path).

输入参数path必填

find_endpoint

Find OpenAPI operations by path glob, method, and/or tag. All filters AND'd. Returns one row per match with {section_id, doc_path, method, path, operationId, summary, tags, deprecated}. Requires the spec to have been indexed under v1.18+ so structured metadata is present.

输入参数tagpathrepo必填method

list_endpoints_by_tag

Return every operation whose tags list contains the given tag (exact). Convenience wrapper around find_endpoint with only a tag filter.

输入参数tag必填repo必填

find_operations_using_schema

Return every operation whose request body or any response references the given schema. Each row gets a referenced_in list of all schema names that operation pulls in (so you can see the broader dependency cluster). Resolves references inside the indexed OpenAPI document only.

输入参数repo必填schema_name必填

get_schema_graph

BFS walk of the schema reference graph from a root schema name. Returns {root, nodes:{name:{type, properties, required, refs}}, edges:[[from, to]], unresolved}. max_depth bounds the walk (default 5).

输入参数repo必填max_depthschema_name必填

lookup_term

Glossary lookup. Returns every entry whose term equals the query (case-insensitive, exact). Glossary entries are extracted at index time from **Term** — definition Markdown patterns and RST .. glossary:: blocks.

输入参数repo必填term必填

list_terms

List glossary terms in alphabetical order, optionally filtered by prefix. Capped at max_results (default 100).

输入参数repo必填prefixmax_results

get_section_diff

Unified diff between the indexed snapshot and the current on-disk byte range for a section. Returns hashes + diff text; identical=true when the section is in sync with disk.

输入参数repo必填section_id必填

get_doc_health

One-shot index health diagnostics. Returns section_count, doc_count, role_distribution, freshness counts, broken_link_count, drift status, BM25 corpus sanity, and embedding coverage. Diagnoses the index, not the writing; a healthy report says nothing about whether the docs are correct.

输入参数repo必填

doc_health_radar

Six-axis health radar for a doc repo: freshness, link_integrity, orphan_health, embedding_coverage, role_coverage, drift_health (omitted when no canary). Each axis is 0-100, plus composite + A-F grade. Pairs with diff_doc_health_radar for snapshot deltas. Mirrors jcm's and jData's health-radar shape — third leg of the suite-wide pattern. Grades the index, not the prose; none of the six axes read the writing itself.

输入参数repo必填

get_doc_pr_risk_profile

Composite doc-PR risk profile. Fuses volume + blast_radius + backlink_burden + tutorial_disruption + role_weight signals over a caller-supplied list of changed sections into a 0-1 risk_score with risk_level (low/medium/high/critical), top-5 blockers, and a one-line recommended_action. Caller computes the change list from a git diff or pairs with get_recent_changes. Mirrors jcm's get_pr_risk_profile.

输入参数repo必填changed_sections必填

diff_doc_health_radar

Diff two doc_health_radar payloads. Pure function — pass the `radar` sub-field from two doc_health_radar responses (e.g. yesterday vs today). Returns per-axis deltas, composite delta, grade change, regression and improvement lists (threshold: 3 points), one-line verdict.

输入参数current必填baseline必填

get_tutorial_path

Reconstruct an ordered tutorial chain starting from section_id. Detects frontmatter next:/prev: keys, inline 'Next:' / 'Previous:' markdown links, or ordered numeric filename prefixes (01-intro.md). Returns chain[] of {section_id, doc_path, title} plus the strategy used. Follows only the three conventions above, so a tutorial wired up any other way returns a short chain.

输入参数repo必填section_id必填

get_undocumented_symbols

Best-effort inverse coverage: enumerate symbols in the jcodemunch code_repo and return those whose name (or qualified name) does not appear anywhere in this doc index. _meta.bridge_available=false when jcodemunch-mcp is not importable in this environment.

输入参数repo必填code_repo必填max_symbols

list_repo_groups

List defined repo groups (v1.26+). Each group is a named alias for a set of indexed repos that search_sections can fan out across via the repo_group kwarg. Lists the group definitions only; it does not check that every member repo is still indexed.

无需输入参数。

define_repo_group

Create, replace, or delete a repo group (v1.26+). Empty repos list deletes the group. Persisted to ~/.doc-index/_groups.jsonc (JSONC — hand-edits welcome).

输入参数name必填repos必填

tune_weights

Online weight tuning. Reads ranking_events from ~/.doc-index/telemetry.db (requires JDOCMUNCH_PERF_TELEMETRY=1) and proposes a per-repo semantic_weight step. dry_run=true skips the disk write. min_events gates against early overfitting. Learns from a recency window of the ledger (default 90 days) so stale events can't anchor the weights. Learning compares confidence WITH vs WITHOUT the semantic channel, so a workload that only ever runs one mode produces no signal at all — use set_weight there instead of waiting.

输入参数repodry_runmin_eventsset_weightmax_age_days

verify_index

Byte-offset integrity check. Walks every section, byte-range-reads the bytes, recomputes SHA-256, and compares to the stored content_hash. source='cache' (default) checks the INDEX MIRROR: a clean result proves the index is internally consistent, NOT that the source document is still current. source='live' checks the real workspace files under the index source_root, so an edited source drifts and a deleted one goes missing. _meta.verify_layer always names which one ran. Reports drift / missing / error counts plus the drifting section ids. Sample N sections via the sample arg for cheap CI checks.

输入参数repo必填samplesource

check_embedding_drift

Embedding-drift canary. Without args, re-embeds the saved CANARY_STRINGS and reports per-canary cosine drift; alarm fires when max_drift > threshold (default 0.05 ≈ cosine<0.95). Pass capture=true to seed the snapshot first (idempotent unless force=true). Catches silent provider model upgrades that would otherwise corrupt index recall without changing dim.

输入参数forcecapturethreshold

find_similar_sections

Multi-signal section dedup detection. Fuses embedding cosine (when available) with lexical Jaccard over the section title and its ACTUAL body bytes, clusters via union-find, ranks each cluster's canonical by backlink_count + size. Verdict tiers: near_duplicate, overlapping_topic, parallel_tutorial. Each cluster and variant carries signal=body|title_only; a title_only comparison had no body evidence and is never near_duplicate. Read-only.

输入参数repo必填min_scoremax_clustersmax_sectionsexclude_same_docnear_duplicate_threshold

get_section_blast_radius

Transitive impact of rewriting / restructuring a section. Walks the inbound reference graph to max_depth (default 3), classifies each hit as anchor / doc / tutorial, and returns direct_impact, transitive_impact, a summary, and a normalised blast_score in [0, 1]. Companion to get_backlinks (which is depth 1 only). Read-only.

输入参数repo必填max_depthsection_id必填

check_section_delete_safe

Composite preflight: is this section safe to delete? Fuses tutorial-path membership, anchor-specific backlinks, transitive doc-level backlinks, and recent-edit recency into a single verdict (safe_to_delete, tutorial_path_blocking, anchor_referenced, backlinks_blocking, recently_edited_blocking) plus up to 5 ranked blockers and a one-line recommended_action. Read-only — never mutates the index.

输入参数repo必填section_id必填recent_edit_daystransitive_depth

jdocmunch_guide

Return the version-current CLAUDE.md / AGENT.md policy snippet for jdocmunch-mcp. Lets an agent keep a one-line CLAUDE.md (e.g. "Call jdocmunch_guide and strictly follow its instructions.") instead of pasting a static snippet that drifts from the installed version. Idempotent, no repo context required. Sibling of jcodemunch_guide.

无需输入参数。

版本历史

20
  1. v1.151.0最新Nov 5, 2026
  2. v1.150.1Oct 24, 2026
  3. v1.150.0Oct 20, 2026
  4. v1.149.0Oct 19, 2026
  5. v1.148.1Oct 18, 2026
  6. v1.148.0Oct 17, 2026
  7. v1.147.1Oct 17, 2026
  8. v1.147.0Oct 16, 2026
  9. v1.146.0Oct 15, 2026
  10. v1.145.5Oct 14, 2026
  11. v1.145.4Oct 14, 2026
  12. v1.145.3Oct 13, 2026
  13. v1.145.2Oct 6, 2026
  14. v1.145.0Sep 25, 2026
  15. v1.144.0Sep 22, 2026
  16. v1.143.0Sep 20, 2026
  17. v1.142.0Sep 19, 2026
  18. v1.141.0Sep 18, 2026
  19. v1.140.0Sep 18, 2026
  20. v1.139.1Sep 16, 2026

评分

已满足适用检查项的 80%

该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。

  • 近 30 天内可连通25 分
  • 已声明认证方式10 分

    请在注册中心条目中声明凭据请求头,或保持端点能够响应探测,以便判定其认证方式。

  • 已列出工具必需15 分
  • 描述必需15 分
  • 图标10 分
  • 文档15 分
  • 许可证10 分

    请在仓库或注册中心条目中声明许可证。