General
enrichr-api - Claude MCP Skill
Direct access to the Enrichr REST API for work the enrichr_analysis MCP tool cannot do — reverse gene lookup (which gene sets contain a gene), downloading a whole library as GMT, unfiltered result tables including non-significant terms, batch enrichment over many gene lists (e.g. per single-cell cluster), and shareable Enrichr web links. Use when the user asks for any of those, or hits a limit of the MCP tool. Do NOT use for ordinary enrichment of a single gene list — the MCP tool is better at that.
SEO Guide: Enhance your AI agent with the enrichr-api tool. This Model Context Protocol (MCP) server allows Claude Desktop and other LLMs to direct access to the enrichr rest api for work the enrichr_analysis mcp tool cannot do — reverse gen... Download and configure this skill to unlock new capabilities for your AI workflow.
Documentation
SKILL.md# Enrichr REST API
## Use the MCP tool first
For "run enrichment on these genes", call the **`enrichr_analysis` MCP tool**. It
filters to significant terms, formats for reading, handles background correction,
and manages token budget. Reach for the raw API only when you need something it
does not expose:
| You need | Use |
|---|---|
| Enrichment of one gene list | `enrichr_analysis` tool |
| Which libraries suit a topic | `suggest_libraries` tool |
| **Which gene sets contain gene X** | this skill — `genemap` |
| **A whole library as GMT** | this skill — `download` |
| **All terms, including non-significant** | this skill — `enrich` |
| **Many gene lists at once** (per-cluster) | this skill — `enrich_batch` |
| **A shareable Enrichr web link** | this skill — `add_list` returns `shortId` |
## The script
`scripts/enrichr.py` — no dependencies beyond the standard library.
```bash
python scripts/enrichr.py libraries # every live library + term count
python scripts/enrichr.py genemap TP53 # TP53 appears in 214 libraries
python scripts/enrichr.py download KEGG_2026 kegg.gmt # 352 terms as GMT
python scripts/enrichr.py enrich genes.txt KEGG_2026 # unfiltered JSON table
python scripts/enrichr.py enrich genes.txt KEGG_2026 --background bg.txt
```
Import it for batch work:
```python
from enrichr import enrich_batch, enrich, genemap, download_library
clusters = {"cluster_0": [...], "cluster_1": [...]} # e.g. Seurat/scanpy markers
results = enrich_batch(clusters, "KEGG_2026") # {name: [term, ...] | None}
```
## Endpoints
Base: `https://maayanlab.cloud/Enrichr`. Background correction lives on a
*different* service: `https://maayanlab.cloud/speedrichr/api`.
| Endpoint | Purpose |
|---|---|
| `POST /addList` | Submit genes → `userListId` + `shortId` |
| `GET /enrich?userListId=&backgroundType=<library>` | Enrichment, all terms |
| `GET /export?userListId=&backgroundType=&filename=` | Same, as TSV |
| `GET /view?userListId=` | Read back a submitted list |
| `GET /genemap?gene=<sym>&json=true` | Reverse lookup: gene → libraries/terms |
| `GET /geneSetLibrary?mode=text&libraryName=<lib>` | Whole library as GMT |
| `GET /datasetStatistics` | Every live library. **The only source of truth.** |
| `POST speedrichr/addList`, `/addbackground`, `/backgroundenrich` | Background-corrected enrichment |
A `shortId` from `addList` is a shareable web page — good for collaborators and
methods sections:
`https://maayanlab.cloud/Enrichr/enrich?dataset=<shortId>`
## Traps
These are the reason this skill exists. Each one has bitten this repo.
**A retired library returns `{}`, not an error.** Enrichr retires libraries
constantly and the API does not tell you — `/enrich` just answers with an empty
object, which reads as "no enrichment" rather than "that library is gone". Never
trust a hardcoded or remembered library name. Check `datasetStatistics`. As of
2026-07 there are 228 live libraries, and names drift in ways that look like typos
(`BioPlanet_2019` is live, `Bioplanet_2019` is dead).
**Prefer the current vintage.** Many libraries ship a dozen years of snapshots
(`GO_Biological_Process_2013` … `_2026`). Use the newest unless the user is
reproducing an old analysis. Current generation: `GO_Biological_Process_2026`,
`GO_Cellular_Component_2026`, `GO_Molecular_Function_2026`, `KEGG_2026`,
`Reactome_Pathways_2024`, `GWAS_Catalog_2025`.
**Enrichr emits bare `Infinity`, which is not valid JSON.** The odds ratio is
infinite whenever every one of a term's background genes is in your gene list —
with a custom background that is *routine*, not rare (36 of 82 terms in a real
run). Consequences by language:
- **JavaScript**: `JSON.parse` throws outright. You must sanitize the text first.
- **Python**: `json.loads` accepts it silently — so you will not notice — and then
`json.dump` writes `Infinity` straight back out, producing an invalid JSON file
that breaks whatever reads it next. `allow_nan=False` does not save you; it
raises instead of converting. Replace non-finite floats with `None` before
encoding. `scripts/enrichr.py` does this in `finite()`.
**Background correction is a different service, and its 500s are ambiguous.**
Custom backgrounds are not available on `/Enrichr/enrich` at all — you must go
through `speedrichr` (`addList` → `addbackground` → `backgroundenrich`). An HTTP
500 from `backgroundenrich` means one of two very different things:
1. *You used the wrong `userListId`.* The two services keep **separate ID
namespaces**, and submitting your genes to `/Enrichr/addList` and then passing
that id to `backgroundenrich` fails with a 500 every time — not a 400, not a
helpful message. Submit to `speedrichr/addList` instead. (Verified: a classic
id 500s on all retries where a speedrichr id returns 82 terms. The ranges even
look different — classic ids are ~1.3e8, speedrichr ~2.0e9.)
2. *The service is having a moment.* It also throws genuinely transient 500s that
clear on retry, sometimes across a whole library family at once, which can look
convincingly like "this library doesn't support backgrounds". It does. Retry.
So: check your id namespace first, then retry. Do not fall through to the
uncorrected endpoint without saying so loudly.
**Background correction changes the answer enormously.** It is not a refinement.
For a 16-gene DNA-damage list against `KEGG_2026`, whole-genome gives 50
significant terms with a top adjusted p of 8.5e-19; a 40-gene background gives 14
significant terms with a top adjusted p of 1.6e-4. If the gene list came from a
restricted universe — expressed genes, a targeted panel, detected proteins — the
whole-genome default is simply the wrong test and will overstate significance.
The background must be the universe the list was drawn *from*, not the list itself.
**Enrichr rate-limits (HTTP 429).** You will hit this within a handful of requests
once you start looping — which is exactly what batch work does. Pace the loop and
back off on 429. `scripts/enrichr.py` sleeps between lists and retries 429s.
**`/enrich` and `/export` return every term with any overlap, not just significant
ones.** A 16-gene list against `KEGG_2026` returns 82 terms, of which 50 are
significant. That is a feature when you want to compute your own FDR or plot the
full p-value distribution, and a token disaster if you paste it into context
unfiltered. Filter before showing results to anyone.
## Interpreting results
Each term is a 7-tuple, mapped to names in `scripts/enrichr.py`:
`rank, term, p_value, odds_ratio, combined_score, genes, adj_p_value`
Use **`adj_p_value`** (Benjamini-Hochberg), not `p_value`, for significance;
`< 0.05` is the usual cut. `combined_score` is Enrichr's own ranking heuristic
(`ln(p) × z`) and is fine for ordering but is not a statistic anyone will accept in
a paper. Report the adjusted p-value and the overlap.Signals
Information
- Repository
- tianqitang1/enrichr-mcp-server
- Author
- tianqitang1
- Last Sync
- 11/3/2026
- Repo Updated
- 7/14/2026
- Created
- 7/14/2026
Reviews (0)
No reviews yet. Be the first to review this skill!
Related Skills
CLAUDE
Claude-Mem: AI Development Instructions
cursorrules
CrewAI Development Rules
firecrawl-build-interact
Integrate Firecrawl `/interact` into product code for dynamic pages and browser actions after scraping. Use when a feature needs clicks, form fills, pagination, authentication-aware flows, or other multi-step interactions that plain `/scrape` cannot complete.
firecrawl-build
Integrate Firecrawl into application code whenever a product, agent, or workflow needs web data inside the app — web search, live search results, page scraping, structured extraction, or browser interaction. Use when building any feature that needs data from the web in code, even if the user does not mention Firecrawl explicitly and only describes wanting web data, website content, search, scraping, or interaction in an application. Trigger for Firecrawl requests, "fire girl" shorthand, and generic app-level web-data needs that should map to `/scrape`, `/search`, or `/interact`. Do not use this skill for one-off terminal-only web tasks during the current session; use `firecrawl/cli` for those.
Related Guides
Bear Notes Claude Skill: Your AI-Powered Note-Taking Assistant
Learn how to use the bear-notes Claude skill. Complete guide with installation instructions and examples.
Mastering tmux with Claude: A Complete Guide to the tmux Claude Skill
Learn how to use the tmux Claude skill. Complete guide with installation instructions and examples.
OpenAI Whisper API Claude Skill: Complete Guide to AI-Powered Audio Transcription
Learn how to use the openai-whisper-api Claude skill. Complete guide with installation instructions and examples.