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:

  1. Looks up the requested name in the verb registry (accepts both short — pubmed_search — and full — scidex.forge.pubmed_search — forms).

  2. POSTs the supplied arguments JSON to ${SUBSTRATE_URL}/api/scidex/forge/<verb>.

  3. Returns the substrate’s response body verbatim as a single TextContent block.

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.create using title and content; revise with scidex.update and base_content_hash; connect evidence with scidex.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.