mcp-agent-docparser
An MCP server that turns documentation websites into clean markdown for LLM contexts, with receipt-based site profiles, parsing, crawling, and discovery tools.
Receipt management: list, view, add, edit, delete, and reload site profiles (
receipt_list,receipt_show,receipt_add,receipt_edit,receipt_delete,receipt_reload).Parse docs: parse a saved receipt (
doc_parse), parse an arbitrary URL using a receipt as template (doc_parse_url), or crawl a whole site via sitemaps/robots with concurrency and politeness (doc_crawl).Discover site structure: probe pages statically (
doc_probe) or via headless Chromium for JS-rendered sites (doc_probe_js), including Copy-as-Markdown detection.Inspect outputs: list emitted markdown files (
doc_output).Utility: get current local/UTC datetime (
get_current_datetime).Output: writes timestamped
.mdfiles todoc_output/and returns rendered markdown inline for direct use by the model.Flexible receipt options: CSS selectors, strip tags, section limits, JS rendering, markdown passthrough, language/code-language overrides, and dry-run previews.
Provides a preconfigured receipt to parse LangChain DeepAgents documentation into clean markdown.
Provides a preconfigured receipt to parse Pydantic AI documentation into clean markdown.
Provides a preconfigured receipt to parse React.dev documentation, including JS-rendered pages with Sandpack, into markdown.
Provides a preconfigured receipt to fetch and extract documentation from the Rust programming language's official docs into clean markdown.
Provides a preconfigured receipt to parse SearXNG documentation into clean markdown.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mcp-agent-docparser Parse https://docs.python.org/3/library/json.html into markdown"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
mcp-agent-docparser
SDK documentation extractor as a local MCP server. Point an
MCP-aware agent harness at a documentation site, and it fetches the pages,
strips navigation noise, converts HTML to clean markdown, and returns (or
writes) a .md file ready to drop into any LLM context window.
Pipeline: fetch → extract → emit.
This is the terminal-menu docparser (a standalone project) rebuilt as an
MCP tool for the agent-tools stack. The interactive REPL commands became
MCP tools: receipt management, parse, and probe are now callable by any
harness (Claude, opencode, etc.) over stdio.
Tool surface
Domain | Tools |
Receipts |
|
Parse |
|
Discovery |
|
Utility |
|
Related MCP server: read-website-fast
Receipts
A receipt is a named profile that tells docparser how to fetch and
extract one documentation site. Receipts live in receipts.json — never in
the Python source. The repo ships a host of prefilled examples covering a
wide range of real documentation stacks: Memvid (memvid-python, static
Mintlify), LM Studio (lmstudio-python and lmstudio-bionic,
JS-rendered Next.js with a Copy-as-Markdown button), Mojo, Rust,
React.dev (Sandpack), Hermes Agent, MCP Specification, Pydantic
AI, HuggingFace smolagents, Google ADK, LangChain DeepAgents,
Invidious and SearXNG — see the urls, selectors, and strip_tags
in receipts.json for ready-made examples per site theme. Delete them or
keep them; they are regular receipts.
Receipt schema
{
"my-sdk-python": {
// Required
"name": "My SDK (Python)", // human label
"language": "python", // used in code blocks and header
"urls": ["https://docs.example.com/overview"], // fetched in order
"selectors": ["#content", ".prose", "article", "body"],
// Optional
"strip_tags": ["nav", "footer", "header", "script", "style"],
"section": null, // restrict to content after this H2 text
"js_render": false, // use Playwright instead of requests
"markdown_passthrough": false, // treat extracted <pre> as raw markdown
"notes": "", // free-text notes about the site
// Managed automatically
"last_fetched": null, // ISO date of last successful parse
"last_output": null // filename of last emitted .md
}
}Workflow for a new site
1. doc_probe → paste the docs URL, see which selectors match and
(or doc_probe_js what H2s exist. Nothing matched? The site is
for JS-rendered) probably JS-rendered — retry with doc_probe_js.
2. receipt_add → save the findings as a receipt (best_selector +
strip_tags / js_render / markdown_passthrough).
3. doc_parse(key) → fetch, extract, emit .md into doc_output/. Returns
the rendered markdown directly. doc_parse with
dry_run=true previews what will be fetched.For a single unfamiliar page that matches an existing receipt's template,
doc_parse_url(template_key, url) parses it without persisting a receipt.
Whole-site ingestion with doc_crawl
1. doc_probe / doc_probe_js → confirm the site renders + pick a template
receipt whose selectors fit.
2. doc_crawl(key, url) with dry_run=true → discovery only: sitemaps/robots
are read, candidate URLs are listed, nothing is fetched. Scope with
max_pages and path_prefix if the list is too big.
3. doc_crawl(key, url) → fetches the discovered pages concurrently, emits one
combined {name}_{timestamp}.md, and returns the markup inline.Crawl discovery order: robots.txt Sitemap: directives → sitemap index →
leaf sitemaps (a .xml seed is parsed directly) → same-host link walk as a
fallback for sites without a sitemap. Politeness is robots-strict: every URL
passes through the site's robots.txt before fetching, a declared
Crawl-delay throttles the workers, and results are deduped, same-origin,
and capped at max_pages (default 200). Crawls never modify the registry —
they are one-shot like doc_parse_url.
Requirements
Python 3.13+
Playwright Chromium (only for
js_renderreceipts):uv sync && uv run playwright install chromium
Install
git clone <repo-url> mcp_agent_docparser
cd mcp_agent_docparser
uv syncUsage
Run as an MCP server (stdio — what harnesses expect)
uv run mcp-agent-docparserOverride paths via environment variables (defaults resolve relative to the project root, never the process CWD):
Var | Default | Purpose |
|
| Path to the receipts registry |
|
| Where emitted |
|
| Rotating DEBUG logs (5×5 MB) |
To serve over HTTP (streamable-http) instead:
uv run mcp-agent-docparser serve --http --port 8000Register in an MCP client
{
"mcpServers": {
"mcp-agent-docparser": {
"command": "uv",
"args": ["--project", "C:/path/to/mcp_agent_docparser", "run", "mcp-agent-docparser"]
}
}
}CLI commands
Command | Purpose |
| Run the MCP server. |
| Offline diagnostics: paths, registry state, emitted files |
Output
Files are written to doc_output/ as {receipt_name}_{YYYYMMDD_HHMMSS}.md.
Each file contains a header block (language, fetch timestamp, source URLs),
the receipt's notes if set, and one <!-- SOURCE: url --> section per
fetched page. doc_parse also returns the rendered markdown in its result,
so the model can use the content even if the harness has no filesystem view.
Development
uv run ruff check .
uv run pytest -qTests cover the receipt registry, config path resolution, extraction, the parse pipeline (mocked fetch), and the full tool surface — no network needed.
Agent skill: fixing noisy fetched pages
When a fetched page comes out malformed (wrong code-fence language, blank
lines in code blocks, leaked navigation noise, heading-anchor junk, CRLF
copy-markdown), opencode loads the docparser-page-fixes skill from
.opencode/skills/docparser-page-fixes/SKILL.md. It teaches the
reproduce → isolate → fix → test → restart loop, maps the real
symptom/cause/fix cases from this repo's history, and lists the extractor's
gotchas (MULTILINE regexes, trailing-newline traps, the stale-MCP-module
restart requirement). Extend it whenever the extractor grows a new fix.
License
MIT © 2026 Christof Milius
Available Tools
12 toolsdoc_outputA
List the extracted .md files currently in the output directory.
Inputs: no named parameters. Returns: result
doc_parseA
Parse a saved receipt: fetch all its URLs, extract the content, and write a timestamped .md file into the output directory.
Returns the emitted filename plus a per-URL character count and the full rendered markdown. With dry_run=true, reports what would be fetched without making any network requests.
Inputs: key (required), dry_run. Returns: result
doc_parse_urlA
Parse an arbitrary URL using an existing receipt as a template for its selectors/strip_tags/language. Does not persist the result as a receipt.
Returns the emitted filename and the rendered markdown.
Inputs: key (required), url (required). Returns: result
doc_probeA
Probe a documentation page to discover its selector structure.
Fetches the URL statically and reports which candidate CSS selectors match, the H2 section structure, and sample internal links. The findings' best_selector can be used to create a new receipt.
Inputs: url (required). Returns: result
doc_probe_jsA
Probe a JS-rendered documentation page via headless Chromium.
Same selector report as doc_probe, but over the rendered DOM, plus detection of a 'Copy as Markdown' button (a saved receipt then pre-fills js_render and markdown_passthrough). Requires Playwright Chromium installed.
Inputs: url (required). Returns: result
get_current_datetimeA
Return the current local and UTC date/time in ISO 8601 format.
Inputs: no named parameters. Returns: result
receipt_addA
Create a new receipt (or replace an existing one).
Required: key, name, language, urls, selectors. Optional: strip_tags, section, js_render, markdown_passthrough, notes, code_language. Validates before writing; returns validation errors if the receipt is malformed.
language is the human language of the documentation. code_language
optionally overrides the ``` fence language when the page's blocks are
in another language (e.g. a React SDK doc in English that emits
TypeScript). When omitted, the fence language is auto-detected from the
page and falls back to language only if it names a code language.
Inputs: key (required), name (required), urls (required), language (required), +7 more. Returns: result
receipt_deleteA
Delete a receipt by key. Returns false if the key does not exist.
Inputs: key (required). Returns: result
receipt_editA
Patch specific fields of an existing receipt.
updates is a JSON object of field → value. Allowed fields: name,
language, urls, selectors, strip_tags, section, js_render,
markdown_passthrough, notes, code_language. Returns false if the key
does not exist.
Inputs: key (required), updates (required). Returns: result
receipt_listA
List all registered receipts with key, language, and last-fetch status.
Inputs: no named parameters. Returns: result
receipt_reloadA
Re-read receipts.json from disk (pick up external edits).
Inputs: no named parameters. Returns: result
receipt_showB
Show the full JSON of a single receipt by its key.
Inputs: key (required). Returns: result
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 12 tools
The receipt CRUD, parse, and probe tools are clearly separated by resource and action. The only potentially confusable pair is doc_parse vs doc_parse_url, but their descriptions distinguish saved-receipt parsing from arbitrary-URL parsing; get_current_datetime is unrelated but unambiguous.
Most tools follow an object_verb pattern such as receipt_list, receipt_add, doc_parse, and doc_probe, making the set predictable. get_current_datetime breaks the pattern, and doc_output is noun-styled, but the prefix grouping keeps names readable and consistent overall.
Twelve tools is a reasonable, well-scoped count for managing receipt configurations, parsing documentation, probing selectors, and listing outputs. The get_current_datetime tool feels slightly out of place, but the set is not bloated or thin.
The receipt lifecycle is fully covered with list/show/add/edit/delete/reload, and the parse/probe workflow handles both static and JS-rendered pages plus dry runs. A minor gap is the inability to read the contents of already-generated output files, since doc_output only lists filenames.
Maintenance
Related MCP Connectors
Convert files, URLs, and documents to clean, AI-ready Markdown via MCP.
MCP server (stdio): fetch web pages as clean readable markdown via the AgentForge API
Pages, crawls and URL batches as clean Markdown and JSON for AI agents, with an Evidence Record.
Web pages, JavaScript sites and PDFs to clean Markdown for AI agents, prompt injection removed.
Related MCP Servers
- AlicenseAqualityCmaintenanceMCP server that turns web pages into clean Markdown, keeping tables, code blocks, and images intact. Agents can fetch pages, save docs to your project or a global library, and crawl whole doc sites.53Apache 2.0
- AlicenseNot gradedqualityAmaintenanceEnables AI agents and MCP clients to fetch web pages or crawl sites and convert them into clean, token-efficient Markdown while preserving links.MIT
- AlicenseNot gradedqualityAmaintenanceEnables AI agents and MCP clients to fetch webpages, strip noise, and convert them into clean, token-efficient Markdown. Supports optional crawling, caching, robots.txt compliance, and link preservation.MIT
- AlicenseNot gradedqualityAmaintenanceEnables AI agents and MCP clients to fetch webpages, strip noisy content, and convert them into clean Markdown with link preservation and optional multi-page crawling, using caching and polite rate limiting for efficient scraping.MIT