opik-mcp

skills

Purpose

This repo authors the Opik agent skills. The server serves them through the read_skill tool and as MCP resources, and CI publishes the same bytes as the pack that npx skills add comet-ml/opik-skills installs. This doc answers how an agent gets a skill, how the pack is built, and how to add a skill.

What it does now

The tree

read_skill

read_skill(skill_name) returns one document. resolve accepts a skill name (opik-instrument, meaning its SKILL.md), a path (opik/references/tracing-python.md) or a URI (opik://skills/opik/SKILL.md). These three are advertised. It also tolerates a sibling path as a SKILL.md cites it (../opik/references/integrations.md) and a bare reference name: opik/tracing-python drops the references/ folder and the .md suffix, and resolves to opik/references/tracing-python.md.

The answer is a header, then the file byte for byte:

[read_skill: opik path=SKILL.md bytes=<n> uri=opik://skills/opik/SKILL.md]

The header names the resolved file, whatever form the caller used. A SKILL.md with references ends with a footer listing their paths.

An unknown skill raises UnknownSkillError (kind validation) listing every skill; an unknown document lists that skill’s documents, in the caller’s form.

read_skill_tool_description renders the tool description: a routing line per skill from SKILL_SUMMARIES, and the name and path forms; the URI form is documented on the skill_name argument. It fits the host’s description cut-off, so no host drops its tail (test_the_description_arrives_whole). It names no reference file; an agent learns a reference’s path from the footer of the SKILL.md that cites it, so adding a reference costs no session anything until that skill is read (test_tool_description_names_no_reference_path, test_every_skill_md_footer_lists_its_references).

Resources

Each served file is a resource at opik://skills/<skill>/<path>, with one template. List and read results carry ttlMs (SKILLS_TTL_MS) and cacheScope (SKILLS_CACHE_SCOPE, public) on the result and in each content’s _meta. An unknown opik://skills/ URI is an error listing what exists.

The pack

make skills-pack builds dist/opik-skills/ with README.md and index.json. It copies files byte for byte and validates each skill with skills_ref (the spec’s reference implementation) before and after. The build fails on an empty source, an invalid skill, or a SKILL.md path that dangles or escapes the pack.

In CI the skills-pack job runs make skills-verify and make skills-verify-source. On a push to main, publish-skills-pack uploads the verified artifact to the pre-release tag skills-pack, where comet-ml/opik-skills pulls it. This repo holds no credentials for that repo.

Adding a skill

  1. Create src/opik_mcp/skills/opik-<verb>/SKILL.md with last_updated and source_commit under metadata:. tests/skills/test_spec_compliance.py checks the name and the provenance.
  2. Add a line to SKILL_SUMMARIES, or the skill is missing from the routing list and test_every_bundled_skill_has_a_summary fails.
  3. The budget tests fail only if the new lines push a total over its cap: test_tool_description_stays_within_a_sane_budget, SURFACE_BUDGET_BYTES and INSTRUCTIONS_BUDGET_BYTES. Trim the summary, or raise the budget and record why in the comment next to it (AGENTS.md).
  4. Run scripts/skills_trigger_eval.py (needs a judge API key, not in CI) and make skills-verify-source.
  5. Restart the server to see the new files. The listing is cached per process, and hosts may keep the old set for SKILLS_TTL_MS.

How it works

read_skill(name)  -> server.read_skill -> skills_catalog.run_read_skill
                     -> resolve -> read_skill_file (importlib.resources)
resources/*       -> skills_resources handlers -> skills_catalog.resolve_uri
                     -> read_skill_file
make skills-pack  -> scripts/build_skills_pack.py -> dist/opik-skills/

Decisions

Traps

Proven by

Log