tracker-mcp

tracker-mcp

Enables querying machine-learning experiments in natural language. Supports listing, inspecting, ranking, and comparing experiment runs.

Category
Visit Server

README

Experiment Tracker MCP

An MCP (Model Context Protocol) server that lets you query your machine-learning experiments in natural language. Train models, log every run to a local store, then ask an AI assistant — Claude Desktop, VS Code Copilot, or any MCP client — questions like "which run had the best recall?" and have it call your tools to answer.

The project is a small, self-contained demonstration of three things: a clean experiment-tracking data model, a backend-agnostic storage layer, and an intent-oriented MCP server on top of it.


What it does

  1. train.py trains scikit-learn models on a dataset and logs each run — hyperparameters, metrics, and the saved model file — through a tracker.
  2. The store persists runs in SQLite behind a swappable interface.
  3. server.py exposes the store as MCP tools, so an LLM can list, inspect, rank, and compare your experiments on request.
train models ──▶ log to store (SQLite) ──▶ MCP server ──▶ "which run is best?" (any MCP client)

Architecture

The codebase is layered by responsibility, and every dependency points inward toward an interface rather than toward a concrete implementation:

server.py ─┐
           ├─▶ store/base.py  ◀── store/sqlite_store.py ──▶ db/connection.py ──▶ schema.sql
train.py ──┘   (Tracker: the        (SQLiteTracker:          (connection +        (the DDL)
                interface)           an implementation)       initialization)

server.py and train.py — the application edges — depend only on the abstract Tracker interface, never on SQLite. SQLite is an adapter plugged in behind the interface. This is the Dependency Inversion Principle in practice: swapping the backend (e.g. for MLflow) means adding one class in store/, and nothing above the interface changes.


Project structure

tracker-mcp/
├── pyproject.toml          # dependencies + package metadata
├── .gitignore              # keeps tracker.db, models, __pycache__ out of git
├── README.md
├── .vscode/
│   └── mcp.json            # VS Code MCP server config
├── tracker_mcp/            # the package
│   ├── __init__.py         # re-exports Tracker, SQLiteTracker
│   ├── config.py           # single source of truth for filesystem paths
│   ├── db/                 # ── infrastructure layer ──
│   │   ├── schema.sql      #    the database structure, as real SQL
│   │   └── connection.py   #    connection config + schema initialization
│   ├── store/              # ── repository layer ──
│   │   ├── base.py         #    the Tracker interface (abstract)
│   │   └── sqlite_store.py #    the SQLite implementation
│   ├── train.py            # ── application: trains models, logs runs ──
│   └── server.py           # ── application: the FastMCP server ──
├── models/                 # saved .joblib model artifacts (gitignored)
└── tracker.db              # the SQLite store (gitignored)

Setup

Requires Python 3.12+.

# from the project root
python -m venv .venv
source .venv/bin/activate          # Windows: .venv\Scripts\activate

pip install fastmcp scikit-learn joblib
pip install -e .                   # editable install: makes `python -m tracker_mcp.*` work anywhere

The editable install is what lets the MCP server be launched by name (-m tracker_mcp.server) from any working directory — important because MCP clients spawn the server from an unpredictable location.


Usage

1. Train some models

python -m tracker_mcp.train

This trains four models on the scikit-learn breast-cancer dataset (a shallow decision tree as a weak baseline, a default and a tuned random forest, and gradient boosting), logs each run to tracker.db, and saves each model to models/.

2. Run the MCP server

python -m tracker_mcp.server      # stdio transport — what MCP clients expect

Or debug it interactively with the MCP Inspector:

fastmcp dev tracker_mcp/server.py

3. Connect it to a client

Claude Desktop — add to claude_desktop_config.json:

{
  "mcpServers": {
    "experiment-tracker": {
      "command": "/absolute/path/to/tracker-mcp/.venv/bin/python",
      "args": ["-m", "tracker_mcp.server"]
    }
  }
}

VS Code (GitHub Copilot, agent mode) — .vscode/mcp.json. Note VS Code uses the servers key, not mcpServers:

{
  "servers": {
    "experiment-tracker": {
      "type": "stdio",
      "command": "/absolute/path/to/tracker-mcp/.venv/bin/python",
      "args": ["-m", "tracker_mcp.server"]
    }
  }
}

Then ask, in natural language:

  • "List my experiment runs."
  • "I'm building a cancer screening model — which run should I use?"
  • "Compare the tuned random forest and gradient boosting."
  • "Show me the details of run 910ced952bb6."

The tools

The server exposes tools designed around what a user asks, not a 1:1 mirror of the store's methods:

Tool Purpose
list_experiments(limit) Recent runs, newest first (summary).
get_experiment(run_id) Full detail of one run, including all metrics.
find_best_model(metric, mode) The run with the best value for a metric (max/min).
compare_experiments(run_ids) Several runs side by side, by params and metrics.

It also exposes each run as a read-only resource at experiment://{run_id}, and ships a server-level instructions block — domain context (what a run is, which metric fits which goal) delivered to the model during the MCP handshake, so it reasons about experiments correctly without the user re-explaining each turn.


Design decisions

These are the choices worth understanding, and the reasoning behind them.

Two tables, split by access pattern. Runs get one table; metrics get their own. Hyperparameters are heterogeneous across model types and rarely queried individually, so they're stored as a single JSON column. Metrics are the opposite — you constantly rank and compare across them, and they can form time series over training steps — so they live in a normalized table where MAX(value) WHERE key = 'accuracy' is trivial. This params-as-JSON, metrics-as-rows asymmetry is the core of the data model.

Backend-agnostic storage. The server and training code depend on the abstract Tracker interface, so the SQLite backend is a detail, not an assumption. A different backend (MLflow, Postgres) would be a new class behind the same interface.

Intent-oriented tools. MCP tools are shaped around user questions (find_best_model, compare_experiments) built on top of the store's primitives, rather than mechanically exposing get_run/list_runs. Clear, distinct tool descriptions are what let the model pick the right tool.

Single source of truth for paths. config.py anchors the database and model directory to the project root via __file__, so the training script (writer) and the server (reader) always resolve to the same files regardless of the working directory a command is launched from. Env vars (TRACKER_DB, TRACKER_MODELS) override when needed.

Reproducibility as a logged value. The random seed lives inside each run's logged params, so a stored run can be recreated exactly — the same dict both builds the model and gets recorded.

Failures are recorded. A run is created before training starts and marked failed if training raises, so the experiment history reflects reality rather than only successes.


Tech stack

  • FastMCP (3.x) — the MCP server framework
  • scikit-learn — model training
  • SQLite (stdlib sqlite3) — the tracking store
  • joblib — model serialization

Possible extensions

  • An MLflowTracker implementation behind the same Tracker interface.
  • A test suite under tests/ (the in-memory fastmcp.Client makes end-to-end tool tests straightforward).
  • Per-step metric logging to support training curves, and a best_run that ranks by each run's final step.
  • A delete_run / archival tool, and filtering list_experiments by model type or dataset.

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured