Benchwarmers
Summary: This MCP server lets you discover Benchwarmers collections, ask a collection’s full LLM panel at once, and record verdicts on individual seat answers.
List available collections with their purpose, members, explorer seats, reply mode, and shared limits.
Ask a collection with a prompt, optionally adding a system message, extra explorer models, or a merged reconciled answer.
Get every seat’s answer labeled by model/seat, plus structured seat data and call IDs for later judging.
Record per-seat verdicts by call ID, including whether the answer was useful and which claims were true or false.
Check which seats from a Claude Code session still need verdicts via the
pending_verdictshelper tool.
Supports the Gemini API format, allowing panel requests to Gemini models through Google's API.
Supports the Ollama API format, enabling panel requests against local or Ollama-served models.
Supports OpenAI chat completions and Responses API formats, enabling one request to fan out to a panel of models and return side-by-side answers, including through OpenAI-compatible providers or hubs.
Benchwarmers is a self-hosted panel gateway for LLMs. Your app asks for one of your collections, and the whole panel answers: the models you picked for that kind of work, plus explorer seats that rotate in the models you have used least. Every answer comes back side by side, labelled by model and seat. You check them against the real work and record a verdict, and those verdicts decide who sits on the next panel.
What it is best at:
Asking several models at once. One request, in the OpenAI, Anthropic, Gemini or Ollama format, a panel of answers. Where they disagree is where to look.
Agents too. Claude Code and other tool-calling clients use a collection through route mode: one member per turn, kept for the conversation, with failover, and every call on the record.
Reviewing. Code review, claims about code, designs: different models catch different things, and two models agreeing is not proof.
Playing to each model's strengths. A collection per kind of work (reviewers, designers, enumerators), each with the models that do it best.
Giving every model playing time. Explorers cycle through the rest of the bench, so new and free models get tried beside the ones you trust, without you choosing them by hand.
Benchmarking on your own projects. A review suite seeded from your own repositories, plus your verdicts on real work, instead of public leaderboards.
Knowing who to bench. Who is confidently wrong, who has stopped answering (retired automatically), and who is resting after a rate limit.
Keeping free and cheap models useful. Health probes, rate limits taken from what providers say and enforced, and one endpoint for every app, over any OpenAI-compatible provider or hub, or Anthropic's and Gemini's own APIs.
Related tools | Examples | What they do | What Benchwarmers does differently |
Gateways and routers | LiteLLM, OpenRouter, Portkey | One request to one model, with fallback | Fans one prompt out to a panel and returns every answer; for agents, routes to one member by its record |
Councils and ensembles | LLM Council, Mixture-of-Agents | Several models merged into one answer | Keeps every answer, because who said what is the evidence; one merged summary only if you ask |
Side-by-side chat | Open WebUI, LMArena | Several answers shown together | Records a verdict per answer and uses them to pick the next panel |
Evaluation harnesses | promptfoo, Inspect, SWE-bench | Score models offline on fixed test sets | Scores them on your real work and your own code, and keeps rotating new models in |
Contents
Day-to-day use (the dashboard's pages, connecting apps, onboarding in bulk) is in USAGE.md. Running it on a server or a hosting platform is in HOSTING.md. A coding agent setting it up for someone should start with AGENTS.md.
Related MCP server: llm-gateway-mcp
Try it
v0.3, early. It runs with Python 3.11 or later on Windows, macOS and Linux, from PyPI, npm, a checkout or Docker. Expect rough edges, and read the code where these pages are thin.
Quickest, with Python 3.11+ installed, from PyPI:
pipx install benchwarmers # or: uv tool install benchwarmers
benchwarmers # or try it first, without installing: uvx benchwarmersor from npm, with Node 18+ as well:
npx @wendellresearch-ai/benchwarmersEither way you get the same two commands, benchwarmers and its short name
bench. It keeps your data in your user profile (BENCHWARMERS_HOME to
choose another folder), sets it up on the first run, and opens the dashboard
on http://localhost:8122, where steps 3 to 5 below continue. The built-in
model client makes every call, so nothing else needs installing. No
dependencies either way: the app is the Python standard library.
From source:
Get the code and a Python 3.11+ environment:
git clone https://github.com/WendellResearch-AI/benchwarmers cd benchwarmers python -m venv .venv # nothing to pip install: the standard library is enoughThe built-in model client (
metrics/client.py) makes every call. ThellmCLI is an alternative for its plugins: install it in the venv and choose it on Settings (orBENCH_CLIENT=llm, which wins).Make a data folder. Everything that is yours (endpoints, model registrations, collections, verdicts, probe history, task answers) lives there, never in the code:
python scripts/init.py # or: python scripts/init.py <folder>It starts the folder from
examples/(in your OS's per-user data folder unless you name one) and points the checkout at it with a.benchwarmers-homefile;BENCHWARMERS_HOMEoverrides that. With--endpoint NAME BASE_URL --keyit also adds a first endpoint and asks for its key, which goes to the key file in llm's user folder (keys.json, shared with thellmCLI if you have it, not needed otherwise), never into the data folder.BENCHWARMERS_KEY_<NAME>in the environment works too.Start the dashboard. With no endpoint yet it opens on adding one: sign in with a provider on its own page (OpenRouter, NanoGPT, Hugging Face, Pollinations, your ChatGPT plan, GitHub Models, or a local Ollama), or paste an API key for any OpenAI-compatible API, a hub such as Open WebUI or LiteLLM included. Anthropic and Gemini keys can also be called through those providers' own APIs (the API choice in the same dialog). Only providers that publish a sign-in for other apps are offered; adding one is an entry in
metrics/connect.py(its docstring says how).python serve.py # http://localhost:8122Onboard a few models from it ("Onboard a model"): tick one or several; each is registered, probed and run through the suite, one at a time, with the progress beside the button. Quick probes now and leaves the suite to the scheduled passes; Quick + ad hoc also keeps the bench from ever calling the model on its own, for a metered or trial key. Tick Vision model for one that reads images and little else: it sits only for questions about images, and is tested on the vision tasks, not the code ones.
Make a collection on the Collections page (the models a panel always includes, and what it is for). The dashboard answers the gateway's routes on its own port (
http://127.0.0.1:8122/v1);python gateway.pyruns the gateway alone onhttp://127.0.0.1:8123/v1.
How it works
Collections and seats. A collection names the models a panel always includes and the shape of work it is for (review, design, enumeration...). Each call adds explorer seats chosen by how long a model has gone unused, so the bench keeps learning about models a router would stop asking.
Verdicts. Each seat's answer carries a call id. Once you have checked an answer against the real work, record whether it was useful, and which of its claims were real or false. Verdicts, not vibes, decide the next panel; a model that is often confidently wrong shows as that.
The catalog. Context window, output limit, tools, vision and price come from models.dev for the provider that actually serves a model, then OpenRouter's public catalog and FreeLLMAPI, and anything you set by hand.
Health. Every morning each model gets a one-word prompt; once a week, a short and a long one for speed. A model that stops answering, or that its endpoint no longer serves, is retired automatically after one confirming call, with the evidence kept, and can be restored in one click. The built-in scheduler runs all of this once Settings switches it on; a fresh install spends no calls until then.
Rate limits and usage. Limits come from providers' rate-limit headers and error messages, and from what you set per connection or model (requests a minute, day or month; tokens a minute or day). They are kept per connection, since models behind one key share them, and enforced: a call waits when the wait fits, or is refused before it goes out. Every call lands in a monthly usage ledger with its tokens, and the Quotas page shows what is left and when it resets.
Discover. models.dev and FreeLLMAPI, merged into one list of models worth adding, each with the routes this install has to it.
Asking a panel
Any OpenAI-compatible client works: ask for the model bench/<collection>.
curl http://127.0.0.1:8122/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{"model": "bench/<collection>", "messages": [{"role": "user", "content": "Where can this function return a stale value? ..."}]}'The reply carries every seat's answer in the message, and the same seats as
data in a bench field: model, seat, status, seconds and a call id. For a chat
window that shows one answer, ask for bench/<collection>:merged: a merger
model writes one answer saying where the seats agreed and disagreed, and every
seat is still in bench. Record a verdict per call once you have checked it:
curl http://127.0.0.1:8122/bench/verdict -H "Content-Type: application/json" \
-d '{"call": "<call id>", "useful": true, "note": "found the real bug", "real": ["..."], "false": ["..."]}'or from the dashboard. See GATEWAY.md for the full contract: images, prompt sizes, who may call, and the reply's shape.
Other clients. The same panel answers in other APIs' shapes, so a client that speaks one of them works with the server's address as its base URL:
Format | Route | For |
OpenAI chat completions |
| OpenAI SDKs, most chat apps |
OpenAI Responses |
|
|
OpenAI legacy completions |
| tools that send a |
Anthropic Messages |
| Anthropic SDKs with |
Ollama |
| Open WebUI's Ollama connection, Ollama apps |
Gemini |
| Google GenAI SDKs with |
curl http://127.0.0.1:8122/v1/messages -H "Content-Type: application/json" \
-d '{"model": "bench/<collection>", "max_tokens": 1024, "messages": [{"role": "user", "content": "..."}]}'Each streams when asked: the reply starts at once, and each seat's answer
arrives as that seat finishes. A panel answers with text, so a request
carrying tools is refused with a 400 that points to route mode
(bench/<collection>:route, one member with its tools; see
below). GATEWAY.md, "Other API formats",
has a curl for each and what is refused or ignored.
From the command line
bench (or benchwarmers, the same program) does what the dashboard does,
without it: ask and judge, and run the bench itself. It is a client of a
running server, so the same commands work against one on another machine.
bench status what is running, and where
bench collections what you can ask
bench ask core "Where can this return a stale value?" -f cache.py
git diff | bench ask core "Review this diff" a pipe is the prompt
bench verdict <call id> --useful --real "the race in refresh()" --false "the SQL injection"
bench models --find mercury the roster, with each model's status
bench candidates --new what your endpoints serve that is not on the bench
bench onboard <served name> --wait onboard it (registered, probed, scored)
bench model retire <alias> --reason "..." and back: bench model restore <alias>
bench collection save reviewers --members a,b,c --description "adversarial review"
bench collection save reviewers --add d --remove a
bench endpoint add openrouter --base https://openrouter.ai/api/v1 (asks for the key, hidden)
bench key create my-app --collections core --rpm 30
bench settings scheduler run --off perf--help on any command lists its options with examples, and --json prints
what the server answered, for scripts. --url points one command at another
server. ask prints every seat's answer on stdout and the table of call ids to
judge them by on stderr, so bench ask core "..." > review.md keeps only the
answers. Retiring a model, deleting a collection or an endpoint and revoking a
key ask first; --yes answers for a script. A key is never an argument (others
on the machine can read those): endpoint add prompts for it, or reads it
from stdin with --key-stdin.
Another program called bench (the Frappe framework's) may come first on your
PATH; type benchwarmers instead, which takes the same commands.
Variable | Meaning |
| the server, default |
| the server's admin token, where it has one; sent as |
| a gateway key, for |
| seconds to wait for a panel, default 900 |
Exit codes: 0 done, 1 refused or failed (the reason on stderr), 2 bad usage, 3
no server at BENCHWARMERS_URL.
From Claude Code and other agents
A running Benchwarmers is an MCP server at /mcp on its own port
(http://127.0.0.1:8122/mcp; /v1/mcp works too), over streamable HTTP,
with three tools: list_collections, ask (a collection, a prompt,
optionally merged, with and system) and verdict. Nothing to start per
client: every agent session shares the one server, behind the same Host,
Origin and gateway-key checks as /v1. The tool descriptions carry the
rules: ask a collection, not a favourite model; verify before acting; name
every seat; send a verdict per seat you judged.
Claude Code plugin. The plugin connects to that /mcp and adds a
/benchwarmers:ask <collection> <what to ask> command and a benchwarmers
skill saying when a panel helps (adversarial review, exhaustive enumeration
over real files) and how to judge it:
/plugin marketplace add WendellResearch-AI/benchwarmers
/plugin install benchwarmers@benchwarmersIt finds the server through BENCHWARMERS_URL (default
http://127.0.0.1:8122; set it if you changed BENCH_PORT) and sends
BENCHWARMERS_KEY where keys are required. It also adds a Stop hook: at
the end of a turn it asks the server (the pending_verdicts tool, so nothing
extra runs on your machine) which seats of that session's panels have no
verdict yet, and reminds Claude of them once, as hook feedback. The server
finds the session's panels in its transcript, so the reminder needs a server
on the same machine; with one elsewhere the hook stays silent. A verdict sent
any way counts, the dashboard's included. With the plugin enabled and no
Benchwarmers running, the hook shows a hook-error notice at the end of each
turn, as /mcp shows the server as failed; start the server, or disable the
plugin for that session.
Cursor and Antigravity plugins. The same skill, with the stdio server below (so they need Node and Python 3.11 or later): Cursor's is on cursor.directory, and Antigravity's installs from the repository:
agy plugin install https://github.com/WendellResearch-AI/benchwarmersAny other MCP client that speaks HTTP:
{"mcpServers": {"benchwarmers": {"type": "http", "url": "http://127.0.0.1:8122/mcp"}}}with "headers": {"Authorization": "Bearer <gateway key>"} where keys are
required. A client that only speaks stdio: run benchwarmers mcp once
installed, uvx benchwarmers mcp or
npx -y @wendellresearch-ai/benchwarmers mcp without installing, or python mcp_server.py from a
checkout, a small process per client that calls the same server. For example:
{"mcpServers": {"benchwarmers": {"command": "npx", "args": ["-y", "@wendellresearch-ai/benchwarmers", "mcp"],
"env": {"BENCHWARMERS_URL": "http://127.0.0.1:8122"}}}}On native Windows, a client that cannot start npx itself needs
"command": "cmd", "args": ["/c", "npx", "-y", "@wendellresearch-ai/benchwarmers", "mcp"].
Variable | Meaning |
| the server, default |
| a gateway key from Settings, sent as |
| seconds to wait for a panel, default 900 |
Behind an MCP aggregator (1mcp, MetaMCP, mcp-proxy, Docker's MCP Gateway
and the like): add http://127.0.0.1:8122/mcp as an HTTP (streamable HTTP)
upstream, with the Authorization header where keys are required; an
aggregator that only runs stdio servers takes benchwarmers mcp as above.
Give it a request timeout of a few minutes or more, as a panel takes that
long; 1mcp's default of 60 seconds ends most of them. With 1mcp, for example:
1mcp mcp add benchwarmers --type http --url http://127.0.0.1:8122/mcp --timeout 900000The aggregator prefixes the tool names (1mcp's are
benchwarmers_1mcp_ask and so on). If you also use the Claude Code plugin,
disable the plugin's own benchwarmers server in /mcp so the tools are not
listed twice; the skill and /benchwarmers:ask keep working, though the
command then asks before each tool call, since its pre-approved tools carry
the plugin's names. The plugin's verdict hook calls the plugin's own server,
so it does not work through an aggregator: with that server disabled it only
shows a hook-error notice at the end of each turn.
An agent running on a collection. The MCP tools ask a panel for a
second opinion; an agent can also be driven by a collection, in route
mode (bench/<collection>:route): one member, picked by its record, gets
each turn with its tools, stays on for the whole conversation, and is
replaced by the next member if it fails before answering. Claude Code
points at it with ANTHROPIC_BASE_URL=http://127.0.0.1:8122 and
ANTHROPIC_MODEL=bench/core:route; Codex, opencode, Cline and other
OpenAI-, Responses- or Ollama-speaking agents with the same base URL.
GATEWAY.md, "Route mode", has the set-up and the limits.
The suite
Models are scored on review work: find the faulty line, or say whether a claim about some code is true. The repository ships a starter pack:
Real bugs (
suite/tasks/rebench-*): recent fixes from public projects, drawn from the SWE-rebench-V2 dataset, each paired with a control.Claims (
suite/tasks/claim-*): true and false statements about this project's own code, with the code attached.
Add your own from your repositories (config/repos.json in the data folder
maps a name to a folder): python suite/seed.py --repo <name> plants
realistic bugs in your real functions, each with a clean control. Private
code makes the best tasks, because no model has trained on it. See
suite/README.md, suite/REBENCH.md and
BENCHMARKS.md.
Docker and hosting
One container runs the dashboard, the gateway (on the same port, at /v1)
and the scheduler, with the data folder as a volume and no llm CLI (the
built-in client makes every call). Put the secrets in a .env file beside
compose.yaml:
BENCHWARMERS_ADMIN_TOKEN=<16 or more characters>
BENCHWARMERS_KEY_OPENROUTER=sk-or-...then docker compose up -d and open http://127.0.0.1:8122. The compose file
publishes on this machine only; see its comments for a proxy.
Hosted, always on: HOSTING.md compares Fly.io, Railway, Render and a VPS with Caddy (cost, sleep, disks, HTTPS), with a template for each under deploy/.
Render is one click: a paid instance with a 1 GB disk and a generated admin
token. Fly.io is four commands from a checkout (cp deploy/fly.toml .,
fly launch --copy-config --no-deploy, fly secrets set BENCHWARMERS_ADMIN_TOKEN=..., fly deploy). Railway is a few steps in its CLI
or browser, in HOSTING.md.
What leaves your machine
Benchwarmers has no account, no telemetry and no server of its own; nothing reaches Wendell Research. What it sends, and where:
Your prompts, only to the endpoints you add: a provider, an aggregator, a hub such as Open WebUI, or a local runtime. That includes the probes, the suite and onboarding, which spend calls on your keys. Add only endpoints you are content to send that work to.
Catalog reads, no key and nothing of yours: models.dev and FreeLLMAPI once a day, and OpenRouter's public model list.
Sign-ins, only when you choose one: the provider's own sign-in page.
Charts: the dashboard's browser page loads Observable Plot from jsDelivr at a pinned version.
Seeding real-bug tasks, only when you run
suite/rebench.py: the SWE-rebench-V2 rows from Hugging Face and the files from GitHub.
Keys stay in the environment or llm's key file (keys.json in its user
folder), never in the data folder. PRIVACY.md and SECURITY.md have the
detail.
Limits
Tools go through route mode only. A panel answers with text; a request with tools is refused there, not trimmed. Route mode passes turns only to members on chat-completions endpoints, keeps its sticky conversations in memory (a restart starts each on a fresh pick), and has been run end to end with Claude Code; the Codex, opencode and Cline set-ups are written from their docs. Shadow seats (other members answering an agent's turn for evaluation) are planned, not built.
Some parts are checked against fakes only. The native Anthropic and Gemini endpoints, and the LiteLLM and CLI Proxy API hub adapters, are built from those APIs' documentation and source and tested against fake servers, not yet against the real services.
A merged reply arrives in one piece once the merger has finished; the seats before it stream as they finish.
Pacing and the ledger cover the built-in client. Calls made through the
llmCLI, when you choose it, are neither paced nor counted.Calls cost. Probes, onboarding and the suite run on your keys and free tiers. Onboarding runs one model at a time for that reason (Quick spreads the suite over the scheduled passes); a suite pass is paced, not burst.
The scheduler lives in the server. Its jobs run while the dashboard (or the container, or the service) is up; a missed run is made up once, within seven days, when it comes back.
One install, one person at heart. Logins and gateway keys exist for a LAN or a server, but there are no per-user views or roles.
The onboarding queue lives in the dashboard's memory. Restarting it drops the rest of a batch; each started model's log stays in
runs/.Free tiers change without notice. Discover's prices come from public catalogs, and some providers' free models work only in their own app (switched per provider on Settings).
Security
Both servers listen on 127.0.0.1 by default and accept only same-origin writes
for their own host name, so a web page in your browser cannot drive them. To
listen anywhere else, set BENCHWARMERS_ADMIN_TOKEN first; without it they
refuse to start. With it, the dashboard asks for a login and the gateway takes
named, revocable gateway keys. Settings, under Server and access, shows how
this stands (whether a secret is set, never its value).
SECURITY.md has the whole model and how to report a vulnerability.
Development
python scripts/check.py # every self-check and test (--quick skips the slow one)The core is the Python standard library only. CI runs the checks on Linux and Windows for Python 3.11 to 3.13, and on macOS.
Benchwarmers isn't taking outside contributions yet; that opens once it is more established. A security problem goes through SECURITY.md.
Licence
MIT, Copyright (c) 2026 Wendell Research (LICENSE). The starter tasks and bundled fonts carry their own licences, listed in NOTICE. Use is also covered by TERMS.md.
Available Tools
4 toolsaskAsk a collectionA
Put a prompt to every seat of one collection at once and get every answer back, each under its seat and model, plus the seats as data (alias, seat, status, call id). Can take minutes. Ask a collection, not a favourite model. Give the seats the real text (code, diff, file contents) in the prompt: they cannot read your files. Verify every claim against the source before acting on it, name every seat that answered in what you tell the user, then send a verdict per seat you judged.
| Name | Required | Description | Default |
|---|---|---|---|
| with | No | Model aliases to seat in explorer chairs, this request only. | |
| merged | No | true: one reconciled answer, every seat still called and listed; false: every answer. Omit for the collection's own. | |
| prompt | Yes | The question, with everything it needs. | |
| system | No | A system message for every seat. | |
| collection | Yes | A collection name, `core` or `bench/core` (list_collections). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
While annotations provide basic hints, the description adds vital behavioral context that annotations cannot: the latency ('Can take minutes'), the scope of the output (getting answers under each seat/model), and the operational constraint regarding file access.
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 very dense, covering function, constraints, workflow, and operational details in one paragraph. While highly efficient, the density prevents a perfect 5, but it earns 4 for its extremely high information density and front-loading of critical information.
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?
The description is complete by setting a functional goal and describing the full lifecycle of the tool. It manages expectations (time, required input format) and guides the agent toward the next logical step in the workflow (the `verdict` sibling tool).
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?
Since schema coverage is 100%, the baseline is already high. However, the description adds semantic value by instructing the user on required input content ('Give the seats the real text') and clarifying that the `merged` parameter should be omitted when querying 'the collection's own' seats, adding critical usage context to specific fields.
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 that the tool broadcasts a prompt to every seat within a specified collection. It effectively distinguishes itself by stating, 'Ask a collection, not a favourite model,' immediately clarifying its purpose relative to potential single-model query tools.
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 provides highly specific usage guidelines, including a critical warning: users must provide 'the real text (code, diff, file contents)' because the seats cannot read external files. It also dictates the required post-call workflow: 'Verify every claim... send a verdict per seat you judged.'
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_collectionsList collectionsARead-only
The collections this Benchwarmers server offers: name, what each is for, tags, members, explorer seats, reply mode, and what the members handle together (smallest context window, shared capabilities, tightest rate limits). Pick by task before calling ask.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is known. The description adds real context beyond that by disclosing the returned fields, including aggregate member constraints (smallest context window, tightest rate limits) — non-obvious derived data an agent would otherwise have to discover empirically.
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?
One front-loaded sentence plus a short call-to-action sentence, with no filler. The parenthetical of aggregate properties is dense but each item earns its place by telling the agent what comparison data is available.
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?
With no output schema, the description carries the burden of describing return contents and does so field-by-field, which is adequate for a no-arg discovery tool. It stops short of explaining ordering or how the 'what each is for' text should be interpreted for selection, but nothing essential for invoking it is missing.
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 tool takes zero parameters, so the baseline is 4; there is nothing for the description to disambiguate and it correctly omits parameter discussion.
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 states the resource (the collections this Benchwarmers server offers) and enumerates the metadata each entry carries (name, purpose, tags, members, seats, reply mode, aggregate limits), which makes clear this is a discovery/enumeration tool. Combined with the title 'List collections' the intent is unambiguous, though the description itself never uses an explicit verb like 'list' or 'returns'.
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?
'Pick by task before calling ask' gives explicit routing guidance: call this first to choose a collection, then invoke ask. It does not address the other siblings (verdict, pending_verdicts) or say when not to use it, so it stops short of full when/when-not coverage.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pending_verdictsSeats still to judgeARead-only
For the Benchwarmers Claude Code plugin's Stop hook, which calls it at the end of a turn: the seats of this session's panels that have no verdict yet. You do not need to call it; send verdicts with verdict.
| Name | Required | Description | Default |
|---|---|---|---|
| active | No | The hook's stop_hook_active: true says nothing. | |
| session | No | The Claude Code session id. | |
| transcript | No | The session's transcript_path. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare `readOnlyHint: true` and `openWorldHint: false`, but the description adds useful context about the Stop-hook lifecycle and what the tool conceptually returns. It does not describe return shape or error behavior, which keeps it just short of fully transparent.
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 two tight sentences that front-load the operational context and the key agent instruction. The plugin-specific phrasing is slightly opaque, but there is no obvious filler.
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?
For a read-only, non-open-world tool whose parameters are fully schema-documented and whose likely caller is a hook, the description gives enough to understand what it returns and why an agent usually should not call it. A bit more detail on the return shape would make it complete.
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 100%, so all three parameters are already documented in the schema. The description mentions 'this session's panels' but does not add meaning beyond the schema for `active`, `session`, or `transcript`, so the baseline of 3 is appropriate.
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 states the resource clearly: the seats of this session's panels that have no verdict yet. It also distinguishes the tool from the `verdict` sibling by saying verdicts are sent there, though it does not use an explicit verb like 'list' or 'return'.
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?
It explicitly explains the usage context: it is called by the Benchwarmers plugin's Stop hook at the end of a turn. It also gives explicit when-not guidance ('You do not need to call it') and names the alternative tool for sending verdicts (`verdict`).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
verdictRecord a verdictAIdempotent
Judge one seat's answer by its call id, once you have checked it against the source. One per seat you judged. List the claims it got right in real and the claims that are untrue in false, one sentence each: they feed routing and the 'confidently wrong' record, so a note alone is not enough.
| Name | Required | Description | Default |
|---|---|---|---|
| call | Yes | The seat's call id, e.g. p20261022-101500-ab12.member1. | |
| note | No | One or two sentences on why. | |
| real | No | Claims it made that are true, one sentence each. | |
| false | No | Claims it made that are untrue, one sentence each. | |
| useful | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare this is a non-read-only, idempotent, non-destructive operation. The description adds meaningful behavioral context: real/false claims feed routing and the 'confidently wrong' record, and a note alone is insufficient.
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 front-loaded with the core action, then conditions and parameter expectations. It is dense but every sentence carries operational meaning, with no wasted preamble.
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?
For a five-parameter tool with annotations and no output schema, the description covers purpose, timing, per-seat requirement, and the importance of real/false. The main gap is that it does not explain the required useful boolean.
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 coverage is 80%, so the schema already documents call, note, real, and false. The description adds semantics for real and false as one-sentence true/untrue claims, and explains why note alone is not enough; however, the required useful boolean remains unexplained.
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 states a specific verb and resource: judging one seat's answer by its call id. It is clear what the tool does, though it does not explicitly differentiate itself from sibling tools such as pending_verdicts.
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?
It gives a clear usage condition: judge once the answer has been checked against the source, and submit one verdict per seat judged. It does not name alternatives or explicit when-not conditions, so it falls short of full routing guidance.
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.
4 tool updates
v0.1.0- First observed
ask - First observed
list_collections - First observed
pending_verdicts - First observed
verdict
TDQS
Scored across 4 tools
Each tool targets a distinct step: discover collections, query a panel, submit a judgement, and enumerate unjudged seats. The only soft boundary is between `verdict` and `pending_verdicts`, which the description partially resolves by telling the agent it never needs to call the latter, though that still invites hesitation.
`list_collections` uses a verb_noun pattern while `ask` and `verdict` are bare action words and `pending_verdicts` is a noun phrase. The names are readable and memorable, but there is no single predictable convention an agent can rely on.
Four tools is lean but matches the narrow discover→ask→judge loop, with no redundant entries. `pending_verdicts` exists mainly for a plugin hook rather than agent use, so the effective agent-facing surface is even smaller, which is acceptable but slightly thin.
The core lifecycle is covered: enumerate collections, fan a prompt to all seats, and record per-seat correctness feedback that feeds routing. Gaps are minor: no way to inspect prior calls or verdicts, cancel a long-running `ask`, or query the 'confidently wrong' record that verdicts supposedly populate.
Maintenance
Related MCP Connectors
AI model routing on your own vendor keys: pick the best model per prompt, or route and run it.
Self-hosted AI prompt library: prompts, collections, tags, teams, chains. 29 MCP tools for agents.
Chat with any LLM, generate images, browse models and check your usage and costs.
LLM cost optimization gateway, repo token-waste auditor & model arbitrage MCP server.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceAn MCP server that queries a panel of LLMs from different providers via OpenRouter and returns their answers side by side, optionally synthesizing them to highlight disagreements.1 npm1MIT
- AlicenseNot gradedqualityDmaintenanceA self-hostable MCP server that routes prompts to multiple LLM providers using declarative policies, with multi-role orchestration for independence and verification.MIT
- AlicenseAqualityAmaintenanceBlind multi-model councils with anonymous LLM seats and direct 1:1 chat as a local MCP server. Enables asking one question to get independent answers from multiple model CLIs, then blind scoring and reveal.17AGPL 3.0
- AlicenseNot gradedqualityBmaintenanceSelf-hosted MCP gateway that aggregates many MCP servers into a single endpoint for AI clients, supporting hosted, local stdio, and Git-sourced MCPs.2MIT