Skip to content

Quickstart

Boot the NovoMCP engine locally in about 2 minutes. No API keys, nothing to provision — it runs on your hardware.

Requirements

  • Python 3.10 or later. Python 3.9 hit end-of-life October 2025; several transitive deps require 3.10+.

Check what you have:

python3 --version

If it says Python 3.10.x or newer, skip ahead. Otherwise install a supported version via any of these paths:

brew install python@3.11

Download from python.org/downloads.

sudo apt install python3.11 python3.11-venv
sudo dnf install python3.11

Download from python.org/downloads, or use WSL and follow the Linux instructions.

pyenv install 3.11.9
pyenv local 3.11.9

All fine — any Python 3.10+ works. python:3.11-slim is a good Docker base.

Install and run

Fastest — uvx (no clone, no venv)

Run the engine straight from PyPI in one command:

uvx novomcp

uvx fetches the novomcp package into a throwaway environment and launches the engine — nothing to clone or install. The first run downloads the dependency set (rdkit, MDAnalysis, …), so give it a minute; later runs are cached.

Just want the lightweight cheminformatics subset?

uvx --from 'novomcp-lite[mcp]' novomcp-lite starts a stdio MCP server in seconds — RDKit properties/profiling + public-API search, no backend. The full engine imports the same code, so the two never drift. See novomcp-lite.

pip install

Into a virtual environment you control:

python3.11 -m venv .venv && source .venv/bin/activate
pip install novomcp
novomcp

novomcp is the console command — it boots the MCP + REST server.

Prebuilt Docker image (GHCR)

No Python, no build — pull the published image and run it:

docker run --rm -p 8018:8018 ghcr.io/novomcp/novomcp:latest

The engine listens on port 8018 (MCP + REST); /health is the readiness check. The image is rebuilt on every push to main (:latest, plus :sha-<short> to pin an exact build) and on each release tag (:vX.Y.Z, with the moving :X.Y and :X). It's public — no login to pull. Pass configuration with -e, e.g. -e NOVOMCP_QM_URL=... to wire a compute service.

From source

For hacking on the engine itself:

git clone https://github.com/NovoMCP/novomcp.git
cd novomcp/orchestrator
python3.11 -m venv .venv && source .venv/bin/activate
python -m pip install --upgrade pip
pip install -e .
python main_https.py      # or: novomcp

The engine boots with:

  • Auth: none required (LocalAuthGate, every request resolves to a local user with unlimited tier)
  • Metering: none (NoopMeter, no usage accounting)
  • Audit: local file (FileAuditSink, appends JSON-lines to ~/.novo/audit.jsonl)

If you accidentally create the venv with Python 3.9, python main_https.py fails fast with an actionable message telling you which install command to run.

Everything at once — Docker Compose (engine + dashboard)

If you have Docker, one command builds and runs both the engine and the web dashboard, wired to each other on a private network:

git clone https://github.com/NovoMCP/novomcp.git
cd novomcp
docker compose up
  • Engine → http://localhost:8018
  • Dashboard → http://localhost:3000

docker compose up starts both and streams both logs; Ctrl-C (or docker compose down) stops both. No start-order to worry about. Compose is also the single-VM cloud recipe — the same file scales from your laptop to one box in the cloud.

First requests

In another shell:

Health check

curl -s http://localhost:8018/health | python3 -m json.tool

Expected: {"status": "healthy", ...}.

List tools

curl -s http://localhost:8018/mcp/tools \
  -H 'Authorization: Bearer x' \
  | python3 -m json.tool

LocalAuthGate accepts any bearer token — x works fine. Returns the 18 always-available tools; the other 51 in the 69-tool catalog appear as you wire their backing services (see tool-availability.md).

Get a molecule profile (aspirin)

curl -s -X POST http://localhost:8018/mcp/tools/get_molecule_profile \
  -H 'Authorization: Bearer x' \
  -H 'Content-Type: application/json' \
  -d '{"arguments": {"smiles": "CC(=O)Oc1ccccc1C(=O)O"}}' \
  | python3 -m json.tool

Returns properties (MW, logP, TPSA, QED, Lipinski) computed on-the-fly via RDKit. admet_available will be false because the ADMET service (addie-models) isn't wired locally — that's expected. See Deploying services to enable ADMET.

MCP JSON-RPC handshake

curl -s -X POST http://localhost:8018/mcp/ \
  -H 'Authorization: Bearer x' \
  -H 'Content-Type: application/json' \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "initialize",
    "params": {"protocolVersion": "2024-11-05", "capabilities": {}}
  }' \
  | python3 -m json.tool

Returns server info, capabilities, and the funnel-id instructions blurb. This is the endpoint MCP-compatible clients (Claude Desktop, Cursor, Zed) connect to.

Audit sink

tail -3 ~/.novo/audit.jsonl

Every tool call is logged as a JSON-lines row: ts, event, and a payload with the tool, its run (funnel_id), success, duration, and:

  • arguments: what was run, enough to repeat the call. Keys that look like secrets (API keys, tokens, passwords) are stored as <redacted>; a very large value, such as a long SMILES list, keeps only its length and a sample.
  • outcome: a short result. For check_compliance, the verdict and its flags; for property and ADMET tools, the headline numbers.

The file is the whole record: copy it to keep or share a history. In the dashboard, Activity lists every call, filters by tool, result or run, opens a call to copy it and run it again, and downloads the history as a CSV for a spreadsheet or as the raw log for scripts. Its Runs tab shows each run as a timeline: the calls it made, plus the stages a discovery funnel saved with save_funnel_stage (molecules in and out, what was filtered and why, and the human decisions). Those stages are kept in the same file, as funnel_stage events. For analysis, load the file directly, for example pandas.read_json("~/.novo/audit.jsonl", lines=True).

The web dashboard

The engine is headless — a REST/MCP backend. The web dashboard (Next.js) is the visual surface: molecule profiles, live engine/service status, and the config screens for LLM keys, compliance, observability, and data connectors.

The engine and the dashboard are two separate processes. The dashboard's server-side routes proxy to the engine at NOVOMCP_ENGINE_URL (default http://localhost:8018); the browser only ever talks to the dashboard.

Start order doesn't matter

The dashboard degrades gracefully when the engine is down — every panel shows what's missing and offers a Recheck button — so you can start either first and connect them in any order.

docker compose up

Brings up the engine and the dashboard together (see above). Open http://localhost:3000.

Two terminals. In the first, run the engine (Install and run). In the second:

cd frontend-nextjs
npm install
npm run dev

Open http://localhost:3000. Set NOVOMCP_ENGINE_URL if your engine runs somewhere other than http://localhost:8018.

Once connected, the dashboard shows Tools available: 18 of 69 — the 18 that work with nothing wired, out of the full catalog. That count climbs as you deploy services; the dashboard lists which env var unlocks each capability. See Tool availability for the full map.

What runs where

Where it runs How you connect it
Engine, RDKit properties, the 18 default tools Your machine Nothing to do
Compute services: ADMET, docking, MD, QM, NN potentials, properties, structure, molecule index Your hardware, or a DGX Spark (Novo Station, which runs all of them plus the dashboard) Connections → Self-hosted compute: the service's URL
Compliance screening (closed source) The paid API, api.novomcp.com Connections → NovoMCP compliance: https://api.novomcp.com/v1/compliance and your API key; each check is billed to that key's account
LLM, data connectors, observability The provider you choose Connections, under each category

Connections saves to ~/.novo/credentials.env, which the engine loads at startup: restart the engine after saving. Each tile's status is live — connected means the service answered, unreachable that it didn't, and for compliance key rejected or needs API key point at the key. With docker compose up, the engine and the dashboard share that file through the novomcp-audit volume.

The dashboard checks services from where it runs, so service URLs must be reachable from there. In Docker, http://addie-models:8025-style names work inside the compose network; for services on another machine, such as a Spark on your network, use that machine's address.

What next