reactome-mcp
# reactome-mcp
> An [MCP](https://modelcontextprotocol.io) server that gives coding agents first-class access to the [Reactome](https://reactome.org) pathway database — search, look up, traverse, export to SBML/SBGN, and run gene-set pathway-enrichment analysis, all from the chat.
[](https://www.python.org/downloads/)
[](https://modelcontextprotocol.io)
[](LICENSE)
Built with the official Python MCP SDK ([FastMCP](https://github.com/modelcontextprotocol/python-sdk)) over stdio. It wraps **both** Reactome REST services:
- **ContentService** — full-text search, entity/pathway lookup, hierarchy traversal, participants, complex subunits, interactors, and SBML/SBGN/diagram export.
- **AnalysisService** — submit a gene/protein list and get back ranked, enriched pathways with p-value/FDR.
Because it speaks plain MCP over stdio (no vendor-specific extensions), it works with **any MCP-capable agent** — Claude Code, Codex, Cursor, and others. Only the registration command differs.
---
## Quickstart
Requires [`uv`](https://github.com/astral-sh/uv) (which manages Python ≥ 3.12 for you).
```bash
git clone https://github.com/tc2fh/reactome-mcp.git
cd reactome-mcp
uv sync # install runtime deps
uv run reactome-mcp # boots the server on stdio (Ctrl+C to exit)
```
Then register it with your agent (see below) and ask it something like:
> *"Run Reactome enrichment on TP53, EGFR, BRCA1, MDM2, CDKN1A and list the 5 most significant pathways with their FDR."*
---
## Register with your agent
The server is a standard stdio MCP server launched with `uv run reactome-mcp`. Run these from inside the cloned directory.
**Claude Code**
```bash
claude mcp add reactome -- uv --directory "$PWD" run reactome-mcp
```
**Codex**
```bash
codex mcp add reactome -- uv --directory "$PWD" run reactome-mcp
```
…or add a table to `~/.codex/config.toml`:
```toml
[mcp_servers.reactome]
command = "uv"
args = ["run", "--directory", "/absolute/path/to/reactome-mcp", "reactome-mcp"]
```
**Cursor** — add to `.cursor/mcp.json` (project) or `~/.cursor/mcp.json` (global):
```json
{
"mcpServers": {
"reactome": {
"command": "uv",
"args": ["run", "--directory", "/absolute/path/to/reactome-mcp", "reactome-mcp"]
}
}
}
```
**Any other MCP client** (Windsurf, Cline, Zed, Pi, …) — point it at the same stdio command. A ready-to-edit example lives in [`.mcp.json`](.mcp.json):
```json
{
"mcpServers": {
"reactome": {
"type": "stdio",
"command": "uv",
"args": ["run", "--directory", "/absolute/path/to/reactome-mcp", "reactome-mcp"],
"env": {}
}
}
}
```
---
## Tools
All tools are async, return JSON-shaped dicts (or a path string for downloads), and degrade to `{"error": ...}` rather than raising on HTTP/network failures.
### Search & lookup
| Tool | Signature | Purpose |
|---|---|---|
| `search` | `(query, species=None, types=None, rows=10, start=0, cluster=True)` | Solr free-text search; returns flattened, highlight-stripped entries + per-type counts. |
| `get_entry` | `(stable_id, enhanced=False, attribute=None, max_chars=50000)` | Full record for any object by stable id/dbId; size-guarded; `attribute` fetches one field. |
| `get_entries` | `(stable_ids)` | Batch lookup for up to 20 identifiers at once. |
### Pathway hierarchy & participants
| Tool | Signature | Purpose |
|---|---|---|
| `list_top_level_pathways` | `(species)` | Top-level pathways (browser entry points) for a species name/taxId. |
| `list_pathway_events` | `(stable_id)` | All sub-pathways and reactions contained in a pathway (recursive). |
| `get_event_ancestors` | `(stable_id)` | Paths from an event up to its top-level pathway(s) — breadcrumbs. |
| `get_event_participants` | `(stable_id)` | Physical entities (+ their reference entities) in a reaction/pathway. |
| `find_pathways_for_entity` | `(stable_id, species=None, all_forms=False)` | Which lower-level pathways contain a given molecule/complex. |
### Entities, interactors, reference data
| Tool | Signature | Purpose |
|---|---|---|
| `get_complex_subunits` | `(stable_id, exclude_structures=False)` | Recursively list the subunits of a complex. |
| `get_interactors` | `(accession, page=-1, page_size=-1)` | Curated IntAct protein–protein interactors for an accession. |
| `list_species` | `(main_only=True)` | Species annotated in Reactome (name, taxId, abbreviation). |
| `list_diseases` | `()` | Diseases (Disease Ontology terms) annotated in Reactome. |
### Exporters
| Tool | Signature | Purpose |
|---|---|---|
| `get_event_sbml` | `(stable_id, fmt="sbml", max_chars=50000)` | Export a pathway/reaction to SBML or SBGN inline; head/tail truncation past `max_chars`. |
| `download_export` | `(stable_id, kind="event", ext="sbml", save_dir="./reactome_downloads")` | Stream an export to disk (event→sbml/sbgn, diagram/reaction/fireworks→png/svg, document→pdf). |
### Enrichment analysis
| Tool | Signature | Purpose |
|---|---|---|
| `analyze_identifiers` | `(identifiers, projection=True, species=None, sort_by="ENTITIES_PVALUE", p_value=1.0, page_size=20, page=1, include_interactors=False)` | Submit a gene/protein list; returns a `token` + ranked enriched pathways with pValue/FDR. |
| `get_analysis_results` | `(token, species=None, sort_by="ENTITIES_PVALUE", p_value=1.0, page=1, page_size=20, resource="TOTAL")` | Page/sort/filter a prior analysis by its token (no re-submission). |
| `get_analysis_not_found` | `(token, page=0, page_size=40)` | Identifiers from the submission that did not map to Reactome. |
**Design notes**
- Reactome stable ids look like `R-HSA-69278`; numeric dbIds and plain accessions (e.g. `P04637`) are also accepted. Path identifiers are validated so they can't escape the intended endpoint.
- `search` strips Reactome's Solr `<span class="highlighting">` markup and flattens the clustered `results[] → entries[]` shape into one list.
- `get_entry` and `get_event_sbml` are **size-guarded** so multi-MB records / SBML never flood the chat — they point you to `download_export`, which streams to disk.
- `analyze_identifiers` returns a `token`; reuse it with `get_analysis_results` / `get_analysis_not_found` to page and inspect without re-running the analysis.
---
## Example prompts
1. **Search + lookup** — *"Search Reactome for TP53, then look up 'Transcriptional Regulation by TP53' and summarise what it does."*
2. **Enrichment** — *"Run Reactome enrichment on TP53, EGFR, BRCA1, MDM2, CDKN1A and list the 5 most significant pathways with their FDR."*
3. **SBML export** — *"Find 'Cell Cycle Checkpoints', export its SBML to ./reactome_downloads, and tell me how many species and reactions it defines."*
4. **Hierarchy** — *"List the top-level human pathways, then drill into 'Cell Cycle' and show its contained events."*
---
## Development
```bash
uv sync --extra dev # install test deps (pytest, pytest-asyncio, respx)
uv run pytest # offline suite — every request is mocked via respx
```
The suite (`tests/`) runs entirely offline against captured fixtures in [`samples/`](samples), so it needs no network. Smoke-test the live server in any of these ways:
```bash
uv run reactome-mcp # console script
uv run python -m reactome_mcp # module entry point
uv run python server.py # source-checkout shim
uv run mcp dev src/reactome_mcp/server.py # MCP Inspector dev UI
```
```
reactome-mcp/
├── src/reactome_mcp/ # installable package (server.py = all tools + helpers)
├── server.py # source-checkout compatibility shim
├── tests/ # offline pytest suite (respx-mocked)
├── samples/ # captured API responses used as fixtures
├── pyproject.toml # uv-managed project
└── .mcp.json # example stdio MCP config
```
---
## Acknowledgements
Powered by [Reactome](https://reactome.org), a free, open-source, open-access, curated and peer-reviewed pathway database. Please cite Reactome when publishing work that uses this data — see <https://reactome.org/cite>.
This project is not affiliated with or endorsed by the Reactome team.
## License
[MIT](LICENSE) © Tien Comlekoglu
TDQS
Scored across 17 tools
Each tool targets a distinct resource and action, from listing species and diseases to fetching entries, exports, and analysis. The only slight overlap between get_event_sbml and download_export is clearly delineated by inline vs. file output, so an agent can reliably select the right tool.
All tool names follow a consistent verb_noun snake_case pattern (e.g., list_diseases, get_analysis_results, find_pathways_for_entity). Even compound names like get_analysis_not_found maintain the convention, with no camelCase or varied verb styles.
At 17 tools, the set is slightly above the typical 3-15 range but well-scoped for Reactome's broad functionality. The tools cover searching, browsing, exporting, and analysis without redundancy, so the count feels justified rather than excessive.
The tool surface covers core Reactome operations: browsing pathways and entities, searching, exporting in multiple formats, and performing over-representation analysis. Minor gaps exist, such as no direct tool for species-wide reaction lists or advanced API features, but agents can work around these with existing tools.