Free Search vs JDocmunch MCP

A side-by-side look at the Free Search and JDocmunch MCP MCP servers: transport, auth, tools, quality signals, and the config to install either one in Claude, Cursor, Windsurf or VS Code.

Free Search logoFree SearchSearch & Data Extraction · Local subprocess (stdio)No-API-key web search, page fetching and document reading across many engines. Local-first.64GoodAuth: no auth requiredJDocmunch MCP logoJDocmunch MCPSearch & Data Extraction · Local subprocess (stdio)Section-level doc search for .md, .rst, .adoc, .ipynb, .html, .yaml, .json, and OpenAPI specs.64GoodAuth: no auth required

Verdict: choose Free Search for search & data extraction work as a local process; choose JDocmunch MCP for search & data extraction as a local process. You can also run both side by side in one mcpServers block.

Which MCP server should you choose?

Free Search logoChoose Free Search when

  • You need dedicated capabilities in the Search & Data Extraction domain.
  • You prefer a local stdio subprocess transport.
  • Its auth model fits you: No auth required.
  • You want tools like search, fetch, fetch_batch.
Explore Free Search

JDocmunch MCP logoChoose JDocmunch MCP when

  • You need dedicated capabilities in the Search & Data Extraction domain.
  • You prefer a local stdio subprocess transport.
  • Its auth model fits you: No auth required.
  • You have the keys it needs: DOC_INDEX_PATH.
  • You want tools like index_local, doc_index_repo, doc_list_repos.
Explore JDocmunch MCP

Feature & specification comparison

Rows where the two servers differ are marked.

SpecFree Search logoFree SearchJDocmunch MCP logoJDocmunch MCP
CategorySearch & Data ExtractionSearch & Data Extraction
Quality signal64/100 · Good64/100 · Good
Install commandConfirmedConfirmed
TransportLocal subprocess (stdio)Local subprocess (stdio)
AuthNo auth requiredNo auth required
PricingFreeFreemium
Required env varsNone listedDOC_INDEX_PATH
Verified ownerCommunity listingCommunity listing
GitHub stars154206
Directory activity 1 views 0 installs 0 upvotes 0 views 0 installs 0 upvotes
Tools1164

Tools & capabilities

