Labsco
comet-ml logo

Comet Opik

209

from comet-ml

Query and analyze your Opik logs, traces, prompts and all other telemtry data from your LLMs in natural language.

🔥🔥🔥✓ VerifiedAccount requiredAdvanced setup

opik-mcp

Migrating from the old npx opik-mcp? The TypeScript server is deprecated and sunsets on 2026-11-15. Swap npx -y opik-mcp for uvx opik-mcp@latest in your MCP client config. Full guide: legacy/typescript/MIGRATION.md.

Model Context Protocol server for Opik + Ollie. Plug your AI host (Claude Code, Cursor, VS Code Copilot, MCP Inspector) directly into your Opik workspace — read traces, log scores, save prompt versions, and ask Ollie investigative questions, all from the chat.

Built for LLM engineers who already run Opik and want to drive it from the same AI assistant they code with.

You:    "Why did the experiment 'gpt-4o-rerank-v3' regress on factuality?"
Claude: → ask_ollie → reads experiment + traces → "Three traces failed because…"

You:    "Score trace 7f2e… 0.9 on helpfulness with reason 'great recovery'."
Claude: → write(score.create) → done

Tools

opik-mcp exposes a small, outcome-oriented surface — six tools that cover the full lifecycle (read → annotate → curate → author → iterate).

ToolPurpose
readUniversal read by id / name / opik:// URI
listUniversal list with optional name filter + pagination
ask_ollieInvestigate / synthesize via the Opik in-product assistant
writeUniversal write — log traces/spans, score, comment, save prompts, manage test suites & experiments
schemaIntrospect write-operation schemas (used by the LLM to construct valid payloads)
run_experimentRun an evaluation experiment end-to-end via Ollie

read

One tool for any "show me X" question. Takes an entity_type plus an id (UUID or, for nameable types, a name) or a full opik:// URI. Composite reads (trace, prompt) inline their children so a single call returns the full picture.

Supported entities: project, trace, span, test_suite, experiment, prompt. Name-based lookup is available for project, experiment, prompt, test_suite (slower — two API calls — and may return multiple matches).

read(entity_type="trace", id="7f2e3c8a-…")
read(entity_type="project", id="demo")          # name lookup
read(entity_type="trace", id="opik://traces/7f2e3c8a-…")

list

Browse a collection with optional name filter and pagination. Project-scoped types (trace, test_suite_item, prompt_version) require their parent UUID.

list(entity_type="experiment", page=1, size=25)
list(entity_type="experiment", name="rerank")          # name substring filter
list(entity_type="trace", project_id="<project-uuid>") # traces of one project

ask_ollie

For investigative questions, cross-entity synthesis, or anything that needs Opik domain expertise. Ollie has direct read access to your workspace and can execute writes (scores, comments, test-suite items, prompt versions) mid-stream when asked.

ask_ollie(query="Why are spans in project 'demo' slower this week than last?")
ask_ollie(query="Compare experiments A and B on factuality. Score the bottom 5 traces of A 0.2 with reason.")

Returns the assistant's final text plus a thread_id. Pass it back on follow-ups to preserve context — Ollie has no memory across threads.

YOLO mode (default). Writes Ollie performs mid-stream execute without a per-action confirmation. Each auto-approval is logged as a JSON audit row on the opik_mcp.audit Python logger. To require confirmation instead, set OPIK_MCP_AUTO_APPROVE=disabled — Ollie's confirm requests then surface as typed errors you can manually re-issue.

Available on Comet Cloud only.

write

Universal write dispatcher. Pass operation + data and the dispatcher validates the payload, applies the right REST verb, and returns the backend response.

Operations:

OperationWhat it does
trace.createLog a single trace (or a batch). Parent for spans / scores / comments.
trace.updateFinalize or amend an existing trace.
span.createLog a span on an existing trace (or a batch).
score.createAttach a numeric feedback score to a trace, span, or thread.
comment.createAttach a free-text comment to a trace, span, or thread.
prompt_version.saveSave a new prompt version (creates the prompt by name if missing).
test_suite.createCreate an evaluation test suite.
test_suite_item.upsertUpsert items into a test suite (always the envelope shape).
experiment.createCreate an experiment scoped to a test suite.
experiment_item.createAttach trace + dataset_item rows to an experiment.
write(operation="score.create", data={
  "target": "trace",
  "target_id": "7f2e3c8a-…",
  "name": "helpfulness",
  "value": 0.9,
  "reason": "great recovery"
})

schema

Inspect the exact JSON shape and required fields of any write operation before you call it — useful when you're not sure what data should look like. Returns the schema, OAuth scope, and one validated example. Pure lookup, no backend call.

schema(operation="score.create")
schema(operation="prompt_version.save")

run_experiment

Run an evaluation experiment end-to-end via Ollie. Takes a single experiment_config dict that mirrors Opik's experiment shape (prompt, test suite, scorers); Ollie executes the run and writes results back as an Opik experiment.

run_experiment(experiment_config={
  "test_suite_name": "qa-eval-v2",
  "prompt_name": "welcome-msg",
  # … see `schema(operation="experiment.create")` for the full shape
})

Available on Comet Cloud only.


Known host limits

The MCP spec lets hosts reset their tool-call timeout on notifications/progressopik-mcp emits one per Ollie SSE event plus a 15-second watchdog heartbeat. Reality is uneven:

  • Claude Code — no documented tool-call timeout; heartbeat keeps the call alive until message_end. Recommended.
  • Cursor — hard 60s timeout that does not reset on progress (upstream bug). Long Ollie turns will fail. Keep ask_ollie queries focused.
  • MCP InspectorMAX_TOTAL_TIMEOUT bounds total duration (default 60s). Raise it in the Inspector UI for long operations.

If a call gets stuck, set OPIK_MCP_LOG_LEVEL=DEBUG — heartbeat failures (usually host disconnects) are logged on opik_mcp.ask_ollie at debug level.


Development

git clone git@github.com:comet-ml/opik-mcp.git
cd opik-mcp
make install        # uv sync --extra dev
make check          # lint + typecheck + test
make run-dev        # uvicorn with --reload + DEBUG logs
make inspect        # MCP Inspector against the running server

Common targets:

TargetWhat it does
make installuv sync --extra dev
make runRun the MCP server (stdio by default).
make run-devRun with DEBUG logging + uvicorn --reload.
make devRun via mcp dev (Inspector dev-mode wrapper).
make inspectLaunch MCP Inspector against a running server.
make testuv run pytest -q.
make test-liveLive end-to-end against dev.comet.com (set OPIK_API_KEY + OPIK_WORKSPACE).
make lintruff check + format check.
make formatruff format + ruff check --fix.
make typecheckmypy.
make checklint + typecheck + test.

Repo layout:

opik-mcp/
├── src/opik_mcp/        ← server, tools, ask_ollie, analytics
├── tests/               ← pytest suites
├── scripts/             ← live-BE smoke + MCP-session smoke
├── legacy/typescript/   ← deprecated v2 TS server
├── pyproject.toml
└── Makefile

Get help


Upgrading from v2? The legacy TypeScript server still ships on npm as opik-mcp@^2 (npx -y opik-mcp); source is preserved under legacy/typescript/. See legacy/typescript/DEPRECATED.md for the support policy.