Skip to main content
Glama

mltree-mcp

test PyPI Python License: MIT

Your ML workflow as a node map, your experiments as a tree — filled in by your coding assistant as it works.

mltree-mcp is an MCP server for Codex, Claude Code and any other MCP client. While the assistant writes and runs your ML / QSAR / GNN code, it calls mltree tools to:

  • register each pipeline step (load → clean → featurize / graph-build → split → HPO → train → evaluate) as a node, with its own .py script, inputs, outputs and default params;

  • wire the steps into a DAG;

  • log every execution as a run with params, metrics and artifacts, branching from a parent run (HPO trials, GNN variants…), so experiments form a mind-map tree instead of being scattered down a notebook.

Everything lives as plain files in your repo under .mltree/, and mltree-mcp view opens a KNIME-style map of it in your browser.

Demo: workflow map, experiment tree, compare, project switcher

Workflow map

Experiment tree

Status: 0.8.0. MCP core, map viewer, scan_project for existing projects, shareable HTML export, running steps and grid sweeps from the map (opt-in), data versions, compare with param changes / curves / code diffs, notes and tags, GNN views, and now PyPI packaging, CI and a multi-project viewer. See the changelog.

Install

Requires Python 3.11+. Works with the MCP Python SDK 1.x (FastMCP) and 2.x (MCPServer).

pip install mltree-mcp      # or: uv tool install mltree-mcp
mltree-mcp --version

# or run it without installing
uvx mltree-mcp --version

The wheel ships the prebuilt viewer, so Node is not needed. From source:

git clone https://github.com/yboulaamane/mltree-mcp
cd mltree-mcp
pip install -e .            # or: uv pip install -e ".[dev]"

# straight from the git repo
uvx --from git+https://github.com/yboulaamane/mltree-mcp mltree-mcp --version

The mltree-mcp command starts a stdio MCP server (that is what Claude Code and Codex expect). Clients launch it for you; you don't run it by hand.

Which project does it use?

The project root is resolved on every call, in this order:

  1. --project <dir> flag / MLTREE_PROJECT environment variable

  2. CLAUDE_PROJECT_DIR (Claude Code sets this for stdio servers automatically)

  3. the server's current working directory

Related MCP server: mlops-mcp-server

Add it to Claude Code

# once on PyPI
claude mcp add mltree -- uvx mltree-mcp

# before that, from your clone
claude mcp add mltree -- uvx --from /path/to/mltree-mcp mltree-mcp

# make it available in every project, or share it with the repo via .mcp.json
claude mcp add --scope user    mltree -- uvx mltree-mcp
claude mcp add --scope project mltree -- uvx mltree-mcp

claude mcp list        # should show: mltree ... ✔ Connected

Inside Claude Code, /mcp shows the server and its tools. Claude Code passes CLAUDE_PROJECT_DIR, so the store lands in the project you opened.

Add it to Codex

Either use the CLI:

codex mcp add mltree -- uvx mltree-mcp
codex mcp list

or edit ~/.codex/config.toml (or a project-scoped .codex/config.toml in a trusted project):

[mcp_servers.mltree]
command = "uvx"
args = ["mltree-mcp"]
# before PyPI: args = ["--from", "/path/to/mltree-mcp", "mltree-mcp"]
startup_timeout_sec = 20   # first uvx run downloads dependencies

# Optional: pin the project instead of using the directory Codex starts in
# [mcp_servers.mltree.env]
# MLTREE_PROJECT = "/home/you/projects/qsar-gnn"

In the Codex TUI, /mcp lists active servers. Codex also reads the server's built-in instructions, which tell it when to call each tool.

Use it on an existing project over SSH with Codex

You already have a project on a GPU server: numbered scripts, a utils.py, a notebook or two, some metrics.json files, maybe mlruns/ or an Optuna study. scan_project builds the map from that code without running any of it. It parses scripts with Python's ast and reads notebooks as JSON.

1. Install on the server (once):

ssh you@server
pip install --user "git+https://github.com/yboulaamane/mltree-mcp"   # or: uv tool install git+https://github.com/yboulaamane/mltree-mcp
mltree-mcp --version

2. Register it with Codex on the server, pinned to the project:

codex mcp add mltree -- mltree-mcp --project /path/to/your/project

3. Ask Codex to scan it. Start codex in the project and say:

Scan this project with mltree and show me the map. Fix anything the scan got wrong.

Codex calls scan_project (the server instructions tell it to do this first on an existing project). It reviews the summary and corrects edges or kinds with connect_steps / add_step. You can also scan from the shell:

mltree-mcp scan --project /path/to/your/project --dry-run   # preview, writes nothing
mltree-mcp scan --project /path/to/your/project             # write .mltree/

4. Look at it from your laptop. On the server:

mltree-mcp view --project /path/to/your/project      # serves on localhost:8765 on the server

On your laptop:

ssh -L 8765:localhost:8765 you@server
# then open http://localhost:8765

What the scan detects

Signal

How

Data reads / writes

pd.read_* / .to_*, open() (by mode), np.load/save, torch.load/save, joblib, pickle, json, yaml, Path.read_*/write_*, h5py, shutil.copy, RDKit / PyG loaders, project helpers such as load("x.json") / save(obj, "y.pkl"). Paths are folded from string constants, f-strings, Path(__file__).parent / "data", os.path.join, and argparse / click defaults.

Params

argparse add_argument and click @option defaults, sys.argv[...] if ... else default, UPPERCASE numeric constants, and literal kwargs like test_size, random_state, n_trials, lr, epochs.

Description

The module docstring, or the notebook's first markdown heading.

Kind

data / clean / split / featurize / hpo / train / eval, from the file name, imports and calls. For example, optuna.create_study gives hpo, train_test_split gives split, .fit or optimizer.step() gives train, and sklearn.metrics gives eval.

Utilities

A helper module such as utils.py (imported, with no entry point and no I/O) is not a step. It is noted in the description of each step that uses it.

Edges

1) one step's output path matches another's input (exact, glob, or folder); 2) imports of other step modules; 3) notebook section order; 4) file numbering (01_, step2_) for steps that have no other upstream. Cycles are never added.

Notebooks

One step per notebook, or one step per markdown-headed section with notebook_sections=true. Magics are ignored.

Existing results → runs tagged imported

*metrics*.json / *results*.csv style files; MLflow mlruns/ (params, last metric values, status); Optuna SQLite studies (one parent run per study, trials as child runs, categorical params decoded, read-only); Lightning lightning_logs/version_* (hparams + last metrics.csv values); wandb offline runs (summary + config). TensorBoard event files are noted but not parsed.

Re-scanning is safe. Steps the scanner owns are refreshed, new scripts become new steps, and nothing is deleted. A step you or the assistant edited with add_step keeps its description, kind and param values; the scan only adds new inputs, outputs and param keys. Results are imported once (they are keyed by source). The summary lists new, updated, merged and unchanged steps, edges, inputs no step produces, outputs no step consumes, skipped files, and imported runs. Default excludes: virtualenvs, .git, tests/, test_*.py, __pycache__, .mltree, node_modules, build/, dist/.

The map viewer

mltree-mcp view                                   # project = $MLTREE_PROJECT / cwd
mltree-mcp view --project ~/projects/qsar-gnn --port 8765
# then open http://localhost:8765

Or ask the assistant: it calls open_map, which starts the viewer in the background if needed and returns the URL.

  • Workflow map. Your steps form a DAG, coloured by each step's latest run (grey not run, blue running, green done, red failed). Nodes are laid out automatically (dagre). If you drag them, their positions are saved to the store (pos_x / pos_y), and Auto layout resets them.

  • Step panel. Click a node to see its inputs, outputs and params, and a read-only editor (Monaco, the VS Code editor) showing the script. A dropdown switches between the current file and the snapshot saved with each run, marked "same as current" or "changed". Below it is the step's runs table.

  • Experiment tree. All runs form a mind-map built from parent_run_id. Pick a metric and "lower/higher is better" to highlight the best run (★). You can filter by step.

  • Compare. Tick 2 or more runs anywhere to get a params/metrics table (rows that differ are marked) and a grouped Plotly bar chart.

  • Live. The page updates by itself as the assistant logs runs, using Server-Sent Events with polling as a fallback. Dark and light themes follow your OS and can be toggled.

The built frontend ships inside the Python package (src/mltree_mcp/static/), so pip install needs no Node. Monaco is bundled too, with no CDN, so it works offline and on air-gapped clusters.

Compare runs

Data versions

Each step's inputs and outputs that are files or folders inside the project are fingerprinted. The fingerprint is the SHA-256 of the content (a folder hashes its sorted relative path + file hash list) and the version shown is its first 12 hex characters. Hashes are cached in mltree.db by path, size and mtime, so unchanged files are not re-read. Files over 4 GiB and folders over 5000 files get a quick digest (size + mtime only, marked ~) instead.

  • Runs record the versions they used: log_run records inputs and outputs, a run started from the map or by run_step records inputs at start and outputs when it succeeds. Runs imported by scan_project record none (it never runs or reads your data beyond the scan).

  • The step panel's Data versions table compares the files now with the latest run. The node shows ⚠ data changed when an input changed since that run and input missing when one is gone, so you know which steps to re-run.

  • Compare has a Data versions row group, and the data_status(step?) tool gives the assistant the same view.

  • Only paths are hashed, never executed or parsed. Paths outside the project are shown by name only in the export.

Data versions in the step panel

Compare: param changes, curves and code diff

