Skip to main content

Measure and improve how well LLM agents select and use the tools exposed by an MCP server

Project description

whetkit

Measure — then improve — how well LLM agents pick and use the tools your MCP server exposes.

whetkit is a local-first CLI that runs an agent against your MCP server on a set of eval tasks, scores its tool-selection hit-rate, and then curates the tool set — renaming cryptic tools, rewriting vague descriptions, pruning noise, and merging duplicates — via a reversible overlay proxy that never modifies your server. It re-runs the eval through the overlay and hands you a before/after report.

Unlike MCP inspectors and testing frameworks, whetkit closes the optimization loop: it measures agent behavior, proposes a curated tool surface, applies it through a reversible proxy, and re-runs the same evals to quantify the improvement.

whetkit doctor    ──►  ten-second lint of the tool surface        (no tasks, no API key)
whetkit inspect   ──►  what does the agent actually see?
whetkit generate  ──►  draft eval tasks from the inventory        (review, then run)
whetkit run       ──►  how often does it pick the right tools?   (hit-rate)
whetkit curate    ──►  fix the tool set, prove it helped          (before → after)

Why tool curation matters

Agents don't read your code — they read your tool names, descriptions, and schemas. A server that grew organically ends up with data_query_1, proc_ord, and do_thing: every one of them costs the model a guess, and every duplicate splits its attention. In practice a large share of agent failures on MCP servers are tool-selection failures — the model calls the wrong tool, loops through near-duplicates, or gives up — and they are fixable without touching a line of server code, because the fix is metadata. whetkit makes that loop measurable: score the failures, patch the metadata through an overlay, and show the hit-rate delta.

Install

uv tool install whetkit   # or: uvx whetkit / pipx install whetkit

(Released to PyPI from tags — see RELEASING.md. PyPI can lag behind main; the quickstart below runs from source.)

Quickstart (5 minutes)

Requires uv and an Anthropic API key (or OpenAI — see --model). Python is pinned via .python-version; uv fetches it automatically.

git clone https://github.com/benlamlih/whetkit && cd whetkit
uv sync
export ANTHROPIC_API_KEY=sk-ant-...

1. Inspect the bundled sample server — a deliberately messy e-commerce server (14 tools: cryptic names, vague descriptions, duplicates, noise):

uv run whetkit inspect --server examples/sample-server

2. Baseline eval — run 5 tasks against it and score the hit-rate (deterministic tool-matching + LLM-judge on the final answers):

uv run whetkit run --server examples/sample-server --tasks examples/tasks

3. Curate and prove it — analyze the failures, generate a curation overlay, re-run the eval through it, and get the before/after:

uv run whetkit curate --server examples/sample-server --tasks examples/tasks

This writes:

  • .whetkit/curation-plan.yaml — the reviewable, hand-editable overlay plan
  • .whetkit/report.html — self-contained before/after report (open it in a browser)
  • .whetkit/report.json — the same data, machine-readable
  • .whetkit/traces.sqlite3 — full reasoning-path traces of every run

The sample server's failures are tool-selection failures, so weaker models flip several tasks from MISS to HIT through the overlay. Frontier models often ace even the messy baseline on a 14-tool server — there the delta shows up in the other columns instead: tools exposed, tokens per task, and extra calls. On large real-world servers (dozens of tools, near-duplicates) the hit-rate delta comes back.

Stdio servers' own logs are hidden so they can't garble the output; set WHETKIT_SERVER_LOGS=1 to see them when debugging a server that won't start.

The plan is yours to edit: tweak a rename the optimizer got wrong, un-hide a tool, then re-score the curated view directly —

uv run whetkit run --server examples/sample-server --tasks examples/tasks \
  --plan .whetkit/curation-plan.yaml --group curated-v2

4. Use the curated view for real — serve it to any MCP client:

uv run whetkit overlay --server examples/sample-server --plan .whetkit/curation-plan.yaml

Nothing about your origin server changes, ever. Delete the plan and you are back to the original world.

