MCP integration for BioInsight Graph — the disease–target knowledge graph application (Neo4j, FastAPI, React explorer). This repo adds an Embabel MCP server so Cursor, Claude Desktop, and other clients can call the same /api/v1 surface the web UI uses.
BioInsight Graph is the product. embabel-mcp is not a replacement, fork, or “wrapper app” — it is agent tooling built on top of that API.
Built with Embabel Agent (embabel-agent-starter-mcpserver).
Data notice: Demo/sample Open Targets–style data only — not for clinical decisions.
flowchart LR
MCP[Cursor / Claude / Inspector]
EMB[embabel-mcp :1337 /sse]
API[bioinsight-graph API :8000]
N4j[(Neo4j)]
MCP --> EMB
EMB --> API
API --> N4j
flowchart TB
C[MCP client]
E[embabel-mcp]
BAPI[BioInsight API :8000]
BWEB[BioInsight UI :8080]
RAG[kg-rag-demo :8001]
C --> E
E --> BAPI
BWEB --> BAPI
E -. KG_RAG_ENABLED .-> RAG
The primary interface — search, ranked associations, and force-directed graph exploration. Run it at http://localhost:8080 (see bioinsight-graph).
| Search | Force-directed graph |
|---|---|
![]() |
![]() |
Full gene detail: screenshot-gene-detail.png · Walkthrough: demo-walkthrough.gif
| MCP export | Description |
|---|---|
research_gene |
GeneResearchAgent — parse symbol → load graph → markdown report + link to web UI |
Starting inputs: GeneSymbolQuery (symbol string) or natural language via UserInput.
Most tools accept optional format: markdown (default) or json.
| Tool | BioInsight API |
|---|---|
bioinsight_health |
GET /api/v1/health |
bioinsight_stats |
GET /api/v1/stats |
search_genes |
GET /api/v1/genes?q= |
search_diseases |
GET /api/v1/diseases?q= |
get_gene |
GET /api/v1/genes/{id} |
get_gene_diseases |
GET /api/v1/genes/{id}/diseases (ranked by score) |
get_disease |
GET /api/v1/diseases/{id} |
get_disease_genes |
GET /api/v1/diseases/{id}/genes (top targets) |
compare_genes |
GET /api/v1/genes/compare?symbols=BRCA1,TP53 |
get_gene_neighbors |
GET /api/v1/genes/{id}/neighbors |
export_gene_subgraph |
GET /api/v1/export/subgraph?gene_id= |
plan_investigation |
JSON plan: intent, entities, tool sequence, stop rules (call before dossier) |
resolve_identifier |
GET /resolve |
get_target_evidence |
Gene–disease evidence breakdown or association scores (standard+) |
get_gene_external_links |
Ensembl, Open Targets, UniProt deep links (standard+) |
export_provenance_bundle |
M7 audit JSON: meta, queries, links, evidence sample (standard+) |
batch_gene_lookup |
Resolve many symbols/ids at once (BioInsight 3.4) (standard+) |
export_gene_report |
Analyst report with provenance columns (BioInsight 3.5) (standard+) |
build_target_dossier |
Full markdown handoff: detail + diseases + neighbors + stats + provenance + UI link |
investigate_gene_symbol |
search + detail + ranked diseases + neighbors (lighter than dossier) |
plan_gap_investigation |
GapForge plan (COU, L2 sequence, stop rules) |
build_program_dossier |
Stalled-program dossier (GET /programs/{id}/dossier) |
propose_gap_hypotheses |
List/create L2 cards (needs_review — HITL required) |
run_critic |
Adversarial critic on a gap id |
export_review_bundle |
Provenance export (team_conclusions = approved only) |
export_approved_rdf |
Turtle export for approved L2 gaps (GET /export/approved-rdf) |
run_gap_discern |
Persist Discern score on a stored gap (approve-gate source of truth) |
run_gap_ontology_validate |
Persist OntoHarness SHACL + vocab gate on a stored gap |
discern_artifact |
Universal I/O weigh: compliance / reliability / provenance / safety thresholds |
OntoHarness (requires ONTOHARNESS_ENABLED=true, sidecar on :8010):
| Tool | Description |
|---|---|
validate_proposal |
Validate raw Turtle (vocab gate + SHACL) |
get_repair_hints |
Validation repair hints for agent loops |
bridge_gap_record |
GapForge JSON → Turtle + optional validate |
list_ontoharness_domains |
Registered validation domains |
Agent export: research_program_gaps · Prompt: investigate-stalled-program
| URI | Description |
|---|---|
bioinsight://schema |
Graph model + example Cypher |
bioinsight://meta |
Live data version, sources, disclaimer (GET /api/v1/meta) |
bioinsight://provenance |
Dataset scope and link to PROVENANCE.md |
bioinsight://stats |
Live counts from the running API |
bioinsight://ecosystem |
All browser/API URLs (BioInsight, Neo4j, KG RAG, MCP) |
bioinsight://investigation-playbook |
Intent routing — which tool for gene vs disease vs compare vs literature |
| Prompt | Use case |
|---|---|
adaptive-gene-investigation |
Plan → resolve → branch (ambiguous symbol / sparse evidence) |
summarize-gene-targets |
Gene-first: plan, resolve, dossier, summarize |
compare-gene-pair |
Compare path: plan, resolve both, compare_genes |
top-targets-for-disease |
Disease-first: plan, resolve disease, get_disease_genes |
graph-and-literature |
Dual-channel: dossier first; kg_rag_ask only if sparse or literature question |
review-gene-report |
HITL: human verifies http://localhost:8080 before trusting report |
public-data-to-mcp-tutorial |
Onboarding: public data → local BioInsight API → MCP in Cursor (no Java edits) |
| Layer | How |
|---|---|
| BioInsight UI | http://localhost:8080 — visual ground truth |
| MCP prompt | review-gene-report |
| Embabel agent | BIOINSIGHT_HITL_ENABLED=true → WaitFor approval form (not for default MCP) |
Guide: docs/HUMAN_IN_THE_LOOP.md · MCP resource bioinsight://human-in-the-loop
Set KG_RAG_ENABLED=true and run kg-rag-demo on port 8001:
| Tool | API |
|---|---|
kg_rag_health |
GET /api/v1/health |
kg_rag_ask |
POST /api/v1/ask |
- “What are the top disease associations for BRCA1?” →
investigate_gene_symbolorget_gene_diseases - “Compare BRCA1 and TP53” →
compare_genes - “Which genes target breast cancer?” →
search_diseasesthenget_disease_genes
- Java 21 and Maven 3.9+
- bioinsight-graph API running on port 8000 (Neo4j seeded)
- OPENAI_API_KEY — required by Embabel at startup (OpenRouter free models work; see
.env.example)
From your bioinsight-graph clone:
cd C:\Users\Lordwill\Documents\projects\bioinsight-graph
docker compose up -d neo4j
# seed once if needed — see bioinsight-graph README
cd api
py -3 -m venv .venv
.\.venv\Scripts\pip install -r requirements.txt
.\.venv\Scripts\uvicorn app.main:app --reload --port 8000Verify: http://localhost:8000/api/v1/health
cd C:\Users\Lordwill\Documents\projects\embabel-mcp
copy .env.example .env
# Edit .env — set OPENAI_API_KEY (OpenRouter key is fine)
$env:OPENAI_API_KEY = "your-key"
$env:OPENAI_BASE_URL = "https://openrouter.ai"
$env:BIOINSIGHT_API_BASE_URL = "http://localhost:8000/api/v1"
mvn spring-boot:runSSE endpoint: http://localhost:1337/sse
Merge into .cursor/mcp.json (see cursor-mcp.example.json):
{
"mcpServers": {
"bioinsight-graph": {
"command": "npx",
"args": ["-y", "mcp-remote", "http://localhost:1337/sse"]
}
}
}npx @modelcontextprotocol/inspectorConnect to http://localhost:1337/sse, then try compare_genes with symbols=BRCA1,TP53 or open prompt summarize-gene-targets.
Large MCP servers inflate the IDE context window; the 120k-token limit is on the host model, not per tool. This repo defaults to full-fidelity responses (no truncation):
BIOINSIGHT_MCP_TOOL_PROFILE—minimal/standard/full(main lever)BIOINSIGHT_MCP_COMPACT_MODE—off(default),warn, or opt-intruncate- Workflow dossiers are never truncated; optional advisory footer only
See docs/CONTEXT_BUDGET.md and docs/RESPONSE_POLICY.md. MCP resource: bioinsight://context-policy.
| Variable | Default | Description |
|---|---|---|
BIOINSIGHT_API_BASE_URL |
http://localhost:8000/api/v1 |
FastAPI base URL |
BIOINSIGHT_WEB_UI_URL |
http://localhost:8080 |
Deep links in markdown dossiers |
BIOINSIGHT_MCP_TOOL_PROFILE |
standard |
minimal | standard | full — tools exposed at startup |
BIOINSIGHT_MCP_COMPACT_MODE |
off |
off | warn | truncate (truncate not recommended) |
BIOINSIGHT_MCP_MAX_RESPONSE_CHARS |
0 |
Hard cap only when compact-mode=truncate |
BIOINSIGHT_MCP_WARN_RESPONSE_CHARS |
12000 |
Advisory footer threshold (chars); does not cut content |
MCP_SERVER_PORT |
1337 |
HTTP port for SSE |
OPENAI_API_KEY |
— | Required (OpenAI or OpenRouter) |
OPENAI_BASE_URL |
https://openrouter.ai |
OpenAI-compatible API base |
EMBABEL_DEFAULT_LLM |
x-ai/grok-4.1-fast:free |
Default model id |
KG_RAG_ENABLED |
false |
Enable kg-rag-demo tools |
KG_RAG_API_BASE_URL |
http://localhost:8001/api/v1 |
KG RAG FastAPI base |
BIOINSIGHT_MCP_METRICS_LOG_LEVEL |
DEBUG |
M12: log bioinsight.mcp.metrics per tool response (chars, profile) |
Clone both repos side by side, add OPENAI_API_KEY to bioinsight-graph .env, then:
cd bioinsight-graph
docker compose -f docker-compose.yml -f docker-compose.mcp.yml up --build| Service | URL |
|---|---|
| MCP (SSE) | http://localhost:1337/sse |
| BioInsight Web UI | http://localhost:8080 |
| API | http://localhost:8000/docs |
cd embabel-mcp
copy .env.example .env
# set OPENAI_API_KEY
docker compose up --buildOr a single image:
docker build -t embabel-mcp .
docker run --rm -p 1337:1337 \
-e OPENAI_API_KEY \
-e BIOINSIGHT_API_BASE_URL=http://host.docker.internal:8000/api/v1 \
embabel-mcp| Doc | Topic |
|---|---|
| docs/ROADMAP.md | Implementation tasks (M1–M13) |
| docs/USE_CASES.md | Worked examples |
| docs/RESPONSE_POLICY.md | When compaction runs; workflow exemption; config |
| docs/CONTEXT_BUDGET.md | Characters vs tokens; staying under host 120k |
| docs/HUMAN_IN_THE_LOOP.md | Review workflows |
| docs/MCP_DEMO.md | Cursor → dossier → UI verify (M10) |
| ECOSYSTEM_CONTEXT | Compact handoff for new agent sessions |
mvn test
mvn spring-boot:run- bioinsight-graph — Neo4j graph, FastAPI, React UI
- Portfolio roadmap — cross-repo plan · kg-rag ROADMAP
- kg-rag-demo — optional document RAG (
KG_RAG_ENABLED=true)
MIT © 2026 LordKay-sudo