Free Search tools 11

  • searchRun a multi-engine web search and return a ranked, deduplicated link list. Best for: - Discovery queries ("what is X", "find me X", "who is X"). - Getting a list of URLs you can hand to `fetch` / `fetch_batch` next. - Topics likely to be after your knowledge cutoff (use `freshness="week"`). - Filtering to specific domains (`include_domains=["python.org"]`) or a kind of source (`category="paper"` / `"finance"`, or a sub-group like `category="paper.biomed"` / `"finance.filings"`; see `engines()` for the full tree). - Looking a fact up at its registry, with no category needed: a current version or support end date ("latest fastapi version"), a CVE ("CVE-2024-3094": NVD record, OSV advisories, CISA exploited status), a forecast ("上海明天天气"), an exchange rate ("100 usd to cny": ECB, and the PBOC parity for 人民币), a coin price, a country indicator ("china gdp", "japan population"), public holidays ("2026年放假安排"), the current time in a city, a domain's expiry, a company's legal entity, an iOS app's version, Wikidata facts ("Shanghai population"). The source that fits the words joins the search and its record arrives as the first result with the publisher's date in `dated …`, so it can be cited without a fetch. Name the thing plainly. `category=` ("software", "security", "weather", "finance.fx", "stats", "calendar", "reference", "docs", "gov") asks the same sources explicitly. Not recommended for: - You already know the URL -> use `fetch` instead. - You want both links AND their full text in one call -> use `research`. - You want to query pages already in the local cache -> use `cache_search`. - Reading PDFs/DOCX from a known URL -> use `read_doc`. - Following one paper's references or citations -> use `paper_graph`. Returns: - markdown (default): numbered list of `n. title`, `<url>`, snippet. About 40% fewer tokens than json. - json: dict with `results` (list of {title,url,snippet,engines,score}), `engines`, `cached`, optional `errors` map, optional `hint` string. `engines` is what was actually ASKED for this answer; each result's own `engines` is what found it. A default engine that failed recently is not asked and appears under `benched_engines` instead; a rescue pass that substituted a source appears as `rescued_via`. Common mistakes: - Answering from snippets. A snippet is an engine's summary of a page as it looked when crawled: it drops qualifiers and is often years old. Use `search` to find the URL, then read the page (`fetch`, `research`) for any date, amount, rule, deadline or number you will state. - Treating a result as recent because `freshness=` was set. The filter keeps undated results; the header says how many could be dated (`dated: 3/10`) and each result is marked `dated …`, `… (from snippet text)` or `undated`. - Passing a URL as `query`: that is `fetch`'s job. - Cranking `max_results` up hoping for better recall; engines cap around 10-20 each, anything beyond is duplicate noise (and 50 is the ceiling). - Naming engines by default. The default pool is already the set that works keylessly over plain HTTP, it benches an engine that starts failing and seats a reserve when it gets thin, and naming engines switches all of that, and `category=` routing, off. Name engines when you want a specific index: `engines=["so360","baidu"]` for Chinese-language sites, `engines=["brave"]` or `["startpage"]` (both need the browser) for a second opinion. - Using `category="news"` for breaking news without also setting `freshness="day"`: the index lags by days. Args: query: Natural-language query (the same string a human would type). engines: Subset of `engines()`. None (recommended) = the health-aware default pool: duckduckgo, bing, anysearch and mojeek, plus googlenews when `freshness` is "day"/"week" and a Chinese index for a Chinese query. max_results: Merged result count after dedup, clamped to 1-50. It is also the PER-ENGINE budget, so it multiplies across the fan-out; 5-20 is the useful range and anything past that is duplicate noise bought with real latency. Omit it for the configured default. use_cache: Reuse the last result for this exact (query, engines, max_results, AND all active filters: freshness, include/exclude domains, category, include/exclude text) within the cache TTL. Changing any filter is a different cache entry. False forces a re-fetch. max_age_hours: Treat cached results older than this as a read miss; a fresh result is ALWAYS written back to the cache regardless of this value, so caching is never disabled. Use 0 to force-refresh while keeping cache writes; None = use server default TTL (7 days). freshness: "day"|"week"|"month"|"year". Restricts to recent results. Best-effort: applied as an engine time-window param AND a client-side date check, but most HTML-engine results carry no parseable date, so undated results are kept rather than dropped (unknown != old). Treat it as a strong hint, not a hard filter; googlenews dates are exact. include_domains: List of domains to restrict to (e.g. ["python.org"]). exclude_domains: List of domains to exclude. category: Which KIND of source to search. The enum lists every value. A bare group widens: "paper" adds one specialist per sub-group to the default web pool. A dotted sub-group narrows to just the sources that index it ("paper.biomed" => the biomedical indexes only). It also RERANKS: engines that natively index the category count double in the fusion, so the filing outranks the commentary about it, and a record looked up by the query (a PyPI release, a CVE, an ECB rate, a forecast) counts five times, so it leads the list. Call `engines()` for the group -> sub-group -> engine tree with a line on each source. Two behaviours worth knowing: "image"/"dataset" REPLACE the web pool rather than augment it (a web engine cannot return an image file), and "news"/"paper"/"forum"/"github"/"blog" also filter general-web hits by hostname, so a strict category can thin those engines out. The specialists it routes to are exempt. include_text: Substring required in title or snippet (case-insensitive). exclude_text: Substring forbidden in title or snippet. format: "markdown" (default) or "json".
  • fetchFetch one URL: page text, or a description of a non-text resource. Handles any http(s) resource, not just HTML: - HTML pages -> reader-mode Markdown (nav/footer/scripts stripped). - PDF/DOCX/XLSX/PPTX/EPUB/CSV/code/archives -> parsed text (same engine as `read_doc`, which you should prefer when you need pagination). - Images, video, audio, fonts, opaque binaries -> a description (media type, byte size, dimensions, sha256), NOT the bytes. Best for: - You already have a URL (from `search`, the user, or your own knowledge) and need the actual page text. - Verifying a single claim by reading the source. - Checking what a resource IS before deciding to spend tokens on it. Not recommended for: - Multiple URLs at once -> use `fetch_batch` (concurrent, one round-trip). - "Search then read top N" -> use `research` (one call, not two). - Long documents you need to page through -> use `read_doc` (start/length). - You don't have a URL yet -> use `search` first. Returns: - markdown (default): a small header (URL, render method, token count) plus the cleaned page body. - json: {url, title, content, method, truncated, tokens_estimated, author, published_date, sitename}, plus {media_type, bytes_size, sha256, width, height} for non-text resources. - With `inline=True` on an image: the image itself, viewable by a vision-capable model. Common mistakes: - Passing a search query instead of a URL. - Using `render="http"` on a JS-only SPA: it returns near-empty content; use "auto" (default) or "browser". - Setting `inline=True` on a large image out of habit. A 1MB image costs well over a thousand tokens; fetch it plainly first and inline only if the description says it's worth looking at. - Forgetting that results are cached 7 days: use `force_refresh=True` or `max_age_hours=0` for a fresh pull. The header says `cached N days ago` when you are not looking at the live page; for deadlines, prices and anything else that moves, that is the cue to refresh. - Reading `no publication date found` as "recent". It means unknown. Args: url: Absolute http(s) URL. render: "auto" (try HTTP, fall back to stealth Chromium), "http" (fast, fails on JS), "browser" (slow, robust). force_refresh: Bypass the page cache entirely. max_age_hours: Treat cached pages older than this as a miss. 0 = same as force_refresh. None = server default TTL (7 days). inline: For images only. Returns the image itself instead of a description, so a vision-capable model can see it. Ignored for text resources. format: "markdown" or "json".
  • fetch_batchFetch a list of URLs in parallel. Per-URL failures do not raise. Best for: - 2+ URLs you want to read in one round-trip. - Reading the top N results of a previous `search` call. Not recommended for: - A single URL -> `fetch` (no list-wrapping overhead). - "Search and then read" -> `research` collapses both into one tool call. - PDFs/DOCX -> `read_doc` per file. Returns: - markdown (default): each page rendered as a Markdown section, separated by horizontal rules; failed URLs become inline error notes. - json: list[dict], one entry per URL, with `error` set on failures. Common mistakes: - Passing a single URL inside a 1-element list: use `fetch` directly. - Assuming an exception means the whole batch failed; check each item's `error` field instead. Args: urls: List of absolute http(s) URLs (max 20 per call). render: Same as `fetch`. format: "markdown" or "json".
  • read_docRead an http(s) document (or a sandboxed local file) into Markdown. Best for: - Remote PDFs and DOCX from an http(s) URL (parsed locally, no remote API). - Local PDF/DOCX/text/Markdown files, ONLY when local reads are enabled (see Security below). - Paginating through a long document via `start` / `length`. Not recommended for: - Arbitrary HTML web pages -> `fetch` does reader-mode cleanup that this tool does not. - Pages discovered through search -> `fetch` or `research`. Security (local files are sandboxed and OFF by default): - Local-file reads are DISABLED unless the server operator sets the SEARCH_MCP_DOCUMENT_ROOT env var to a directory. With it unset, a local path raises a "local file reads are disabled" error. Pass an http(s) URL instead, or ask the operator to enable the sandbox. - When enabled, `source` must resolve INSIDE that root; relative paths resolve against the root (not the process CWD) and any `..` traversal that escapes the root is rejected. `file://` URLs are always rejected. - Remote http(s) sources are unaffected by this setting. Returns: - markdown (default): rendered document text with a small header. - json: {content, title, format, total_chars, start, returned_chars, truncated}. Use `total_chars` and `returned_chars` to drive pagination. Common mistakes: - Calling this on a normal article URL: you'll get raw HTML noise. Use `fetch` instead. - Forgetting to advance `start` when paginating: next call should pass `start = previous_start + returned_chars`. - Passing a negative `length` (raises an error) or a `start` past the end (clamped to EOF: you'll get `returned_chars == 0`, `start == total_chars`, and `truncated == False`, which is the signal you've paged off the end). Args: source: http(s) URL, or a local path UNDER SEARCH_MCP_DOCUMENT_ROOT when local reads are enabled (disabled by default; see Security). start: Character offset to begin reading from. Default 0. Clamped into [0, total_chars]; a negative value is treated as 0. length: Max characters to return; None = read to end (still capped by the per-call max content size). Must be >= 0. A negative length is rejected with a ValueError. format: "markdown" or "json".
  • researchOne-shot research: search the web, fetch the top results, return both. Best for: - Open-ended questions that need finding sources AND reading them ("what's new with X", "summarize the controversy around Y"). - Replacing a `search` + N x `fetch` chain with one call. - Producing a citable brief with [n]-style source references. Not recommended for: - You only need links -> `search` (cheaper, no fetching). - You only need to read one URL you already have -> `fetch`. - You want to query previously-fetched cached pages -> `cache_search`. - Checking or expanding one paper's citations -> `paper_graph`. Returns: - markdown (default): a "Research brief" with a Sources index then the full Markdown body of each fetched document, separated by horizontal rules; includes a token estimate. - json: {question, engines, sources:[{rank,title,url,snippet,...}], documents:[...], tokens_estimated, errors}. Common mistakes: - Using `depth=8` for a quick lookup: that's 8 page fetches, and 2-3 is almost always enough. - Calling `research` for a known URL: that is what `fetch` is for. - Forgetting that `fetch=False` returns sources only (much cheaper if the LLM only needs to pick which one to read). Args: question: What you want to know, in natural language. depth: How many top results to fetch (1-8). 3 is a good default. engines: Override the engine set (see `engines()` for names). Prefer `category=`. Naming engines turns category routing off. fetch: If False, return source list without reading them. freshness: "day"|"week"|"month"|"year". Restricts to recent results. Best-effort; undated results are kept rather than dropped. include_domains: Restrict to these domains (e.g. ["python.org"]). exclude_domains: Drop results from these domains. category: Which KIND of source to search; a bare group widens, a dotted sub-group narrows. Same values as `search`; see `engines()`. include_text: Substring required in title or snippet (case-insensitive). exclude_text: Substring forbidden in title or snippet. use_cache: Reuse cached search/page data within TTL. max_age_hours: Treat cached search results AND cached page bodies older than this as a read miss; fresh data is always written back. 0 = force-refresh both the engine search and every fetched page body; None = server default TTL (7 days). A non-zero value is honored for both halves (it used to be ignored for anything but 0). format: "markdown" or "json".
  • paper_graphFollow the citations of ONE paper, and check whether it still stands. `search` finds papers that MENTION your words. This follows the edges instead: what a specific paper built on, and what has built on it since. Best for: - Checking a citation before repeating it: is the DOI real, and has the paper been retracted or corrected? - "What happened after this result": citing works come back ordered by how much the field cited them, so a 2019 paper leads to the current state of the art rather than to the most recent preprint about it. - Building a reading list backwards from one good paper. Not recommended for: - Finding papers by topic -> `search(category="paper")`, or a sub-group like `"paper.biomed"` / `"paper.cs"` / `"paper.preprint"`. - Reading the paper itself -> `read_doc` on the returned URL. Returns: - markdown (default): the paper with its retraction/correction notices, then "References" and "Cited by" sections. - json: {paper, references, citations, notes}, where `paper.crossref` carries `registered` and every post-publication `notices` entry. Common mistakes: - Passing a topic instead of a paper. A title resolves to its single best match; a phrase that names no specific paper resolves to the wrong one. - Reading an empty `citations` list as "uncited" when `notes` says the lookup was truncated. Args: paper: DOI (`10.1145/1571941.1572114`, or a doi.org URL), an OpenAlex ID (`W2148972377`), or the paper's exact title. direction: "both", "references" (what it cites) or "citations" (what cites it). limit: Max neighbours per direction, 1-50. format: "markdown" or "json".
  • cache_searchFull-text search over pages already fetched into the local SQLite FTS5 index. Best for: - Recalling something the user/agent fetched earlier in the conversation ("what did that Wikipedia page say about X"). - Avoiding re-fetching content already in the local cache. - Quick keyword grep across the corpus you've built up. Not recommended for: - Discovering new pages on the open web -> use `search` or `research`. - When the cache is empty (fresh install) -> `search`/`research` first to populate it. Returns: - markdown (default): a per-hit list of title, URL, and a `[bracket]`- highlighted snippet around the matched terms. - json: list of {url, title, snippet, author, date, sitename}. The last three are "" when the cached row predates metadata capture. Common mistakes: - Treating this like web search: it ONLY hits pages already in the local cache. If the user hasn't fetched anything, you'll get zero hits. - Using natural-language phrases without quoting them; FTS5 splits on whitespace as AND. For an exact phrase use `"like this"`. Args: query: FTS5 query. Bare terms = AND. Supports OR / NOT, prefix (`term*`), and phrase (`"exact phrase"`). limit: Max hits to return. format: "markdown" or "json".
  • enginesList the available sources, grouped by what they index. Best for: - Choosing a source deliberately: which one indexes filings, or preprints, or Chinese-language pages. - Checking a name before passing it to `engines=` on `search` / `research`. Not recommended for: - Calling on every search: the list is static, so read it once. Returns (markdown): a `group -> sub-group -> engine` tree, one line of description per engine. `group="paper"` restricts it to that group. Returns (json): `{"engines": [...names...], "taxonomy": {...}, "descriptions": {...}}`. Prefer `category=` over `engines=`. `category="paper"` WIDENS: it routes to one specialist per sub-group. A dotted sub-group NARROWS: `"paper.biomed"` queries only the biomedical indexes. Naming engines explicitly turns that routing off entirely, so reach for it only to force a specific source. Common mistakes: - Passing one of these names as `query`: they belong in `engines=`. - Passing a key-only engine with no key configured; it returns an actionable error, not results.
  • compareFetch 2-5 URLs concurrently and return per-URL excerpts so the LLM can compare them against a single question in one round trip. Best for: - Side-by-side product/feature/article comparisons. - "Compare X to Y" or "How does A differ from B" queries. - Triangulating a fact across multiple sources. Not recommended for: - >5 URLs -> use `fetch_batch`. - 1 URL -> use `fetch`. - Don't have URLs yet -> use `search` or `research` first. Returns: - markdown (default): a comparison brief with per-URL sections, each containing title, sitename, published date, and a smart-truncated excerpt. - json: {question, urls, excerpts:[{url, title, excerpt, ...}], tokens_estimated}. Common mistakes: - Asking `compare` to actually answer the question: it returns material, the LLM does the comparison. - Passing >5 URLs and expecting them all to fit in context: use `fetch_batch` for bulk reads. Args: question: The comparison question the LLM will answer using the returned excerpts. urls: 2-5 absolute http(s) URLs. format: "markdown" (default) or "json".
  • extract_structuredPull JSON-LD, OpenGraph, Twitter cards, and microdata from a web page. Best for: - Product pages (price, currency, availability, brand, rating). - Article pages (author, publish date, image, headline). - Recipe / event / video pages where rich metadata IS the answer. - Cases where `fetch` returns prose but you need fields. Not recommended for: - Just reading a page -> use `fetch`. - PDFs / DOCX -> use `read_doc`. - Pages that don't publish schema.org metadata (most blogs): you'll get empty lists; fall back to `fetch`. Returns: - json: {url, json_ld:[], microdata:[], opengraph:[], rdfa:[]}. Twitter card meta tags are surfaced inside the `opengraph` list. - markdown (default): a flattened key/value view with each block printed as a JSON code block under its syntax heading. Common mistakes: - Calling on every URL "just in case": most sites have no structured data, and `fetch` is what you actually want. Args: url: Absolute http(s) URL. format: "markdown" (default) or "json".
  • downloadSave a file from a URL to a local, auto-expiring download directory. Downloads are enabled by default and saved under `SEARCH_MCP_CACHE_DIR/downloads`. Set `SEARCH_MCP_DOWNLOAD_ENABLED=false` to disable them or `SEARCH_MCP_DOWNLOAD_DIR` to override the destination. Best for: - Keeping an actual file (installer, dataset, archive, image) rather than its text. - Handing a path to another tool that needs a real file on disk. Not recommended for: - Reading a document's contents -> use `read_doc`, which parses it without touching the filesystem. - Looking at a web page -> use `fetch`. - Viewing an image -> use `fetch(inline=True)`. Returns: - markdown (default): where the file was saved, its size and type. - json: {url, saved_path, media_type, bytes_size, sha256, expires_in_hours}. An expires_in_hours value of 0 means TTL cleanup is disabled. Retention: files older than SEARCH_MCP_DOWNLOAD_TTL_HOURS (default 24) are deleted before the next download and at startup. A value of 0 disables TTL cleanup. Otherwise, treat the path as short-lived and copy it elsewhere if you need to keep it. Args: url: Absolute http(s) URL of the file to save. format: "markdown" or "json".

JDocmunch MCP tools 64

  • index_localIndex 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_anchor_warning` for explicit `{#id}` headings written twice in one document.
  • doc_index_repoIndex 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.
  • doc_list_reposList 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_overviewv1.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.
  • get_docv1.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.
  • list_docsv1.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.
  • get_tocGet 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).
  • get_toc_treeGet a nested table of contents tree per document. Shows parent/child heading relationships. Content is excluded.
  • get_document_outlineGet the section hierarchy for a single document file, without content. Headings only, no content. Read a section with get_section.
  • search_sectionsSearch 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.
  • count_sectionsv1.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.
  • search_titlesv1.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.
  • +52 more on the listing page

Ready-to-paste client configs

Paste either block (or both) into your client config, e.g. claude_desktop_config.json or ~/.cursor/mcp.json. We only show a config when the install command is confirmed.

Free Search

mcpServers (Claude Desktop / Cursor)
{
  "mcpServers": {
    "free-search": {
      "command": "uvx",
      "args": [
        "free-search-mcp"
      ]
    }
  }
}

JDocmunch MCP

mcpServers (Claude Desktop / Cursor)
{
  "mcpServers": {
    "jdocmunch-mcp": {
      "command": "uvx",
      "args": [
        "jdocmunch-mcp"
      ],
      "env": {
        "DOC_INDEX_PATH": "YOUR_DOC_INDEX_PATH_HERE"
      }
    }
  }
}

Frequently asked questions

Free Search is categorized under Search & Data Extraction and uses a local stdio subprocess. JDocmunch MCP belongs to Search & Data Extraction and uses a local stdio subprocess. Pick Free Search for search & data extraction work and JDocmunch MCP for search & data extraction.

Copy the mcpServers block from the config section on this page into your client's config (for example claude_desktop_config.json or ~/.cursor/mcp.json), then fully restart the client.

Free Search is listed as free. Auth: no auth required. JDocmunch MCP is listed as freemium — a free tier with paid plans. Auth: no auth required. If a server needs environment variables such as API keys, define them under the env key in your client's MCP config.

Yes. MCP clients support multiple servers: add free-search and jdocmunch-mcp as separate keys in the same mcpServers object, and your assistant will call tools from either one.

On AllMCPs, Free Search has a quality signal of 64/100 (Good) with 1 views, 0 installs and 154 GitHub stars. JDocmunch MCP has 64/100 (Good) with 0 views, 0 installs and 206 GitHub stars.