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 分

    請在儲存庫或註冊中心條目中宣告授權條款。