Skip to main content
LLMs are probabilistic—the same prompt might produce different results each time. Running a test once tells you it can work, not that it reliably works. Evals run the same test many times and measure statistical accuracy.

Why Run Evals?

A single test pass can be misleading:
  • The LLM might get lucky on one attempt
  • Temperature introduces randomness
  • Different phrasings might fail where others succeed
Running 30+ iterations gives you confidence in real-world performance:
  • “This tool is called correctly 97% of the time”
  • “Arguments are correct in 90% of cases”
  • “Average latency is 1.2 seconds”

EvalTest: Single Test Scenario

EvalTest runs one test function multiple times:

Writing Test Functions

Test functions receive an HostExecutor (implemented by HostRunner and mock agents) and return boolean:

Run Options

Metrics

After running, access various metrics:

EvalSuite: Multiple Tests

Group related tests together:

Save Results to MCPJam

Both EvalTest and EvalSuite can automatically save results to MCPJam when a run completes. Set MCPJAM_API_KEY to an MCPJam API key (sk_…) from Settings → API keys and results are saved automatically:
Results are filed under the project in MCPJAM_PROJECT_ID (or the project option), defaulting to your organization’s Default project. For manual save APIs, CI metadata, and artifact uploads, see the Save Results to MCPJam guide.

Tool errors vs. passed on upload

By default, when results are built from traces (auto-save and reporter helpers), a failed tool execution (MCP isError, errored tool spans, or error tool-results in messages) sets passed: false for that iteration even if your test function returned true. That keeps CI pass rate aligned with real server behavior. To disable that for a run (for example you only assert which tools were called, not that every call succeeded), set failOnToolError: false on the mcpjam block:
See Eval reporting — Tool execution and passed for full detail and createEvalRunReporter overrides.

Predicate gate

successPredicates lets you express richer pass/fail criteria beyond tool-call matching — without an LLM judge. Predicates are pure functions of the iteration transcript, so they produce the same verdict every time and are safe to use as a CI release gate. A case passes iff all predicates pass. An absent or empty list means no predicate gate. The eight built-in predicate types: Predicates are authored in the corpus JSON (V1) and threaded through the runner automatically. See Predicate gate reference for the full type definitions and a code example.

Suite Results

Choosing Iteration Count

Best Practices

Use Low Temperature

More deterministic results for testing:

Handle Rate Limits

Reduce concurrency for rate-limited APIs:

Test Edge Cases

Don’t just test the happy path:

Set Quality Thresholds

Fail CI if accuracy drops below a threshold:

Bring your own host

HostRunner is the right starting point when you just need an LLM + tools + a model string. For richer setups — pinning a host style/profile, applying sandbox/permission policy, or running the same configuration in CI that the MCPJam Inspector uses for its Playground — start from a Host spec instead:
HostRuntime (returned by host.withManager(...)) snapshots the live Host on every .run(), so mutating the bound host between iterations takes effect on the next iteration. HostRunner snapshots once at construction — pick HostRunner for a static spec, HostRuntime when you want the spec editable across calls. Personal computer. A Host can declare a personal cloud workstation via the computer property (type HostComputer, exported from @mcpjam/sdk). When set, the chatbox surfaces a bash tool and a web terminal for signed-in members. Use setComputer() to attach or detach it fluently:
Or pass it directly in the constructor:
null and an absent computer field hash identically, so existing host configs are unaffected. The computer field is automatically stripped from eval wire configs — evals never target personal computers. Statelessness. HostRuntime.run() does NOT auto-replay history across turns. Use PromptOptions.context to thread context explicitly:
Eval reporting (Stage 5). When you upload results to MCPJam, the reporter additionally sends the canonical host config alongside each run ({ hostConfig, hostConfigHash }) so the persisted row in the Evals UI shows the exact host you ran with. Pass 1 sends a run-level snapshot only when all iteration snapshots match; heterogeneous runs (mutating the bound Host between iterations) omit the run-level field for now. Old backends without the capability are unaffected. Source order is iteration.hostSnapshotexecutor.getHostSnapshot?.()MCPJamReportingConfig.host.

Generate evals from the Inspector

You can also generate eval code from the MCPJam Inspector. Click ⋮ → Copy markdown for evals on any server card, then paste it into an LLM. See the Quickstart for details.

Next Steps

Testing Across Providers

Compare performance across LLMs

EvalTest Reference

Full EvalTest API

EvalSuite Reference

Full EvalSuite API

Save Results to MCPJam

Auto-save, manual APIs, CI metadata, and artifact upload