Skip to main content
Glama

Jev MCP

Local Model Context Protocol server that lets expensive frontier coding agents delegate routine probabilistic judgment to TypeSafe Jev.

Jev answers: what does the available evidence suggest?

The frontier model answers: given that evidence, what should I do?

Codex Desktop / Claude Code / other MCP clients
                    │
                    │ MCP stdio
                    ▼
                 Jev MCP
          validation · policy · cache · telemetry
                    │
                    │ HTTPS  (lazy, never on startup)
                    ▼
           TypeSafe System One
                    │
                    ▼
                   Jev
            cheap calibrated Noul

Version 1.0. First-class clients: Codex Desktop and Claude Code. Architecture stays client-agnostic so Cursor, VS Code, JetBrains, CI, and custom harnesses can attach later without new tools.

License: MIT.


Contents


Related MCP server: jev-agent-mcp

Why it exists

Frontier coding models (Astra/Sol-class Codex models, Claude Opus) spend a lot of inference on work that is classification, not generation:

  • is this failure related to the current diff?

  • are we repeating the same failed strategy?

  • which requirements still look uncovered?

  • which files are worth reading next?

Jev MCP moves those questions to a cheap System One model. The metric that matters is not “Jev calls per minute.” It is:

frontier inference cost
────────────────────────
successful completed task

Cost reduction that increases regressions is a failure. Quality and regression rate must stay near the no-Jev baseline.


What it is not

Jev MCP must not:

  • write or modify production code

  • run shell commands or tests

  • create commits or approve merges

  • certify correctness, safety, or security

  • replace CI, typechecking, lint, or static analysis

  • generate architecture or resolve ambiguous product decisions

  • become a second coding agent

If TypeSafe is down, the MCP returns a structured error. The frontier agent continues the task. No fabricated probabilities.

Never returned as a status:

APPROVED
CORRECT
SAFE_TO_MERGE
SECURE

How judgment is ordered

DETERMINISTIC EVIDENCE
        ↓
CHEAP PROBABILISTIC (Jev)
        ↓
FRONTIER REASONING

Example: test exit_code → parser → jev_triage_failure → Opus/Sol root-cause.

Do not call Jev when an exit code, type error, or deterministic check already answers the question.


Install

Requires Python 3.11+.

git clone <this-repo>
cd jevmcp
python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"

Set a TypeSafe key (never commit it):

export TYPESAFE_API_KEY=...          # from ~/.env or the TypeSafe console
# optional
export TYPESAFE_MODEL=jev-latest
export TYPESAFE_BASE_URL=https://api.typesafe.ai

Copy examples if you want a project file:

cp config.example.yaml jev-mcp.yaml
cp .env.example .env                 # then fill TYPESAFE_API_KEY locally

Check the install without calling TypeSafe:

python scripts/doctor.py

Confirm the live provider (explicit opt-in):

python scripts/doctor.py --ping

Startup never contacts TypeSafe. --ping is the only doctor path that does.


Quick start

jev-mcp --profile interactive --shadow
# or
python -m jev_mcp --profile autonomous --shadow

Default is stdio: JSON-RPC on stdin/stdout, logs on stderr. The client must spawn the process.

Optional Streamable HTTP for a shared local daemon, Docker, or CI:

export JEV_MCP_HTTP_TOKEN=$(python -c 'import secrets; print(secrets.token_urlsafe(32))')
jev-mcp --transport streamable-http --profile interactive --shadow

Listens on 127.0.0.1:8765/mcp. Bearer token required. /health is public and has no secrets. Non-loopback bind needs JEV_MCP_HTTP_BIND_ALL=1 and a token. Project YAML cannot set transport, host, or token.

