opik-mcp

project-overview

Purpose

read('project') answers “how is my project doing”; list('project_metric') charts one metric over time. This doc answers what a project read returns, what happens when one of its calls fails, and why a metric request was refused.

What it does now

read(‘project’, id_or_name, since=…, until=…)

A name is looked up as in tool-surface. For a project, search_by_name asks for 5 candidates, and more than one is refused even when one matches exactly (test_read_project_by_ambiguous_name_lists_candidates). No match, or a failed lookup, ends in the not-found error for the name. Unverified: the backend matches substrings (the test uses a fake client).

The answer is one JSON object:

When a part fails, that part becomes {"error": "Could not load …"} and the rest still arrive. A failed summary keeps window and source, has error in place of traces, and names a list('trace', …) call that counts by hand. The other parts run on a deadline through decorations.block (tool-surface). The summary has none, since its figures are the answer (#187). Only the client timeout bounds a hanging kpi-cards call (runtime).

list(‘project_metric’, …)

Refused before any backend call, each with the valid options: an unknown or missing metric, an unknown interval, an unknown filter field, a thread filter on source or environment, a grouping the metric does not take (the refusal names a metric that does), a bad or missing series, and page, size, sort or fields.

Other lists

How it works

read  → read_tool._fetch_with_name_lookup → project.read.fetch_project
        → get_project, then gather(summary, 4 vocabulary loaders, contents)
        → project_links (read_tool attaches, strips _project_id)
list  → list_tool → project_metric HANDLER.run_fn = runner.run_project_metric
        → catalog (validate) → require_project_id → get_project_metrics (+ count) → table.render

Where to start:

Decisions

Traps

Proven by

Log