An MCP (Model Context Protocol) server that exposes Dockstore to AI assistants and other MCP clients.
Dockstore is a registry of bioinformatics tools and workflows described in CWL, WDL, Nextflow, and Galaxy. It serves them through the GA4GH Tool Registry Service (TRS) API and through Dockstore's own API. This server is a standalone process that sits in front of those APIs and speaks MCP, so it is deployed alongside the Dockstore webservice rather than inside it.
It is built on FastMCP 4 and ships as a container image.
Status: scaffold. The only tool with a body is
hello, which reports the configured Dockstore instance and proves the plumbing end to end. The four Dockstore tools are declared — names, arguments, and response shapes — but each one raisesNotImplementedErroruntil it is wired up to the Dockstore API.
- Python 3.11 or newer (the container image uses 3.13)
- Docker, if you want to build or run the image
make install # create .venv and install the package plus dev dependencies
make test # run the test suite
make run # start the server on stdioOr without make:
python3 -m venv .venv && .venv/bin/pip install -e '.[dev]'
.venv/bin/dockstore-mcp --helpThe server supports the two standard MCP transports.
stdio — the client launches the server as a subprocess. This is how desktop MCP clients normally work:
dockstore-mcp --transport stdioHTTP — the server runs as a long-lived service, which is how it is deployed:
dockstore-mcp --transport http --host 0.0.0.0 --port 8000Over HTTP it serves two paths:
| Path | Purpose |
|---|---|
/mcp |
The MCP endpoint (streamable HTTP) |
/health |
Liveness probe, returns {"status": "ok", ...} |
docker build -t dockstore/dockstore-mcp:local .
docker run --rm -p 8000:8000 \
-e DOCKSTORE_MCP_DOCKSTORE_URL=https://qa.dockstore.org \
dockstore/dockstore-mcp:localThe image defaults to the HTTP transport on port 8000 and runs as a non-root user. A
docker-compose.yml is included for local runs against a Dockstore webservice on your
machine:
DOCKSTORE_URL=http://host.docker.internal:8080 docker compose up --buildTo use a local checkout from a client that launches servers itself, point it at the
entry point. For example, in Claude Desktop's claude_desktop_config.json:
{
"mcpServers": {
"dockstore": {
"command": "/path/to/mcp/.venv/bin/dockstore-mcp",
"env": { "DOCKSTORE_MCP_DOCKSTORE_URL": "https://dockstore.org" }
}
}
}To connect to a running HTTP deployment instead, point the client at
https://<host>/mcp. In Claude Code that is:
claude mcp add --transport http dockstore https://<host>/mcpEvery option can be set with a DOCKSTORE_MCP_-prefixed environment variable, in a
.env file (see .env.example), or with a command line flag. Flags win
over the environment.
| Variable | Flag | Default | Meaning |
|---|---|---|---|
DOCKSTORE_MCP_TRANSPORT |
--transport |
stdio |
stdio or http |
DOCKSTORE_MCP_HOST |
--host |
127.0.0.1 |
Interface to bind, HTTP only |
DOCKSTORE_MCP_PORT |
--port |
8000 |
Port to bind, HTTP only |
DOCKSTORE_MCP_PATH |
--path |
/mcp |
Path the MCP endpoint is served from |
DOCKSTORE_MCP_LOG_LEVEL |
--log-level |
INFO |
Logging verbosity |
DOCKSTORE_MCP_DOCKSTORE_URL |
--dockstore-url |
https://dockstore.org |
Dockstore instance whose APIs are exposed |
The container image overrides the first four so that it listens on 0.0.0.0:8000 out of
the box. It also sets a few FASTMCP_* variables so that a deployed server logs plainly
and does not check PyPI for updates on startup; see the
FastMCP settings for the full list.
| Tool | Description |
|---|---|
hello |
Greets the caller and reports the Dockstore instance and server version. No I/O. |
search_entries |
Searches entries by keyword and facet, the equivalent of the site's Search page. |
get_entry |
Retrieves the requested fields of one entry. |
get_version |
Retrieves the requested fields of one version of an entry. |
get_file |
Retrieves the requested fields of one file belonging to a version. |
The last four are scaffolding and are not implemented yet. They are a chain:
search_entries yields entry identifiers, an entry yields version identifiers, and a
version yields file paths. Each lookup takes a list of fields so that a caller can ask
for a name and a date without also pulling down a README or a whole descriptor.
src/dockstore_mcp/
├── __main__.py command line entry point (`dockstore-mcp`)
├── config.py settings, read from the environment
├── models.py entry, version, and file types shared by the tools
├── server.py server construction, /health route
└── tools/
├── __init__.py registers every tool group
├── entries.py get_entry, get_version, get_file
├── hello.py the hello tool
└── search.py search_entries
tests/ pytest suite, using FastMCP's in-memory client
Dockerfile two-stage build of the deployable image
Add a module under src/dockstore_mcp/tools/ that exposes
register(mcp: FastMCP, settings: Settings) -> None, and call it from
register_all in tools/__init__.py. Group related tools in one module.
Keep tool docstrings written for the model that will read them: say what the tool
returns and when to reach for it. Note that FastMCP can also generate tools directly
from an OpenAPI specification (FastMCP.from_openapi), which may be the right way to
cover large parts of the Dockstore API.
make check # lint, type check, and test
make format # apply ruff formatting and safe fixesTests use FastMCP's in-memory client, so they exercise real tool dispatch without starting a server or opening a socket.
Dockstore uses git-secrets to help make sure that keys and private data stay out of the source tree. For information on installing it on your platform check https://github.com/awslabs/git-secrets#id6.
If you're on mac with homebrew use brew install git-secrets.
With git-secrets on your path, make install (or make git-hooks) registers the AWS
patterns and points core.hookspath at git-hooks/, so the scan runs on
every commit. CI runs git secrets --scan over the whole repository as well. False
positives can be listed in .gitallowed.
Apache License 2.0. See LICENSE.