See integrations/*/mcp-config.http.example.json. Do not expose this port on the public internet.

Default shadow mode is on. Results include an advisory: treat them as telemetry, not mandatory control actions. That is the recommended first deployment.


MCP clients

Client differences belong in instructions and profile, not tool schemas. Both V1 clients see the same seven tools.

Client

Default profile

Typical models

Bias

Codex Desktop

autonomous

Astra, Sol, other Codex

Aggressive triage / stuck detection on long autonomous runs

Claude Code

interactive

Claude Opus

Selective use; human is already in the loop

Codex Desktop

  1. Install jev-mcp on PATH (or point the config at .venv/bin/jev-mcp).

  2. Merge integrations/codex/mcp-config.example.json into Codex MCP settings.

  3. Merge integrations/codex/AGENTS.example.md into the target repo AGENTS.md.

  4. Put TYPESAFE_API_KEY in the process environment, not in a committed JSON file. Some clients do not expand ${TYPESAFE_API_KEY}.

Claude Code

Same pattern with integrations/claude-code/mcp-config.example.json and CLAUDE.example.md.

Claude Code should call Jev less often. Skip it when the next step is already obvious from deterministic evidence or the user is directing the work.

Future clients

Cursor, VS Code agents, JetBrains, CI, GitHub agents, custom harnesses: add a config snippet and an instruction file. Do not add client-specific tools.


Tools

All tools return JSON. Every successful response includes meta:

{
  "provider": "typesafe",
  "model": "jev-1.13.0",
  "latency_ms": 112,
  "cached": false,
  "request_id": "…",
  "tool": "jev_triage_failure",
  "shadow_mode": true,
  "jev_input_units": 312,
  "jev_estimated_cost": null
}

If input was truncated, warnings is present. Treat those judgments more cautiously.

Optional on every call: client (name, mode, model, session_id, task_id) and use_cache. client.mode does not change policy. It is telemetry only. Profile comes from server config / CLI / JEV_MCP_PROFILE.

Core

jev_triage_failure

Help the user decide the next attempt toward a predefined goal after a failure. Cheap triage before a broad investigation of a test/build/lint/typecheck failure. Returns user_decision.

Signals: related_to_current_change, likely_localized, likely_preexisting, requirement_related, same_as_previous_failure, needs_deeper_reasoning.

Classification: relationship, scope, escalation. These are labels over thresholds, not diagnoses.

Does not explain the bug or propose a fix. The user decides the next attempt. The failing check stays in scope.

jev_compare_attempts

Help the user decide the next attempt toward a predefined goal. Compare two unsuccessful attempts. Use after two materially similar failures. Returns user_decision. Does not write the next fix.

Signals: same_failure, same_strategy, meaningful_new_evidence, meaningful_progress, reconsider_approach.

status

control_signal

PROGRESSING

CONTINUE

UNCERTAIN

CONTINUE

LIKELY_STUCK

REASSESS or ESCALATE

Initial stuck rule (configurable):

same_failure >= 0.85
AND same_strategy >= 0.80
AND meaningful_new_evidence <= 0.30
AND meaningful_progress <= 0.30

A connection-refused failure followed by a UNIQUE violation is progress, not stuck. Both tests failed; the failure advanced.

jev_check_completion

Help the user decide whether the current attempt reached the predefined goal. Requirement/evidence coverage before an expensive full-task review. Returns user_decision.

Per requirement: appears_satisfied, evidence_present, possible_gap.

Global: scope_appropriate, unresolved_requirement, further_review_warranted.

Statuses: APPEARS_COMPLETE, REVIEW_REQUIRED, INCOMPLETE.

APPEARS_COMPLETE is not approval. Investigate anything in review_requirements. The user still decides whether the goal is achieved.

Missed requirements (false complete) are scored 5× worse than extra escalations in the eval suite.

Extended

jev_rank_context

Help the user decide what to inspect next toward the predefined goal. Ranks discovery candidates. Never deletes. Tiers: HIGH, MEDIUM, LOW.

Do not suppress LOW items until critical-context Recall@10 is proven ≥ 0.98 on the golden set. V1 is ranking only.

jev_classify_findings

Help the user decide which findings to act on in the next attempt. Normalize findings from reviewers, linters, tests, humans. Signals include likely_valid, requirement_related, requires_code_change, security_relevant, data_integrity_relevant.

A high security_relevant is a triage flag, not a confirmed vulnerability.

jev_assess_risk

Help the user decide whether to buy a deeper review before the next attempt. Whether a change looks like it warrants more expensive frontier review (auth, payment, schema, public API, …). Same rule: signals, not conclusions.

jev_judge

Generic Noul primitive: caller supplies state and a list of {id, question}. During implementation, ask about evidence toward the predefined goal so the user can decide the next attempt.

Rejects generative work and product/planning decisions (write this function, draft the Q3 roadmap, should we enter the EU market, …). Ask one evidence-grounded proposition per question.


Profiles and policy

Profiles change recommended usage and threshold aggressiveness. They do not change tool schemas or Jev’s underlying questions.

autonomous

interactive

custom

Default client

Codex large tasks

Claude Code

user override

Failure triage

aggressive

moderate

moderate

Stuck detection

aggressive (easier ESCALATE)

enabled

enabled

Context HIGH bar

lower

conservative

medium

Set with --profile, JEV_MCP_PROFILE, or profile.default in YAML.


Probability interpretation

Do not treat p > 0.5 as true.

Range

Band

0.00 – 0.30

LOW

0.30 – 0.70

UNCERTAIN

0.70 – 1.00

HIGH

Individual tools use stricter cutoffs (stuck detector). All thresholds live in config.

Ambiguous engineering is a valid outcome. The eval suite tracks ambiguous_case_overconfidence_rate — overconfident YES/NO on uncertain cases is a safety failure.


Configuration

Precedence (highest last-applied wins):

built-in defaults
        ↓
~/.config/jev-mcp/config.yaml          user
        ↓
./jev-mcp.yaml  or  ./config.yaml      project
        ↓
JEV_MCP_CONFIG / --config              explicit file
        ↓
environment
        ↓
CLI flags

See config.example.yaml.

Project YAML cannot set:

  • provider.api_key

  • provider.base_url

  • telemetry.store_content

Those restrictions exist so a cloned repo cannot steal TYPESAFE_API_KEY by pointing base_url at an attacker host, and cannot silently persist source into SQLite.

api_key and base_url come from the environment only. store_content may be enabled in the user config or by constructing AppConfig locally for debugging — not from project files.

Provider limits:

Field

Bound

timeout_seconds

1–120 (default 30)

max_retries

0–2 (default 1; only transient errors)


Environment

Variable

Role

TYPESAFE_API_KEY

Required for live Jev

TYPESAFE_BASE_URL

Default https://api.typesafe.ai

TYPESAFE_MODEL / TYPESAFE_DEFAULT_MODEL

Default jev-latest

TYPESAFE_TIMEOUT_SECONDS

Provider timeout

TYPESAFE_ALLOWED_HOSTS

Extra HTTPS hosts (default is only api.typesafe.ai)

JEV_MCP_PROVIDER

typesafe or mock

JEV_MCP_PROFILE

autonomous / interactive / custom

JEV_MCP_SHADOW_MODE

true/false

JEV_MCP_TRANSPORT

stdio (default) or streamable-http

JEV_MCP_HTTP_TOKEN

Required for HTTP

JEV_MCP_HTTP_HOST / PORT / PATH

Default 127.0.0.1 / 8765 / /mcp

JEV_MCP_HTTP_BIND_ALL

Required to bind non-loopback

JEV_MCP_LOG_LEVEL

Logging (stderr)

JEV_MCP_DATA_DIR

Cache + telemetry directory

JEV_MCP_CONFIG

Explicit YAML path

JEV_MCP_ALLOW_FAULTS

Must be 1 before JEV_MCP_TEST_FAULT works (tests only)

JEV_MCP_LIVE

1 to run live TypeSafe pytest


Provider

Tools depend on JudgmentProvider, not TypeSafe types.

validate → normalize → Noul questions → System One → validate p ∈ [0,1] → cache → telemetry
  • TypeSafeProvider — POST {base_url}/v1/systemone, HTTPS, host allowlist, follow_redirects=False, one retry on transient status (429, 529, 5xx, timeout).

  • MockProvider / MockJudgmentProvider — deterministic local answers for tests and doctor without a key.

State sent to Jev is untrusted evidence (repo text, test output). Questions are our Noul instructions. Injection in a source file must not be copied into instructions. Jev may still be influenced by adversarial evidence; treat HIGH confidence plus injection-looking content as a reason for deeper frontier review.

Cost estimates use cost.jev_input_per_million from config. Prices are not hard-coded.


Cache and telemetry

Default data dir: ~/.local/share/jev-mcp/ (JEV_MCP_DATA_DIR overrides). Files are created 0600, directory 0700.

Cache (SQLite WAL) key:

provider · model · tool · tool_version · policy_version · normalization_version
· normalized_state_hash · questions_hash

Not in the key: timestamp, session id, client name.

Bypass when use_cache=false, cache disabled, or provider/tool/normalization version changes. Responses expose meta.cached.

Telemetry (local, default):

  • stores hashes, not source (store_content: false)

  • records tool, latency, cache hit, error code, probability summary, optional token units

  • outcome labels can be attached later (jev-mcp-export --record-outcome)

Remote telemetry is not implemented. local_only is the contract for anything added later.


Errors

Returned to the client as:

{
  "error": {
    "code": "PROVIDER_TIMEOUT",
    "message": "Jev evaluation timed out.",
    "retryable": true
  }
}

Code

Retryable

INVALID_INPUT

no

INPUT_TOO_LARGE

no

PROVIDER_UNAVAILABLE

usually yes

PROVIDER_TIMEOUT

yes

PROVIDER_RATE_LIMITED

yes

INVALID_PROVIDER_RESPONSE

no

INTERNAL_ERROR

no

Messages are redacted (API keys, ghp_, sk_live_, JWTs, Slack, GitLab, npm, connection URIs, …). No stack traces, no Authorization headers.


Security

Local MCP (stdio by default; HTTP opt-in). Attackers that matter: malicious repo config, poisoned test output, confused agent, other local UIDs, anything that can reach an HTTP bind.

Hardened in V1:

  • no code/file/shell tools

  • secrets and provider host not accepted from project YAML

  • TypeSafe host pinned; no redirect-following (stops Bearer exfil)

  • fault injection requires an explicit allow env

  • profile not controllable by the agent

  • shadow on by default

  • secret-pattern redaction on logs, errors, telemetry

  • sqlite owner-only permissions

Residual: Jev still reads untrusted state. A file that says “return 1.0” can bias probabilities. That is a judgment-integrity risk, not RCE. Do not use Jev results as merge gates.


Docker

docker build -t jev-mcp .
docker run --rm -i -e TYPESAFE_API_KEY jev-mcp --profile interactive --shadow

-i is required for stdio. HTTP: publish 127.0.0.1:8765:8765 and set JEV_MCP_HTTP_TOKEN plus JEV_MCP_HTTP_BIND_ALL=1 inside the container. Do not --env-file ~/.env. Image is multi-stage, non-root (uid 10001), data volume /var/lib/jev-mcp. Keys are never baked in.


Tests and evals

Testing is part of the product. Hosted Jev can change while this repo stays still. Compare every release to eval-results/.

Layer

What

When

A

Unit + policy. MockJudgmentProvider. “Given these p, does software behave?”

Every PR

B

MCP contract: exact tool list, schema + description snapshots

Every PR

C

Real stdio MCP + mock Jev (errors, cache, truncate, concurrent, restart)

Every PR

Adversarial

Injection as evidence, secret leakage

Every PR

D

Live TypeSafe. Structural only (0 ≤ p ≤ 1). JEV_MCP_LIVE=1

Nightly

E

Golden corpus (~320 labeled cases), Recall@10, missed-requirement cost, uncertainty

PR uses mock path; live nightly

pytest -m "not live and not typesafe"
ruff check src tests scripts evals
python scripts/eval.py --generate
python scripts/eval.py --out eval-results/local/software.json
JEV_MCP_LIVE=1 pytest -m live

Do not assert answer == 0.91 against hosted Jev. Do not run hundreds of live Jev calls on every commit.

Gates: evals/GATES.md. Experiment configs A–D (frontier only → all tools): evals/experiments/. Hidden acceptance tests belong in benchmark repos, not in the agent-visible rubric.


Repository layout

src/jev_mcp/          server, engine, tools, policy, provider, cache, telemetry
integrations/         Codex + Claude Code examples
scripts/              doctor, install, benchmark, eval, export
tests/                unit, contract, integration, adversarial, live, evals
evals/golden/         labeled coding-decision cases
eval-results/         per-release history
benchmarks/           smaller fixture corpus

Commands

Command

Purpose

jev-mcp

MCP server (stdio default; --transport streamable-http)

python -m jev_mcp

same

jev-mcp-doctor / python scripts/doctor.py

config + optional --ping

python scripts/install.py

print client MCP snippets

python scripts/benchmark.py --provider mock

small local corpus

python scripts/eval.py

golden suite

jev-mcp-export

dump local telemetry JSON

CLI flags for the server: --config, --provider {typesafe,mock}, --profile {autonomous,interactive,custom}, --shadow, --log-level.

Available Tools

7 tools
jev_assess_riskA

Cheap change-risk triage to decide whether a more expensive frontier review appears warranted. Returns sensitivity likelihoods only. These are not security conclusions and do not certify safety.

Inputs: task_goal (required), client, use_cache, diff_summary, +2 more. Returns: object

jev_check_completionA

Cheap requirement/evidence coverage check before an expensive full-task review. Use on large tasks with explicit requirements. Returns per-requirement likelihoods and which items warrant review. Never certifies correctness, safety, or merge readiness.

Inputs: task (required), implementation (required), client, use_cache, +1 more. Returns: object

jev_classify_findingsA

Cheap normalization of review findings from tests, linters, humans, or frontier reviewers. Use to triage a large finding set before expensive reasoning. Returns likelihood signals only. Does not confirm that a vulnerability or defect exists.

Inputs: findings (required), task_goal (required), client, use_cache, +1 more. Returns: object

jev_compare_attemptsA

Cheap comparison of two unsuccessful implementation attempts. Use when repeated work may be spending frontier inference on the same failed strategy. Returns stuck/progress signals and an advisory control signal; does not choose the next fix.

Inputs: task_goal (required), current_attempt (required), previous_attempt (required), client, +1 more. Returns: object

jev_judgeB

Generic bounded judgment primitive. Ask one evidence-grounded yes/no proposition per question and receive calibrated probabilities. Rejects generative requests such as writing code, designing architecture, or fixing bugs. Jev evaluates supplied evidence; it does not invent it.

Inputs: state (required), questions (required), client, use_cache. Returns: object

jev_rank_contextA

Cheap ranking of repository context candidates before deeper frontier inspection. Use when discovery produced many plausible files or symbols. Ranks only; never deletes or permanently excludes candidates.

Inputs: task_goal (required), candidates (required), current_step (required), client, +1 more. Returns: object

jev_triage_failureA

Cheap probabilistic triage for test/build/lint/typecheck failures. Use before broad reasoning when the relationship or scope of a failure is unclear. Returns structured likelihood signals; does not diagnose or fix the problem.

Inputs: task (required), failure (required), current_step (required), client, +4 more. Returns: object

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A4/5.0

    Scored across 7 tools

    Disambiguation4/5

    Each tool targets a distinct stage in a review/diagnosis workflow: change risk, failure triage, attempt comparison, completion checks, context ranking, findings classification, and generic judgment. A few tools share the same cheap-likelihood framing, but their input types and intended uses are clearly differentiated.

    Naming Consistency5/5

    All tools follow the consistent jev_ prefix with a verb_noun pattern (assess_risk, triage_failure, compare_attempts, check_completion, rank_context, classify_findings, judge). There is no mixed casing or stylistic drift.

    Tool Count5/5

    Seven tools is well-scoped for a probabilistic triage suite, with each tool earning its place as a distinct decision-support primitive. The count is neither too thin nor overloaded.

    Completeness5/5

    For the stated domain of cheap probabilistic triage, the set covers the major pre-review decision points and even provides a generic judge fallback for arbitrary yes/no propositions. Potential gaps like diagnosing or fixing are intentionally excluded rather than left as dead ends.

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      A
      quality
      C
      maintenance
      Enables coding or reasoning agents to request structured judgments from TypeSafe's Jev model at decision points, including choices, scores, claim verification, and code reviews, with probabilities and confidence returned as data.
      5
      6 npm
      MIT
    • A
      license
      B
      quality
      C
      maintenance
      Enables AI agents to obtain typed judgments from TypeSafe's Jev System One models, including yes/no probabilities, multiple-choice selections with distributions, and rubric-based scores, directly usable in code.
      5
      2
      AGPL 3.0
    • F
      license
      Not graded
      quality
      B
      maintenance
      Enables Claude Code agents to perform structured decision-making through TypeSafe Jev, supporting yes/no checks, route selection, scoring, and batched multi-question judgments with confidence values.
      1
      -