Dev Tools·
advanced
·12 min read·Sep 24, 2026
By Rad Tome·Lead AI Systems Architect

JEM Trajectory Evaluation for MCP Tool Calls

Implement Judged Exact Match (JEM) and Joint Step Verification to evaluate, benchmark, and regression-test multi-turn Model Context Protocol tool calling trajectories.

jemevaluationbenchmarksmcptrajectory-analysistesting
Interactive Tool
1-Click Export

Generate & Validate Multi-Client MCP Config

One-click export with environment variables & path locators for Claude Desktop, Cursor, Windsurf, and OpenAI Codex CLI.

Open in Generator

JEM Trajectory Evaluation for MCP Tool Calls

Traditional LLM evaluation relies on lexical string matching (BLEU, ROUGE, Exact Match). In autonomous agent orchestration with the Model Context Protocol (MCP), these metrics fail completely. An agent debugging a repository might choose git diff before git log, query a table with varying column order, or rephrase JSON query parameters while producing a strictly correct execution result.

To solve this evaluation bottleneck, production AI engineering teams have standardized on Judged Exact Match (JEM) and Joint Execution Verification (JEV).

JEM evaluates whether an agent trajectory achieves mathematical and semantic goal equivalence across multi-step MCP tool calls. This guide demonstrates how to build an automated JEM evaluation pipeline for continuous regression testing of MCP agents.


1. The Anatomy of a JEM Metric

A multi-turn MCP trajectory $\tau$ consists of an alternating sequence of states, tool calls, and observations:

$\tau = (s_0, a_0, o_1, a_1, o_2, \dots, a_T, o_{T+1}, s_{final})$

Standard evaluation checks whether $s_{final}$ matches a reference string. JEM (Judged & Joint Exact Match) evaluates two complementary dimensions:

  1. ▸Step-Level Validity ($JEM_{step}$): Was every intermediate tool call syntactically compliant with the server's published JSON Schema, free of destructive side effects, and logically sound?
  2. ▸Outcome Verification ($JEM_{goal}$): Did the final environment state transition satisfy the user specification (e.g., database table created, PR opened, git branch checked out)?
code
┌────────────────────────────────────────────────────────┐
│               AGENT TRAJECTORY TRACE                   │
├───────────────┬────────────────────────┬───────────────┤
│ Step 1        │ Step 2                 │ Step 3 (Final)│
│ MCP Tool:     │ MCP Tool:              │ Assertion:    │
│ tools/list    │ tools/call (postgres)  │ State Verify  │
├───────────────┴────────────────────────┴───────────────┤
│                JEM EVALUATOR ENGINE                    │
│   [Schema Check] -> [Step Logic] -> [Semantic Judge]   │
└────────────────────────────────────────────────────────┘

2. Implementing a Python JEM Evaluation Harness

Below is a complete test harness in Python utilizing Pydantic and an LLM-as-judge verifier to score MCP agent tool traces:

python
# jem_mcp_evaluator.py
import json
from typing import List, Dict, Any
from pydantic import BaseModel, Field

class ToolExecutionStep(BaseModel):
    step_index: int
    tool_name: str
    arguments: Dict[str, Any]
    output: Any
    latency_ms: int

class JEMScore(BaseModel):
    trajectory_id: str
    step_validity_score: float = Field(ge=0.0, le=1.0)
    outcome_accuracy_score: float = Field(ge=0.0, le=1.0)
    passed: bool
    failure_step: int | None = None
    diagnostics: str

