Skip to main content
Glama
README.md
# Iggy Docs MCP

MCP server for answering questions from the Apache Iggy documentation.

Serves two corpora to any MCP client, so an AI assistant answers Iggy questions from the project's own current material rather than from training data:

- **the guides** — the `content/docs` tree of [apache/iggy-website](https://github.com/apache/iggy-website), around seventy-five pages covering the server, every SDK, connectors, clustering, the CLI and the web UI. Keyed by site path (`server/docker`), linked to iggy.apache.org.
- **the Rust API** — the inline `///` doc comments of the SDK and core crates in [apache/iggy](https://github.com/apache/iggy), read from rustdoc's JSON output. Keyed under `api/` (`api/iggy/clients/client/IggyClient`), linked to docs.rs.

The two answer different questions — the guides say how Iggy is meant to be used, the Rust API says what is actually callable — so results are labelled with the half they came from, and `list_docs` and `search_docs` take a `source` argument (`all`, `website`, `rust-api`) to restrict to one.

Search is chunked BM25, with a small vocabulary bridge (container → docker, typescript → node, ssl → tls). Code blocks are first-class content: an SDK answer usually *is* the code block.

Each half is ranked on its own. BM25 normalises against average chunk length, and generated API items are uniformly shorter than prose, so one pooled average would penalise every guide chunk and flatter every API one. The two lists are then interleaved 2:1 in favour of prose — an explanation usually answers the question and a signature confirms it. A query that matches one half alone returns that half in full.

Distinct from the MCP server the Iggy project itself ships, which speaks the broker protocol to a running server. This one serves documentation and needs no server running.

Modelled on PolicyMCP, an MCP server for ASF policy documents: same layout, same tool surface, same conventions.

## Corpus sources

### Guides (apache/iggy-website)

Two modes, checked in this order:

1. **Local checkout**, when `IGGY_DOCS_ROOT` points at an iggy-website checkout (either the repo root or `content/docs` directly; the repo root resolves to `content/docs`, so blog posts and `node_modules` are never indexed). Files are read fresh on every call, so `git pull` is the refresh.
2. **GitHub**, otherwise: the docs tree is discovered via the GitHub API and fetched from raw files, cached in `~/.cache/iggy-doc-mcp/` for seven days.

### Rust API (apache/iggy)

A second local root, `IGGY_RUST_ROOT`, pointing at an apache/iggy checkout. There is no GitHub mode: unlike the guides, these files are *generated*, and generating them needs the source tree.

Only the public API of the SDK and core crates is indexed — `iggy`, `iggy_common`, `iggy_binary_protocol`, overridable with `IGGY_RUST_CRATES`. That keeps the index in the hundreds of items rather than the tens of thousands a whole-workspace private-item index would produce, which matters because every extra short item competes with the guides in search.

Doc comments are read from rustdoc's JSON, which `cargo` writes to `target/doc/<crate>.json`:

```sh
cargo +nightly rustdoc -p iggy --lib -- -Z unstable-options --output-format json
```

Building is never implicit — a search must not trigger a Rust build — so:

- when the JSON is present it is parsed fresh on every call, exactly like the website checkout, and re-running `cargo rustdoc` is the refresh;
- `refresh_docs` runs the build explicitly, once per configured crate;
- when the JSON is absent the Rust corpus is simply empty and the guides answer alone. A configured `IGGY_RUST_ROOT` with nothing built under it says so rather than returning silently.

`IGGY_RUST_DOC_JSON` overrides where the `<crate>.json` files are looked for, if they are not under `<root>/target/doc`.

One wrinkle on the first build: it takes minutes, and some MCP clients cut a tool call off after 60 seconds, so `refresh_docs` may report a timeout while `cargo` carries on and finishes normally. Call `list_docs` afterwards to confirm — if the item count is in the hundreds, the build landed. Later refreshes return promptly, because cargo has nothing to redo.

Two caveats worth knowing. rustdoc's JSON format is explicitly unstable and renumbers on breaking changes; the parser handles both the current and previous spellings of the shapes it uses and warns when it meets a `format_version` outside its checked range, rather than silently rendering signatures as `_`. And `--output-format json` is nightly-only, though a stable toolchain will emit it under `RUSTC_BOOTSTRAP=1` if you would rather not install one.

## Install

```sh
python3 -m venv .venv
. .venv/bin/activate
pip install -e .
```

## Run

```sh
iggy-doc-mcp
```

For local development:

```sh
python -m iggy_doc_mcp.server
```

## Test

```sh
pip install -e ".[dev]"
make check
```

## Configure with Claude Desktop or Codex

On macOS the Claude Desktop config lives at
`~/Library/Application Support/Claude/claude_desktop_config.json`; create it if
it is not there. Add the server, then quit and reopen Claude Desktop.

```json
{
  "mcpServers": {
    "iggy-docs": {
      "command": "<path to IggyDocMCP>/.venv/bin/python",
      "args": ["-m", "iggy_doc_mcp.server"],
      "env": {
        "IGGY_DOCS_ROOT": "<path to iggy-website>",
        "IGGY_RUST_ROOT": "<path to iggy>"
      }
    }
  }
}
```

Omit `IGGY_DOCS_ROOT` to use the GitHub-fetched guides instead of a local checkout. Omit `IGGY_RUST_ROOT` to serve the guides alone.

## Tools

- `list_docs` — every documentation page, organised by section, with word counts and corpus source; `source` restricts to one half.
- `get_doc` — full text of one page by key (e.g. `server/docker`, `sdk/python/intro`); unambiguous partial keys resolve automatically.
- `search_docs` — ranked keyword search across both halves, returning excerpts with their code blocks, each labelled Guide or Rust API and linked to iggy.apache.org or docs.rs; `source` restricts to one half.
- `find_examples` — search fenced code examples by topic and language, with source doc keys, headings and URLs.
- `extract_code_snippets` — inventory code fences for snippet verification work, filtered by language or doc key.
- `get_related_docs` — find pages related to a doc key using links, backlinks, shared section and shared terms.
- `explain_doc_map` — guided overview of the documentation sections, likely entry points for an audience or goal, and obvious top-level gaps.
- `find_broken_links` — local-checkout link scan for broken internal docs links and optional external URL checks.
- `refresh_docs` — re-fetch the GitHub guides, bypassing the seven-day cache (reporting git pull as the path when a local checkout is in use), and rebuild the Rust API corpus with `cargo rustdoc`.

## Example questions

- What flags does the Iggy server need under Docker?
- How do I create a consumer group from Python?
- What is the exact signature of `send_messages` on the Rust client?
- Which errors can `IggyClient::connect` return?
- How do I enable TLS?
- How is message retention configured?
- Show me a TypeScript producer example.

## Licence

Apache License 2.0. See [LICENSE](LICENSE).

## Disclaimer

This is an independent, third-party tool. It is not a release of, endorsed by, or affiliated with the Apache Software Foundation or the Apache Iggy project. Apache, Apache Iggy and Iggy are trademarks of the Apache Software Foundation.

TDQS

A4.1/5.0

Scored across 9 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: listing, fetching, searching, finding examples, extracting snippets, getting related docs, explaining structure, checking links, and refreshing. Even search_docs and find_examples are well-separated by their focus on general search versus example discovery.

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern (list_docs, get_doc, search_docs, find_examples, extract_code_snippets, get_related_docs, explain_doc_map, find_broken_links, refresh_docs). The pattern is predictable and easy to infer.

Tool Count5/5

Nine tools is well-scoped for a documentation server. Each tool covers a distinct aspect of doc navigation, search, extraction, and maintenance without unnecessary redundancy.

Completeness5/5

The tool surface covers the full lifecycle of documentation access: discover, retrieve, search, extract examples, find related content, understand structure, validate links, and refresh data. No obvious gaps for a read-only docs MCP.

Maintenance

ActivityMaintained
ResponsivenessNo issues