mcp-tournament
Summary: mcp-tournament is a local-first, BYOK MCP server that runs multi-judge LLM benchmark tournaments over declarative benches and returns ranked, auditable results.
Run evaluations (
tournament.evaluate): 1–4 candidate models × scenarios with a 1–5 judge panel, ranked output (paid via OpenRouter).Quick sanity checks (
tournament.quick_test): one model, one scenario, one judge, no synthesis call (paid, usually under a minute).Read the leaderboard (
tournament.leaderboard): best cached score per model, optionally filtered by bench/limit (free, local).Inspect past runs (
tournament_get_run,tournament://runs/{runId}, .../report): full models, judges, per-scenario scores, failures, and a markdown scorecard.List or save benches (
tournament_list_benches,tournament_create_bench;tournament://benches): read existing benches or define new scenarios and judging criteria from chat, usable immediately as a plugin.Use MCP prompts (
compare_models,choose_model_for_task,explain_run): head-to-head comparisons, task-to-bench matching, and plain-English run explanations.Get progress + safety signals: paid tools stream progress notifications; annotations (
readOnlyHint,openWorldHint) and connection instructions tell clients to confirm before spending.Also usable beyond MCP: same pipeline runs through a local BYOK GUI, an unsigned Electron desktop preview, or a CLI (
run,leaderboard,serve).
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mcp-tournamentRun the business-strategy benchmark on my model"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
mcp-tournament
Build a custom LLM benchmark in a form, run it from a local GUI, MCP client, or CLI, and turn independent judge opinions into ranked, auditable results.

Explore the interactive demo: compare a recorded business-strategy experiment, inspect the evidence, and try your own criterion weights. No key needed.
Why this is interesting:
Disagreement is data: multiple specialist judges score independently; the arbiter preserves outliers and explains where they diverged.
Benches are declarative: anyone can define scenarios and criteria as JSON or build them in a form, no pipeline code required.
BYOK and local-first: bring one OpenRouter key, keep the GUI on your machine, and run budget-tier tournaments for cents.
A model choice you can explain
The evaluation studio turns the recorded pipeline output into a decision workflow:
Results overview: the original leaderboard, criterion comparisons, and material judge dissent in one place.
Compare evidence: choose up to three candidates and inspect their original answers and arbiter assessments side by side.
Decision lab: change the importance of each criterion with sliders or presets, then see the weighted ranking respond immediately.
Export a report: download original scores, judge identities, dissent, and optional exploratory weights as Markdown.
Follow the evidence: open any model's scorecard, individual judge matrix, transcript, or animated run replay.

