Index docs by heading hierarchy with byte offsets; serve sections over MCP.
| Phase | Scope | State |
|---|---|---|
| P0 | module skeleton, section model, id/byte-offset contract | ✅ done |
| P1 | fetch: HTTPS/streaming/redirects, SSRF guard, raw cache, platform detect | ✅ done |
| P2 | DOM helpers + Readability-compatible extraction + metadata | ✅ done (4/4 fixtures, avg Jaccard 0.91) |
| P3 | HTML → CommonMark, link absolutization, golden files | ✅ done |
| P4 | section split: ATX + setext, fence-aware, hashes, stable slugs | ✅ done |
| P5 | index store, search, byte-range retrieval | ✅ done |
| P6 | MCP server (stdio) | ✅ done |
| P7 | link-density pruning, CI, benchmark, delivery docs | ✅ done |
| P8 | body-aware search (section keywords), MCP HTTP transport | ✅ done |
| P9 | audit fixes: repo identity/delete, doc_path rules, MCP response cap, frontmatter/fence, cache TTL/retry, stderr, DNS double-resolve + index mutex | ✅ done |
| P10 | charset-aware decoding, cache final_url, explicit JSON extends, acceptance self-check | ✅ done |
| P11 | maintainability pass: core/text package, one registration per MCP tool, split the two 500+ line files | ✅ done |
| P12 | BM25 search (k1=1.2, b=0.75, field weights), index v3 | ✅ done |
| P13 | 12 MCP tools (added get_doc / list_docs / get_section_descendants / search_titles) | ✅ done |
moon build --target native
moon test
# fetch one URL: prints status/bytes/platform, writes .doc-index/raw/<sha256>.bin
moon run cmd/main --target native -- fetch https://docs.moonbitlang.cn/language/ffi.html
# platform fingerprint only (no network)
moon run cmd/main --target native -- detect https://github.com/mozilla/readability
# extract main content + metadata (URL or local file)
moon run cmd/main --target native -- extract fixtures/html/readability-readme.html --out-html out.html
# HTML -> CommonMark (+ absolutized links when the input is a URL)
moon run cmd/main --target native -- markdown fixtures/html/readability-readme.html --out out.md
python tools/markdown_golden.py
# section tree with byte offsets + hashes, then verify the byte contract
moon run cmd/main --target native -- toc fixtures/markdown/readability-readme.md --verify
python tools/toc_check.py
# index -> search -> retrieve (O(1) byte-range read, hash-verified)
moon run cmd/main --target native -- index fixtures/markdown/readability-readme.md --repo local
moon run cmd/main --target native -- search local readability # BM25 by default
moon run cmd/main --target native -- search local readability --mode weighted
moon run cmd/main --target native -- section local "<id from search>" --verify
moon run cmd/main --target native -- repos
moon run cmd/main --target native -- delete local
# MCP server: stdio (default) or Streamable HTTP
python tools/mcp_e2e.py
moon run cmd/main --target native -- mcp --http --port 4240 --root .doc-index
python tools/mcp_http_e2e.py
# compare extraction against the Node Readability oracle
python tools/compare.py
# 10-site smoke run (see docs/p1-smoke.md)
moon run cmd/main --target native -- smoke fixtures/smoke-urls.txtpython tools/acceptance.py --since 2026-11-01 # round start datecore/ shared model: Section, DocIndex, slug + id rules, UTF-8 byte length
section/ heading-based splitting, byte offsets, hierarchy
http/ fetch stage: SSRF guard, raw cache (TTL/retry), doc_path rules
extract/ mutable DOM arena + Readability-compatible scorer (P2)
md/ HTML -> CommonMark normalization (P3)
index/ JSON index + raw cache, atomic writes, version gating (P5)
mcp/ MCP tool surface and response envelope (P6)
cmd/main/ CLI entry point
fixtures/ golden documents for differential tests
tools/ test oracles (Node-based Readability reference)
docs/ pre-research, decision records, competition notesInstall
Download zipIndex docs by heading hierarchy with byte offsets; serve sections over MCP.