Metadata-Version: 2.5
Name: gbdocs-mcp
Version: 0.1.0
Summary: MCP server exposing the Game Boy Pan Docs as structured, citable lookups for decompilation work
Project-URL: Homepage, https://github.com/Nighthawk42/gbdocs-mcp
Project-URL: Repository, https://github.com/Nighthawk42/gbdocs-mcp
Project-URL: Issues, https://github.com/Nighthawk42/gbdocs-mcp/issues
Project-URL: Changelog, https://github.com/Nighthawk42/gbdocs-mcp/blob/main/CHANGELOG.md
Project-URL: Pan Docs, https://gbdev.io/pandocs/
Author: Nighthawk42
License-Expression: MIT
License-File: LICENSE
License-File: NOTICE.md
Keywords: decompilation,game-boy,gameboy,gbdev,mcp,model-context-protocol,pandocs,retro,reverse-engineering,sm83
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Disassemblers
Classifier: Topic :: Software Development :: Documentation
Classifier: Topic :: System :: Emulators
Requires-Python: >=3.11
Requires-Dist: mcp[cli]>=2.0.0
Requires-Dist: rapidfuzz>=3.9
Provides-Extra: semantic
Requires-Dist: numpy>=1.26; extra == 'semantic'
Requires-Dist: sentence-transformers>=3.0; extra == 'semantic'
Description-Content-Type: text/markdown

# gbdocs-mcp

