MCP Server Operations
Running the substrate MCP server for editor/agent clients.
Source: docs/operations/mcp-server.md
SciDEX Forge MCP server
Status: M28 ships an MCP-protocol server that exposes the 14 SciDEX Forge tools to any third-party AI client that speaks Model Context Protocol — Claude Desktop, Cursor, Continue, Zed, and so on.
This document covers what it does, how to install it, and how to wire it into common MCP clients.
What is exposed
The server narrows the substrate verb surface to just the
scidex.forge.* namespace — the scientific tools that an external
agent typically wants without being given access to governance,
economy, or debate verbs.
| MCP tool name | Substrate verb | What it does |
|---|---|---|
allen_brain_expression |
scidex.forge.allen_brain_expression |
Allen mouse brain ISH energy by substructure |
alphafold_structure |
scidex.forge.alphafold_structure |
UniProt → AlphaFold predicted structure |
clinical_trials_search |
scidex.forge.clinical_trials_search |
ClinicalTrials.gov search |
crossref_lookup |
scidex.forge.crossref_lookup |
Crossref metadata lookup by DOI / query |
drug_indications |
scidex.forge.drug_indications |
openFDA drug label → indications + mechanism |
ensembl_xref |
scidex.forge.ensembl_xref |
Ensembl gene ID ↔ external cross-references |
gnomad_variant |
scidex.forge.gnomad_variant |
Variant → gnomAD population AF + ClinVar significance |
gtex_expression |
scidex.forge.gtex_expression |
Gene symbol → GTEx tissue-level TPM |
interpro_domains |
scidex.forge.interpro_domains |
UniProt accession → InterPro domain annotations |
opentargets |
scidex.forge.opentargets |
Gene → ranked disease associations + evidence counts |
pdb_lookup |
scidex.forge.pdb_lookup |
PDB ID → structure metadata + viewer URLs |
pubmed_search |
scidex.forge.pubmed_search |
NCBI PubMed search → structured citations |
semantic_scholar_search |
scidex.forge.semantic_scholar_search |
Semantic Scholar paper search |
uniprot_lookup |
scidex.forge.uniprot_lookup |
Gene symbol / accession → UniProt protein record |
The full verb name is preserved on the wire; only the displayed MCP tool name is shortened.
Installation
The MCP SDK is an optional dependency of the substrate. Install it together with the rest of the dev deps:
pip install -e ".[mcp]"
# or, if you want test + lint deps too:
pip install -e ".[dev,mcp]"
Verify the server starts and reports the Forge surface:
SUBSTRATE_URL=http://127.0.0.1:8200 python -m tools.mcp.scidex_forge_mcp
# stderr should read:
# [scidex-forge-mcp] serving 14 Forge tools -> http://127.0.0.1:8200
Hit Ctrl-C to stop. MCP clients launch this command themselves over
stdio — you do not need to run it manually in normal operation.
Wiring into MCP clients
All four clients below follow the same pattern: declare a command /
args pair that runs python -m tools.mcp.scidex_forge_mcp, and pass
the substrate URL via env.SUBSTRATE_URL.
If you installed into a virtualenv, replace python with the full
path to that venv’s interpreter — desktop MCP clients do not inherit
your shell’s PATH.
Claude Desktop
Edit claude_desktop_config.json (on macOS:
~/Library/Application Support/Claude/claude_desktop_config.json):
{
"mcpServers": {
"scidex-forge": {
"command": "python",
"args": ["-m", "tools.mcp.scidex_forge_mcp"],
"env": {
"SUBSTRATE_URL": "http://127.0.0.1:8200"
}
}
}
}
Restart Claude Desktop. The 14 Forge tools will appear in the tool picker.
Cursor
Cursor reads MCP servers from its global settings (Settings → Features → Model Context Protocol). Add a new server with:
-
Name:
scidex-forge -
Command:
python -m tools.mcp.scidex_forge_mcp -
Working directory: your local checkout of
SciDEX-Substrate -
Environment:
SUBSTRATE_URL=http://127.0.0.1:8200
Continue
config.json:
{
"experimental": {
"modelContextProtocolServers": [
{
"transport": {
"type": "stdio",
"command": "python",
"args": ["-m", "tools.mcp.scidex_forge_mcp"],
"env": {"SUBSTRATE_URL": "http://127.0.0.1:8200"}
}
}
]
}
}
Zed
~/.config/zed/settings.json (or the workspace .zed/settings.json):
{
"context_servers": {
"scidex-forge": {
"command": {
"path": "python",
"args": ["-m", "tools.mcp.scidex_forge_mcp"],
"env": {"SUBSTRATE_URL": "http://127.0.0.1:8200"}
}
}
}
}
Environment variables
| Variable | Default | Meaning |
|---|---|---|
SUBSTRATE_URL |
http://127.0.0.1:8200 |
Base URL of the running substrate (where /api/scidex/forge/* POSTs land). Trailing slash is trimmed automatically. |
SUBSTRATE_TIMEOUT |
30 |
Per-call HTTP timeout in seconds. Non-numeric or non-positive values fall back to the default. |
SUBSTRATE_API_KEY |
(unset) | If set, sent as Authorization: Bearer <value> on every dispatch. Required only if the substrate has the ApiKeyAuthMiddleware enabled and refuses anonymous viewer reads. |
How dispatch works
Each call_tool invocation:
-
Looks up the requested name in the verb registry (accepts both short —
pubmed_search— and full —scidex.forge.pubmed_search— forms). -
POSTs the supplied
argumentsJSON to${SUBSTRATE_URL}/api/scidex/forge/<verb>. -
Returns the substrate’s response body verbatim as a single
TextContentblock.
If the substrate returns HTTP ≥ 400 the response is wrapped in a
structured _mcp_error envelope with the upstream payload nested
under details.upstream so clients can still surface a useful
diagnostic. Network failures (DNS, refused, timeout) become
transport_error / timeout envelopes for the same reason — MCP
clients tend to treat raised exceptions as session-fatal.
Relationship to the substrate’s built-in MCP server
The substrate already ships a general-purpose MCP server at
scidex_substrate.skill.mcp_server which exposes every registered
verb (currently 230+). That server runs verbs in-process and needs DB
credentials, full migrations, and the substrate’s Python environment.
The Forge MCP server in tools/mcp/scidex_forge_mcp.py is
deliberately lightweight: it speaks HTTP to whatever substrate is
already serving the network, exposes only the 14 scientific tools, and
needs no DB pool of its own. Use the general server for operator
workflows on a substrate host; use the Forge server for handing tools
to external AI clients.
Artifact and SciDEX Interaction Guidance
Both MCP surfaces should guide agents back to the Substrate verb contract:
-
Read context with
scidex.get,scidex.list,scidex.search, and typed paper/Forge read verbs. -
Create durable scientific state with
scidex.createusingtitleandcontent; revise withscidex.updateandbase_content_hash; connect evidence withscidex.link, comments, signals, and provenance fields. -
Store file payloads through registered S3 blob metadata or Forgejo artifact repository pointers. MCP tools should not ask agents to write payloads into local scratch directories and then treat those paths as durable state.
-
Treat
/data/scidex-artifacts,/data/artifacts,/home/ubuntu/scidex/data/scidex-artifacts, and archived SciDEX GitHub repositories as historical provenance only.
Troubleshooting
serving 0 Forge tools — the verb registry didn’t pick up the
scidex.forge.* modules. Confirm scidex_substrate.skill.verbs
imports cleanly:
python -c "from scidex_substrate.skill.framework import get_verb_registry; \
import scidex_substrate.skill.verbs as _; \
print(sum(1 for n in get_verb_registry() if n.startswith('scidex.forge.')))"
# should print 14
Calls return transport_error — the substrate URL is wrong, the
substrate is not running, or it is bound to a different interface than
SUBSTRATE_URL points at. curl -i ${SUBSTRATE_URL}/v1/readiness
should answer 200.
Calls return substrate_error with status: 401 or 403 — the
substrate has ApiKeyAuthMiddleware or RateLimitMiddleware enforcing
non-anonymous access. Set SUBSTRATE_API_KEY in the MCP client’s env
block.
Tool list appears in the client but inputs render as a single
arguments blob — the client is using mcp SDK < 1.0 which doesn’t
honour per-tool inputSchema. Upgrade the client.