The demo contains real, dated recordings across business strategy, customer support, creative writing, and the D&D showcase. It makes no live model calls. Results are scenario-specific observations, not a statistically validated or universal model ranking. The decision lab recomputes scores from final criteria; it never changes recorded results or hides missing evidence. Candidate and judge models may overlap.
Related MCP server: AgentOps EvalBench MCP
How it works
flowchart LR
A["Scenario + criteria<br/>plugin / bench JSON"] --> B["EXECUTE<br/>candidate + tool calls"]
B --> C["JUDGE<br/>N specialists in parallel"]
C --> D["SYNTHESIZE<br/>merge + flag outliers<br/>never scores independently"]
D --> E["AGGREGATE<br/>leaderboard + JSON audit trail"]Three entry points feed the same pipeline:
GUI: build benches, launch runs, and inspect results locally.
MCP client: ask Claude Desktop, Cursor, or Windsurf to run, compare, and explain evaluations (6 tools, 5 resources, 3 prompts), including saving your own benches from chat.
CLI: script runs, serve MCP over stdio, or print the leaderboard.
Domain logic is pluggable; the pipeline is not. Benches are declarative plugins: a JSON file (or the Build Bench form) defines scenarios, rounds, an optional simulated participant persona, and judging criteria. Code plugins can go further with custom tools; see docs/PLUGINS.md.
Plugin | Domain | Kind |
| SMB pricing decision with real numbers to reason about | 📄 bench (JSON) |
| Opening chapter + 3 rounds with a developmental-editor persona | 📄 bench (JSON) |
| Billing dispute with an escalating customer persona | 📄 bench (JSON) |
| Showcase: D&D 5e Dungeon Master with dice/damage tools and an LLM player | ⚙️ code plugin |
| Code generation & review | ⚙️ code plugin |
Yours | Build in the GUI ( | 🛠 you |
Why multi-judge?
Single evaluators miss things. A Rules judge catches mechanical errors; a Creative judge catches boring output; a Holistic judge catches "would I keep using this?" The synthesizer never scores independently: it arbitrates, flags outlier judges, and records why they disagreed. Judge disagreements are first-class data, rendered in the viewer:

When to use this (and when not to)
You want | Reach for |
CI-style assertions and regression gates over prompts at scale | |
Standardized academic benchmarks (MMLU, HellaSwag, …) | |
Rubric-scored comparisons on your own scenarios (multi-round conversations, personas, tool use) with judge disagreement preserved instead of averaged away | mcp-tournament |
Those tools are better at what they do; this one is for judgment-heavy, domain-specific evals where a single aggregate score hides the story.
Quick start
git clone https://github.com/samalbanese/mcp-tournament.git
cd mcp-tournament
npm run setup # installs + builds server and GUI
export OPENROUTER_API_KEY=sk-or-... # one key, every roleOr skip local setup entirely:
As a local app (BYOK GUI)
node dist/cli.js gui # http://localhost:4600Paste your OpenRouter key in Settings (stored in your browser, sent only to this local server, never written to disk), then set your model routing right below it (default candidates from the live catalog with prices, plus the model behind each judge and the synthesizer) and start a run from NEW RUN. BUILD BENCH creates a new benchmark from a form (question, rounds, persona, judging criteria, with an AI-suggest button) and saves it as a JSON plugin, live immediately.
As a desktop app (Windows, unsigned preview)
The same server + GUI wrapped in an Electron window, with the API key stored
via OS-level encryption (safeStorage) instead of the browser:
npm --prefix electron install
npm --prefix electron run dist # unsigned NSIS installer + portable exe → electron/dist-app/Builds are unsigned for now, so Windows SmartScreen will warn on first run; see electron/README.md.
As an MCP server (Claude Desktop, Cursor, Windsurf)
{
"mcpServers": {
"tournament": {
"command": "node",
"args": ["<path-to-repo>/dist/index.js"],
"env": {
"OPENROUTER_API_KEY": "sk-or-...",
"TOURNAMENT_RESULTS_DIR": "<path-to-repo>/results"
}
}
}
}MCP clients start the server from their own working directory, so
TOURNAMENT_RESULTS_DIR is what lets it find (and add to) the repo's saved runs.
The server runs over stdio and uses all three MCP primitives: tools, resources, and prompts.
Tool | What it does | Cost |
| Every bench and its scenario IDs | Free, local read |
| Best score per model across saved runs, optionally per bench | Free, local read |
| One saved run in full: models, judges, per-scenario scores, failures | Free, local read |
| One model, one scenario, one judge: a cheap sanity check | Paid (OpenRouter), usually under a minute |
| 1–4 models × every scenario × a judge panel, ranked; optionally pick each judge's model | Paid (OpenRouter), several minutes |
| Saves a new bench (your scenarios and scoring criteria), usable immediately | Free, local write |
Every tool returns a readable markdown answer plus typed structuredContent that matches a
declared outputSchema. Tools carry annotations (readOnlyHint, openWorldHint) so a client
can tell a free read from a paid run, and the two paid tools stream notifications/progress
(one step as each model/scenario pair starts and finishes) so long runs don't look frozen. The
server also sends connection-time instructions telling the assistant to confirm with you
before spending money.
Your own scenarios and judges. Describe what you want tested and the assistant drafts a
bench (scenarios, a prompt for each, and the criteria judges score against), shows it to you,
then saves it with tournament_create_bench. The bench is written to benches/ and works
right away as plugin: "<name>". tournament_evaluate accepts judgeModels (one model ID per
judge seat, in the order Rules, Creative, Holistic, Authentic Voice, Context; the list length
sets the panel size) and synthesizerModel for the model that reconciles their scores.
Resources (data a client can attach without a tool call):
URI | Contents |
| Benches and scenarios (JSON) |
| All-time best score per model (JSON) |
| Index of saved runs with each winner (JSON) |
| One run in full (JSON) |
| One run as a markdown scorecard |
The two templates list every saved run and autocomplete run IDs.
Prompts (slash commands in clients that support them):
compare_models(models, plugin, judges): runs a head-to-head evaluation, then explains who won and why.choose_model_for_task(task): matches the task to a bench and checks existing results first, asking before any paid run.explain_run(runId): attaches a run's scorecard and asks for a plain-English explanation.
Once it's connected, you can just ask:
"Which benches does mcp-tournament have, and who leads the customer-support leaderboard?"
"Quick-test deepseek/deepseek-v3.2 on the coding bench."
"Compare deepseek/deepseek-v3.2 and openai/gpt-5.4-mini on business-strategy."
"Make a bench that tests how models handle a customer disputing a late fee, then run deepseek/deepseek-v3.2 against openai/gpt-5.4-mini with qwen/qwen3.5-flash-02-23 and deepseek/deepseek-v3.2 as the judges."
As a CLI
# The demo: 3 cheap models, 1 bench scenario, 3 judges (~a few cents)
node dist/cli.js run --plugin business-strategy \
--models "deepseek/deepseek-v3.2,google/gemini-2.5-flash-lite,meta-llama/llama-4-scout" \
--scenario pricing-pivot --judges 3
# Or the tool-calling showcase: D&D DM with dice/damage tools and an LLM player
node dist/cli.js run --plugin dnd --models "deepseek/deepseek-v3.2" \
--scenario dnd-combat --judges 3
node dist/cli.js leaderboard
node dist/cli.js serve # MCP stdio serverResults viewer
gui/ is a self-contained Vite + React static site with no backend; it deploys
to any static host (Cloudflare Pages works as-is). It reads committed run JSON and
renders rankings, per-judge breakdowns, disagreement callouts, and full
transcripts with tool-call inspection.

cd gui && npm install
npm run import-run -- ../results/<runId> # copy a run into the viewer
npm run build && npm run preview
Model routing
Every role (the candidates, each judge, the synthesizer, the participant agent) is independently model-selectable and routes through OpenRouter by default. One key, any model, no paid first-party API in the demo path. Defaults are all budget-tier (DeepSeek, Qwen Flash, Gemini Flash Lite; a full run costs cents); override per role:
TOURNAMENT_MODEL_JUDGE_RULES=openai/gpt-5.4-mini
TOURNAMENT_MODEL_SYNTHESIZER=moonshotai/kimi-k2.5
TOURNAMENT_MODEL_PARTICIPANT=deepseek/deepseek-v3.2The routing layer resolves a pluggable ModelClient per role
(src/clients/types.ts). That registry is the documented extension point for a
Claude Agent SDK route, which
authenticates against a local claude /login session so Claude-judged runs draw
on a Max/Pro subscription instead of the metered API: the original
oracle-tournament design. Two regression tests guard the default: the demo path
never resolves to the paid Anthropic API, and the MCP server's logger stays on
stderr (stdout is reserved for JSON-RPC).
Environment variables
Variable | Required | Purpose |
| Yes | All roles by default |
| No | Per-role model overrides (see above) |
| No | Results output root (default |
How it's tested
npm run test:unit runs 66 unit tests with no API key required. The MCP layer
is tested at the protocol level: a real SDK client connects over an in-memory
transport and checks every tool (including saving a bench and passing chosen judges through to the pipeline), resource, template, prompt, completion,
structured output, and error path, plus progress notifications from the real
pipeline (strictly increasing, ending at 100%). The suite also covers the decision
lab (changing priorities, zero weights, missing evidence, ties, preserved original
scores, report provenance) and runs the committed demo fixtures through the viewer
loaders, including known partial judge archives. Two regression guards have a story:
The MCP logger writes to stderr only. stdout is reserved for JSON-RPC: one stray
console.logcorrupts the protocol stream and silently breaks every connected MCP client. The guard makes that a failing test instead of a mystery bug report.The default route can never resolve to a paid first-party API. The demo path stays BYOK-through-OpenRouter at budget-tier prices; a config regression that would quietly bill someone's Anthropic key fails CI.
An e2e suite (npm run test:e2e) exercises real model calls when a key is
present. CI runs build + unit tests + the GUI build on every push and PR.
Roadmap
Deferred deliberately: a Streamable HTTP transport for remote hosting, a judges
tool for per-run panel overrides, npm publish, and MCP registry submission.
Provenance
Generalized from oracle-tournament, a D&D-specific model evaluator whose pipeline proved out the multi-judge + arbiter design; this repo makes the domain pluggable.
Contributing
Issues and PRs welcome; the easiest contribution is a new bench JSON. See CONTRIBUTING.md.
License
MIT
Available Tools
3 toolstournament.evaluateB
Evaluate one to four candidate models with a judge panel.
| Name | Required | Description | Default |
|---|---|---|---|
| judges | No | ||
| models | Yes | ||
| plugin | No | dnd | |
| scenarios | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must cover behavioral aspects. It only states 'evaluate with a judge panel' without disclosing whether the operation is read-only, what side effects occur, authentication needs, or rate limits. This is insufficient for a tool that likely performs comparative analysis.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single concise sentence that front-loads the verb and resource with no extraneous words. Every part is useful.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has 4 parameters, no output schema, and no parameter descriptions, the description is severely lacking. It does not explain what the evaluation returns, how results are presented, or what 'plugin' and 'scenarios' entail, leaving significant gaps for the AI agent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 0% description coverage, and the description adds minimal parameter insight. It mentions 'judge panel' which relates to the 'judges' parameter but does not explain 'plugin' or 'scenarios'. The meaning of parameters beyond their names is largely opaque.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'evaluate' and the resource 'one to four candidate models' with a 'judge panel'. It distinguishes from sibling tools like quick_test and leaderboard by specifying the use of a judge panel for evaluation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for evaluating models with a panel but provides no explicit guidance on when to use this tool versus alternatives like quick_test or leaderboard. No when-not-to-use or prerequisite information is given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tournament.leaderboardC
Read the best cached score per model from result files.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| plugin | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must fully disclose behavior. It states 'Read the best cached score' implying a read-only operation, but does not mention potential side effects, authentication requirements, or data source details beyond 'result files'.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single concise sentence with no unnecessary words. It is well-structured and front-loaded with the key action.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite having only 2 parameters and no output schema, the description lacks details about return format, data structure, or how parameters affect results. The 'plugin' parameter is left entirely unexplained.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, and the description does not explain the purpose or valid values of the 'limit' and 'plugin' parameters. The agent cannot infer parameter semantics from the description alone.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool reads cached scores per model from result files, using a specific verb and resource. It distinguishes itself from sibling tools quick_test and evaluate by focusing on cached leaderboard data.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is given on when to use this tool versus alternatives like tournament.quick_test or tournament.evaluate. The agent has no context about preferred use cases.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tournament.quick_testC
Run one scenario with one judge and no synthesis model call.
| Name | Required | Description | Default |
|---|---|---|---|
| model | Yes | ||
| plugin | No | dnd | |
| scenario | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Without annotations, the description should fully disclose behavioral traits. It mentions specifics like single scenario/judge and no synthesis call, but it does not indicate whether the operation is safe (e.g., read-only), destructive, or has other side effects.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single concise sentence with no unnecessary words. It front-loads the core action and key constraints ('one scenario', 'one judge', 'no synthesis model call').
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has 3 parameters (none with schema descriptions), no output schema, and no annotations, the description is severely incomplete. It fails to explain parameters, return values, or usage context, leaving an agent unable to invoke the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must explain parameter meanings. The description only mentions 'one scenario' and 'one judge' but does not map to the parameters 'model', 'plugin', or 'scenario', nor does it clarify their roles or constraints.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool performs a quick test with one scenario, one judge, and no synthesis call. This distinguishes it from sibling tools like tournament.leaderboard and tournament.evaluate, which imply broader or more comprehensive evaluation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit guidance on when to use this tool versus alternatives. The description implies it is for quick tests but does not state prerequisites, limitations, or when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
3 tool updates
v0.1.0- First observed
tournament.evaluate - First observed
tournament.leaderboard - First observed
tournament.quick_test
TDQS
Scored across 3 tools
Each tool has a distinct purpose: quick test runs a minimal scenario, leaderboard reads cached scores, and evaluate runs a full evaluation. No overlap or ambiguity.
Naming is inconsistent: 'quick_test' uses underscore and adjective+noun, 'leaderboard' is a single noun without underscore, and 'evaluate' is a bare verb. No consistent pattern in structure or part of speech.
With 3 tools, the server is at the low end of the typical 3-15 range but still reasonable for a focused evaluation service. The scope is narrow enough that each tool earns its place.
The tools cover the core workflow: quick test, full evaluation, and reading results. Minor gaps exist, such as no tool for configuring judges or scenarios, but these are likely predefined or managed externally.
Maintenance
Related MCP Connectors
MCP server providing access to the Scorecard API to evaluate and optimize LLM systems.
MCP-native AI evaluation: rubric audits, eval suites, and proof reports for AI/LLM output.
MCP server for building and testing AI agents with multi-model experimentation and insights.
Pay-per-call AI evaluation MCP server. Score LLM outputs against benchmark rubrics via Workers AI.
Related MCP Servers
AlicenseNot gradedqualityDmaintenanceEnables running LLM evaluations, experiments, and custom evaluators through a standardized MCP interface.16Apache 2.0- AlicenseNot gradedqualityAmaintenanceEnables LLM evaluation and observability by uploading documents, building test sets, running RAG pipelines, and automatically scoring answers for groundedness, hallucination risk, retrieval quality, latency, and cost, with tools exposed to MCP-compatible clients.1MIT
- AlicenseNot gradedqualityCmaintenanceEnables benchmarking of local LLM models (performance and quality) and sharing results to a public leaderboard via MCP tools.16 npm8Apache 2.0
- FlicenseNot gradedqualityBmaintenanceEnables running deterministic multi-model prompt regression and golden dataset benchmark suites, exposing structured results and telemetry through the Model Context Protocol for integration with MCP-compliant clients.8-