[![CI](https://github.com/Nighthawk42/gbdocs-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/Nighthawk42/gbdocs-mcp/actions/workflows/ci.yml)
[![PyPI](https://img.shields.io/pypi/v/gbdocs-mcp.svg)](https://pypi.org/project/gbdocs-mcp/)
[![Python](https://img.shields.io/pypi/pyversions/gbdocs-mcp.svg)](https://pypi.org/project/gbdocs-mcp/)
[![License](https://img.shields.io/pypi/l/gbdocs-mcp.svg)](LICENSE)

An MCP server that turns the Game Boy [Pan Docs](https://gbdev.io/pandocs) into precise,
low-token, **citable** lookups for decompilation work.

Instead of grepping 456 KB of markdown, an agent can ask directly:

- *What is `$FF41`?* → `gb_lookup_register`
- *What does `ld a,$91 / ldh [rLCDC],a` configure?* → `gb_decode_register_value`
- *What does a write to `$2000` do on MBC1?* → `gb_mbc_decode_write`
- *What is opcode `$CB 7C`?* → `gb_decode_opcode`
- *What register state does my ROM inherit from the boot ROM?* → `gb_boot_state`

Two rules shape every response:

1. **Nothing is fabricated.** Each response carries a `source` block naming the page,
   section and `https://gbdev.io/pandocs/...` URL it came from. Where Pan Docs does not
   cover something (opcode cycle counts, for instance), the server says so.
2. **`pandocs/` is never modified.** The docs are read live at startup, so a
   `git pull` inside the clone updates the server with no rebuild.

## Install

The Pan Docs markdown ships inside the package, so there is nothing else to download.

```sh
pip install gbdocs-mcp                # or: uv tool install gbdocs-mcp
pip install "gbdocs-mcp[semantic]"    # adds embedding-backed search (pulls in torch)
```

Register with Claude Code:

```sh
claude mcp add gbdocs -- uvx gbdocs-mcp
```

<details>
<summary>Or with any MCP client, via <code>mcpServers</code> config</summary>

```json
{
  "mcpServers": {
    "gbdocs": {
      "command": "uvx",
      "args": ["gbdocs-mcp"]
    }
  }
}
```
</details>

### From source

```sh
git clone https://github.com/Nighthawk42/gbdocs-mcp && cd gbdocs-mcp
uv sync --extra semantic --dev
uv run gbdocs-mcp
```

Optionally clone [pandocs](https://github.com/gbdev/pandocs) beside the checkout; a
local clone takes precedence over the bundled copy, so `git pull` in it updates the
server with no rebuild.

### Configuration

| Variable | Meaning |
| --- | --- |
| `PANDOCS_ROOT` | Use a specific pandocs checkout instead of the bundled copy. |
| `GBDOCS_CACHE` | Where embedding vectors are cached. Defaults to `~/.cache/gbdocs-mcp`. |
| `GBDOCS_EMBED_MODEL` | Sentence-transformers model. Defaults to `all-MiniLM-L6-v2`. |

Docs are resolved in that order: `PANDOCS_ROOT`, then a sibling `pandocs/` clone,
then the bundled copy. Whichever is in use is reported by `pandocs_toc` as
`docs_revision`, including the upstream commit hash.

Semantic search loads lazily — the model is only downloaded the first time a search
actually needs it, and vectors are cached thereafter. Without the `semantic` extra,
search degrades to BM25 and says so in its response rather than failing.

## Tools

### Navigation & retrieval
| Tool | Answers |
| --- | --- |
| `pandocs_toc` | What chapters exist, and where does a topic live? |
| `pandocs_search` | Hybrid BM25 + semantic search over ~580 sections. |
| `pandocs_get_page` | Give me a whole chapter (or just its heading outline). |
| `pandocs_get_section` | Give me one section, with its bitfields and caveats. |
| `pandocs_resolve_link` | Where does this `#Section Name` cross-reference point? |

### Registers
| Tool | Answers |
| --- | --- |
| `gb_lookup_register` | What is `$FF40` / `LCDC` / `rLCDC` / "LCD control"? |
| `gb_list_registers` | Show me all CGB-only registers / all audio registers. |
| `gb_decode_register_value` | What does writing `$91` to `LCDC` actually configure? |
| `gb_encode_register_value` | What byte turns the LCD on with 8000-addressing? |

### Memory
| Tool | Answers |
| --- | --- |
| `gb_memory_map` | What lives at this address — region, register, vector, header field, MBC range? |

### Cartridge
| Tool | Answers |
| --- | --- |
| `gb_cartridge_header` | What is the header layout / the field at `$0147`? |
| `gb_lookup_cart_code` | Cart type `$13`? ROM size `$05`? Licensee `01`? |
| `gb_decode_cart_header` | Decode these 80 header bytes and verify the checksum. |

### MBCs
| Tool | Answers |
| --- | --- |
| `gb_mbc_info` | What control registers and quirks does MBC5 have? |
| `gb_mbc_decode_write` | This ROM writes `$05` to `$2000` — what did it just do? |

### CPU
| Tool | Answers |
| --- | --- |
| `gb_decode_opcode` | Disassemble this byte stream. |
| `gb_lookup_instruction` | How is `ld hl, imm16` encoded? What flags does `daa` touch? |
| `gb_opcode_table` | Show me the encoding structure of block 2 / the `$CB` block. |

### Hardware behaviour
| Tool | Answers |
| --- | --- |
| `gb_interrupts` | What is at `$48`, and when does it fire? |
| `gb_gotchas` | What hardware caveats apply to OAM / the PPU / MBC1? |
| `gb_boot_state` | What register values does a DMG ROM start with? |

Pages are also exposed as MCP resources (`pandocs://page/LCDC`).

## Opcode data provenance

Pan Docs' `CPU_Instruction_Set.md` is an **encoding** reference — it has no cycle counts
and no flag effects, and explicitly defers to [gbz80(7)](https://rgbds.gbdev.io/docs/gbz80.7)
and [the optables](https://gbdev.io/gb-opcodes/optables). This server therefore:

- derives mnemonics, operands and instruction length from Pan Docs' `{{#bits}}` groupings,
- merges cycles and flag effects from a vendored copy of `gbdev.io/gb-opcodes/Opcodes.json`,
- and labels every field with which of the two it came from.

The two are cross-checked against each other across all 512 opcodes in the test suite.

## Development

```sh
uv run pytest                             # 599 tests, ~1s
uv run python scripts/smoke.py            # call all 21 tools, print a digest of each
uv run python scripts/client_probe.py     # drive the server as a real MCP stdio client
uv run mcp dev src/gbdocs_mcp/server.py   # MCP Inspector
```

The heaviest test decodes all 512 opcodes from Pan Docs' `{{#bits}}` groupings and
asserts they agree with the vendored table. A disagreement there means the markdown
parser has drifted, so it is worth keeping green.

## Contributing

See [AGENTS.md](AGENTS.md) for the architecture, the corpus quirks the parsers have to
keep handling, and the invariants that must not regress.

## Licence

Server code is MIT (see [LICENSE](LICENSE)).

The bundled documentation is not mine: **Pan Docs is released into the public domain
(CC0-1.0)** by the gbdev community, and the opcode timing table comes from
[gb-opcodes](https://github.com/gbdev/gb-opcodes). This project only reformats their
work for machine consumption. Full attribution is in [NOTICE.md](NOTICE.md).
