EvalTest/EvalSuite, or manually using the APIs below.
Environment Variables
Use
MCPJAM_BASE_URL only when you need to override the default ingest host, such as internal development against a non-production backend.
MCPJAM_API_KEY controls whether results are uploaded. Replay credential capture only happens when you provide serverReplayConfigs, agent, or mcpClientManager. MCP App widget snapshots in each result’s trace (for iframe replay in MCPJam) come from PromptResult.getWidgetSnapshots(), which is only populated when HostRunner was constructed with mcpClientManager.
Tool execution and passed
Uploaded iterations have a single boolean passed that drives pass rate on the dashboard. The SDK distinguishes:
- Structural pass — Your test returned
true, or expected tool calls were satisfied (Inspector/UI flows use shared matching logic). - Tool execution — The trace shows a real tool failure: MCP results with
isError: true, timeline spans where a tool step ended inerror, tool-result parts the UI would treat as errors, or a runner-leveliterationErrorafter a thrown tool step.
passed from a trace (for example EvalTest / EvalSuite auto-save, PromptResult.toEvalResult(), createEvalRunReporter helpers, or Inspector suite runs), structural success is not enough if tool execution failed — the iteration is recorded as failed unless you opt out.
Opt out: set failOnToolError: false on MCPJamReportingConfig (global for that reporter or auto-save), or pass it on specific helper options (addFromPrompt / recordFromRun / RunToEvalResultsOptions, etc.). Use this when you only care that the model invoked the right tools with the right arguments, not that every MCP call returned a success payload.
Manual reportEvalResults: If you build results[] yourself and set passed explicitly, MCPJam stores your values as-is. The execution gate applies to code paths that compute passed from prompts, traces, and iterations.
Programmatic reuse: @mcpjam/sdk also exports finalizePassedForEval, traceIndicatesToolExecutionFailure, isCallToolResultError, traceMessagePartIndicatesToolFailure, classifyToolFailurePart, and extractToolErrors for custom ingestion pipelines. The @mcpjam/sdk/predicates sub-package exports the full predicate evaluator (evaluatePredicate, evaluatePredicates, allPredicatesPassed, buildIterationTranscript) and all predicate types.
reportEvalResults()
One-shot reporting. Sends all results in a single call. Throws on failure.Signature
Example
reportEvalResultsSafely()
Same asreportEvalResults(), but returns null instead of throwing on failure. Warnings are logged to the console.
Signature
Example
Use
reportEvalResultsSafely() when you don’t want eval reporting failures to break your CI pipeline. Use reportEvalResults() (strict) when reporting is critical.createEvalRunReporter()
Creates an incremental reporter for long-running processes. Results are buffered and flushed in batches (up to 200 results or 1MB per batch).Signature
CreateEvalRunReporterInput accepts the same replay source fields as reportEvalResults(): serverReplayConfigs, agent, and mcpClientManager.
EvalRunReporter Methods
PromptResult Helpers
EvalTest/EvalSuite Run Helpers
Example
Example with manual replay source resolution
Replay credential sources
Authenticated HTTP evals can securely persist replay credentials for reruns and debugging. Manual reporting APIs resolve replay configs in this order:serverReplayConfigsagent.getServerReplayConfigs()mcpClientManager.getServerReplayConfigs()
agent or mcpClientManager directly. Use serverReplayConfigs only when you need a low-level override.
If you also provide serverNames, inferred replay configs are filtered to those server IDs before upload. Explicit serverReplayConfigs are left unchanged.
Replay metadata for the MCPJam UI
Uploaded runs can show Replay this run / server-side MCP replay when the ingest payload includes derivedserverReplayConfigs (stored as hasServerReplayConfig on the run). In practice:
- HTTP MCP (
url) — Replay configs are built for typical streamable HTTP connections. Stdio transports do not produce entries fromMCPClientManager.getServerReplayConfigs(); use HTTP when you need dashboard replay. HostRunnervs reporter — PuttingmcpClientManageronHostRunnerfills MCP App widget snapshots onPromptResult. The reporter (and one-shotreport*) resolves server replay from its ownagent/mcpClientManagerfields. PassagentormcpClientManagerintocreateEvalRunReporteras well; agent-only wiring can still upload traces and widgets but omithasServerReplayConfig.- Teardown order —
finalize()/ one-shot reporting callsgetServerReplayConfigs()against connected registrations. InafterAll, runawait reporter.finalize()(orreportEvalResults) beforeawait manager.disconnectAllServers(). Disconnecting first clears manager state and uploads without replay metadata.
Using with PromptResult
Using with EvalTest Runs
uploadEvalArtifact()
Parses test artifacts (JUnit XML, Jest JSON, Vitest JSON) and reports the results to MCPJam.Signature
Supported Formats
Example
Types
ReportEvalResultsInput
MCPJamReportingConfig
Run-level host snapshot
When a usable host snapshot is available, the reporter includes a normalized + content-hashed host config alongside the run body (the v1 ingest surface always accepts the pair — the old per-baseUrl capability probe is gone):
iteration.hostSnapshot— per-iteration capture fromHostRuntime(Stage 4). Reflects the boundHoststate at the iteration’s end.executor.getHostSnapshot?.()— fallback for executors that don’t expose per-iteration snapshots.MCPJamReportingConfig.host— explicit override, compatibility path.
{ hostConfig, hostConfigHash } when all available iteration snapshots canonicalize to the same hash. Heterogeneous runs (e.g. mutating the bound Host between iterations) omit the run-level field — per-iteration wire support is a later stage.
Fail-safe omission. Any error while resolving or canonicalizing the snapshot — malformed hostSnapshot, an executor that throws, non-canonicalizable host JSON — logs a warning and omits the wire pair rather than failing the eval upload. The body shape stays the same without it.
Server-id normalization. Runtime-manager identifiers (serverIds, optionalServerIds, serverConnectionOverrides) are stripped by normalizeSdkEvalHostConfigForWire on both ends so SDK runtime ids like "everything" never reach the backend’s validateServerScope as Id<'servers'>. The persisted hostConfigsV2 row’s hash will differ from the wire hostConfigHash because suite-resolved Convex server ids are layered on top at storage time — the wire hash is a transport-integrity check, not the storage id.
MCPServerReplayConfig
Advanced replay override. Most users should not construct this manually.EvalCiMetadata
EvalResultInput
Predicate gate
successPredicates adds a deterministic, state-based assertion layer on top of tool-call matching. Each predicate is a pure function of the iteration transcript — same transcript, same verdict — which makes it suitable as a CI release gate.
A case passes the predicate gate iff all predicates pass. An absent or empty list means no predicate gate (the case is judged solely by tool-call matching and failOnToolError).
Predicate types
ArgMatcher
Used bytoolCalledWith to specify expected arguments and matching mode.
Fail-closed behavior
Malformed predicates (unknown type, missing required fields, invalidminCount, empty needle/pattern) always fail the case rather than silently passing. responseMatches also fails closed on patterns with nested quantifiers (ReDoS guard) and on messages exceeding 100,000 characters.
Example
Predicate results in metadata
When the Inspector runner evaluates predicates, it persists one row per predicate totestIteration.metadata.predicates:
ReportEvalResultsOutput
Related
- Running Evals - Conceptual guide
- EvalTest Reference - EvalTest API
- EvalSuite Reference - EvalSuite API