Pointing it at your own server

  • --server accepts a URL (streamable HTTP; --http-mode stateless for 2026-07-28-spec servers), a directory containing server.json or server.py, or a .py/.json path directly.
  • Write tasks in YAML — format reference in docs/task-format.md — or draft them: whetkit generate --server <your-server> --out tasks/generated.yaml writes candidate tasks from the tool inventory (validated against the live tool list; review before trusting).
  • --model / --judge-model / --optimizer-model take provider:model_id, e.g. anthropic:claude-sonnet-5 or openai:gpt-5.2. Keys come from ANTHROPIC_API_KEY / OPENAI_API_KEY.

Commands

Command What it does
whetkit doctor Lint the tool surface: vague descriptions, cryptic names, near-duplicates, context bloat. --json; --fail-on warn for CI.
whetkit inspect Tool inventory: names, params, description tokens, schema complexity.
whetkit generate Draft eval tasks from the inventory; validated, review-before-trust YAML.
whetkit run Agentic eval loop with real tool execution; scored results + traces. --plan scores a curated view.
whetkit curate Baseline → LLM-proposed overlay plan → curated eval → before/after report.
whetkit report Rebuild the HTML/JSON report from stored traces.
whetkit overlay Serve the curated view as a stdio MCP server.

How scoring works

  • Deterministic tool-match: each task lists the expected tool calls (with acceptable alternatives, optionally ordered). Order-tolerant by default, --match-mode exact for strict grading. Reports precision/recall, missing and extra calls.
  • LLM-as-judge: grades the agent's final answer against the task's natural-language success_criteria with a strict calibrated prompt; verdicts are cached in SQLite. --judge auto|on|off.
  • Hit = right tools and (when judged) task success. The headline metric is the hit-rate across tasks.

More docs: docs/task-format.md · docs/curation.md · VERSIONS.md · MIGRATION.md

Development

uv sync
uv run pytest        # full suite, no API key needed (scripted fake provider)
uv run ruff check .

Dependency versions are pinned exactly and documented with sources and check dates in VERSIONS.md. The MCP transport layer supports stdio, legacy stateful streamable-HTTP (2025 spec), and stateless streamable-HTTP (2026-07-28 spec); the SDK-facing code is isolated for the v1→v2 migration (MIGRATION.md).

Scope note: whetkit is deliberately a local-first CLI. Hosting, dashboards, multi-tenancy, and security tooling are out of scope for Stage 1 — the architecture just leaves room for them.

License

Apache-2.0 — see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

whetkit-0.3.0.tar.gz (51.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

whetkit-0.3.0-py3-none-any.whl (66.3 kB view details)

Uploaded Python 3

File details

Details for the file whetkit-0.3.0.tar.gz.

File metadata

  • Download URL: whetkit-0.3.0.tar.gz
  • Upload date:
  • Size: 51.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for whetkit-0.3.0.tar.gz
Algorithm Hash digest
SHA256 a8c2b2ad3bc2134ee588f8abbb61e6bc8e6ecd25190c5d90ce54b1a7fc4a6073
MD5 6be5dbdcabf3c7f4fac0a754bdbd92d2
BLAKE2b-256 98851463d5f4e1ecb5d5e87c76609cff388948aad0466e775baef1be3a52b1e3

See more details on using hashes here.

Provenance

The following attestation bundles were made for whetkit-0.3.0.tar.gz:

Publisher: release.yml on benlamlih/whetkit

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file whetkit-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: whetkit-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 66.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for whetkit-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 14eae65039a6039799b30909460c6168afd4f3299c5fdd680752e670cce41363
MD5 268c1ec96db303f4222ca113a0d005a2
BLAKE2b-256 72fa99749d9069a533a27c81d93c6484d58ac9ddbee569ab7be3ffcd7fc2d9fa

See more details on using hashes here.

Provenance

The following attestation bundles were made for whetkit-0.3.0-py3-none-any.whl:

Publisher: release.yml on benlamlih/whetkit

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page