MCP GeneLab Server
Summary: This MCP server lets AI assistants query and analyze NASA's spaceflight biology knowledge graph (spoke-genelab v0.3.1) in Neo4j using natural language instead of Cypher.
Natural-language querying — Ask plain-English questions about spaceflight experiments; the server converts them to Cypher and runs them read-only against Neo4j.
Differential gene expression — Find up/downregulated genes per assay (
find_differentially_expressed_genes), or intersect DEGs across multiple assays (find_common_differentially_expressed_genes).DNA methylation & organism abundance — Query hyper/hypomethylated regions (with promoter/exon/intron/distance filters) and differentially abundant microbes (DESeq2 / ANCOM-BC).
Cross-assay analyses — Common DEGs, common DMRs, common DA organisms, and expression–methylation coupling (DE genes whose promoter is also differentially methylated).
Study & assay browsing — Get study details and filter/select assays by organism, technology, or measurement (
select_assays).Schema & metadata exploration — List node types, attributes, relationships, and metadata (
get_neo4j_schema,get_node_metadata,get_relationship_metadata).Visualization — Generate volcano plots and Venn diagrams (2- or 3-way), plus Mermaid class diagrams of the KG schema.
Cypher fallback — Run arbitrary read-only Cypher via
querywhen specialist tools don't cover a question.Biomedical context — Connect spaceflight results to genes, pathways, diseases, and other graphs like SPOKE via federated queries.
Utilities & deployment — Chat transcripts, plot fetch/save, per-session state, STDIO/SSE/Streamable HTTP transports, Docker, and a hosted endpoint at
https://visualization.osdr.nasa.gov/kg/mcp.Safety — Read-only enforcement at both the regex-filter and Bolt
READ_ACCESSlevel; writes, dangerous procedures, and unsafe APOC calls are rejected.
Executes Cypher queries against Neo4j databases containing the NASA GeneLab Knowledge Graph, enabling natural language querying of differential gene expression, DNA methylation, and other spaceflight experiment data integrated with biomedical knowledge.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@MCP GeneLab Server show me genes upregulated in mouse liver during spaceflight"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
MCP GeneLab Server
A Model Context Protocol (MCP) server that converts natural language queries into Cypher queries and executes them against the configured Neo4j endpoints. Customized tools provide seamless access to the NASA GeneLab Knowledge Graph (spoke-genelab v0.3.1), enabling AI-assisted analysis of spaceflight experiments and their biological effects. This server allows researchers to query differential gene expression, DNA methylation, and differential organism abundance data from NASA's space biology experiments through natural language interactions with AI assistants like Claude.
The GeneLab Knowledge Graph integrates omics data from NASA's Open Science Data Repository (OSDR), with nodes that can be used as connectors to other knowledge graphs, such as the SPOKE (Scalable Precision Medicine Open Knowledge Engine) knowledge graph. This integration connects spaceflight experimental results with a comprehensive biological context, including genes, proteins, anatomical structures, pathways, and diseases.
This server is part of the NSF-funded Proto-OKN Project (Prototype Open Knowledge Network). It's an extension of the Neo4j Cypher MCP server.
Table of Contents
Related MCP server: SPARQL MCP Server
Building and Querying the SPOKE-GeneLab Knowledge Graph
Presentation
Knowledge Graph Schema (v0.3.1)
The SPOKE-GeneLab KG v0.3.1 contains the following node and relationship types:
The MCP-GeneLab server uses the SPOKE-GeneLab v0.3.1+20260311 release. Any new datasets or processed data added to OSDR after March 11, 2026 is not available through the MCP-GeneLab server.
Nodes: Study, Mission, Assay, MGene, Gene, MethylationRegion, Organism, Anatomy, CellType
Relationships:
(Mission)-[:CONDUCTED_MIcS]->(Study)— Mission conducted a study(Study)-[:PERFORMED_SpAS]->(Assay)— Study performed an assay(Assay)-[:MEASURED_DIFFERENTIAL_EXPRESSION_ASmMG]->(MGene)— Differential gene expression(Assay)-[:MEASURED_DIFFERENTIAL_METHYLATION_ASmMR]->(MethylationRegion)— Differential methylation(Assay)-[:MEASURED_DIFFERENTIAL_ABUNDANCE_ASmO]->(Organism)— Differential organism abundance(Assay)-[:INVESTIGATED_ASiA]->(Anatomy)— Assay investigated an anatomical structure(Assay)-[:INVESTIGATED_ASiCT]->(CellType)— Assay investigated a cell type(MGene)-[:IS_ORTHOLOG_MGiG]->(Gene)— Model organism gene is ortholog of human gene(MGene)-[:METHYLATED_IN_MGmMR]->(MethylationRegion)— Gene is methylated in a region
Features
Querying & Analysis
Natural Language Querying: Ask questions in plain English — no need to write complex graph queries
NASA GeneLab Queries: Ask questions about spaceflight experiments in the NASA GeneLab knowledge graph
Differential Gene Expression Analysis: Find genes that are upregulated or downregulated in spaceflight conditions compared to ground controls
DNA Methylation Data: Access epigenetic changes observed in spaceflight experiments, including promoter / exon / intron / distance-to-feature filtering
Differential Organism Abundance: Query amplicon/metagenomics data showing changes in microbial community composition during spaceflight (DESeq2 and ANCOM-BC method-aware significance filtering)
Cross-Assay Intersection Analyses: Find features differentially detected across multiple assays — common DEGs, common DMRs, common DA organisms — each direction (up/down, hyper/hypo, increased/decreased) kept separate so the LLM can reason about them independently
Expression-Methylation Coupling: Identify differentially expressed genes whose promoter (or other gene region) is also differentially methylated in matched assays; supports pooled DM evidence across multiple methylation assays
Multi-Organism Support: Query data across multiple model organisms including mice, rats, and other species used in space research
Anatomy & Cell Type Filtering: Filter results by specific anatomical structures (UBERON ontology) or cell types (Cell Ontology) used in experiments
Assay Selection: Browse and filter assays by study, organism, technology, or measurement type
Biomedical Context Integration: Connect spaceflight gene expression changes to pathways, diseases, and other biological knowledge from SPOKE
Federated Queries: Combine data from GeneLab with other Neo4j knowledge graphs for comprehensive biomedical analysis
Visualization
Volcano Plots: Generate volcano plots showing differentially expressed genes / methylated regions / abundant organisms with significance thresholds
Venn Diagrams: Create Venn diagrams comparing differentially expressed genes (or DMRs, or DA organisms) across 2 or 3 assays, including an
expression_methylation2×2 grid variant for paired transcriptomic-epigenomic comparisonsPlot Resource Layer: Every generated plot is exposed as an MCP resource under
plot://<session_id>/<filename>and via afetch_plottool, so clients can retrieve PNG bytes through a separate request from the tool call that produced them. A failed fetch can be retried without re-running the analysisSchema Visualization: Generate visual representations of the knowledge graph schema
Mermaid Class Diagrams: Create and clean Mermaid-format class diagrams of the KG schema
Infrastructure
Read-Only Enforcement: All Neo4j sessions use
READ_ACCESSmode — write operations are rejected at the Bolt protocol level, protecting the knowledge graph from modificationMultiple Transport Modes: Supports STDIO (local), SSE, and Streamable HTTP (remote deployment)
Remote Deployment: Deploy as a web service behind a TLS reverse proxy (target: CloudFront + WAF → ALB → ECS Fargate), accessible via HTTPS URL from any MCP client. Ships
GET /healthz/GET /readyzroutes for load-balancer health checks and built-in usage metrics (JSON usage log, CloudWatch EMF, optional/metrics) — see docs/deployment.mdSession Scoping: The hosted server is one shared process serving many users, so per-user state (output directory, plot registry) is keyed on a
session_idobtained fromcreate_sessionand passed on every tool call — nothing a user does is visible to another sessionDocker Support: Build and deploy as a Docker container for consistent, reproducible environments
Multiple Access Methods: Use through Claude Desktop / claude.ai, ChatGPT, VS Code with GitHub Copilot, Gemini, or any MCP-compatible client
Pre-configured Setup: Ready-to-use mcp-genelab configuration files for a local STDIO connection to the spoke-genelab-v0.3.1 KG, or connect to the public endpoint at
https://visualization.osdr.nasa.gov/kg/mcpwith no local install
Prerequisites
Before using mcp-genelab, ensure you have:
Client Application: One of the following:
Claude Desktop or claude.ai — connect via Settings → Connectors → Add Custom Connector
ChatGPT (web, Developer mode) — connect via Add custom MCP server
VS Code with GitHub Copilot — connect via MCP server settings
Gemini app (personal Google Account) or Gemini CLI — connect via Connected Apps or
gemini mcp addAny MCP client that supports the STDIO or Streamable HTTP transport
Connection to the spoke-genelab-v0.3.1 knowledge graph via one of the two paths below:
Remote public endpoint: Connect to the hosted mcp-genelab server at
https://visualization.osdr.nasa.gov/kg/mcpover HTTPS — no local install required. See Option A.Local install with STDIO: Run mcp-genelab on your own machine against a local Neo4j instance holding the spoke-genelab-v0.3.1 KG. See Option B.
For the local STDIO setup you also need:
Operating System: macOS, Linux, or Windows
Python 3.10+ and the uv package manager
Neo4j Desktop with the spoke-genelab-v0.3.1 KG imported (installation links are provided in Option B)
Quick Start
mcp-genelab can be reached two ways: by connecting to the remote public endpoint (https://visualization.osdr.nasa.gov/kg/mcp) or by running mcp-genelab locally with STDIO. Both serve the spoke-genelab-v0.3.1 knowledge graph.
Option A: Connect to the Remote mcp-genelab Server
The public mcp-genelab endpoint is:
https://visualization.osdr.nasa.gov/kg/mcpIt is a Streamable HTTP MCP server hosted by NASA OSDR with no authentication required, so you can connect without installing anything locally. Pick your client below. (If you would rather run against your own Neo4j instance, use Option B.)
Claude (Desktop or claude.ai)
Open Claude Desktop (or claude.ai)
Go to Settings → Connectors (or Manage Connectors)
Click Add Custom Connector
Enter:
Name:
mcp-genelabMCP Server URL:
https://visualization.osdr.nasa.gov/kg/mcp
Click Save
In the chat prompt, click the + button and toggle the mcp-genelab connector on
Documentation: Getting started with custom connectors using remote MCP
ChatGPT
In ChatGPT on the web, open Settings → Apps → Advanced settings and enable Developer mode (Pro; on Business/Enterprise/Edu an admin must enable it)
Go to chatgpt.com/plugins, click +, then Add custom MCP server
Enter:
Name:
mcp-genelabServer URL:
https://visualization.osdr.nasa.gov/kg/mcpAuthentication: No authentication
Accept the risk notice (I understand and want to continue), then click Create as a plugin and install it
In the chat prompt, type @ and select mcp-genelab
Documentation: Add custom MCP server · Developer mode and MCP apps in ChatGPT
VS Code with GitHub Copilot
Open the Command Palette (Cmd+Shift+P) and run MCP: Add Server
Choose HTTP, enter
https://visualization.osdr.nasa.gov/kg/mcpas the URL andmcp-genelabas the server ID, and pick where to save it (workspace or global)When prompted, confirm that you trust the server so it starts
Equivalently, add this to .vscode/mcp.json (or your user MCP configuration):
{
"servers": {
"mcp-genelab": {
"type": "http",
"url": "https://visualization.osdr.nasa.gov/kg/mcp"
}
}
}In Copilot Chat, open the Configure Tools button in the chat input to confirm the mcp-genelab tools are enabled.
Documentation: Use MCP servers in VS Code
Gemini
Gemini app (web; personal Google Account):
Go to gemini.google.com, click Settings → Connected Apps (if you don't see it, click Personal Intelligence first)
Under Custom apps, click Add a custom app and enter
https://visualization.osdr.nasa.gov/kg/mcpClick Next and follow the on-screen instructions
In the chat prompt, type @ and select the custom app
Documentation: Connect & manage custom apps for Gemini Apps
Gemini CLI (any Google account):
gemini mcp add --transport http mcp-genelab https://visualization.osdr.nasa.gov/kg/mcpor add to ~/.gemini/settings.json: {"mcpServers": {"mcp-genelab": {"httpUrl": "https://visualization.osdr.nasa.gov/kg/mcp"}}}, then run /mcp inside Gemini CLI to confirm it is connected.
Documentation: Gemini CLI — MCP servers
Then ask a question like: "What organisms are represented in the spoke-genelab-v0.3.1 knowledge graph?"
Option B: Run mcp-genelab Locally with STDIO
Running mcp-genelab locally has two parts: (1) stand up a local Neo4j instance holding the spoke-genelab-v0.3.1 KG, and (2) point mcp-genelab at it via STDIO.
Step 1 — Install Neo4j Desktop and import the spoke-genelab-v0.3.1 KG
Install Neo4j Desktop and create a
spoke-genelabinstance (with the APOC plugin) by following the Neo4j Desktop installation instructions.Import the spoke-genelab-v0.3.1 KG into that instance by following the database import instructions. Name the database exactly
spoke-genelab-v0.3.1and start the instance once the import completes.
Note the Bolt URI (default bolt://localhost:7687), username, and password of your running instance — you will need them in Step 2.
Step 2 — Install uv and configure mcp-genelab
Install uv if you don't already have it:
# macOS/Linux
curl -LsSf https://astral.sh/uv/install.sh | sh# Windows
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"Then configure your MCP client to launch mcp-genelab over STDIO. For Claude Desktop, go to Claude → Settings → Developer → Edit Config and add the following mcp-genelab entry:
{
"mcpServers": {
"spoke-genelab-local": {
"command": "uvx",
"args": ["mcp-genelab"],
"env": {
"NEO4J_URI": "bolt://localhost:7687",
"NEO4J_USERNAME": "neo4j",
"NEO4J_PASSWORD": "neo4jdemo",
"NEO4J_DATABASE": "spoke-genelab-v0.3.1",
"INSTRUCTIONS": "Query the spoke-genelab-v0.3.1 KG to identify NASA spaceflight experiments containing omics datasets, specifically differential gene expression (transcriptomics), DNA methylation (epigenomics), and Amplicon (metagenomics) data."
}
}
}
}For VS Code with GitHub Copilot, add the same mcp-genelab entry to your .vscode/mcp.json (note the top-level key is servers, not mcpServers):
{
"servers": {
"spoke-genelab-local": {
"command": "uvx",
"args": ["mcp-genelab"],
"env": {
"NEO4J_URI": "bolt://localhost:7687",
"NEO4J_USERNAME": "neo4j",
"NEO4J_PASSWORD": "neo4jdemo",
"NEO4J_DATABASE": "spoke-genelab-v0.3.1",
"INSTRUCTIONS": "Query the spoke-genelab-v0.3.1 KG to identify NASA spaceflight experiments containing omics datasets, specifically differential gene expression (transcriptomics), DNA methylation (epigenomics), and Amplicon (metagenomics) data."
}
}
}
}Note: Set
NEO4J_USERNAME,NEO4J_PASSWORD, andNEO4J_URIto match the Neo4j instance you started in Step 1. Theuvxcommand automatically downloads and runs the latest published mcp-genelab from PyPI. KeepNEO4J_DATABASEset tospoke-genelab-v0.3.1to match the database name you imported.
Docker Deployment
Build the MCP Server Image
cd mcp-genelab
docker build -t mcp-genelab:latest .Run with Streamable HTTP Transport
docker run \
--name mcp-server \
--publish=127.0.0.1:8000:8000 \
--env NEO4J_URI=bolt://host.docker.internal:7687 \
--env NEO4J_USERNAME=neo4j \
--env NEO4J_PASSWORD=yourpassword \
--env NEO4J_DATABASE=spoke-genelab-v0.3.1 \
--env MCP_TRANSPORT=streamable-http \
--env MCP_HOST=0.0.0.0 \
--env MCP_PORT=8000 \
--detach \
mcp-genelab:latestThe MCP server is then accessible at http://localhost:8000/mcp/, with GET http://localhost:8000/healthz (liveness) and GET http://localhost:8000/readyz (readiness — pings Neo4j) for load balancers (all under MCP_PATH_PREFIX if one is set, e.g. /kg/mcp). In any remote transport the server defaults to MCP_SESSION_POLICY=strict: clients must call create_session first and pass the returned session_id on every tool call (see docs/api.md).
Environment Variables
Variable | Default | Description |
|
| Neo4j Bolt connection URI — required in remote transports (no default; the server refuses to start without it) |
|
| Neo4j username — required in remote transports |
|
| Neo4j password — required in remote transports; inject from a secret store |
|
| Neo4j database name for the spoke-genelab-v0.3.1 KG |
|
| Transport mode: |
|
| HTTP listener host (use |
|
| HTTP listener port |
| (empty) | Public path prefix when a load balancer publishes the service under one, e.g. |
|
|
|
|
| Session idle and absolute lifetimes |
|
| Session-store bounds |
|
| Minimum idle time before a session may be recycled to make room at the |
|
| Maximum size of one |
|
| Budget for the |
|
| Per-query timeout; row cap for the |
|
| Bolt pool per process; fail-fast on saturation |
|
| Usage metrics: JSON usage log, CloudWatch EMF, |
| random per process | Salt for the |
|
| CloudWatch namespace for EMF metrics; |
|
| Application log level |
| (see source) | System instructions for the LLM |
Example Queries
Each link below points to a chat transcript that demonstrates how to use the mcp-genelab server to query and analyze GeneLab data hosted in the spoke-genelab-v0.3.1 Neo4j Knowledge Graph. To create a transcript of your own chat, use the prompt Create a chat transcript; the transcript can then be downloaded in .md or .pdf format.
Knowledge Graph Overview & Class Diagram
Overview of spoke-genelab v0.3.1
Node and Relationship Metadata Examples
List spoke-genelab-v0.3.1 assay node, properties, and relationships
Differential Expression Analysis with MCP tools
Differential Expression and Differential Methylation Analysis with MCP tools
Differential Abundance Analysis with MCP tools
Cross-Graph Differential Expression and Associated Disease Analysis with MCP tools
OSD-161 DE and spoke-okn disease analysis
Note: To perform this example query, you will need to add the NSF OKN MCP server to your MCP client by following the instructions at https://okn.us/mcp.
Demos
Recorded demo sessions and transcripts
MCP Tools Reference
The server exposes 24 tools (22 analysis/utility tools plus create_session / end_session) and a plot://{session_id}/{filename} resource template. On the hosted endpoint every tool except create_session takes a session_id argument (see docs/api.md). Tools are listed below grouped by category. The specialist tools should be preferred over the generic query tool — server.py's DEFAULT_INSTRUCTIONS carries a TOOL SELECTION POLICY that routes natural-language requests to the right specialist.
Schema & metadata
Tool | Description |
| List all node types, their attributes, and relationships in the knowledge graph |
| Get descriptions of all node types from MetaNode entries |
| Get descriptions of all relationship types and their properties |
| Generate a visual schema diagram of the knowledge graph |
Study / assay browsing
Tool | Description |
| Get detailed information about a specific study and its assays (metadata + assay inventory) |
| Browse and filter assays by study, organism, technology, or measurement; resolve a factor pair to one or more assay IDs |
Single-assay analyses
Tool | Description |
| Find up/downregulated genes for a given assay (DESeq2) |
| Find hyper/hypomethylated regions for a given assay, with optional |
| Find organisms with differential abundance for a given assay (DESeq2 and/or ANCOM-BC) |
Cross-assay analyses
Tool | Description |
| Intersect DEGs across multiple assays (up and down directions kept separate) |
| Intersect DMRs across multiple assays, with optional MethylationRegion filters |
| Intersect differentially abundant organisms across multiple assays |
| Identify DE genes whose promoter (or other region) is also differentially methylated — supports method-aware significance filtering and pooled-DM evidence across multiple methylation assays |
Cypher fallback
Tool | Description |
| Execute a read-only Cypher query on the Neo4j database. Fallback for questions the specialists don't cover — the |
Plot generation, delivery, and saving
Tool / resource | Description |
| Generate a volcano plot of differential expression / methylation / abundance results; PNG returned inline and registered for resource fetch |
| Create a Venn diagram comparing DEGs / DMRs / DA organisms across 2 or 3 assays (also supports the |
| Re-fetch the canonical PNG bytes of a plot previously generated in the same session from the in-memory registry (last 8 plots per session, FIFO eviction). Returns the bytes as an |
| Return a markdown block with multiple save options for a previously generated plot: right-click save, ask-LLM-client-to-save, or fetch via the |
| MCP resource template — clients fetch PNG bytes via |
Sessions and output paths
Tool | Description |
| Start a session and obtain the |
| End a session immediately, discarding its output directory and plots |
| Set the user-facing directory where plots and CSV files should be saved (per session) |
| Return the currently configured output directory (per session) |
Mermaid & transcript utilities
Tool | Description |
| Clean and validate a Mermaid class diagram of the KG schema |
| Export the current chat as a formatted transcript |
Security
All Neo4j sessions are opened with default_access_mode=READ_ACCESS, which is enforced at the Bolt protocol level by Neo4j. Any write operation is rejected with the error: "Write operations are not allowed for READ transactions." This works on both Community and Enterprise Edition.
As a second layer of defense, the query tool includes a regex-based write filter (_is_write_query()) that catches the Cypher write keywords MERGE, CREATE, SET, DELETE, REMOVE, ADD, and DROP (case-insensitive) before the query is sent to Neo4j. All queries also use session.execute_read() for transaction-level read enforcement. The two layers — server-side regex + Bolt-level READ_ACCESS — protect the knowledge graph from modification even if one layer is bypassed.
The query tool additionally rejects read-only-but-dangerous procedures that READ_ACCESS does not block (_is_forbidden_query()): LOAD CSV, apoc.load.*, apoc.export.*, apoc.trigger/periodic/refactor/create/merge/cypher/systemdb.*, dbms.*, and db.create* / db.drop* / full-text index creation. apoc.meta.* and apoc.help remain allowed for the schema tools. Every query runs with a server-side timeout (MCP_QUERY_TIMEOUT_SECONDS, 60 s) and the query tool caps results at MCP_MAX_QUERY_ROWS (1,000) rows; error messages never echo the submitted Cypher or raw driver exceptions. On the hosted endpoint, Neo4j credentials are injected at runtime (the image contains none, and remote transports refuse to start without them), per-user state is isolated by session (see MCP_SESSION_POLICY), and the usage log records only salted digests — never raw session ids or IP addresses. See docs/deployment.md for the full hardening checklist.
Development
Instructions for local development
Release history: CHANGELOG.md
Testing
The project ships a pytest suite (201 tests across 11 test files) that runs offline — no Neo4j connection, no network, no MCP transport. It guards against regressions in tool registration, annotation completeness, routing-policy language in tool docstrings, Cypher invariants (read-only enforcement, conditional LIMIT, lnfc null-safety, MethylationRegion filter propagation, pooled IN $assay_ids clause for cross-assay queries), the plot resource layer (plot:// URI registration, fetch_plot round-trips, save-instruction size guarantees), per-session isolation (two sessions can never see each other's output directory or plots; missing/unknown/expired session errors; TTL and memory bounds), the /healthz / /readyz load-balancer routes, and the usage-metrics pipeline.
pip install -r mcp-genelab-tests/requirements-test.txt
pytestThe suite runs in roughly 10 seconds and is safe to run on every commit. A GitHub Actions workflow at mcp-genelab-tests/.github/workflows/test.yml runs the suite on Python 3.10 through 3.13 for every push and pull request. See mcp-genelab-tests/tests/README.md for the per-file breakdown and instructions on adding tests for new tools.
Building and Publishing (maintainers only)
Instructions for building, testing, and publishing the mcp-genelab package on PyPI
API Reference
Troubleshooting
Common Issues
MCP server not appearing in Claude Desktop:
Ensure you've completely quit and restarted Claude Desktop (not just closed the window)
Check that your JSON configuration is valid (attach your config file to a chat and ask it to fix any errors)
Verify that
uvxis installed and accessible in your PATH
Connection errors:
Verify the Neo4j endpoint URL is correct and accessible
For a local Neo4j Desktop instance, ensure the
spoke-genelabinstance is started and thespoke-genelab-v0.3.1database has finished loadingCheck that
NEO4J_DATABASEis set tospoke-genelab-v0.3.1and matches the database name you imported
Query rejected ("This query was rejected. Only read-only graph queries are permitted…"):
This is expected behavior. The
querytool refuses write operations (CREATE, MERGE, SET, DELETE, REMOVE, ADD, DROP) and procedures that perform network I/O, bulk export, or database administration (LOAD CSV,apoc.load.*,apoc.export.*,dbms.*, …) before they reach Neo4j; anything that slips past is still blocked at the Bolt protocol level because every session uses READ_ACCESS mode.
"Error (missing session)" / "Error (unknown session)" / "Error (expired session)":
On the hosted endpoint every tool except
create_sessionrequires a validsession_id. Ask the assistant to callcreate_sessionand retry; sessions expire after 60 minutes idle or 8 hours total, and are lost when the server restarts.
Performance issues:
Complex Cypher queries may take time to execute
Consider breaking down complex queries into smaller parts
Check the endpoint's documentation for query best practices
License
This project is licensed under the BSD 3-Clause License. See the LICENSE file for details.
Citation
If you use MCP GeneLab in your research, please cite the following works:
@software{rose2026mcp-genelab,
title={MCP GeneLab Server},
author={Rose, P.W. and Saravia-Butler, A.M. and Nelson, C.A. and Shi, Y. and Baranzini, S.E.},
year={2026},
url={https://github.com/sbl-sdsc/mcp-genelab}
}
@software{rose2026spoke-genelab,
title={NASA SPOKE-GeneLab Knowledge Graph},
author={Rose, P.W. and Nelson, C.A. and Saravia-Butler, A.M. and Gebre, S.G. and Soman, K. and Grigorev, K.A. and Sanders, L.M. and Costes, S.V. and Baranzini, S.E.},
year={2026},
url={https://github.com/BaranziniLab/spoke_genelab}
}Related Publications
Nelson, C.A., Rose, P.W., Soman, K., Sanders, L.M., Gebre, S.G., Costes, S.V., Baranzini, S.E. (2025). "Nasa Genelab-Knowledge Graph Fabric Enables Deep Biomedical Analysis of Multi-Omics Datasets." NASA Technical Reports, 20250000723. Link
Sanders, L., Costes, S., Soman, K., Rose, P., Nelson, C., Sawyer, A., Gebre, S., Baranzini, S. (2024). "Biomedical Knowledge Graph Capability for Space Biology Knowledge Gain." 45th COSPAR Scientific Assembly, July 13-21, 2024. Link
Acknowledgments
Funding
This work is supported in part by:
National Science Foundation Award #2333819: "Proto-OKN Theme 1: Connecting Biomedical information on Earth and in Space via the SPOKE knowledge graph"
Related Projects
Proto-OKN Project - Prototype Open Knowledge Network initiative
NSF Open Knowledge Network - 40+ interconnected knowledge graphs supported by NSF
NASA Open Science Data Repository (OSDR) - Repository of multi-modal space life science data
NASA GeneLab KG, spoke-genelab - Git Repository for creating the spoke-geneLab KG v0.3.1
Model Context Protocol - AI assistant integration standard
Original Neo4j Cypher MCP server - Base implementation reference
For questions, issues, or contributions, please visit our GitHub repository.
Available Tools
24 toolsclean_mermaid_diagramARead-onlyIdempotent
Clean a Mermaid class diagram by removing unwanted elements.
This tool removes:
- All note statements that would render as unreadable yellow boxes
- Empty curly braces from class definitions (handles both single-line and multi-line)
- Strings after newline characters (e.g., truncates "ClassName
extra" to "ClassName")
Args:
mermaid_content: The raw Mermaid class diagram content
Returns:
Cleaned Mermaid content with note statements, empty braces, and post-newline strings removed
Inputs: mermaid_content (required), session_id.
create_chat_transcriptCRead-onlyIdempotent
Prompt for creating a chat transcript in markdown format with user prompts and Claude responses.
Inputs: session_id.
create_sessionA
Start a session and obtain the session_id that EVERY other tool
on this server requires.
WHEN TO USE THIS TOOL: Call this ONCE at the beginning of a conversation, before any other mcp-genelab tool. Also call it again whenever a tool replies that the session is unknown or expired.
WHY:
This server runs as a single shared process serving many users at
once. The session id is the only thing that keeps YOUR output
directory and YOUR generated plots (retrievable via fetch_plot,
get_save_script and the plot://{session_id}/{filename} resource)
separate from everyone else's. It is an opaque bearer token —
treat it as private to this conversation and never guess one.
LIFETIME: A session expires after a period of inactivity (default 60 min) or an absolute maximum age (default 8 h), whichever comes first. Expired sessions drop their plots; regenerate them under a new session.
RETURNS:
A short message containing session_id: <token>. Extract the token
and pass it as the session_id argument on every subsequent call.
Inputs: no named parameters.
create_venn_diagramA
Create Venn diagrams comparing differential data between 2 or 3 assays.
Supports multiple data types:
'expression': Compares differentially expressed genes (upregulated/downregulated by log2fc)
'methylation': Compares differentially methylated genes (hypermethylated/hypomethylated by methylation_diff)
'abundance': Compares differentially abundant organisms (increased/decreased by log2fc; works for both DESeq2 and ANCOM-BC)
'expression_methylation': Cross-comparison showing directional overlaps between differentially expressed genes from one assay and differentially methylated genes from another assay (2-way only)
Creates side-by-side Venn diagrams showing:
Left: Positive direction (upregulated / hypermethylated / increased abundance)
Right: Negative direction (downregulated / hypomethylated / decreased abundance)
For 'expression_methylation' mode, this tool computes FOUR directional overlaps so the user can see which kind of expression–methylation coupling is happening. By default (direction_pair='all') it renders all four as a 2x2 grid:
Hypermethylated + Downregulated (classical epigenetic silencing — promoter methylation reducing expression)
Hypomethylated + Upregulated (loss of methylation enabling expression)
Hypermethylated + Upregulated (less canonical; e.g. gene-body methylation activating expression)
Hypomethylated + Downregulated (less canonical; non-classical) If the user names a specific pairing (e.g. "create a Venn of hypermethylated and downregulated genes"), pass direction_pair='hyper_down' to render just that one. The summary always reports the size of all four overlaps, regardless of which subset is rendered.
Methylation region location filters (for data_type='methylation' and the methylation side of 'expression_methylation'):
in_promoter, in_exon, in_intron: each accepts True (include only regions where this flag is true), False (exclude regions where this flag is true), or None (no filter). Multiple filters combine with AND. For example, in_promoter=True alone restricts to promoter-overlapping regions; in_promoter=True with in_intron=False restricts to promoter regions that are NOT intronic.
dist_to_feature_max: when set, include only regions whose distance to the nearest gene feature is <= this value (in bp). Useful for narrowing to regions tightly associated with gene bodies. dist_to_feature on the MethylationRegion node is the bp distance from the region to the nearest annotated feature. These filters apply during the Cypher query — they reduce the set of methylation regions BEFORE the overlap computation, so each gene set is the genes that have at least one methylation region passing all the filters and the magnitude/significance criteria.
Significance filtering:
'expression' and 'expression_methylation' (expression side): adj_p_value <= adj_p_threshold (default 0.05).
'methylation' and 'expression_methylation' (methylation side): q_value <= q_value_threshold (default 0.05).
'abundance' is method-aware: DESeq2 rows are filtered by adj_p_threshold, ANCOM-BC rows by q_value_threshold.
Magnitude filtering for 'abundance':
log2fc_threshold applies to every row (log2fc is populated for both methods).
lnfc_threshold (optional) adds an ANCOM-BC-specific |lnfc| filter; DESeq2 rows (lnfc IS NULL) pass through.
Returns a link to the plot and summary statistics.
Inputs: assay_id_1 (required), assay_id_2 (required), in_exon, data_type, +13 more.
create_volcano_plotA
Create a volcano plot for differential data from the given assay.
Works for three differential measurement types:
'expression': -[MEASURED_DIFFERENTIAL_EXPRESSION_ASmMG]-> MGene x = log2fc, y = -log10(adj_p_value), labels = gene symbol Magnitude filter: log2fc_threshold (default 1.0 = 2-fold)
'methylation': -[MEASURED_DIFFERENTIAL_METHYLATION_ASmMR]-> MethylationRegion x = methylation_diff, y = -log10(q_value), labels = gene symbol (joined via METHYLATED_IN_MGmMR back to MGene for labeling) Magnitude filter: methylation_diff_threshold (default 10.0 = 10%)
'abundance': -[MEASURED_DIFFERENTIAL_ABUNDANCE_ASmO]-> Organism x = log2fc, y = -log10(significance), labels = organism name Magnitude filter: log2fc_threshold (default 1.0 = 2-fold) Significance is method-aware: DESeq2 rows use adj_p_value, ANCOM-BC rows use q_value.
Points are colored by significance:
Red: positive direction (upregulated / hypermethylated / increased)
Blue: negative direction (downregulated / hypomethylated / decreased)
Gray: not significant
Returns a markdown summary, an inline PNG image (if small enough), and the saved file path. Designed to handle assays with thousands of features without timing out.
Inputs: assay_id (required), top_n, data_type, session_id, +6 more.
end_sessionAIdempotent
End a session immediately, discarding its output-directory setting
and all plots it holds. Optional — sessions also expire on their own.
Call it when the user is done, to free server memory promptly. After
this, a new create_session() is needed before further tool calls.
Inputs: session_id.
fetch_plotARead-onlyIdempotent
Re-fetch the PNG bytes of a plot previously generated IN THIS SESSION.
WHEN TO USE THIS TOOL: Call this when you need the canonical PNG bytes for a plot that's already been generated. Common cases:
The inline image in the original plot tool response was corrupted or didn't render in the client.
You need the bytes for a downstream step (e.g. embedding in a transcript, saving to a side file, base64-encoding for an external API).
The user asked to see the plot again without re-running the analysis.
WHAT THIS TOOL DOES NOT DO: It does NOT re-render the plot. It returns the same bytes that were registered when the plot was originally generated. If the underlying data has changed, re-run the plot tool itself (create_volcano_plot, create_venn_diagram); don't expect fetch_plot to pick up new data.
EQUIVALENT RESOURCE URI:
This tool returns the same bytes that resources/read would return
for plot://<session_id>/<filename>. Use whichever path your client
supports better — resources for clients that render them well, this
tool for clients that don't.
REGISTRY BOUNDS: Each session holds its last 8 plots (FIFO eviction). Older plots, and plots from other or expired sessions, return a clear "not in registry" error and need to be regenerated by re-running the source plot tool under the current session.
Inputs: filename (required), session_id.
find_common_de_genes_overlapping_dm_regionsARead-onlyIdempotent
USE THIS TOOL (not the query tool) for any
"expression-methylation coupling", "classical epigenetic
silencing", "DE genes that are also DM", "downregulated genes
with promoter hypermethylation", or any cross-type
intersection between differential expression and differential
methylation. Falling back to query for this category reproduces
the four-quadrant intersection logic this tool already does
correctly (parallel DE+DM fetches across DIFFERENT assays,
pooled-methylation aggregation when multiple methylation assays
are passed as a list, MethylationRegion location filtering on the
DM side, up_hyper/up_hypo/down_hyper/down_hypo direction
categorization) and loses the four-quadrant markdown summary and
the inline combined CSV.
Find differentially expressed genes that overlap with differentially methylated regions.
This cross-analysis tool:
Gets DE genes from the expression assay (filtered by log2fc and adj_p thresholds)
Gets genes associated with DM regions from the methylation assay(s) (filtered by methylation_diff, q_value, and any MethylationRegion location filters: in_promoter, in_exon, in_intron, dist_to_feature_max). If
methylation_assay_idis a list, the methylation evidence is POOLED across the listed assays before the intersection — a gene is treated as hypermethylated if it passes the threshold in ANY of the pooled assays.Finds the intersection (genes that are BOTH differentially expressed AND differentially methylated)
Reports the overlap categorized by direction (up+hyper, up+hypo, down+hyper, down+hypo)
For the classical epigenetic-silencing question — promoter hypermethylation reducing expression — pass in_promoter=True. When a study has replicate methylation assays (e.g. OSD-48 has two methylKit assays for the same Space Flight vs. Ground Control comparison), pass them as a list to capture the combined methylation evidence on the methylation side of the intersection.
Inputs: expression_assay_id (required), methylation_assay_id (required), in_exon, in_intron, +7 more.
find_common_differentially_abundant_organismsARead-onlyIdempotent
USE THIS TOOL (not the query tool) for any "common
differentially abundant organisms across assays", "organisms
increased in BOTH assays", "shared abundance signals across
methods" (e.g. DESeq2 vs ANCOM-BC concordance), or any cross-assay
abundance intersection question. Falling back to query for this
category reproduces the per-assay fetch + inner-join logic this
tool already does correctly (parallel fetches, method-aware
significance filtering, lnfc handling that doesn't drop DESeq2
rows, separate increased vs. decreased intersections) and loses
the formatted markdown + inline CSV side-channel and the
assay-reference legend.
Find common differentially abundant organisms across multiple assays.
Useful for comparing results from different analysis methods (e.g., DESeq2 vs ANCOM-BC 1 vs ANCOM-BC 2) to identify organisms consistently detected as differentially abundant.
Direction (increase vs. decrease) and ranking use log2fc, which is populated for BOTH DESeq2 and ANCOM-BC edges in the GeneLab KG. log2fc is therefore the universal magnitude filter (log2fc_threshold); lnfc is ANCOM-BC-only and would null-filter every DESeq2 row if used for direction.
Significance filtering is method-aware:
DESeq2 edges populate adj_p_value (not q_value); the adj_p_threshold applies.
ANCOM-BC edges populate q_value (not adj_p_value); the q_value_threshold applies. Each row is kept if its populated significance field meets the matching threshold.
Magnitude filtering:
log2fc_threshold (default 0.0) applies to every row, since log2fc is populated for both methods.
lnfc_threshold (default None = no filter) is method-aware: when set, it requires |lnfc| >= lnfc_threshold on rows where lnfc is populated. Rows where lnfc is null (i.e., DESeq2 rows) are not affected by this filter.
This function:
Takes a list of assay IDs as input (2 or more)
Gets ALL organisms passing the magnitude and method-aware significance filters for each assay
Inner joins among increased and among decreased abundance organisms
Returns markdown tables showing common organisms and their log2fc values
Inputs: assay_ids (required), session_id, lnfc_threshold, adj_p_threshold, +2 more.
find_common_differentially_expressed_genesARead-onlyIdempotent
USE THIS TOOL (not the query tool) for any "common DEGs across
assays", "genes upregulated in BOTH assays", "shared
up/downregulated genes", or any cross-assay DE intersection
question. Falling back to query for this category reproduces the
per-assay fetch + inner-join logic this tool already does correctly
(parallel fetches via the driver's connection pool, |log2fc| >
threshold filtering, separate up vs. down intersections) and loses
the formatted markdown tables, the inline CSV side-channel, and
the assay-reference legend.
Find common differentially expressed genes across multiple assays.
This function:
Takes a list of assay IDs as input (2 or more)
Gets ALL genes with |log2fc| > threshold for each assay
Inner joins among the upregulated genes and among the downregulated genes
Returns a markdown table with columns: gene, assay_1, assay_2, ..., assay_n showing log2fc values
Inputs: assay_ids (required), session_id, adj_p_threshold, log2fc_threshold.
find_common_differentially_methylated_regionsARead-onlyIdempotent
USE THIS TOOL (not the query tool) for any "common DMRs
across assays", "genes hypermethylated in BOTH assays", "shared
hyper/hypomethylated regions", or any cross-assay methylation
intersection question — including promoter/exon/intron-filtered
and distance-bounded variants. Falling back to query for this
category reproduces the per-assay fetch + inner-join logic this
tool already does correctly (parallel fetches, MethylationRegion
location filtering applied during the Cypher so the common set
reflects the filtered universe, methylation_diff/q_value
thresholds, separate hyper vs. hypo intersections) and loses
the formatted markdown + inline CSV side-channel and the
assay-reference legend.
Find common differentially methylated genes across multiple assays.
This function:
Takes a list of assay IDs as input (2 or more)
Gets ALL genes associated with differentially methylated regions for each assay, applying the methylation_diff threshold, q_value threshold, and any MethylationRegion location filters (in_promoter, in_exon, in_intron, dist_to_feature_max)
Inner joins among hypermethylated genes and among hypomethylated genes
Returns markdown tables showing common genes and their methylation_diff values
Use the location filter parameters rather than post-filtering — they are applied during the Cypher query so the common gene set reflects the filtered universe correctly.
Inputs: assay_ids (required), in_exon, in_intron, session_id, +4 more.
find_differentially_abundant_organismsARead-onlyIdempotent
USE THIS TOOL (not the query tool) for any "differentially abundant
organisms", DESeq2/ANCOM-BC abundance, or "increased/decreased
abundance" question for a single assay.
The query tool can express the same Cypher, but using it for this
category loses the formatted markdown tables, the inline CSV
side-channel, the method-aware significance filtering (DESeq2
adj_p_value vs. ANCOM-BC q_value), and the safe lnfc handling that
avoids silently dropping DESeq2 rows (where lnfc IS NULL would fail a
naive lnfc > 0 filter).
Return the top-N organisms with increased and decreased differential abundance for a given assay_id.
Direction (increase vs. decrease) and ranking use log2fc, which is populated for BOTH DESeq2 and ANCOM-BC abundance edges in the GeneLab KG. log2fc is therefore used as the universal direction/ordering field and as the default magnitude filter.
The lnfc property is only populated for ANCOM-BC edges (DESeq2 leaves it null). It is returned in the result for reference and can be used as an additional magnitude filter via the lnfc_threshold parameter. log2fc is the direction filter because it is populated for both DESeq2 and ANCOM-BC rows; using lnfc for direction would null-filter every DESeq2 row out of the result.
Significance filtering is method-aware:
DESeq2 edges populate adj_p_value (not q_value); the adj_p_threshold applies.
ANCOM-BC edges populate q_value (not adj_p_value); the q_value_threshold applies. Each row is kept if its populated significance field meets the matching threshold.
Magnitude filtering:
log2fc_threshold (default 0.0) applies to every row, since log2fc is populated for both methods.
lnfc_threshold (default None = no filter) is method-aware: when set, it requires |lnfc| >= lnfc_threshold on rows where lnfc is populated. Rows where lnfc is null (i.e., DESeq2 rows) are not affected by this filter. Set lnfc_threshold to a positive number to add an ANCOM-BC-specific magnitude filter on top of log2fc.
This tool runs two queries on the GeneLab KG:
Top-N organisms with increased abundance (log2fc > log2fc_threshold, significance and optional lnfc filters met, highest log2fc first)
Top-N organisms with decreased abundance (log2fc < -log2fc_threshold, significance and optional lnfc filters met, lowest log2fc first)
Results include organism name, log2fc, lnfc, q-value, adj-p-value, and group means and standard deviations.
Inputs: assay_id (required), top_n, session_id, lnfc_threshold, +3 more.
find_differentially_expressed_genesARead-onlyIdempotent
USE THIS TOOL (not the query tool) for any "up/down-regulated genes",
"DEGs", or "differential expression" question for a single assay.
The query tool can express the same Cypher, but using it for this
category loses the formatted markdown tables, the inline CSV
side-channel, the proper adj_p_value handling, and the parallel
execution of the count queries this tool already provides correctly.
Return the top-N up- and down-regulated genes for a given assay_id.
This tool runs two queries on the GeneLab KG:
Top-N upregulated genes (log2fc > 0, adj_p_value <= adj_p_threshold, highest log2fc first)
Top-N downregulated genes (log2fc < 0, adj_p_value <= adj_p_threshold, lowest log2fc first)
Returning all passing rows:
Pass top_n=None to return ALL rows that pass the filters rather
than a top-N ranking. Use this when the user asks for "all
significantly up/downregulated genes" or wants the complete
filtered set as CSV.
Results include gene symbol, gene name, log2 fold change, adjusted p-value, and group means and standard deviations for each condition.
Inputs: assay_id (required), top_n, session_id, adj_p_threshold.
find_differentially_methylated_regionsARead-onlyIdempotent
USE THIS TOOL (not the query tool) for any "hyper/hypo-methylated
regions", "DMRs", or "differential methylation" question — including
all-rows requests, promoter/exon/intron-filtered methylation queries,
and pooling methylation across replicate assays. Falling back to query
for this category reproduces the work this tool already does (proper
IS-NOT-NULL guards, gene-symbol join, parallel count queries, location
filtering, deterministic CSV emission) and loses the formatted markdown
inline CSV side-channel.
Return hyper- and hypo-methylated regions for one or more assays.
This tool runs two queries on the GeneLab KG:
Hypermethylated regions (methylation_diff > methylation_diff_threshold, q_value <= q_value_threshold, highest first)
Hypomethylated regions (methylation_diff < -methylation_diff_threshold, q_value <= q_value_threshold, lowest first)
Pooling across assays:
Pass a list to assay_id to pool results across multiple methylation
assays (the Cypher uses a.identifier IN $assay_ids). Common use case:
a study has 2+ methylation assays representing replicate runs of the
same comparison, and the user wants the combined evidence rather than
per-assay tables. The output adds an assay_id column so each row's
source is visible.
Returning all passing rows:
Pass top_n=None to return ALL rows that pass the filters rather
than a top-N ranking. Use this when the user asks for "all
hypermethylated promoter regions" or wants the complete filtered
set as CSV. To keep the response readable when the full set is
large, the inline markdown table is capped at the first 100 rows
and a note is shown; the CSV contains every row.
MethylationRegion location filters (in_promoter, in_exon, in_intron, dist_to_feature_max) are applied DURING the Cypher query. This means when a user asks for "top hypermethylated regions in the promoter", pass in_promoter=True and the tool will correctly rank within the promoter universe. Do NOT post-filter the unfiltered top-N — that produces wrong results because regions outside the filter (e.g. non-promoter regions) occupy slots in the unfiltered top-N and displace correctly-ranked filtered regions. Multiple filters combine with AND, so in_promoter=True with in_intron=False returns promoter regions that are not intronic.
WHEN TO USE THIS TOOL vs. direct Cypher via the query tool:
Use THIS tool for any "hyper/hypo methylated regions" question,
including pooled-across-assays, all-passing-rows, and filter-by-location
variants. It produces formatted markdown tables AND an inline CSV
that the user can save directly. Falling back to direct Cypher loses
the formatted output and the CSV.
Inputs: assay_id (required), top_n, in_exon, in_intron, +5 more.
get_neo4j_schemaARead-onlyIdempotent
List all nodes, their attributes and their relationships to other nodes in the neo4j database. If this fails with a message that includes "Neo.ClientError.Procedure.ProcedureNotFound" suggest that the user install and enable the APOC plugin.
Inputs: session_id.
get_node_metadataBRead-onlyIdempotent
Get metadata for all nodes from MetaNode nodes in the knowledge graph.
Inputs: session_id.
get_output_directoryARead-onlyIdempotent
Return the currently-configured output directory for this session.
Returns the path previously set by set_output_directory in the same session, or a note explaining that no path has been set yet (and how to set one).
Inputs: session_id.
get_relationship_metadataBRead-onlyIdempotent
Get descriptions of properties of all relationships in the knowledge graph.
Inputs: session_id.
get_save_scriptARead-onlyIdempotent
Return guidance for saving a plot generated in THIS SESSION to the user's local filesystem.
WHEN TO USE THIS TOOL: Call this only when the user explicitly asks for save guidance for a specific plot — for example, "how do I save the volcano plot to my Downloads folder?" or "I can't right-click — give me another way to save the plot." By default plot tools (create_volcano_plot, create_venn_diagram) return only a SHORT save hint to keep response sizes manageable. The detailed save options are delivered on demand via this tool, so they don't burn conversation context unless the user actually wants them.
HOW IT WORKS: Each plot tool registers the PNG bytes of the plot it generated in the calling session's registry (up to the last 8 plots; older entries are evicted FIFO). Calling this tool with the plot's suggested filename returns a markdown block with three save options:
Option A (right-click save on the inline image)
Option B (ask your LLM client to save via filesystem access, optionally re-fetching the canonical bytes through fetch_plot or the plot:// resource if the inline image was corrupted)
Option C (fetch the canonical PNG bytes via resources/read on the plot://<session_id>/ URI for clients that support MCP resources)
The response itself contains no PNG bytes — only references to the plot:// resource URI and the fetch_plot tool, both of which deliver the bytes through a separate request.
LISTING AVAILABLE PLOTS:
Call this tool with no filename argument to list the filenames
of all plots currently held in this session's registry. Useful when
the user asks for save guidance but doesn't remember which plot they
want.
Inputs: filename, session_id.
get_study_infoARead-onlyIdempotent
USE THIS TOOL (not the query tool) for any study-metadata question:
"what assays does study X have", "tell me about OSD-267", project title,
description, host organism, missions, factor space, or any inventory of
a study's assays. Falling back to query for these reproduces the work
this tool already does and loses the formatted markdown + inline CSV
side-channel.
Return detailed information about a study, including its assays with their technology and measurement types.
This tool queries the GeneLab KG for:
Study metadata (name, project title, description, organism, etc.)
All assays for the study with their technology, measurement type, differential analysis method, factors, and materials
Associated missions
For example, OSD-267 should return that it has both 16S and ITS amplicon sequencing data.
Inputs: study_id (required), session_id.
queryARead-onlyIdempotent
FALLBACK Cypher executor. Use this ONLY when no specialist tool covers the question.
DO NOT call this tool when the question matches one of these patterns — call the named tool instead, EVEN IF you think Cypher would be more flexible:
"up/down-regulated genes", "DEGs", "differential expression", "log2fc rankings", "top N up/downregulated genes for assay X" → find_differentially_expressed_genes(assay_id=...)
"hyper/hypo-methylated regions", "DMRs", "methylation_diff", "hypermethylated promoter regions", "all DMRs passing q<0.05", pooling methylation across replicate assays → find_differentially_methylated_regions(assay_id=...)
"differentially abundant organisms", DESeq2/ANCOM-BC abundance, "increased/decreased abundance for assay X" → find_differentially_abundant_organisms(assay_id=...)
study metadata, what assays a study has, study factors/materials, project title, description, host organism/strain → get_study_info(study_id=...)
factor-pair → assay-id resolution (e.g. "give me the assay for Space Flight,Carcass vs Ground Control,Carcass in OSD-48") → select_assays(study_id=..., selection=...)
"what groups / conditions / control and experimental (treatment) groups are in study X", "what comparisons does OSD-48 have", "which factors were compared" — any question about the groups a study contains, even with no factor pair named → select_assays(study_id=...) (list mode; omit
selection)common DEGs/DMRs/DA organisms across multiple assays, intersections → find_common_differentially_expressed_genes(assay_ids=[...]) → find_common_differentially_methylated_regions(assay_ids=[...]) → find_common_differentially_abundant_organisms(assay_ids=[...])
DE genes overlapping DM regions, expression-methylation coupling, classical epigenetic silencing analysis → find_common_de_genes_overlapping_dm_regions(...)
listing nodes / properties / relationships in the KG → get_neo4j_schema(), get_node_metadata(), get_relationship_metadata()
If you only have a study identifier and need assay IDs, call
select_assays or get_study_info FIRST; do not write Cypher to
discover assay IDs.
The specialist tools return formatted markdown tables AND an inline CSV
side-channel that this query tool does not produce. Falling back to
query for the categories above also loses the parallel multi-query
execution, the method-aware significance filtering (DESeq2 adj_p_value
vs. ANCOM-BC q_value), the region-vs-gene aggregation, and the
MethylationRegion location filter plumbing the specialists already
implement correctly.
Only call this tool for ad-hoc Cypher that the specialist tools cannot express: schema exploration, custom multi-hop traversals, exotic aggregations, or one-off counts the specialists don't expose.
OUTPUT FORMAT - CRITICAL:
The response begins with a total_rows: N header followed by rows: and then the
JSON array of records. When reporting counts to the user (e.g. "how many
hypermethylated regions are there"), ALWAYS use total_rows, NEVER count rows
visible in the JSON array. Large results may be truncated by the MCP transport
and stored to a side-file, leaving only a partial preview of the array — but the
total_rows count is computed server-side from the materialized result before
any truncation and is always accurate. For aggregate queries (RETURN count(*))
total_rows will be 1 and the count itself lives in the row's count(*) field.
EDGE PROPERTIES - CRITICAL: Many relationships in this knowledge graph have properties stored as edge attributes (data ON the relationship itself).
MEASURED_DIFFERENTIAL_EXPRESSION_ASmMG: log2fc, adj_p_value, group_mean_1, group_stdev_1, group_mean_2, group_stdev_2 MEASURED_DIFFERENTIAL_METHYLATION_ASmMR: methylation_diff, q_value, group_mean_1, group_stdev_1, group_mean_2, group_stdev_2 MEASURED_DIFFERENTIAL_ABUNDANCE_ASmO: log2fc, lnfc, q_value, adj_p_value, group_mean_1, group_stdev_1, group_mean_2, group_stdev_2
ABUNDANCE EDGE - METHOD-AWARE FIELDS (CRITICAL for correct queries):
The MEASURED_DIFFERENTIAL_ABUNDANCE_ASmO edge stores different fields depending
on which differential analysis method produced the row. Use log2fc (not lnfc)
for direction and ranking, since it is populated for BOTH methods:
DESeq2 edges: log2fc populated, lnfc = null, adj_p_value populated, q_value = null
ANCOM-BC edges: log2fc populated, lnfc populated, adj_p_value = null, q_value populated
To filter by significance in a method-agnostic way, OR both fields together: WHERE r.log2fc > 0 AND ( (r.adj_p_value IS NOT NULL AND r.adj_p_value <= 0.05) OR (r.q_value IS NOT NULL AND r.q_value <= 0.05) )
Filtering on r.lnfc > 0 will silently drop every DESeq2 row because Cypher's
null > 0 evaluates to null and fails the WHERE clause. If you want to use lnfc
as an ANCOM-BC-specific magnitude filter alongside log2fc-based direction, write
the clause defensively:
AND (r.lnfc IS NULL OR abs(r.lnfc) >= 0.5)
This applies the lnfc threshold only to rows where lnfc is populated (ANCOM-BC)
and leaves DESeq2 rows untouched.
RELATIONSHIP DIRECTIONS (always use directed arrows in queries): (Assay)-[:MEASURED_DIFFERENTIAL_EXPRESSION_ASmMG]->(MGene) (Assay)-[:MEASURED_DIFFERENTIAL_METHYLATION_ASmMR]->(MethylationRegion) (Assay)-[:MEASURED_DIFFERENTIAL_ABUNDANCE_ASmO]->(Organism) (MGene)-[:METHYLATED_IN_MGmMR]->(MethylationRegion) (Study)-[:PERFORMED_SpAS]->(Assay) (Mission)-[:CONDUCTED_MIcS]->(Study)
NODE PROPERTIES - CRITICAL (use EXACTLY these property names, no others exist): MGene: identifier, symbol, name, organism, taxonomy MethylationRegion: identifier, name, chromosome, start, end, in_promoter, in_exon, in_intron, dist_to_feature Assay: identifier, name, technology, measurement, differential_analysis_method, factors_1, factors_2, material_1, material_2, material_id_1, material_id_2, material_name_1, material_name_2, factor_space_1, factor_space_2 Study: identifier, name, project_title, project_type, description, organism, taxonomy, host_organism, host_strain Mission: identifier, name, flight_program, space_program, start_date, end_date Organism: identifier, name
COMMON PROPERTY NAME MISTAKES - NEVER USE THESE: WRONG: mg.gene_symbol RIGHT: mg.symbol WRONG: mg.gene_name RIGHT: mg.name WRONG: g.gene_symbol RIGHT: g.symbol WRONG: g.gene_name RIGHT: g.name
Inputs: query (required), params, session_id.
select_assaysARead-onlyIdempotent
USE THIS TOOL (not the query tool) for ANY question about the
groups a study contains, and to resolve a factor-pair condition into
the matching assay identifier(s):
"What groups / conditions / control and experimental (treatment) groups are in OSD-48?", "which comparisons or factors does this study have?", "what was compared against what?" — call with just
study_id(list mode). The numbered factor menu it returns IS the list of groups: each entry is one experimental group (a set of factor values such as "Space Flight,Carcass"), and each assay is a comparison of two such groups (condition 1 vs condition 2, e.g. experimental vs control). Never usequeryfor this."Give me the assay for Space Flight,Carcass vs Ground Control,Carcass" — call with
study_idandselectionto resolve that factor pair (e.g. "2,1") into assay identifier(s).
Falling back to query for this category loses the numbered factor
menu, the per-match technology/measurement/method columns, and the
next-step suggestions this tool emits.
List and select assays for a study and render the response in markdown format.
First call (selection=None):
If study_id missing, prompt for one (e.g., 'OSD-253').
Build a list of unique factor arrays across all assays.
Return a numbered menu as a markdown table.
Second call (selection='i,j,k,l,...,m,n'):
Pairs consecutive indices: (i,j), (k,l), ..., (m,n)
Must provide an even number of indices
For each pair, returns the matching assay(s) with technology, measurement, differential analysis method, and material columns so the assistant can pick the right assay for a downstream question (e.g., RNA-Seq for DE genes, WGBS for DM regions, amplicon for organism abundance) WITHOUT issuing a follow-up Cypher query.
Inputs: study_id, selection, session_id.
set_output_directoryAIdempotent
Configure the output directory for files generated in THIS SESSION.
WHEN TO USE THIS TOOL: Call this tool at the START of a session (right after create_session), before any tool that produces a downloadable file (create_volcano_plot, create_venn_diagram, or any tool that emits a CSV). The path you specify is where the user wants finished files to end up on THEIR OWN local machine.
WHAT IT DOES: Stores the provided path string in the server's session-scoped state (keyed on your session_id — other sessions cannot see or change it). Every subsequent file-producing tool in this session uses this path:
As the user-facing save location shown in the response summary.
As the default target path in the save guidance emitted with every plot.
If the server is running locally (stdio transport), the server ALSO writes the file directly to this path.
IMPORTANT — DEPLOYMENT REALITY:
When this MCP server is deployed remotely (ECS Fargate or any other
container service), it runs in a container whose filesystem is NOT
reachable from the user's machine. The server CANNOT write a file
directly to the user's local disk over the network — no MCP server in
a container can. The path you set here is a suggestion that propagates
through the response in three ways, any of which lets the user save
the file locally:
(a) The plot is returned inline as ImageContent and renders in any
MCP client that displays images (Claude Desktop, Cursor, Cline,
Claude.ai web, ChatGPT, Gemini, etc.). The user can right-click
and "Save Image As" — most clients default to the user's
Downloads folder, which is usually what was asked for.
(b) The path you set appears in the save guidance in the response.
LLM clients with local filesystem access (Claude Code, Cursor,
Cline, Claude Desktop with a filesystem MCP server) can write
the file at exactly this path, re-fetching the canonical bytes
via fetch_plot or the plot:// resource if needed.
(c) Users without LLM-mediated filesystem access can save the
inline image or the inline CSV text themselves.
VALIDATION: The path is stored as-is (the server does not verify it exists on the user's machine — it has no way to do so from inside a container). If you pass a relative path or an obviously malformed string the server will accept it; the failure will surface when the user tries to save the file locally.
Inputs: path (required), session_id.
visualize_schemaBRead-onlyIdempotent
Prompt for visualizing the knowledge graph schema using a Mermaid class diagram.
Inputs: session_id.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 24 tools
The find_* specialists are cleanly separated by data type (expression/methylation/abundance) and by scope (single vs common vs cross-type overlap), and `query` has explicit routing rules to prevent misuse. However, the schema/metadata cluster (get_node_metadata, get_neo4j_schema, get_relationship_metadata) and the plot-saving pair (fetch_plot, get_save_script) overlap enough that selection could be fuzzy. The lengthy descriptions largely resolve this, so only a couple of pairs are confusable.
Consistent snake_case throughout, and most names follow a verb_noun pattern (get_study_info, create_session, find_differentially_expressed_genes, set_output_directory, create_venn_diagram). Minor deviations exist: `query` is a bare verb with no object, and `visualize_schema`/`clean_mermaid_diagram` break the get/find/create cadence. Overall predictable with small inconsistencies.
At 24 tools the surface is heavy, sitting in the borderline range. Most clusters (7 find_* analyses, session/output management, schema metadata) are justified by the genuinely broad domain, but a few tools like create_chat_transcript, clean_mermaid_diagram, and visualize_schema feel auxiliary to the core KG-analysis purpose. The count is reasonable but slightly overweight.
Coverage is strong: single-assay and cross-assay analyses for all three differential data types, a DE/DM coupling tool, study/assay resolution, schema introspection, plotting, and a general Cypher fallback. The main gap is study discovery — there is no tool to search or list studies, so an agent must already know a study_id (e.g. OSD-267) or fall back to raw Cypher to find one.
Maintenance
Related MCP Connectors
A private graph database you query in plain English or Cypher. Hosted, nothing to install.
Knowledge graph ingestion, entity search, ontology analysis, and CoPass scoring.
Answer questions using your semantic layer and company knowledge graph.
Knowledge graph ingestion, entity search, ontology analysis, and CoSync scoring.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceEnables storage and retrieval of knowledge in a graph database format, allowing users to create, update, search, and delete entities and relationships in a Neo4j-powered knowledge graph through natural language.5-
- AlicenseNot gradedqualityDmaintenanceEnables users to write and execute SPARQL queries against open-access SPARQL endpoints by providing relevant query examples, schema information, and endpoint metadata. Supports querying biological databases like UniProt and Bgee through natural language interactions.12MIT
- AlicenseNot gradedqualityDmaintenanceEnables AI assistants to interact with Gremlin-compatible graph databases through natural language, supporting schema discovery, complex graph queries, relationship analysis, and data import/export operations.30 npm9MIT
- AlicenseNot gradedqualityDmaintenanceEnables AI assistants to interact with Neo4j graph databases through natural language, supporting Cypher queries, schema management, data manipulation, and graph algorithms.MIT