Tick 2 or more runs (or use the Runs table's Compare):

  • Param changes: for each run, the params that differ from the first one (alpha: 1 → 0.5).

  • Params / metrics / data versions table, rows that differ marked, and a grouped bar chart of the ticked metrics.

  • Curves: step-wise metrics (MLTREE_METRIC lines, or log_run(history=[{"epoch": 1, "loss": 0.9}, ...])) overlaid per run, with a metric picker and log-y.

  • Code diff of two runs' script snapshots, unified or side by side, hunks or the whole file. It is computed in the browser, so it also works in the HTML export.

Metric curves

Side-by-side code diff

Notes and tags

Click + Add note / Edit in a step's panel or a run's panel to write free-text notes (Ctrl+Enter saves, Esc cancels). Runs also get tags: type one or more (comma-separated) in the run panel's tag box, × removes one. Notes show as ✎ on map nodes, tree cards and the runs table; the experiment tree's Tag filter dims every run without that tag. The assistant uses add_note and tag_run, and get_pipeline returns each step's notes and the tags in use. Notes and tags are in the HTML export (read-only there).

Editing notes doesn't need --allow-run, but the same request checks apply as for runs: an X-MLTree: 1 header, a loopback Host and, if present, a loopback Origin.

Notes and tags in the experiment tree

GNN views

For graph-learning steps the step panel gets a Graph model & data section, and the node a chip like GCNConv ×3 · hidden 64 · global_mean_pool or 20 graphs.

  • Architecture summary (static). mltree parses the step's script and the project modules it imports (it never imports or runs them). For torch.nn.Module subclasses that use PyTorch Geometric or DGL layers it lists the layers in __init__ (type, library, in → out channels, heads, repeats from for _ in range(num_layers) / ModuleList comprehensions), the readout / pooling and the order the layers are called in forward. Prebuilt models (GCN(in, hidden, num_layers), GAT, GIN, …) and literal / default / module-constant dimensions are resolved; anything else is shown as the source text.

  • Dataset stats (opt-in introspection). The section lists dataset classes the script uses (TUDataset, MoleculeNet, DGLDataset, …) and .pt / .bin graph files among the step's outputs. Inspect dataset… loads the file in a separate Python process (--python / $MLTREE_PYTHON with torch installed) without importing your code, and caches: number of graphs, nodes / edges min/mean/max, node and edge feature sizes, self loops, isolated nodes, average degree, labels (classes and counts, or the regression range) and train/val/test masks. A state_dict checkpoint gives tensor shapes and the parameter count. Stats are marked stale when the file changes. This loads data with torch.load (which can run code embedded in a pickle if weights_only=True fails), so it needs view --allow-run, MLTREE_ALLOW_RUN (MCP gnn_summary(introspect=true)) or the explicit CLI:

mltree-mcp gnn --project . --step featurize                  # static summary + cached stats (JSON)
mltree-mcp gnn --project . --step featurize --introspect --python ~/envs/pyg/bin/python

Broken or unusual scripts never break the map; the section just shows less. The export keeps the summaries and cached stats (not the source fragments when scripts are left out) and never offers introspection.

GNN architecture summary

Dataset stats

On a remote server or HPC cluster

The viewer binds to 127.0.0.1 by default. Run it on the server and tunnel the port from your laptop:

# on the server (or let the assistant call open_map there)
mltree-mcp view --project ~/projects/qsar-gnn

# on your laptop
ssh -L 8765:localhost:8765 you@server
# open http://localhost:8765

Use --host 0.0.0.0 only on a network you trust. The viewer has no authentication; without --allow-run its only writes are node positions and notes/tags, and notes/tags are refused unless the request comes through a loopback Host (an SSH tunnel). --allow-run refuses any bind other than 127.0.0.1, so run steps through the SSH tunnel.

Several projects in one viewer

One viewer can serve several projects, with a switcher in the header. Each project gets its own URL prefix (/p/<slug>/), API, live stream and run manager, so tabs on different projects work side by side.

mltree-mcp view --projects ~/projects/qsar-egfr ~/projects/tox21-gnn

# or register them once (stored in ~/.mltree/projects.json, or $MLTREE_HOME/projects.json)
mltree-mcp projects add ~/projects/qsar-egfr --name "QSAR EGFR"
mltree-mcp projects add ~/projects/tox21-gnn
mltree-mcp projects list
mltree-mcp projects remove tox21-gnn      # by folder or by name
mltree-mcp view --projects                # serves everything in the registry

http://localhost:8765/ redirects to the first project, GET /api/projects lists them all (name, steps, runs), and every route in the HTTP API is available under /p/<slug>/. --allow-run and the edit guards apply per project exactly as in single-project mode. When the assistant calls open_map and a multi-project viewer is already running on the port, it links to that project's page (or warns if the project isn't in the viewer). The registry file is plain JSON:

{"projects": [{"path": "/home/you/projects/qsar-egfr", "name": "QSAR EGFR"}, {"path": "/home/you/projects/tox21-gnn"}]}

Project switcher

Run steps from the map

Start the viewer with --allow-run and each node gets a ▶ button, and the step panel gets ▶ Run… and Grid sweep…:

mltree-mcp view --project ~/projects/qsar-gnn --allow-run           # Python: see "Which interpreter" below
mltree-mcp view --project ~/projects/qsar-gnn --allow-run --python ~/miniconda3/envs/gnn/bin/python

Run dialog

  • Run dialog. The params are prefilled from the step's last run, or from its scanned / declared params. You can edit them, add extra CLI arguments and see the exact command before you launch. A checkbox confirms that you know it executes the script on this machine (remembered for the browser tab).

  • Live log. stdout and stderr stream into a panel at the bottom, over Server-Sent Events, with stderr in red. Cancel sends SIGTERM, then SIGKILL after 5 s. Closing the page doesn't stop the run, and reopening it re-attaches.

  • Automatic record. Every run is logged by itself: params, the script snapshot (SHA-256 and git commit), the exact command, exit code, duration, the full log (.mltree/runs/<id>/log.txt) and metrics. A failed exit code marks the run failed, and its last stderr lines go into the notes. A run branches in the experiment tree from the newest succeeded run of an upstream step, so evaluate hangs under the train run that made its model.

Live log panel

How params reach your script. mltree reads the script (it doesn't run it) to choose a style:

Script uses

Params passed as

argparse / click options

--alpha 0.5 --layers 2 (booleans as bare flags; only options the script declares)

sys.argv[1], sys.argv[2] …

positional values, in that order

@hydra.main

alpha=0.5 layers=2 overrides

none of these

environment only

Every run also gets the following environment variables, so params the CLI doesn't declare still arrive and the dialog warns about them:

Variable

Value

MLTREE_PARAMS

all params as JSON

MLTREE_PARAM_<NAME>

one param, with the name upper-cased

MLTREE_RUN_ID, MLTREE_STEP, MLTREE_PROJECT

the run, the step, the project root

MLTREE_METRICS_FILE

.mltree/runs/<id>/metrics.json; write a JSON dict here to record metrics

Runs use the project root as the working directory, with python -u (unbuffered output).

Which interpreter. --python, else $MLTREE_PYTHON, else the project's .venv/ or venv/, else the active $VIRTUAL_ENV / $CONDA_PREFIX, else python3 on PATH.

Reporting metrics. Print lines like these. Nested JSON is flattened to val.rmse.

print(f"MLTREE_METRIC epoch={epoch} train_loss={loss:.4f} val_rmse={rmse:.4f}")   # key=value pairs
print("MLTREE_METRIC " + json.dumps({"val": {"rmse": rmse, "r2": r2}}))           # or a JSON object

Alternatively, write a JSON dict to $MLTREE_METRICS_FILE (or to a metrics*.json file the step declares as an output). The last value of each metric becomes the run's metric; a file overrides printed values. Every MLTREE_METRIC line is also kept as one point of a step-wise history (.mltree/runs/<id>/metrics_history.jsonl, GET /api/runs/{id}/history), which will feed the loss-curve overlays. Lines without the prefix are just log, so the script still works without mltree.

Sweeps

Grid sweep… takes comma-separated values per param (0.05, 0.2, 0.5), a metric to rank by, and lower or higher is better. It shows how many runs the grid makes (64 at most by default) and then runs them one after another as children of a sweep run. The log panel shows the progress, a child table with the best one starred, and each child's log. Cancel stops the current child and skips the rest.

Sweep progress

In the experiment tree a sweep is one card: its label, the number of runs, ✓/✗ counts and the best value. The children fan out below it with the best child highlighted (★ sweep best). Sweeps with more than 8 children start folded to the best one. ▸ unfold shows them all.

Sweep fan in the experiment tree

Sweeps also come from:

  • scan_project: an Optuna study becomes a sweep with its trials as children, ranked by the study's direction. A scikit-learn GridSearchCV / RandomizedSearchCV cv_results_ CSV becomes a sweep over its param_* columns, ranked by mean_test_score.

  • The assistant: run_sweep runs a grid for you. For trials it runs itself (Optuna, a manual loop), it calls start_sweep, then log_run(..., sweep_id=...) per trial, then finish_sweep.

Safety model

Running code from a browser page is the one dangerous thing the viewer can do, so it takes several locks:

  1. Off by default. Without --allow-run every run/sweep/cancel POST returns 403 and the buttons are greyed out. The shareable HTML export never has them.

  2. Loopback only. With --allow-run the viewer won't bind anything but 127.0.0.1. Use an SSH tunnel for remote machines.

  3. No cross-site requests. Each POST needs an X-MLTree: 1 header, which a plain form or a cross-origin page can't send without a CORS preflight that mltree never approves. It also needs a loopback Host (this defeats DNS rebinding) and, if an Origin header is present, a loopback Origin.

  4. Only the project's own scripts. A step's .py script_path must resolve inside the project. Nothing is run through a shell, and params become separate argv entries.

  5. An explicit confirm in the dialog for each tab session.

scan_project still never executes anything.

The MCP tools run_step / run_sweep are allowed by default, because the assistant can already run commands in your shell. Set MLTREE_ALLOW_RUN=0 in the server's environment to turn them off, for example on a shared machine.

HTTP API

Route

Returns

GET /api/health

project, root, revision (bumped on every store change)

GET /api/pipeline

nodes (params, script, position, latest run status), edges, order

PUT /api/positions

body {"positions": {"step": {"x": 0, "y": 0} | null}}

GET /api/steps/{step}

one node

GET /api/steps/{step}/script[?run_id=]

current script, or the snapshot stored with a run

GET /api/steps/{step}/snapshots

runs of the step that carry a script snapshot

GET /api/runs[?step=&status=&parent_run_id=&limit=]

runs, newest first

GET /api/runs/{run_id}

one run

GET /api/tree[?metric=&mode=min|max&step=]

run forest (runs, edges, roots) and the best run

GET /api/compare?ids=a,b[,c]

runs, param/metric keys and which ones differ

GET /api/metrics

numeric metric names

GET /api/export[?scripts=0|1]

the shareable single-file HTML (as a download)

GET /api/events

text/event-stream of revision events

GET /api/steps/{step}/plan[?params=json&extra_args=]

command preview, param-passing style, form defaults, warnings

POST /api/steps/{step}/run

{"params", "extra_args", "parent_run_id"} → {"run_id"} (needs --allow-run)

POST /api/steps/{step}/sweep

{"grid": {"p": [..]} | {"p": "1, 2"}, "params", "metric", "mode", "max_runs"} → {"sweep_id", "total"}

POST /api/runs/{run_id}/cancel

cancel a run or a whole sweep

GET /api/active

runs and sweeps in progress in this viewer

GET /api/runs/{run_id}/log[?offset=&tail=]

log lines {"s": "out"|"err", "line"} and done

GET /api/runs/{run_id}/log/stream[?offset=]

text/event-stream of lines events, then end

GET /api/runs/{run_id}/history

step-wise metrics (MLTREE_METRIC lines or log_run(history=))

GET /api/data[?step=]

data versions of every step (or one): each input/output now vs the latest run, changed_inputs

PUT /api/steps/{step}/notes / PUT /api/runs/{run_id}/notes

{"notes": "..."} (loopback + X-MLTree)

PUT /api/runs/{run_id}/tags

{"add": [..], "remove": [..]} or {"tags": [..]}

GET /api/steps/{step}/gnn

static model summary, dataset candidates, cached stats

POST /api/steps/{step}/gnn/introspect

load the step's graph file(s) in a subprocess and cache stats (needs --allow-run)

With view --projects, every route above lives under /p/<slug>/ and the root has GET /api/projects (slug, name, root, url, steps, runs) and GET /api/health (multi: true, the project roots).

The POST and PUT routes need the X-MLTree: 1 header (see Safety model).

Share the map

Export ▾ in the viewer header gives you:

  • Shareable HTML: one self-contained <project>-mltree.html file. It opens offline in any browser by double-click, with no server, no install and no network requests. It is read-only and includes the workflow map, the step panel with each script (current file and the snapshot stored with every run), the experiment tree and the compare view. It inlines a lighter build of the viewer: a small highlighted code view instead of Monaco and SVG bar charts instead of Plotly. The bundled demo exports to about 530 KB: ~500 KB of app and the rest data, with scripts deduplicated by SHA-256. docs/example-export.html is a sample.

  • Shareable HTML without scripts: the same file with the code left out.

  • Map as PNG / SVG: an image of the current map view (pan and zoom first), for slides and papers.

From the shell or through the assistant:

mltree-mcp export --project /path/to/project                    # -> ./<project>-mltree.html
mltree-mcp export --project /path/to/project -o share/map.html --no-scripts
export_map(path=None, include_scripts=True)   # MCP tool; returns {"path", "bytes", "size", ...}

The MCP tool writes to <project root>/<project>-mltree.html by default. On a remote server, copy the file to your machine with scp you@server:/path/to/project/<project>-mltree.html .

Ways to send it

  • Email or Slack. Attach the .html file. The recipient downloads it and opens it in a browser. (Previews inside Slack or a mail client won't run it; it has to be opened in a browser.)

  • GitHub Pages. Commit it as docs/index.html (or any .html in a Pages-enabled repo) and share the URL.

  • Gist. gh gist create --secret myproj-mltree.html, then open it through a raw-HTML viewer such as https://gist.githack.com/ (gist.github.com itself shows HTML as source).

Warning: the export contains your scripts. The default file embeds the full source of every step script and every run's script snapshot, plus params, notes, tags and artifact paths. If any of that is private (unpublished methods, internal paths, credentials someone hard-coded), use Shareable HTML without scripts, or --no-scripts / include_scripts=false, and don't publish the file on a public Pages site or a public gist. The absolute project path on the server is never included. *-mltree.html is in this repo's .gitignore; add it to yours too so an export isn't committed by accident.

Tools

Tool

What the assistant uses it for

export_map(path?, include_scripts=True)

Write the single-file, offline, read-only HTML of the map and return its path and size. It includes the scripts unless include_scripts=false. See Share the map.

scan_project(path=".", include?, exclude?, dry_run=False, notebook_sections=False, import_results=True)

Build the map of an existing project by static analysis (never runs your code): steps, params, edges, utilities, and existing results imported as runs. Idempotent; dry_run previews. See above.

init_project(name?)

Create .mltree/ (pipeline.yaml, mltree.db, runs/) in the project. Idempotent.

add_step(name, script_path?, inputs?, outputs?, params?, description?)

Register a node, or update it if the name exists. Script paths are relative to the project and may not escape it.

connect_steps(source, target, label?)

Add an edge. Both steps must exist; self-loops and cycles are rejected; warns when outputs and inputs don't match.

get_pipeline()

Nodes (script, params, latest run status, run count), edges and a topological order.

run_step(step, params?, extra_args?, parent_run_id?, wait=True, timeout_s=900)

Execute the step's script and record the run by itself: params, snapshot, command, exit code, duration, log and metrics. Returns the run and the log tail. Off with MLTREE_ALLOW_RUN=0.

run_sweep(step, grid, metric?, mode, params?, extra_args?, max_runs=64, wait=True)

Run every grid combination one after another as children of a sweep run, and return the best one.

run_log(run_id, tail=200) / cancel_run(run_id)

Follow or stop a run or sweep started with run_step / run_sweep.

start_sweep(step, metric?, mode, name?, search_space?, parent_run_id?) / finish_sweep(sweep_id, status)

Group trials that the assistant runs itself: start_sweep, then log_run(..., sweep_id=...) per trial, then finish_sweep returns the best one.

log_run(step, params?, metrics?, artifacts?, parent_run_id?, notes?, status?, tags?, sweep_id?, history?, record_data=True)

Record a run. Metrics must be numbers. Artifacts ≤ 50 MB are copied into .mltree/runs/<run_id>/artifacts/; bigger ones are referenced. The step's script is snapshotted with its SHA-256 and the git commit, and the versions of its inputs/outputs are recorded. history is a list of step-wise points ({"epoch": 1, "val_loss": 0.8}) for the curves.

data_status(step?)

Data versions now vs each step's latest run: which inputs changed or are missing, so the assistant knows what to re-run.

compare_runs(run_ids, code_diff=True)

Param changes, differing metrics and data versions of 2+ runs, and a unified diff of the first two runs' scripts.

list_runs(step?, status?, parent_run_id?, limit?)

Runs, newest first.

add_note(text, step? | run_id?, replace=False)

Append to (or replace) the notes of a step or a run.

tag_run(run_id, add?, remove?, tags?)

Add / remove tags on a run, or set the whole list.

gnn_summary(step?, introspect=False)

GNN architecture summary (static) and dataset stats of one step or all; introspect=true loads the step's graph files in a subprocess (off with MLTREE_ALLOW_RUN=0).

best_run(metric, mode="max"|"min", step?)

Best succeeded run by a metric.

open_map(start=True, port?, allow_run=False)

URL of the map viewer. It starts mltree-mcp view in the background if the viewer isn't running, and includes the ssh -L tip for remote servers.

Resource: mltree://pipeline — the same JSON as get_pipeline.

Errors come back as normal MCP tool errors with a message the assistant can act on (e.g. "Unknown step 'trian'. Known steps: split, train").

Project layout

your-project/
├── steps/                      # one script per node (your code)
│   ├── featurize.py
│   └── train_gcn.py
└── .mltree/
    ├── pipeline.yaml           # nodes, edges, default params — commit this
    ├── mltree.db               # SQLite: steps, edges, runs, file-hash cache
    └── runs/<run_id>/
        ├── run.json            # params, metrics, parent, status, timestamps
        ├── script.py           # snapshot of the step script for this run
        ├── log.txt             # stdout/stderr of runs started by mltree (stderr lines prefixed)
        ├── metrics.json        # $MLTREE_METRICS_FILE, if the script wrote it
        ├── metrics_history.jsonl  # one line per MLTREE_METRIC print (or log_run history point)
        └── artifacts/          # copied outputs (plots, small models…)

mltree.db is the source of truth; pipeline.yaml is rewritten on every change so it diffs well in git. If you commit only pipeline.yaml, a fresh clone rebuilds the steps and edges from it. Whether you commit mltree.db and runs/ is up to you.

Tell your assistant to use it (AGENTS.md / CLAUDE.md)

Codex reads AGENTS.md, Claude Code reads CLAUDE.md. Paste this into either:

## Experiment tracking with mltree (MCP)

This repo tracks its ML workflow with the `mltree` MCP server. Keep the map up to date as you work:

- At the start, call `get_pipeline`. If the project is not initialized and already has code, call `scan_project`
  (`dry_run=true` first to preview) and fix its proposals; for a brand-new project call `init_project`.
- Put each pipeline stage in its own script under `steps/` (e.g. `steps/split.py`, `steps/train_gcn.py`).
  Whenever you create or materially change one, call `add_step` with its name, `script_path`,
  `inputs`, `outputs`, default `params` and a one-line `description`.
- Call `connect_steps` for every data dependency (upstream → downstream).
- After every execution of a step, call `log_run` with the exact `params` used, numeric `metrics`,
  produced `artifacts` (plots, model files) and `status` ("failed" if it crashed, with the error in `notes`).
- When a run is a variation of an earlier one (HPO trial, new architecture, different split seed),
  pass that run's id as `parent_run_id` so the experiment tree branches correctly.
- Prefer `run_step` over running a step script yourself: it records the run (params, script, log, metrics) by
  itself. Make scripts print `MLTREE_METRIC name=value` lines. For a grid search use `run_sweep`. For trials you
  run yourself (Optuna), use `start_sweep`, then `log_run(..., sweep_id=...)`, then `finish_sweep`.
- Before re-running, call `data_status` to see which steps have changed inputs; to explain how two runs differ,
  call `compare_runs`.
- To answer "which model was best?" use `best_run` (mode "min" for losses/RMSE, "max" for AUC/R²)
  and `list_runs`; don't guess from memory.
- Record decisions with `add_note` (on the step or run) and label runs with `tag_run` ("baseline", "paper").
- When the user wants to see the workflow, call `open_map` and give them the URL. When they want to send it to
  someone, call `export_map` (warn them that it includes the scripts unless `include_scripts=false`).

Demo: a tiny GNN pipeline

examples/gnn_demo/ is a toy molecular-property pipeline: load SMILES → featurize to graphs → split → train a toy GCN (mean aggregation + ridge, stdlib only) → evaluate. It runs without torch; featurize.py uses RDKit if installed.

cd examples/gnn_demo
python steps/load_smiles.py && python steps/featurize.py && python steps/split.py 0.2 42 \
  && python steps/train.py 1.0 && python steps/evaluate.py

# register the steps and log a few FAKE runs (tagged "demo") to see the tree
python register_demo.py --reset
mltree-mcp view --project .            # http://localhost:8765
mltree-mcp view --project . --allow-run   # same, with Run / Grid sweep buttons (the demo needs only the stdlib)

With --allow-run, run load_smiles → featurize → split → train → evaluate from the map, then try Grid sweep… on train with alpha = 0.05, 0.2, 0.5, 1, 2 and rank by train_rmse (lower is better).

The values in data/molecules.csv and the metrics logged by register_demo.py are illustrative demo data, not real measurements.

Development

uv venv && uv pip install -e ".[dev]"
pytest -q

The tests cover:

  • the store, and every tool called in-process through the MCP server

  • the mltree://pipeline resource and the demo

  • a smoke test that launches the stdio server and talks to it with the MCP client SDK

  • every viewer API route, the SPA fallback, the live event stream and open_map

  • the runner (CLI detection, param passing, metric parsing, logs, cancel, grid sweeps, schema migration) and the run safety guard (403 without --allow-run, without X-MLTree, with a foreign Origin or Host)

  • data versions, compare/diffs, notes/tags, GNN summaries (static and introspected) and the HTML export (with a headless-Chrome render check when Playwright is installed)

  • the multi-project registry, /p/<slug>/ routing, the projects CLI and open_map against a multi-project viewer

Frontend (React + TypeScript + Vite + React Flow + Monaco + Plotly) lives in frontend/:

cd frontend && npm install
npm run dev          # http://localhost:5173, proxies /api to a running `mltree-mcp view`
npm run build        # type-checks and writes the bundle into src/mltree_mcp/static/ (commit it)

CI (.github/workflows/test.yml) runs pytest on Python 3.11–3.13 (plus macOS and the 1.x MCP SDK), checks that the committed static/ bundle matches npm run build, and builds the sdist and wheel, runs twine check and installs the wheel in a clean venv.

Screenshots: pip install -e ".[screenshots]" && playwright install chromium, start the viewer on the demo, then python scripts/screenshots.py. For the run screenshots, start it on a fresh copy of the demo with --allow-run and run python scripts/screenshots_run.py (this really runs the demo scripts); for the data-version / curves / diff screenshots run python scripts/screenshots_data.py --project <copy> the same way; for the notes / GNN screenshots start it with --allow-run --python <python with torch_geometric> and run python scripts/screenshots_gnn.py; for the project switcher and docs/demo.gif, register two copies of the demo, start view --projects and run python scripts/screenshots_projects.py (needs ffmpeg). If you have a local Chrome, use --chrome /usr/bin/google-chrome instead of installing Playwright's browser.

Roadmap

  1. MCP core ✅

  2. Map viewer ✅ (map, script panel with run snapshots, experiment tree, compare, live refresh)

  3. scan_project ✅ (static import of existing projects and their MLflow / Optuna / Lightning / wandb results)

  4. Run steps and sweeps ✅ (0.5.0: Run button, live logs, auto-recorded runs, grid sweeps, sweep fans, run_step)

  5. Data versioning and compare ✅ (0.6.0: input/output hashes per run, changed-input flags, param changes, code diff, metric curves)

  6. Notes, tags and GNN views ✅ (0.7.0: editable notes/tags, static architecture summary, opt-in dataset stats)

  7. PyPI packaging, CI, multi-project viewer ✅ (0.8.0)

Releasing

Releases go to PyPI from .github/workflows/release.yml with trusted publishing (no API token). One-time setup:

  1. On PyPI, under Your projects → Publishing → Add a new pending publisher, enter: project mltree-mcp, owner yboulaamane, repository mltree-mcp, workflow release.yml, environment pypi. (Optional: the same on TestPyPI with environment testpypi.)

  2. On GitHub, Settings → Environments: create pypi (and testpypi); adding yourself as a required reviewer makes every upload wait for your click.

To release: bump version in pyproject.toml, src/mltree_mcp/__init__.py and frontend/package.json, rebuild the frontend, commit, then publish a GitHub release with tag vX.Y.Z (gh release create v0.8.0 --generate-notes). The workflow checks the tag matches the version, builds, runs twine check and uploads. Actions → release → Run workflow uploads to TestPyPI instead. Locally: python -m build && twine check --strict dist/*.

Changelog

0.8.0

  • Multi-project viewer: mltree-mcp view --projects DIR ... or a registry (~/.mltree/projects.json, managed with mltree-mcp projects add|list|remove); each project under /p/<slug>/, a project switcher in the header, GET /api/projects; open_map links into a running multi-project viewer.

  • PyPI-ready packaging: classifiers, project URLs, py.typed, a lean sdist; the wheel ships the viewer and export bundles. python -m build + twine check --strict pass.

  • CI: GitHub Actions test matrix (3.11–3.13, macOS, MCP SDK 1.x), frontend bundle freshness check, wheel smoke test; release workflow with PyPI trusted publishing.

  • README: demo GIF, badges, refreshed screenshots.

0.7.0

  • Notes on steps and runs and tags on runs, editable in the viewer (loopback + X-MLTree only), shown on nodes, tree cards and the runs table, with a Tag filter in the experiment tree; MCP tools add_note, tag_run; get_pipeline returns notes and tags; both are in the export.

  • GNN views: static nn.Module architecture summary for PyG / DGL models (layers, dims, repeats, pooling, forward order) and opt-in dataset / checkpoint stats loaded in a subprocess; MCP tool gnn_summary, CLI mltree-mcp gnn, GET /api/steps/{step}/gnn, POST …/gnn/introspect. The demo gets a PyG MolGCN model file.

  • Store schema v4 (step notes, gnn_stats cache).

0.6.0

  • Data versions: inputs/outputs are fingerprinted (SHA-256, cached by size + mtime) and recorded with each run; the step panel, the node badge (⚠ data changed / input missing), Compare and the export show them.

  • Compare: param changes per run, a data-versions row group, overlaid step-wise curves (SVG, works offline) and a unified / side-by-side code diff of the script snapshots (computed in the browser, works in the export).

  • MCP tools data_status and compare_runs; log_run(history=, record_data=); GET /api/data.

  • Store schema v3 (run data, file_hashes cache); older databases migrate on open.

  • The viewer runs file hashing off the event loop, so live updates keep flowing on big data folders.

0.5.0

  • Run steps from the map (view --allow-run): Run dialog with prefilled params and a command preview, live stdout/stderr panel (SSE), Cancel, and automatic run records (params, snapshot, command, exit code, duration, log, metrics from MLTREE_METRIC lines or $MLTREE_METRICS_FILE, step-wise history).

  • Grid sweeps: sweep runs that group their children, a sweep launcher in the viewer, collapsible sweep fans with the best child highlighted in the tree, and sweep cards in the HTML export.

  • MCP tools run_step, run_sweep, run_log, cancel_run, start_sweep, finish_sweep, and log_run(sweep_id=).

  • scan_project imports Optuna studies and GridSearchCV cv_results_ CSVs as sweeps.

  • Store schema v2 (run kind, sweep_id, sweep, command, exit_code); v1 databases migrate on open.

  • Export: commands are made portable (interpreter basename, project-relative paths).

0.4.0 shareable single-file HTML export · 0.3.0 scan_project · 0.2.0 map viewer · 0.1.0 MCP core

License

MIT © Yassir Boulaamane

Available Tools

21 tools
add_noteA

Add a note to a step or a run, e.g. why a run failed, what a step assumes, or a conclusion from a comparison. Notes show in the viewer (where the user can edit them), in get_pipeline / list_runs and in the HTML export.

NameRequiredDescriptionDefault
stepNoNote on this step (give step OR run_id)
textYesThe note, plain text (markdown is fine); appended as a new paragraph
run_idNoNote on this run (give step OR run_id)
replaceNoReplace the existing notes instead of appending

Output Schema

NameRequiredDescription

No output parameters

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the load, and it does disclose meaningful behavior: notes surface in the viewer, are user-editable, and appear in get_pipeline, list_runs, and the HTML export. It doesn't cover permissions or whether the note is returned, which keeps it from a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, no filler; the core action comes first and the visibility/consumers detail follows as supporting context. Every clause contributes information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be explained, and the description covers purpose, use cases, and downstream visibility. What's missing is minor but real: no note on permissions or limits, and no mention of what happens when both step and run_id are omitted.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and every parameter (step, run_id, text, replace) is documented in-schema, so the schema already does the heavy lifting. The description's 'to a step or a run' only echoes the schema's own 'give step OR run_id' guidance, adding no new syntax or format details.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Uses a specific verb (add) plus resource (note) and states the two attachment targets (step or run), so the agent can distinguish it from siblings such as tag_run or log_run with no schema inspection.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The examples 'why a run failed, what a step assumes, or a conclusion from a comparison' give concrete situations that call for this tool, which is stronger than generic context. It stops short of naming alternatives or exclusions, so it stays at 4 rather than 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

add_stepB

Register a pipeline step (a node on the map), or update it if the name already exists.

NameRequiredDescriptionDefault
nameYesUnique step name, e.g. 'load_smiles', 'split', 'train_gcn'
inputsNoData this step consumes, e.g. ['graphs.pkl']
paramsNoDefault parameters, e.g. {'test_size': 0.2, 'seed': 42}
outputsNoData this step produces, e.g. ['train.pkl', 'test.pkl']
descriptionNoOne-line description of what the step does
script_pathNoPath of the step's Python script, relative to the project root

Output Schema

NameRequiredDescription

No output parameters

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full behavioral burden. It usefully discloses that an existing name is updated rather than rejected, but is silent on what an update replaces (are stale inputs/outputs/params discarded or merged?) and on whether the step is persisted immediately.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with zero filler; the upsert caveat is placed where it will be read.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With a rich six-parameter schema and an output schema present, the description need only cover intent and side effects. Intent and upsert semantics are covered; the only real gap is the precise overwrite/merge semantics of the update path.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and every parameter carries a concrete example, so the schema does the heavy lifting. The description adds no extra meaning about parameter interaction, such as whether outputs must match a downstream step's inputs.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Register a pipeline step') plus the domain framing ('a node on the map'). It also discloses the upsert behavior, which distinguishes it from a pure create. It doesn't explicitly contrast with sibling connect_steps, but the resource distinction is inferable.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no statement of when to call this versus connect_steps, get_pipeline, or init_project, and no prerequisites (e.g., must a project exist first?). The only guidance is implicit in the upsert clause.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

best_runB

Find the best succeeded run by a metric.

NameRequiredDescriptionDefault
modeNo'min' for losses/errors, 'max' for scoresmax
stepNoRestrict to one step
metricYesMetric name, e.g. 'val_rmse' or 'roc_auc'

Output Schema

NameRequiredDescription

No output parameters

TDQS

B3.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the burden of behavioral disclosure. It does disclose that only succeeded runs are considered and that selection is metric-based, but it omits tie-breaking behavior, permission requirements, and whether 'succeeded' has any special semantics.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single front-loaded sentence with no wasted words. It is appropriately brief for a tool whose schema and output schema carry most of the structural detail, though it could provide slightly more framing around the key qualifier 'best'.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is simple, with full schema coverage and an output schema, so the description does not need to explain parameters or return values. However, with no annotations, it remains incomplete on behavioral details such as tie handling and permission expectations.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so metric, mode, and step are already well documented. The description mentions the metric concept but adds no syntax or usage detail beyond what the schema provides, making the baseline 3 appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: find the best succeeded run by a metric. It is understandable without opening the schema, but it does not differentiate itself from list_runs or explain what 'best' means, so it falls short of full sibling-level clarity.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no explicit guidance on when to use this tool versus list_runs or other siblings. The phrase 'Find the best succeeded run' implies the use case, but no alternatives, prerequisites, or exclusions are mentioned.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

cancel_runB

Stop a run (SIGTERM, then SIGKILL after 5 s) or a whole sweep started from this session.

NameRequiredDescriptionDefault
run_idYesRun or sweep id started by run_step / run_sweep

Output Schema

NameRequiredDescription

No output parameters

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full behavioral burden, and it does add real value by disclosing the termination mechanism (SIGTERM, escalating to SIGKILL after 5 s), signalling a forced, likely non-graceful termination. It omits other important traits: whether cancellation is reversible, what happens to partial results or checkpoints, and whether cancelling a sweep cascades to its child runs.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single compact sentence with the core action and the key mechanic (SIGTERM/SIGKILL timing) front-loaded, and no filler. The parenthetical is dense but every clause earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be explained, which lowers the bar. Still, for a destructive, annotation-free operation on runs and sweeps, the description should say what happens to in-flight work and whether sweep cancellation propagates to child runs; those gaps matter for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the run_id description already states it accepts a sweep id as well as a run id, so the description adds little parameter-level detail. Its mention of 'a whole sweep' echoes rather than extends the schema, which is consistent with the baseline 3 for fully-covered single-parameter tools.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (stop) and resource (run or sweep) with an added scope qualifier ('started from this session') that separates it from other run-level tools. It does not explicitly name which siblings it supersedes or differs from, so identification relies on the reader inferring against run_step/run_sweep/start_sweep.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'started from this session' implies a precondition for use, and 'or a whole sweep' hints at the sweep-cancellation case. However, there is no explicit when-to-use vs when-not-to-use guidance and no alternative tool is named for cases where the run was not started in this session.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

compare_runsA

Compare runs: params that differ (baseline -> each run), metrics side by side, data versions used, and a unified diff of the script snapshots of the first two runs.

NameRequiredDescriptionDefault
run_idsYesTwo or more run ids; the first is the baseline
code_diffNoInclude a unified diff of the first two runs' script snapshots

Output Schema

NameRequiredDescription

No output parameters

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full disclosure burden, and it does surface meaningful behavior: the four categories of comparison output and the non-obvious constraint that the script diff only covers the first two runs. It stops short of stating that this is a read-only/non-mutating operation or any limits on run count or cost.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single sentence, front-loaded with the verb, then a tight enumeration of outputs. No filler, no restatement of the title, and every clause carries information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists and parameters are fully documented, so the description needn't explain return shapes; what it adds is the right shape of summary for a read-only comparison tool. Minor gaps remain around minimum run count enforcement and error behavior with a single run id.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so run_ids and code_diff are already fully documented, including the baseline rule and the first-two-runs diff scope. The description restates rather than extends that semantics, which is the defined baseline of 3.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ("Compare runs") and enumerates exactly what the comparison yields: differing params, metrics, data versions, and a script diff. It is clearly distinct from list_runs, best_run, and run_log. It loses a point only because it never names a sibling to contrast against explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied rather than stated: "params that differ (baseline -> each run)" signals that you supply multiple run ids with the first as baseline, which tells an agent when the tool fits. There is no explicit when-to-use, when-not-to-use, or alternative such as best_run for picking a winner instead of comparing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

connect_stepsA

Draw a directed edge source -> target. Both steps must exist; cycles are rejected.

NameRequiredDescriptionDefault
labelNoOptional edge label, e.g. the data passed along
sourceYesUpstream step name
targetYesDownstream step name

Output Schema

NameRequiredDescription

No output parameters

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It usefully discloses two key constraints (existence prerequisite and cycle rejection), but omits what happens on failure, whether the edge is idempotent, or whether it mutates persisted graph state.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two compact sentences with the operation first and the constraints immediately after; every clause carries information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists so return values need no explanation, and the essential preconditions are stated. Only the failure/error behavior of the cycle or missing-step cases is left unstated.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so source/target direction and the optional label are already documented in the schema. The description's ordering implicitly reinforces direction but adds no syntax or format detail beyond the structured fields.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a concrete verb (draw a directed edge) with explicit source -> target roles, which cleanly separates it from node-creating siblings like add_step. It doesn't name a sibling directly, but the semantics are unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Preconditions ("both steps must exist; cycles are rejected") imply when the call will succeed, but there is no explicit guidance on when to use this vs. alternatives like add_step or log_run, and no mention of what to do on rejection.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

data_statusA

Data versions: the current SHA-256 of every step's input and output files, what the step's latest run used, and which inputs changed since (so the step is stale and should be re-run). Reads files only; runs nothing.

NameRequiredDescriptionDefault
stepNoOnly this step (default: all)

Output Schema

NameRequiredDescription

No output parameters

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the load and does it: it declares the read-only contract ('Reads files only; runs nothing') and explains the comparison logic against the latest run, which is the key behavioral trait. It omits cost/latency considerations for hashing large file sets.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The core output (hashes, latest-run comparison, staleness) is front-loaded, and the trailing 'Reads files only; runs nothing' earns its place as a safety signal. The parenthetical is slightly dense but no sentence is wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be spelled out, and the description still covers read-only behavior, scope, and the staleness interpretation. Nothing an agent needs in order to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The single `step` parameter is fully documented in the schema ('Only this step (default: all)'), and the description's 'every step's input and output files' corroborates the all-steps default. That is baseline-level value, no additional semantics about step identifiers or scoping.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States the concrete resource precisely: SHA-256 hashes of each step's input/output files, the hashes the latest run used, and which inputs changed since. That is a specific, unambiguous verb+resource pair an agent can distinguish from siblings like list_runs or run_log, though no sibling is named explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Implies the decision it supports -- 'which inputs changed since (so the step is stale and should be re-run)' -- giving the agent a clear trigger for calling it before re-running or sweeping. It also closes off misuse with 'reads files only; runs nothing', though it never names run_step or list_runs as the alternative actions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

export_mapA

Write a single self-contained HTML file of the map (steps, code, runs, experiment tree, compare).

It opens offline in any browser, read-only, with no server, so the user can email it, post it in Slack or host it on GitHub Pages / a gist. Returns the file path and size. It contains the scripts unless include_scripts=false: tell the user that before they share it.

NameRequiredDescriptionDefault
pathNoOutput file or folder (relative to the project root). Default: <project root>/<project>-mltree.html
include_scriptsNoEmbed the step scripts and their run snapshots

Output Schema

NameRequiredDescription

No output parameters

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does well: it discloses the output is self-contained, read-only, offline, requires no server, and returns file path and size. It flags that scripts are embedded by default and that the user must be warned before sharing – a genuine safety trait. It omits what happens to an existing file at `path` (overwrite/failure), which keeps it from a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The core action and the contents list are front-loaded in the first sentence, and the sharing caveat is separated so it reads as a distinct instruction. The parenthetical content list and the stray line breaks add slight clutter but no wasted sentences.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be spelled out, yet the description still notes path and size. All parameters are documented, the behavioral scope is covered, and the share-safety caveat is included – nothing an agent needs to call this correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so baseline is 3, but the description adds real meaning beyond the schema: it explains the consequence of `include_scripts=false` (scripts omitted, and the sharing warning no longer applies). It does not add anything about `path` semantics, which the schema already covers with its default.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and artifact: 'Write a single self-contained HTML file of the map', and enumerates its contents (steps, code, runs, experiment tree, compare). It does not distinguish itself from the sibling open_map, which an agent could easily confuse it with, so it falls short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives clear situational context: the file opens offline with no server so the user can email it, post it in Slack, or host it on GitHub Pages/gist. This tells the agent when the tool is appropriate, but there is no explicit exclusion or pointer to open_map as the interactive alternative.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

finish_sweepB

Mark a sweep finished and return its summary (trial counts and the best trial).

NameRequiredDescriptionDefault
statusNoOutcome of the sweepsucceeded
sweep_idYesId returned by start_sweep

Output Schema

NameRequiredDescription

No output parameters

TDQS

B3.3/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description must carry the full behavioral burden for this mutation operation. It states that the sweep is marked finished and that a summary is returned, but it does not disclose important details like idempotency, required permissions, effects on in-flight trials, or error conditions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single focused sentence with no wasted words. It front-loads the action and then mentions the return summary, which is appropriately sized for this simple tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool has an output schema, so the description does not need to explain return formatting in detail. However, with no annotations and only implicit usage guidance, the definition is somewhat thin for a mutation operation whose status parameter has behavioral implications.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the parameters are already well documented by the schema. The description adds no parameter-level detail beyond what the schema provides, which is acceptable at the baseline for high coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific verb and resource: 'Mark a sweep finished'. It also clarifies that the tool returns a summary with trial counts and the best trial. It does not explicitly compare itself to siblings like start_sweep or best_run, but its purpose is unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The usage is implied by 'finished', meaning this should be called when a sweep is complete. However, there is no explicit guidance on when to choose finish_sweep versus alternatives such as cancel_run, or how to pick the status value.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_pipelineB

Return the whole map: nodes (with params, script and latest run status), edges and a topological order.

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription

No output parameters

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations exist, so the description carries the burden; it does establish that this is a retrieval ("Return") with no arguments and tells the agent the data includes run status, which signals freshness comes along with the map. It says nothing about cost, size, permissions, or whether the call has side effects, which matters for a zero-param call whose name does not itself imply read-only semantics.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One sentence, front-loaded with the object returned, then the enumerated contents. No filler and nothing buried.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no parameters and an output schema present, the description needn't document return values, and the shape of the payload is briefly characterized. But with zero annotations and several plausible sibling tools that also surface map data, the definition leaves the agent without routing criteria or any note on cost/freshness.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so there is nothing to disambiguate and the baseline is 4. The description correctly implies no scoping inputs are needed to fetch the whole map.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a clear verb ("Return") and specific resource ("the whole map"), then enumerates the payload: nodes with params, script and latest run status, edges, and a topological order. An agent knows exactly what it gets. It falls short of a 5 because it never distinguishes itself from siblings like open_map or export_map, which plausibly return the same map.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance on when to call this versus open_map, export_map, or list_runs. The word "whole" faintly implies a full fetch rather than a partial one, but no explicit condition or alternative is named.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

gnn_summaryA

GNN view of a step: the model architecture read statically from its script and imported project modules (conv layer types and counts, hidden sizes, heads, pooling, head, forward order; nothing is imported or run), dataset classes it constructs (TUDataset, MoleculeNet, QM9, OGB, DGL ...), and cached dataset stats (graphs, nodes/edges per graph, feature dims, classes or target range, self loops, isolated nodes).

NameRequiredDescriptionDefault
stepNoOne step in full (default: every step with GNN models or graph data)
introspectNoAlso load the step's .pt/.bin graph files to compute dataset stats. Only when the user asked for it: it runs torch.load / dgl.load_graphs in a subprocess with the project's Python, and unpickling can execute code

Output Schema

NameRequiredDescription

No output parameters

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description excels here by contrasting two behavioral states: the default state where models are read 'statically... nothing is imported or run' versus the `introspect` state, which explicitly states that loading files 'can execute code.' This is critical behavioral context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense and highly technical, serving as a comprehensive single block of text. While efficient, its structure is very complex, typical of GNN tooling.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given that an output schema exists, the description does not need to explain return values. It comprehensively defines the inputs, the scope of the summary, and the behavioral risks, making it a complete definition.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Even with 100% schema coverage, the description adds massive value, especially for the `introspect` parameter, by detailing the dangerous subprocess actions (torch.load, unpickling) that occur when that flag is set.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description precisely defines the scope of the tool as a 'GNN view of a step,' detailing exactly what information is extracted (model architecture, dataset classes, cached stats). This highly specific definition clearly separates it from other general step management tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

While it doesn't start with a high-level 'when to use' statement, it defines its utility by listing the specific GNN data it provides. The strong warning within the `introspect` parameter provides crucial usage guidance regarding potential execution risks.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

init_projectA

Create the .mltree/ store (pipeline.yaml, mltree.db, runs/) in the project root. Safe to call again.

NameRequiredDescriptionDefault
nameNoProject name; defaults to the folder name

Output Schema

NameRequiredDescription

No output parameters

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations at all, the description carries the full behavioral burden, and it does disclose the key risk trait: idempotency ('safe to call again'). It leaves open what happens to pre-existing files (overwrite vs preserve), whether permissions are required, and whether the call is slow — gaps that matter for an initialization/mutation tool with zero annotation coverage.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences, zero filler, with the concrete side effects front-loaded before the idempotency note. Every clause earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Output schema exists and annotations are absent but the tool is simple (one optional param), so the description covers nearly everything needed: what is created, where, and that re-invocation is safe. Only the overwrite/permission behavior on existing stores is unaddressed.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the single optional 'name' parameter is fully documented in the schema ('defaults to the folder name'). The description adds no parameter-level detail, so the schema baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (Create) and resource (.mltree/ store) and enumerates the artifacts produced (pipeline.yaml, mltree.db, runs/), so the agent knows exactly what will exist afterward. It does not distinguish itself from siblings such as scan_project, but no sibling plausibly competes for the same action.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied: creating the store is obviously a prerequisite step, but the description never says when to call it, when not to, or how it relates to scan_project. 'Safe to call again' informs repeated invocation but is not selection guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_runsB

List runs, newest first.

NameRequiredDescriptionDefault
stepNoOnly runs of this step
limitNoMaximum runs to return (1-1000)
statusNoOnly runs with this status
parent_run_idNoOnly direct children of this run

Output Schema

NameRequiredDescription

No output parameters

TDQS

B3.1/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full behavioral burden. It discloses that results are ordered newest first, but does not state that the operation is read-only, whether it has side effects, or how pagination behaves beyond the schema's limit parameter.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single front-loaded sentence with zero waste. Every word contributes directly to the operation and its ordering behavior.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The schema fully documents all parameters and an output schema exists, so the description needn't explain return values or parameter details. However, with no annotations and no usage guidance, the description leaves important behavioral and selection context unstated.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all four parameters are already documented in the schema. The description adds no parameter-specific meaning beyond the ordering note, making the baseline score of 3 appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a clear verb and resource ('List runs') plus an ordering behavior ('newest first'), so an agent can understand the core operation. It does not explicitly differentiate itself from sibling tools such as best_run or log_run, though those appear to be distinct operations.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance on when to use this tool versus alternatives, nor any exclusions or prerequisites. The agent must infer usage entirely from the tool name and schema.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

log_runB

Record one execution of a step: params, metrics, artifacts and its parent run in the experiment tree. The versions (SHA-256) of the step's input and output files are recorded too, so later runs can tell when the data changed.

NameRequiredDescriptionDefault
stepYesName of the step that was executed
tagsNoOptional tags, e.g. ['hpo', 'gcn']
notesNoFree-text notes about the run
paramsNoParameters actually used for this run
statusNoRun outcomesucceeded
historyNoStep-wise metrics for curves, e.g. [{'epoch': 1, 'train_loss': 0.9, 'val_rmse': 1.1}, ...]
metricsNoNumeric results, e.g. {'val_rmse': 0.61, 'r2': 0.78}
sweep_idNoSweep this run is a trial of (from start_sweep)
artifactsNoFiles produced (paths relative to project), as a list or {name: path}; copied into .mltree/runs/<run_id>/ when <= 50 MB
record_dataNoFingerprint the step's input/output files now (data versions). False for results from elsewhere
parent_run_idNoRun this one branches from (e.g. the base config of an HPO trial)

Output Schema

NameRequiredDescription

No output parameters

TDQS

B3.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full behavioral burden. It adds useful context that SHA-256 versions of input/output files are recorded so later runs can detect data changes, but it does not state that this is a write/mutation operation, nor does it cover permissions, duplicate handling, or error behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with the core action and followed by one sentence of useful behavioral context about data versioning. No filler and no repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be explained, and full schema coverage documents the parameters. But with 11 parameters and no annotations, the description should still clarify write semantics and distinguish this tool from run_step and run_log; those gaps keep it from being complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all 11 parameters are already documented in the schema. The description restates some of the same fields (params, metrics, artifacts, parent run) without adding syntax, format, or edge-case semantics beyond what the schema provides, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: 'Record one execution of a step', and enumerates what is captured (params, metrics, artifacts, parent run). However, it gives no differentiation from similarly named siblings such as run_step, run_log, and list_runs, so an agent cannot tell from the description alone which tool to pick.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no explicit when-to-use or when-not-to-use guidance, and no mention of alternatives like run_step or run_log. Usage is only weakly implied by 'Record one execution of a step', leaving the agent to infer routing from the name alone.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

open_mapA

Return the URL of the mltree map viewer (and start it if needed). Give the URL to the user.

NameRequiredDescriptionDefault
portNoViewer port (default $MLTREE_VIEW_PORT or 8765)
startNoStart the viewer in the background if it is not running
allow_runNoStart it with Run buttons enabled (only if the user asked to run steps from the map)

Output Schema

NameRequiredDescription

No output parameters

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the burden, and it does disclose the key side effect: the viewer may be started in the background. It says nothing about process lifetime, what happens if the port is occupied, or the security implication of enabling Run buttons, so meaningful gaps remain.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences, zero filler, with the action and its conditional side effect front-loaded ahead of the delivery instruction.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so the return value (a URL) needn't be explained, and the description covers the conditional start behavior. Minor gaps remain around failure modes and whether the started viewer persists, but nothing essential to invoking it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% – port defaults, the start flag, and the allow_run condition are all documented in the schema itself. The description adds no parameter meaning beyond that, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a concrete verb and resource: return the URL of the mltree map viewer, and start it if needed. It is clearly distinguishable from siblings like export_map or get_pipeline, though it never names an alternative to contrast with.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

'Give the URL to the user' is a delivery instruction, not a selection rule. There is no statement of when to prefer this over export_map or get_pipeline, and no exclusions; usage context is only implied.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

run_logA

Return the status and the last lines of a run's log (live while it runs).

NameRequiredDescriptionDefault
tailNoLast N lines
run_idYesRun id

Output Schema

NameRequiredDescription

No output parameters

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the behavioral burden. It does disclose that output is live during execution and includes status alongside log tail, but it omits details like permissions, truncation behavior, or handling of finished/failed runs. Given the presence of an output schema, the return format gap is mitigated, making a 3 appropriate.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single, efficient sentence that front-loads the action and resource. The parenthetical adds a useful nuance without bloat, though there is minimal structure beyond that one sentence.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple two-parameter read tool with a fully described schema and an output schema, the description covers the essentials: what it returns and when it is live. Missing details (e.g., behavior on completed runs) are minor given the structured coverage.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so both parameters (run_id and tail) are already documented in the schema. The description adds no extra meaning about the tail parameter's behavior or run_id format, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Return') and resource ('status and the last lines of a run's log'), making the tool's function immediately clear. It does not explicitly differentiate itself from siblings like log_run or list_runs, which keeps it just short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The parenthetical '(live while it runs)' hints that the tool can be polled during an active run, which is useful implied guidance. However, there is no explicit when-to-use vs. when-not-to-use guidance or reference to alternatives such as log_run, leaving usage to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

run_stepA

Execute a step's script as a subprocess and record it as a run automatically.

Params are passed as CLI flags when the script uses argparse/click (or positionally for sys.argv scripts, or key=value for hydra), and always as $MLTREE_PARAMS (JSON). Records params, script snapshot, command, exit status, duration, log (.mltree/runs//log.txt) and metrics from MLTREE_METRIC name=value stdout lines or a JSON file written to $MLTREE_METRICS_FILE / a declared metrics*.json output. Returns the run and the end of its log.

NameRequiredDescriptionDefault
stepYesStep to execute (its script_path is run with Python from the project root)
waitNoWait for the run to finish (up to timeout_s)
paramsNoParams for this run; default: the last run's params, else the step's
timeout_sNoMax seconds to wait; the run keeps going after that
extra_argsNoExtra command-line arguments appended verbatim
parent_run_idNoRun this one branches from (default: newest succeeded run of an upstream step)

Output Schema

NameRequiredDescription

No output parameters

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full load and does well: it discloses that arbitrary script code is executed as a subprocess, that params are injected three different ways plus $MLTREE_PARAMS, and exactly what gets persisted (params, script snapshot, command, exit status, duration, log path, metrics). It does not state whether a run record is still written when the script fails or whether execution mutates project state beyond recording, which keeps it from a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The core action is front-loaded in sentence one, and the following clauses are dense but information-bearing rather than filler. The long parenthetical enumerating param-passing styles is slightly cramped reading but not wasteful.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 6-param mutating execution tool with no annotations, the description covers the mechanism, the side effects recorded, the log and metrics conventions, and even summarizes the return value (the run plus the tail of its log) despite an output schema existing. An agent has enough to call it correctly without opening anything else.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description genuinely adds semantics the schema lacks: it explains how `params` is transformed per script framework (argparse/click flags, positional sys.argv, hydra key=value, always $MLTREE_PARAMS JSON) and how metrics are detected from stdout or $MLTREE_METRICS_FILE. The remaining params (wait, timeout_s, extra_args, parent_run_id) are already well documented in the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening sentence gives a specific verb and resource: 'Execute a step's script as a subprocess and record it as a run automatically.' An agent knows exactly what happens (subprocess execution plus automatic run recording). It does not, however, explicitly contrast itself with nearby siblings like run_sweep or cancel_run, so it falls short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied by the mechanics described (params get passed as CLI flags, which presupposes a script that accepts arguments), but the description never states when to choose run_step over run_sweep, or what preconditions exist (step must exist, project must be initialized). No exclusions or alternatives are named.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

run_sweepB

Run a grid search: one sweep run plus one child run per combination, executed one after another.

NameRequiredDescriptionDefault
gridYesParam -> list of values, e.g. {'alpha': [0.1, 1, 10], 'layers': [1, 2]}
modeNoWhether lower or higher metric is bettermax
stepYesStep to execute for every combination
waitNoWait for the whole sweep (up to timeout_s)
metricNoMetric that ranks the runs, e.g. 'val_rmse'
paramsNoFixed params shared by all runs
max_runsNoRefuse grids larger than this
timeout_sNoMax seconds to wait
extra_argsNoExtra command-line arguments for every run

Output Schema

NameRequiredDescription

No output parameters

TDQS

B3.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden of behavioral disclosure. It usefully states that execution creates one sweep run plus child runs and runs combinations one after another, but it does not disclose permissions, failure behavior, blocking semantics, or side effects.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single front-loaded sentence with no wasted words. It communicates the core action and execution model efficiently.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool has nine parameters, a nested grid object, and an output schema, so the description is only moderately complete. It explains the run structure but omits operational details such as blocking behavior, failure handling, and how the sweep relates to start_sweep/finish_sweep.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all nine parameters, including grid, mode, step, wait, metric, and max_runs. The description adds the notion that each combination produces a child run, but it otherwise does not add meaning beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource ('Run a grid search') and explains the resulting run structure: one sweep run plus one child run per combination, executed sequentially. This is clear, but it does not distinguish the tool from sibling tools such as start_sweep, run_step, or finish_sweep.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description contains no explicit guidance about when to use this tool instead of start_sweep, run_step, or other sibling tools. The name and short description imply a grid-search use case, but there are no stated exclusions, prerequisites, or alternative-selection rules.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

scan_projectA

Build the map of an EXISTING project by static analysis (ast only; user code is never executed).

Detects data reads/writes, argparse/click params, local imports, docstrings and step kinds, links steps whose output paths match other steps' inputs (falling back to file numbering and imports), and imports existing results as runs tagged 'imported'. Idempotent: re-scans update scanner-owned fields, add new steps, never delete, and keep edits made with add_step. Review the returned summary and fix it with connect_steps / add_step.

NameRequiredDescriptionDefault
pathNoFolder to scan, relative to the project root.
dry_runNoReturn the proposed map without writing anything
excludeNoGlob patterns to skip (default: venvs, .git, tests, __pycache__, .mltree, build dirs)
includeNoGlob patterns to scan (default **/*.py, **/*.ipynb)
import_resultsNoImport existing metrics/MLflow/Optuna/Lightning/wandb results as runs
notebook_sectionsNoMake each markdown-headed notebook section a step

Output Schema

NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does so: it discloses the safety profile (AST only, user code never executed), mutation semantics (re-scans update scanner-owned fields, add steps, never delete), edit preservation (keeps changes made with add_step), and side effects (imports results as runs tagged 'imported').

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core purpose and no filler; each subsequent sentence covers detection scope, idempotency, and next steps. The middle sentence is a dense run-on list that could be split for faster scanning.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

All six parameters are documented in the schema, an output schema exists so return details needn't be restated, and the description still covers safety, idempotency, and correction workflow. Nothing an agent needs to invoke it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so parameters are already documented; the description nevertheless adds meaning the schema lacks, notably what import_results produces (runs tagged 'imported'). It does not explain include/exclude interaction or default traversal cost, keeping it below schema-plus-extra depth.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb+resource ('Build the map of an EXISTING project') and immediately scopes the mechanism ('by static analysis (ast only; user code is never executed)'). The capitalized EXISTING implicitly separates it from init_project, and the enumerated detections (data reads/writes, CLI params, imports, step kinds) make the output concrete.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Clearly positions the tool in the workflow: run it, then 'fix it with connect_steps / add_step', and explains the idempotent re-scan case. It never explicitly says when NOT to use it (e.g., a brand-new project should use init_project), so exclusions stop short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

start_sweepA

Create a sweep (an HPO study / grid search) that groups trial runs. Pass its sweep_id to log_run for each trial; the map shows the sweep as one collapsible fan with the best trial highlighted. Use run_sweep instead to have mltree launch a grid itself.

NameRequiredDescriptionDefault
modeNoWhether lower or higher metric is bettermax
nameNoShort label, e.g. 'alpha x layers grid'
stepYesStep the trials run, e.g. 'train'
metricNoMetric that ranks the trials, e.g. 'val_rmse'
search_spaceNoOptional search space, e.g. {'alpha': [0.1, 1, 10]}
parent_run_idNoRun the sweep branches from (e.g. the baseline)

Output Schema

NameRequiredDescription

No output parameters

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the burden and does disclose meaningful behavior: it creates a grouping that persists, its id must be threaded into subsequent log_run calls, and the map renders the group as a collapsible fan with the best trial highlighted. It does not say whether creation mutates/commits project state or what happens on a duplicate/invalid step, so it stops short of full disclosure.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tight sentences: what it creates, how to consume its output, and the sibling alternative. The parenthetical 'an HPO study / grid search' is a worthwhile disambiguation rather than filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists so return values need not be explained, and the description covers the creation semantics, the id hand-off, and the routing decision. It leaves open what happens if metric is omitted (no best-trial ranking) and whether the sweep must be closed with finish_sweep, both of which an agent would benefit from knowing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and each parameter carries its own description (mode, name, step, metric, search_space, parent_run_id), so the schema does the parameter work. The description adds no syntax or semantics for any of the six parameters beyond referencing the returned sweep_id, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Create a sweep') and immediately glosses it as 'an HPO study / grid search that groups trial runs', which makes the concept unambiguous. It also distinguishes the tool from its closest sibling by describing what log_run and run_sweep do relative to it.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit usage protocol ('Pass its sweep_id to log_run for each trial') and an explicit alternative with the condition that selects it ('Use run_sweep instead to have mltree launch a grid itself'). An agent knows both the follow-up step and when to pick the other tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

tag_runA

Add or remove tags on a run (e.g. 'baseline', 'best', 'final'). The tree can highlight runs by tag.

NameRequiredDescriptionDefault
addNoTags to add, e.g. ['best', 'paper-fig-3']
removeNoTags to remove
run_idYesThe run to tag

Output Schema

NameRequiredDescription

No output parameters

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the burden. It discloses the mutation intent and a real side effect (tags drive tree highlighting), which is genuine context, but it omits idempotency, behavior on duplicate/absent tags, and permission requirements.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences, front-loaded with the core action and followed by the observable effect. Nothing wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be explained. Still, for a mutation with zero annotation coverage, the description leaves open whether add/remove are exclusive, how existing tags are preserved, and what errors to expect.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so each parameter is already documented in the schema. The description adds only naming-convention examples for tag values, which is a modest increment over what the schema states.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Specific verb pair ('Add or remove') plus resource ('tags on a run'), with concrete tag examples. It is implicitly distinct from siblings like add_note or log_run, though it never names an alternative to bound the scope.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The example tags ('baseline', 'best', 'final') imply the intended use case, and the second sentence hints at why tagging matters (tree highlighting). There is no explicit when-to-use, no exclusion of alternatives, and no statement about whether add and remove can be combined in one call.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 13 tool updatesv0.8.0
    • Addedadd_note
    • Addedcancel_run
    • Addedcompare_runs
    • Addeddata_status
    • Addedfinish_sweep
    • Addedgnn_summary
    • Changedlog_run3 fields changed
      • addedInput schema / properties / history
        Added value: +{
        +  "anyOf": [
        +    {
        +      "items": {
        +        "additionalProperties": {
        +          "type": "number"
        +        },
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Step-wise metrics for curves, e.g. [{'epoch': 1, 'train_loss': 0.9, 'val_rmse': 1.1}, ...]",
        +  "title": "History"
        +}
      • addedInput schema / properties / record_data
        Added value: +{
        +  "default": true,
        +  "description": "Fingerprint the step's input/output files now (data versions). False for results from elsewhere",
        +  "title": "Record Data",
        +  "type": "boolean"
        +}
      • addedInput schema / properties / sweep_id
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Sweep this run is a trial of (from start_sweep)",
        +  "title": "Sweep Id"
        +}
    • Changedopen_map1 field changed
      • addedInput schema / properties / allow_run
        Added value: +{
        +  "default": false,
        +  "description": "Start it with Run buttons enabled (only if the user asked to run steps from the map)",
        +  "title": "Allow Run",
        +  "type": "boolean"
        +}
    • Addedrun_log
    • Addedrun_step
    • Addedrun_sweep
    • Addedstart_sweep
    • Addedtag_run
  2. 10 tool updatesv0.4.0
    • First observedadd_step
    • First observedbest_run
    • First observedconnect_steps
    • First observedexport_map
    • First observedget_pipeline
    • First observedinit_project
    • First observedlist_runs
    • First observedlog_run
    • First observedopen_map
    • First observedscan_project

TDQS

A3.5/5.0

Scored across 21 tools

Disambiguation4/5

Most tools target a distinct resource+action: steps (add_step, connect_steps, scan_project), runs (log_run, run_step, list_runs, best_run, run_log, cancel_run), sweeps (start_sweep, finish_sweep, run_sweep), and outputs (get_pipeline, open_map, export_map). The closest overlaps are start_sweep vs run_sweep (explicitly cross-referenced in the descriptions) and add_step vs scan_project (manual upsert vs static analysis), both of which are clarified in text. gnn_summary is a narrowly scoped inspection tool that stands clearly apart.

Naming Consistency4/5

Nearly all names are snake_case verb_noun (add_step, connect_steps, list_runs, log_run, compare_runs, run_step, cancel_run, export_map). A few deviate from that pattern—best_run (adjective_noun), data_status (noun_noun) and gnn_summary (noun_verb)—but they remain readable and unambiguous. No mixing of camelCase or inconsistent delimiters.

Tool Count3/5

At 21 tools the surface sits in the heavy band, spread across pipeline modeling, run logging/execution, sweeps, data versioning, notes/tags, and three output mechanisms (viewer, pipeline read, HTML export). Each tool maps to a recognizable capability, so nothing is obviously redundant, but the set is larger than the core job strictly requires.

Completeness3/5

Lifecycle coverage is broad (init_project, scan_project, add/connect steps, run/log/compare/tag/note, sweeps, export), but there is no way to delete a step, run, or note, and no tool to remove or edit an edge once created with connect_steps. Those omissions are notable in a mutable graph store, since mistakes require editing underlying files by hand. Agents can work around gaps but cannot fully clean up the model.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    Not graded
    maintenance
    Enables building and querying code knowledge graphs for project analysis, with tools for exploring code relationships, managing workflows, and automating development tasks. Integrates with Git and GitHub for branch management and pull request creation.
    42 npm
    6
    -
  • A
    license
    D
    quality
    D
    maintenance
    Enables AI assistants to perform MLOps workflows such as experiment tracking, model registry, dataset management, pipeline orchestration, and data lineage by wrapping DVC, MLflow, and Git.
    100
    1
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables AI-assisted scientific research workflow management through MCP, including project creation, ideation, experiment execution, and artifact handling, with integration for ChatGPT, Codex, and Claude Code.
    Apache 2.0
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables building, running, and optimizing cheminformatics pipelines via composable blocks, with an MCP agent interface for natural language interaction.
    2
    MIT