class MCPEvaluator:
    def __init__(self, judge_client, schemas: Dict[str, Any]):
        self.client = judge_client
        self.schemas = schemas

    def evaluate_trajectory(
        self,
        trajectory_id: str,
        goal: str,
        steps: List[ToolExecutionStep],
        expected_state: Dict[str, Any]
    ) -> JEMScore:
        # Phase 1: Deterministic Schema & Type Verification
        for step in steps:
            schema = self.schemas.get(step.tool_name)
            if not schema:
                return JEMScore(
                    trajectory_id=trajectory_id,
                    step_validity_score=0.0,
                    outcome_accuracy_score=0.0,
                    passed=False,
                    failure_step=step.step_index,
                    diagnostics=f"Unknown tool invoked: {step.tool_name}"
                )

        # Phase 2: Semantic Trajectory Validation via Judge Model
        judge_prompt = f"""
You are a JEM (Judged Exact Match) evaluator for Model Context Protocol agents.
User Goal: {goal}
Execution Steps Taken:
{json.dumps([s.model_dump() for s in steps], indent=2)}

Expected Environment State:
{json.dumps(expected_state, indent=2)}

Score the trajectory on:
1. Step Efficiency: No redundant or circular tool calls.
2. Parameter Accuracy: Correct filter keys, valid SQL, safe queries.
3. Outcome Equivalence: Did the tools produce the expected result?

Respond with JSON:
{{
  "step_validity": 0.0 to 1.0,
  "outcome_accuracy": 0.0 to 1.0,
  "reasoning": "string"
}}
"""
        # Call judge model (e.g., Claude 3.7 Sonnet or Gemini 2.5 Flash)
        judge_res = self.client.complete(judge_prompt)
        parsed = json.loads(judge_res.text)

        step_score = parsed["step_validity"]
        outcome_score = parsed["outcome_accuracy"]
        passed = (step_score >= 0.8) and (outcome_score >= 0.9)

        return JEMScore(
            trajectory_id=trajectory_id,
            step_validity_score=step_score,
            outcome_accuracy_score=outcome_score,
            passed=passed,
            diagnostics=parsed.get("reasoning", "")
        )

3. Continuous Integration: MCP Regression Audits

By combining JEM scoring with automated CI pipelines, organizations prevent agent regressions when updating prompt templates or model versions:

yaml
# .github/workflows/mcp-agent-eval.yml
name: MCP Agent JEM Regression Suite
on: [push, pull_request]

jobs:
  evaluate-mcp-trajectories:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.12'
      - name: Run JEM Benchmarks
        run: |
          pip install pydantic pytest
          python -m pytest tests/eval/test_mcp_trajectories.py --junitxml=results.xml

With JEM scoring in place, teams can safely iterate on complex MCP toolchains knowing that agent decision quality is mathematically and semantically verified.

Ready to Deploy?

Build your full agent toolstack in the Visual Generator

Combine JEM Trajectory Evaluation for MCP Tool Calls with databases, search APIs, and memory graphs in a single configuration file.

Customize in Generator
Developer Verification & Feedback

Did this setup guide work with your AI host?

Real-time developer votes ensure configurations stay current across client updates.

JEM Trajectory Evaluation for MCP Tool Calls FAQ

What is the JEM Trajectory Evaluation for MCP Tool Calls?

Implement Judged Exact Match (JEM) and Joint Step Verification to evaluate, benchmark, and regression-test multi-turn Model Context Protocol tool calling trajectories.

How do I configure JEM Trajectory Evaluation for MCP Tool Calls in Claude Desktop or Cursor?

You can copy the configuration JSON from our guide or launch the interactive MCP Codex Config Generator at https://mcp-codex.com/generator to export valid configs in 1 click.

Can I use JEM Trajectory Evaluation for MCP Tool Calls with the OpenAI Codex CLI?

Yes, OpenAI Codex CLI supports Model Context Protocol. You can add it directly to ~/.codex/config.toml or pass arguments to codex mcp add.

RT

Written by Rad Tome

Lead AI Systems Architect & Founder, MCP Codex

@RadTome

Specializing in Model Context Protocol (MCP) integrations, autonomous AI agent orchestration, and distributed developer toolchains. Researches and benchmarks production MCP client-server architectures across OpenAI Codex, Claude, and Cursor.

Editorial Integrity: All configurations, schemas, and commands verified against live GitHub repositories and tested in local sandbox runtimes.

Related Guides