claude plugin eval: A Reproducible, CI-Ready Evaluation Runner for Your Plugins
Claude Code v2.1.269 ships the most significant plugin development feature since the plugin system launched: claude plugin eval, a built-in evaluation runner that executes a suite of test prompts against your plugin, scores outputs using one of six grader types, and produces a JSON + HTML report you can gate in CI. Crucially, it also runs the same prompts against a no-plugin baseline — so you get an empirical answer to the question "does my plugin actually help?"
The six grader types
Four graders are free (no additional API calls); two call a judge model and consume tokens:
exact— string equality after normalisation. Use for deterministic outputs (IDs, structured JSON keys).contains— checks that the response includes a required substring. Use for mandatory disclaimers, required field mentions, or keyword presence.regex— matches against a regular expression. Use for format validation (phone numbers, dates, codes).json-schema— validates response against a JSON Schema. Use for any plugin that returns structured data.llm-judge— sends the prompt, expected criteria, and Claude's response to a judge model for a pass/fail verdict with reasoning. Use for open-ended quality or tone requirements.rubric— a scored variant ofllm-judgethat returns a 0–10 score on each rubric dimension. Use when you want aggregate quality tracking over time.
Running an eval
# Run eval suite defined in plugin-eval.yaml
claude plugin eval --config plugin-eval.yaml
# Output: JSON report + HTML visualisation in ./eval-results/
# Exit code 0 if all pass-threshold checks pass, 1 if any fail
# --baseline flag included by default; suppress with --no-baseline
The eval config file declares test cases, expected outputs, and which grader(s) to use per case. A minimal two-grader example:
version: 1
plugin: my-plugin
threshold: 0.85 # overall pass rate required; CI fails below this
cases:
- id: basic-lookup
prompt: "What is the capital of France?"
graders:
- type: contains
value: "Paris"
- id: tone-check
prompt: "Explain quantum entanglement in one sentence."
graders:
- type: llm-judge
criteria: "Response is accurate, uses an analogy, and is under 30 words."
Add a GitHub Actions step after your plugin test suite:
- name: Plugin eval gate
run: claude plugin eval --config plugin-eval.yaml
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
The command exits non-zero if your overall pass rate falls below threshold or if any exact/regex/json-schema case fails. The HTML report is available as an artifact for debugging. The no-plugin baseline score is emitted to stdout so you can track the delta over time — a shrinking delta means your plugin is losing its edge.
The baseline comparison
This is the feature most plugin developers have been waiting for. Without a baseline, a plugin's 82% pass rate on your eval suite tells you nothing — is that good? Bad? The baseline run executes the same prompts with the plugin disabled and scores them with the same graders. If Claude scores 79% without your plugin, your plugin is adding 3 percentage points of net value. If Claude scores 84% without it, your plugin is actively hurting quality and you need to investigate why before shipping.