Most AI agents still explore documentation the expensive way:
open file → skim hundreds of irrelevant paragraphs → open another file → repeat
That burns tokens, floods context windows with noise, and forces models to reason through a lot of text they never needed in the first place.
jDocMunch-MCP lets AI agents navigate documentation by section instead of reading files by brute force.
It indexes a documentation set once, then retrieves exactly the section the agent actually needs, with byte-precise extraction from the original file.
Task
Traditional approach
With jDocMunch
Find a configuration section
~12,000 tokens
~400 tokens
Browse documentation structure
~40,000 tokens
~800 tokens
Explore a full doc set
~100,000 tokens
~2,000 tokens
Index once. Query cheaply forever. Precision context beats brute-force context.
jDocMunch MCP
AI-native documentation navigation for serious agents
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.
jDocMunch indexes documentation once by heading hierarchy and section structure, then gives MCP-compatible agents precise access to the explanations they actually need instead of forcing them to brute-read files.
It is built for workflows where token efficiency, context hygiene, and agent reliability matter.
Why this exists
Large context windows do not fix bad retrieval.
Agents waste money and reasoning bandwidth when they:
open entire documents to find one configuration block
repeatedly re-read headings, boilerplate, and unrelated sections
lose important explanations inside oversized context payloads
consume documentation as flat text instead of structured knowledge
jDocMunch fixes that by changing the unit of access from file to section.
Instead of handing an agent an entire document, it can retrieve exactly:
an installation section
a configuration section
an API explanation
a troubleshooting section
a specific subtree of related headings
That makes documentation exploration cheaper, faster, and more stable.
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.
Local-first architecture
Indexes and raw docs are stored locally. No hosted dependency required.
MCP-native workflow
Works with Claude Desktop, Claude Code, Google Antigravity, and other MCP-compatible clients.
What gets indexed
Every section stores:
title and heading level
one-line summary
extracted tags and references
SHA-256 content hash for drift detection
byte offsets into the original file
This allows agents to discover documentation structurally, then request only the specific section they need.
Why agents need this
Traditional doc retrieval methods all break in different ways:
File scanning loads far too much irrelevant text
Keyword search finds terms but often loses context
Chunking breaks authored hierarchy and separates explanations from examples
jDocMunch preserves the structure the human author intended:
heading hierarchy
parent/child relationships
section boundaries
coherent explanatory units
Agents do not need bigger context windows.
They need better navigation.
How it works
jDocMunch implements jMRI-Full — the open specification for structured retrieval MCP servers. jMRI-Full covers the full stack: discover, search, retrieve, and metadata operations with batch retrieval, hash-based drift detection, byte-offset addressing, and a complete _meta envelope on every call.
Parsing
Format-aware section splitting: heading-based (Markdown/MDX/HTML/RST/AsciiDoc), structure-based (OpenAPI tags, JSON keys, XML elements), or cell-based (Jupyter)
Hierarchy wiring
Parent/child relationships established
Summarization
Heading text → AI batch summaries → title fallback
Storage
JSON index + raw files stored locally under ~/.doc-index/
Retrieval
O(1) byte-offset seeking via stable section IDs
Stable section IDs
{repo}::{doc_path}::{ancestor-chain/slug}#{level}
The slug is prefixed with the ancestor heading chain, making IDs both readable and stable. A new heading inserted in one branch of a document never renumbers IDs in another branch.
IDs remain stable across re-indexing when the file path, heading text, heading level, and parent heading chain do not change.
Installation
Prerequisites
Python 3.10+
pip
Install
pip install jdocmunch-mcp
Verify:
jdocmunch-mcp --help
Configure an MCP client
PATH note: MCP clients often run with a restricted environment where jdocmunch-mcp may not be found even if it works in your shell. Using uvx is the recommended approach because it resolves the package on demand without relying on your system PATH. If you prefer pip install, use the absolute path to the executable instead.
For Anthropic or Gemini, the base uvx jdocmunch-mcp command is enough once the
corresponding API key is present. For OpenAI-compatible providers such as OpenAI,
MiniMax, or GLM-5, include the optional dependency in the launcher command:
After saving the config, restart Claude Desktop / Claude Code.
Claude Code hooks (recommended)
jDocMunch ships enforcement hooks that keep your agent honest:
PreToolUse — warns when Claude tries to Read a large doc file, suggesting search_sections + get_section
PostToolUse — auto-reindexes doc files after Edit/Write so the index never goes stale
PreCompact — injects a session snapshot before context compaction so doc orientation survives
Install everything in one command:
jdocmunch-mcp init
This detects your MCP clients, patches their config, installs a Doc Exploration Policy into CLAUDE.md, sets up enforcement hooks, and indexes your current directory. Use --dry-run to preview, --demo for a benefit summary, or --yes for non-interactive mode.
Without explicit instructions, your agent will ignore jDocMunch even though it's connected. Create a system prompt file (e.g. ~/.openclaw/agents/researcher.md) with:
## Documentation Policy
Always use jDocMunch-MCP tools for documentation exploration.
- Before reading a doc file: use search_sections or get_toc
- To retrieve specific content: use get_section with the section ID
- To index local docs: use index_local with the docs folder path
- Never open documentation files directly — navigate by section.
Point your agent at it in ~/.openclaw/openclaw.json:
total_tokens_saved and total_cost_avoided accumulate across tool calls and persist to ~/.doc-index/_savings.json.
Check your token savings
Every jDocMunch tool response includes a _meta block with tokens_saved (this call) and total_tokens_saved (lifetime). To check your cumulative savings, ask your agent to call any jDocMunch tool (e.g. get_toc or search_sections) and look at the _meta envelope. Lifetime stats persist in ~/.doc-index/_savings.json across sessions.
Supported formats
Format
Extensions
Notes
Markdown
.md, .markdown
ATX (# Heading) and setext headings
MDX
.mdx
JSX tags, frontmatter, import/export stripped before parsing
Plain text
.txt
Paragraph-block section splitting
reStructuredText
.rst
Adornment-based heading detection
AsciiDoc
.adoc
= and == heading hierarchy
Jupyter Notebook
.ipynb
Markdown cells used as sections; code cells attached as content
HTML
.html
<h1>–<h6> headings; boilerplate stripped
OpenAPI / Swagger
.yaml, .yml, .json, .jsonc
OpenAPI 3.x and Swagger 2.x; operations grouped by tag as sections
JSON / JSONC
.json, .jsonc
Top-level keys as sections; JSONC comments stripped before parsing
XML / SVG / XHTML
.xml, .svg, .xhtml
Element hierarchy used for section structure
Office documents
.pdf, .docx, .pptx, .epub
Optional: pip install jdocmunch-mcp[office] — converted to Markdown locally via markitdown at index time
Office document support (optional [office] extra)
pip install jdocmunch-mcp[office] adds PDF, Word, PowerPoint, and EPUB
ingestion for local indexing (index_local / index-file / the watch
daemon). Files are converted to Markdown on your machine at index time and then
sectioned, searched, and health-checked like any other doc.
Disclosure, in full:
Conversion is 100% local. markitdown's optional cloud converters (LLM
image description, Azure Document Intelligence, YouTube transcription) are
never enabled — no network request originates from office conversion.
Converted Markdown is cached under the index storage root (.office_cache/,
keyed by file-content hash), so refreshes don't re-convert unchanged files.
Tabular formats (.csv, .xlsx) are deliberately not wired in — the
jMunch suite routes tabular data to
jdatamunch-mcp.
GitHub remote indexing (doc_index_repo) does not fetch office files; the
feature is local-only.
Without the extra installed, office files are skipped at discovery and the
coverage report names the reason (office_extra_not_installed).
PDF text extraction is best-effort: layout-heavy or scanned (image-only)
PDFs may yield sparse Markdown. Section quality follows heading detection in
the converted output.
See ARCHITECTURE.md for parser details.
Security
Built-in protections include:
path traversal prevention
symlink escape protection
secret file exclusion (.env, *.pem, and similar)
binary file detection
configurable file size limits
storage path injection prevention via _safe_content_path()
source code symbol indexing (use jCodeMunch for that)
cross-repository global search
semantic/vector similarity search as a standalone product (hybrid BM25 + semantic fusion is supported when embeddings are enabled — defaults to "auto", on whenever a provider is configured — but the core workflow remains structure-first)
Environment variables
Variable
Purpose
Required
GITHUB_TOKEN
GitHub API auth
No
ANTHROPIC_API_KEY
Section summaries via Claude Haiku
No
GOOGLE_API_KEY
Section summaries via Gemini Flash; also Gemini embeddings
No
OPENAI_API_KEY
OpenAI embeddings (text-embedding-3-small)
No
JDOCMUNCH_EMBEDDING_PROVIDER
Force provider: gemini, openai, openai-compatible, sentence-transformers, none
No
JDOCMUNCH_OPENAI_COMPAT_URL
Endpoint URL for openai-compatible embeddings
No
JDOCMUNCH_OPENAI_COMPAT_MODEL
Model for openai-compatible embeddings
No
JDOCMUNCH_OPENAI_COMPAT_API_KEY
Dedicated optional API key for openai-compatible embeddings
No
JDOCMUNCH_OPENAI_COMPAT_BATCH_SIZE
Batch size for openai-compatible embeddings (default: 32)
No
JDOCMUNCH_ST_MODEL
sentence-transformers model (default: all-MiniLM-L6-v2)
No
DOC_INDEX_PATH
Custom cache path
No
JDOCMUNCH_SHARE_SAVINGS
Set to 0 to disable anonymous community token savings reporting
No
JDOCMUNCH_SESSION_TOKEN_BUDGET
Advisory session budget over response tokens served. When set, responses carry _meta.budget at >=80% (approaching) / >=100% (over) and get_session_stats reports the block. Never blocks or truncates. Unset/0 = off
No
JDOCMUNCH_WATCH_POLL_DELAY_MS
Poll interval (ms) used only when the watcher falls back to polling (e.g. under WSL); default 1000
No
JDOCMUNCH_LAUNCH_ID
Opaque launch token echoed back as launch_id in the munch://runtime/identity resource (fallback: MUNCH_LAUNCH_ID); omitted when unset
No
get_session_stats also reports a tool_surface receipt: visible vs catalog tool counts, estimated schema tokens for each (bytes/4 scale), tokens avoided by the active tool profile, and the heaviest tool schemas. Computed inline on the stats call; nothing persisted.
Runtime identity resource
The server exposes one MCP resource, munch://runtime/identity — a read-only munch.runtime.identity/v1 JSON document identifying this exact server process (product, version, transport, pid, OS-derived process_start, per-process-lifetime instance_id, optional launch_id echo). Multi-agent harnesses use it to tell command-line-identical servers apart and detect restarts. Computed on demand with no disk reads, writes, or network; when the OS process-start probe is unavailable the timestamp is disclosed as source: "self_recorded", never fabricated. Command lines, env, cwd, hostnames, and corpus paths are deliberately excluded. Same contract in jcodemunch-mcp and jdatamunch-mcp.
A multi-step documentation audit can end with one authoritative, server-attested result. The assistant authors the analysis; finalize_handoff takes those sections plus evidence_refs, validates every reference 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), deterministically assembles one canonical Markdown handoff (jdocmunch.handoff/v1), and returns a compact receipt: {handoff_id, resource_uri, sha256, length, canonical: true}. The immutable body is served by the munch://handoff/<id> resource — repeated reads are byte-identical. Session-scoped, in-memory, never writes to your documentation corpus; appendices appear exactly once; no character limit. Suite parity with jcodemunch-mcp and jdatamunch-mcp.
Keeping indexes fresh (the watch daemon)
By default jDocMunch's index freshness rides the PostToolUse hook, which only
fires when the agent itself edits a doc file. Docs changed outside the agent (a
git pull, an editor, a build step, a teammate) go stale until the agent happens
to touch that file again.
The watch daemon closes that gap. It auto-discovers every locally-indexed doc
repo and re-indexes the owning index incrementally whenever a documentation file
(.md, .rst, .txt, .adoc, .ipynb, .html, and the other supported
formats) changes on disk.
# Foreground — stays running, Ctrl+C to stop:
jdocmunch-mcp watch
# Or install it as a background login service (systemd / launchd / Task Scheduler):
jdocmunch-mcp watch-install
jdocmunch-mcp watch-status # is it active? which repos are covered?
jdocmunch-mcp watch-uninstall # remove it
Repos indexed while the watcher runs are picked up on the next discovery pass.
GitHub-sourced indexes (no local source_root) are skipped — there's nothing
on-disk to watch. Coverage is also queryable from an agent via the
get_watch_status tool.
Background behavior, fully disclosed
jDocMunch does nothing over the network or in the background that isn't listed
here. Keep this section current whenever any new background, persistent, or
network behavior ships.
File watching (opt-in):jdocmunch-mcp watch runs a foreground daemon
that watches your locally-indexed doc folders and re-indexes changed files.
It runs only while you run it; nothing is watched unless you start it.
Watch login service (explicit opt-in):jdocmunch-mcp watch-install
registers the watch daemon as a per-user login service (systemd user unit /
launchd LaunchAgent / Task Scheduler task) so it starts at login.
jdocmunch-mcp watch-uninstall removes it. Never installed unless you run
watch-install.
PostToolUse / PreToolUse / PreCompact hooks (opt-in): installed only if
you run jdocmunch-mcp init --hooks. The PostToolUse hook spawns a throttled
single-file re-index after an Edit/Write to a doc file.
Anonymous savings telemetry (opt-out): a tokens-saved delta + a random
anonymous install ID are POSTed to a live counter (see "Community savings
meter" below). Disable with JDOCMUNCH_SHARE_SAVINGS=0.
Local index store: indexes live under ~/.doc-index/ (override with
DOC_INDEX_PATH). No index content leaves your machine.
Community savings meter
Each tool call can contribute an anonymous delta to a live global counter, POSTed to https://j.gravelle.us/APIs/savings/post.php and displayed at jcodemunch.com. Only two values are sent:
tokens saved
a random anonymous install ID
No content, file paths, repo names, or identifying material are sent.
The anonymous install ID is generated once and stored in ~/.doc-index/_savings.json.
To disable reporting, set:
JDOCMUNCH_SHARE_SAVINGS=0
Contributing
PRs welcome! All contributors must sign the Contributor License Agreement before their PR can be merged — CLA Assistant will prompt you automatically. See CONTRIBUTING.md for details.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to use, copy, modify, merge, publish, and distribute the Software for personal, educational, research, hobby, or other non-commercial purposes, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
Any modifications made to the Software must clearly indicate that they are derived from the original work, and the name of the original author (J. Gravelle) must remain intact. He's kinda full of himself.
Redistributions of the Software in source code form must include a prominent notice describing any modifications from the original version.
2. Commercial use
Commercial use of the Software requires a separate paid commercial license from the author.
“Commercial use” includes, but is not limited to:
use of the Software in a business environment
internal use within a for-profit organization
incorporation into a product or service offered for sale
use in connection with revenue generation, consulting, SaaS, hosting, or fee-based services
Until a commercial license is obtained, commercial use is not permitted.
3. Disclaimer of warranty
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHOR OR COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
FAQs
Token-efficient MCP server for structured documentation retrieval via section-level indexing
The pypi package jdocmunch-mcp receives a total of 2,189 weekly downloads. As such, jdocmunch-mcp popularity was classified as popular.
We found that jdocmunch-mcp demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago.It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
A misconfiguration gave three Anthropic models internet access, and one, believing it was in a simulation, shipped a credential-stealing package to PyPI.
Socket has joined the new Composer and Packagist sponsorship program as a launch sponsor, supporting the team that keeps PHP's package ecosystem secure.