Skip to main content
Glama
rilfi

token-optimizer-jev-mcp

by rilfi

token-optimizer-jev-mcp

A read-only Model Context Protocol server for TypeSafe Jev — the System One model that answers typed questions instead of writing prose.

Jev returns a decision your code can consume directly: a label, a score, or P(yes), each with calibrated probabilities. This server exposes exactly that surface, with three token-economy behaviours built in:

Jev is a decision model, not a chat or code-completion model. It never writes prose, code, summaries, translations or explanations of its reasoning — every question must define its answer space up front. Point an agent here and it stays in control of the workflow, calling Jev for the decisions inside it; that is the whole point of the server.

  • One request, many questions. jev_ask takes every question at once. Jev evaluates them against the state in parallel, so extra questions cost a few tokens and almost no latency — one call instead of N round trips.

  • A hard context-budget guard. The request is measured locally and refused before it is sent if it would exceed the model's budget, with the numbers in the error.

  • Compact answers by default. You get the answer, its confidence, and whether it needs review. Probability tables and the echoed rubric are opt-in.

  • No client lock-in. A plain stdio MCP server with no vendor extensions: Claude Code and Desktop, Cursor, VS Code, Cline, Windsurf, Zed, JetBrains, Codex, Gemini CLI, or an agent you write against the Python/TypeScript SDK — same six tools, same answers.

Install

npx -y token-optimizer-jev-mcp        # run directly, no install
npm install -g token-optimizer-jev-mcp

Requires Node 20.12+ and a TypeSafe API key from console.typesafe.ai/settings/keys.

Related MCP server: jev-judge-mcp

Client setup

This is a stdio MCP server, so any host that speaks MCP can run it — nothing below is Claude-specific and no vendor is special-cased. Most hosts take the same mcpServers block:

{
  "mcpServers": {
    "jev": {
      "command": "npx",
      "args": ["-y", "token-optimizer-jev-mcp"],
      "env": { "TYPESAFE_API_KEY": "your-key" }
    }
  }
}

Host

Where that block goes

Claude Code

claude mcp add --scope user jev --env TYPESAFE_API_KEY=your-key -- npx -y token-optimizer-jev-mcp, or .mcp.json

Claude Desktop

claude_desktop_config.json (<APPDATA>/Claude/ on Windows, ~/Library/Application Support/Claude/ on macOS)

Cursor

.cursor/mcp.json (project) or ~/.cursor/mcp.json (global)

Cline

cline_mcp_settings.json, via the extension's MCP Servers panel

Windsurf

~/.codeium/windsurf/mcp_config.json

JetBrains / Junie

mcp.json (Settings → Tools → MCP Server), or .junie/mcp/mcp.json in the project

Gemini CLI

~/.gemini/settings.json

Three hosts use their own shape instead:

VS Code (Copilot) — .vscode/mcp.json, under servers rather than mcpServers:

{
  "servers": {
    "jev": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "token-optimizer-jev-mcp"],
      "env": { "TYPESAFE_API_KEY": "your-key" }
    }
  }
}

Zed — settings.json, under context_servers:

{
  "context_servers": {
    "jev": {
      "command": "npx",
      "args": ["-y", "token-optimizer-jev-mcp"],
      "env": { "TYPESAFE_API_KEY": "your-key" }
    }
  }
}

Codex CLI — ~/.codex/config.toml:

[mcp_servers.jev]
command = "npx"
args = ["-y", "token-optimizer-jev-mcp"]
env = { TYPESAFE_API_KEY = "your-key" }

And an agent you write yourself just needs an MCP client library:

from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client

params = StdioServerParameters(
    command="npx", args=["-y", "token-optimizer-jev-mcp"],
    env={"TYPESAFE_API_KEY": "your-key"},
)
async with stdio_client(params) as (read, write):
    async with ClientSession(read, write) as session:
        await session.initialize()          # server instructions arrive here
        await session.call_tool("jev_ask", {"state": "...", "questions": {...}})

The TypeScript equivalent (Client + StdioClientTransport from @modelcontextprotocol/sdk) is what scripts/smoke.mjs runs.

What every host gets

Only standard MCP fields, so a client that does not understand one simply ignores it:

  • instructions in the initialize result — how to use the tools, written for whatever agent is asking (batch your questions, treat needs_review as unresolved, branch on error codes).

  • A title and a description per tool, and an inputSchema on every tool — {} where a tool takes no parameters, because the field is required by the spec.

  • Self-contained JSON Schemas: no $ref for a host to resolve, so a client can hand the schema to its model's function-calling API as-is.

  • readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true on every tool. Hosts that gate approvals on annotations (Cursor, VS Code, Cline, Windsurf, Zed) therefore see a read-only server, not one that needs a prompt before each call.

  • Typed failures: isError with { tool, code, message, suggestion? }.

Transport is stdio only — this server opens no socket, so an agent that can only reach a URL needs a stdio↔HTTP bridge in front of it.

The key is read from the server's environment only. It is never a tool argument, never returned by a tool, and never logged.

Tools

Tool

What it answers

jev_ask

A batch of questions — noul, choice and score mixed freely — against one state, in one request.

jev_choice

Pick exactly one label from a defined set: the label, its confidence, and optionally every label's probability.

jev_score

Rate a state against an ordered rubric: the expected score (may fall between levels), its confidence, optionally per-level probabilities.

jev_noul

A yes/no question, answered as calibrated P(yes).

jev_list_models

The model names this account can send, what jev-latest and jev-preview currently point to.

jev_server_info

Base URL, default model, whether a key is present (never the key), the context budget, the confidence threshold, the tool list.

Question shapes

// noul — yes/no
{ "type": "noul", "instructions": "Is this message about billing?" }

// choice — one label from a set
{ "type": "choice",
  "instructions": "What is this about?",
  "criteria": { "billing": "money, invoices or charges", "technical": "a broken feature", "other": null } }

// score — ordered rubric, lowest first, indexed from 0
{ "type": "score",
  "instructions": "How urgent is this?",
  "criteria": ["no rush", "normal", "urgent", "drop everything"] }

instructions and the criteria descriptions accept a string, a JSON object, or an array — put the question in one field and the data it refers to in others.

Answer shape

{
  "model": "jev-1.13.0",
  "answers": {
    "billing": { "type": "noul",   "noul": 0.94, "uncertain": false },
    "topic":   { "type": "choice", "choice": "billing", "confidence": 0.88, "needs_review": false },
    "urgency": { "type": "score",  "score": 2.1, "confidence": 0.55, "needs_review": true }
  },
  "usage": { "input_tokens": 128, "output_tokens": 0 }
}
  • needs_review (choice/score) is true when the reported confidence is below the threshold — route those to a human, or to a second opinion.

  • uncertain (noul) is true when P(yes) sits inside the mirrored threshold band (0.4–0.6 by default). A noul answer has no separate confidence: the probability is the answer.

  • include_probabilities: true adds the full probability table; include_legend: true adds the score rubric echoed back; raw: true returns the API result untouched.

Context budget

The published model card allows 64k tokens per request, 32k of which may be state plus the longest question. This server estimates the serialized request at roughly 4 characters per token and refuses anything over JEV_MAX_INPUT_TOKENS / JEV_MAX_STATE_TOKENS (defaults 60000 / 30000) before sending it:

{ "tool": "jev_ask", "code": "BUDGET_STATE",
  "message": "`state` is an estimated 31000 tokens, over the 30000-token budget for state (JEV_MAX_STATE_TOKENS). The request was not sent.",
  "suggestion": "Send the part of the state the question actually needs, or split the state across several calls." }

The estimator is a heuristic guard rail, not a tokenizer — the headroom under the real limits is deliberate.

Error codes

Every failure comes back as { tool, code, message, suggestion? } with isError: true, so a caller can branch on the code instead of parsing prose.

Code

Meaning

CONFIG_MISSING_API_KEY

No key in the server environment. The fix is in suggestion.

CONFIG_INVALID_API_KEY

The API rejected the key (HTTP 401).

CONFIG_INVALID_ENV

A bad JEV_* / TYPESAFE_* value; the process exits at startup naming it.

VALIDATION / VALIDATION_EMPTY_QUESTIONS

The questions are malformed (a choice with fewer than 2 labels, a score with fewer than 2 levels, no questions at all).

BUDGET_STATE / BUDGET_TOTAL

The estimated request is over budget; it was not sent.

RATE_LIMIT

HTTP 429 after retries; includes retry_after_ms when the server sent one.

MODEL_NOT_FOUND

HTTP 404 — usually an unknown model name. Call jev_list_models.

PERMISSION_DENIED / BAD_REQUEST / SERVER_ERROR / API_ERROR

HTTP 403 / 400+422 / 5xx / anything else. A BAD_REQUEST in practice means an unknown model name or a state the API will not accept; the suggestion says which to check.

TIMEOUT / CONNECTION

Transport failure, after the SDK's own retries with backoff.

TYPESAFE_ERROR / UNEXPECTED

The SDK rejected a response shape, or something unexpected was thrown.

Read-only posture

There is nothing to write. Jev calls are stateless inference — no records, no files, no server-side state — and this server adds no write path of its own:

  • no filesystem access, no shell, no database;

  • no tool accepts a file path, so nothing can be read off your disk either;

  • the only network egress is the configured TYPESAFE_BASE_URL;

  • the API key is environment-only and never appears in a tool call or a tool result.

Environment variables

Variable

Required

Default

Description

TYPESAFE_API_KEY

Yes*

TypeSafe API key. Read by this server and by the SDK.

JEV_API_KEY

Fallback if TYPESAFE_API_KEY is unset.

TYPESAFE_BASE_URL

No

https://api.typesafe.ai

API root (for a proxy).

TYPESAFE_DEFAULT_MODEL

No

jev-latest

Model used when a call omits model.

JEV_TIMEOUT_MS

No

30000

Timeout per attempt, in milliseconds.

JEV_MAX_INPUT_TOKENS

No

60000

Estimated request budget before a local refusal.

JEV_MAX_STATE_TOKENS

No

30000

Estimated state budget before a local refusal.

JEV_CONFIDENCE_THRESHOLD

No

0.6

Below this, answers are flagged needs_review / uncertain.

JEV_BUDGET_WARN_RATIO

No

0.8

Fraction of the budget past which a response carries a warning.

* Without a key the server still starts and lists its tools; each judgment call returns CONFIG_MISSING_API_KEY with the fix. An invalid environment value stops the process at startup with a named reason on stderr instead of failing silently.

Development

npm install
npm run build     # tsc -> dist/
npm test          # jest: config, budget, question schemas, formatting, error mapping, request/response wiring
                  # src/protocol.test.ts drives the real server through a plain MCP client over a
                  # linked transport: instructions, tool titles, annotations, and typed errors
npm run smoke     # speak MCP to dist/index.js over stdio as a host does; skips the live call without a key
npm run test:live # tier B: the real API, the real server (needs TYPESAFE_API_KEY); see TEST-PLAN.md
python bench/run_three_way.py   # Hermes vs +MCP vs +MCP+hooks on six check-verified tasks
                                # measured results: bench/THREE-WAY.md

Publishing

npm login
npm publish       # prepublishOnly runs build + tests

jev-mcp and typesafe-jev-mcp were already taken on npm; token-optimizer-jev-mcp is this package's published name.

Hooks — Jev decisions at every lifecycle step

hooks/ ships six hooks that ask Jev for one judgement at each point where a judgement changes what happens next, plus agent-bridge.mjs, which runs the same hooks under Claude Code, Gemini CLI and Cursor. What each hook decides, its measured latency/cost, and its failure model: hooks/README.md.

Hook

Event

Decision

Effect

H1

pre_llm_call

is this request irreversible/destructive?

inject context when P ≥ 0.5

H2

pre_tool_call

deny-list, then "is this destructive or hard to reverse?"

block

H3

post_tool_call

did this result actually fail?

record (this event cannot block)

H4

pre_verify

complete / with caveats / incomplete

push back with continue

H5

on_session_start

code / docs / data / ops session?

inject the profile

H6

on_session_end

does a human need to be told?

append to the follow-up ledger

Files (all under hooks/)

File

What it is

hooks/install.mjs

registers/unregisters the six hooks in Hermes (merges config + allowlist, backs the config up)

hooks/jev_pre_llm_call.mjs

H1 — irreversible-request pre-read

hooks/jev_pre_tool_call.mjs

H2 — deny-list + Jev risk gate

hooks/jev_post_tool_call.mjs

H3 — outcome triage (records failures)

hooks/jev_pre_verify.mjs

H4 — completion gate

hooks/jev_on_session_start.mjs

H5 — session profile

hooks/jev_on_session_end.mjs

H6 — follow-up ledger

hooks/agent-bridge.mjs

runs any of the above under Claude Code / Gemini CLI / Cursor

hooks/jev-client.mjs

the MCP stdio client the hooks use (handshake, key resolution, cache, daily budget)

hooks/hook-common.mjs

payload reading, the four emit shapes, the one-emitter wrapper

hooks/stub-mcp-server.mjs

canned MCP server used by the tests

hooks/selftest.mjs

33 offline cases — run before trusting an edit

Hermes — one command (verified end to end)

node hooks/install.mjs          # merges 6 entries + allowlist rows; backs up config.yaml first
hermes hooks doctor             # exec + allowlist + valid JSON per hook
hermes hooks test pre_tool_call --for-tool terminal --payload-file <payload.json>
node hooks/install.mjs --uninstall   # removes exactly these six

Hooks are not hot-reloaded: they apply from the next session. JEV_HOOKS_OFF=1 makes the whole set a no-op. Measured: DROP TABLE customers; blocked in 0.16 s without an API call; a docker system prune -af scored P(destructive)=0.95 and blocked in 1.6 s.

Claude Code

Paths in these snippets are written relative to this repository: substitute <REPO> with the checkout's absolute path where you paste them, because a hook is spawned from an arbitrary working directory and cannot resolve a relative path from inside a config file.

hooks/agent-bridge.mjs normalises Claude's payload (its tool_input/tool_name/session_id/ cwd are the fields our hooks already read), maps Claude's tool names onto ours (Bashterminal, Writewrite_file, Editpatch) and translates the answer back: a block becomes Claude's own {"decision":"block","reason":…} and exit-2-style stderr, context becomes hookSpecificOutput.additionalContext, and a Stop push-back becomes decision: "block" so the conversation continues.

.claude/settings.json (project) or ~/.claude/settings.json, merged with whatever is already there:

{
  "hooks": {
    "PreToolUse": [
      { "matcher": "Bash|Write|Edit|MultiEdit",
        "hooks": [{ "type": "command", "timeout": 20,
                    "command": "node \"<REPO>/hooks/agent-bridge.mjs\" claude jev_pre_tool_call.mjs" }] }
    ],
    "PostToolUse": [
      { "matcher": "Bash|Write|Edit|MultiEdit",
        "hooks": [{ "type": "command", "timeout": 20,
                    "command": "node \"<REPO>/hooks/agent-bridge.mjs\" claude jev_post_tool_call.mjs" }] }
    ],
    "UserPromptSubmit": [
      { "hooks": [{ "type": "command", "timeout": 20,
                    "command": "node \"<REPO>/hooks/agent-bridge.mjs\" claude jev_pre_llm_call.mjs" }] }
    ],
    "Stop": [
      { "hooks": [{ "type": "command", "timeout": 20,
                    "command": "node \"<REPO>/hooks/agent-bridge.mjs\" claude jev_pre_verify.mjs" }] }
    ],
    "SessionStart": [
      { "hooks": [{ "type": "command", "timeout": 20,
                    "command": "node \"<REPO>/hooks/agent-bridge.mjs\" claude jev_on_session_start.mjs" }] }
    ]
  }
}

Notes: PreToolUse/PostToolUse take a matcher; the lifecycle events (UserPromptSubmit, Stop, SessionStart, SessionEnd, PreCompact, …) do not. Blocking works through stdout JSON or exit code 2 with the reason on stderr. Set timeout (seconds) — the default for a command hook is 600, which is far longer than a judgement needs. ${CLAUDE_PROJECT_DIR} is available if you prefer project-relative paths. Cursor loads Claude Code hooks natively, so this block can serve both.

Gemini CLI

Gemini CLI's settings.json takes a hooks object with PascalCase events (BeforeTool, AfterTool, BeforeAgent, AfterAgent, SessionStart, SessionEnd), a matcher (tool-name regex for tool hooks), and hook entries of {type: "command", name?, command, timeout}timeout in milliseconds. Its stdout contract is close to ours: decision: "deny" (alias "block") plus reason refuses a tool, hookSpecificOutput.additionalContext appends context, continue: false kills the loop, systemMessage shows a line to the user, and exit code 2 blocks with stderr as the reason. The bridge emits exactly those.

{
  "hooks": {
    "BeforeTool": [
      { "matcher": "run_shell_command|write_file|replace",
        "hooks": [{ "type": "command", "name": "jev risk gate", "timeout": 20000,
                    "command": "node \"<REPO>/hooks/agent-bridge.mjs\" gemini jev_pre_tool_call.mjs" }] }
    ],
    "AfterTool": [
      { "hooks": [{ "type": "command", "timeout": 20000,
                    "command": "node \"<REPO>/hooks/agent-bridge.mjs\" gemini jev_post_tool_call.mjs" }] }
    ],
    "BeforeAgent": [
      { "hooks": [{ "type": "command", "timeout": 20000,
                    "command": "node \"<REPO>/hooks/agent-bridge.mjs\" gemini jev_pre_llm_call.mjs" }] }
    ]
  }
}

Cursor

~/.cursor/hooks.json (user) or <project>/.cursor/hooks.json, camelCase events, one command per hook. Cursor's block signal for preToolUse / beforeShellExecution / beforeMCPExecution / beforeReadFile / subagentStart is exit code 2 with the reason on stderr — which is what the bridge emits for a block; it is also committed to a config file Cursor auto-reloads:

{
  "version": 1,
  "hooks": {
    "preToolUse": [
      { "command": "node \"<REPO>/hooks/agent-bridge.mjs\" cursor jev_pre_tool_call.mjs", "timeout": 20 }
    ],
    "postToolUse": [
      { "command": "node \"<REPO>/hooks/agent-bridge.mjs\" cursor jev_post_tool_call.mjs", "timeout": 20 }
    ],
    "beforeSubmitPrompt": [
      { "command": "node \"<REPO>/hooks/agent-bridge.mjs\" cursor jev_pre_llm_call.mjs", "timeout": 20 }
    ],
    "stop": [
      { "command": "node \"<REPO>/hooks/agent-bridge.mjs\" cursor jev_pre_verify.mjs", "timeout": 20 }
    ]
  }
}

Project hooks run from the project root, user hooks from ~/.cursor/ — so keep the bridge path absolute (as above) and you never think about it again. Other Cursor events you can wire the same way: afterFileEdit, beforeShellExecution, sessionStart, sessionEnd, preCompact, afterAgentResponse.

Agents with no hook API (and what to do instead)

Windsurf, Cline, Zed, VS Code (Copilot agent mode), Aider, Continue and Codex CLI do not expose a before-tool/after-tool shell hook I could verify on this machine, so there is no config to paste for them. Three honest fallbacks, in order of how much they buy you:

  1. Register the MCP server itself (they all speak MCP) and put one line in the agent's rules file — AGENTS.md, .windsurfrules, .clinerules, .github/copilot-instructions.md, … — telling it to call jev_noul / jev_choice for risky or uncertain decisions, and to treat needs_review: true as "ask the human".

  2. Git-level gates: the same bridge works as a .git/hooks/pre-commit script (read the staged diff as the state, jev_noul "does this change look destructive or unfinished?"), which every one of these tools respects because it is git, not the agent.

  3. Wrap the command you launch the agent with, running agent-bridge.mjs hermes jev_pre_llm_call.mjs on the prompt first if you want the pre-read regardless of the host.

What each agent honours (and how this was verified)

Agent

Block

Context injection

Continue / push-back

Hermes

{"decision":"block","reason":…} (and exit 2)

{"context":"…"} on every event

{"action":"continue","message":…} on pre_verify

Claude Code

{"decision":"block","reason":…} or exit 2 + stderr

hookSpecificOutput.additionalContext (verified for Stop)

decision:"block" on Stop keeps the conversation going

Gemini CLI

{"decision":"deny","reason":…} or exit 2 + stderr

hookSpecificOutput.additionalContext

continue:true + systemMessage

Cursor

exit 2 + stderr (→ permission: deny)

not wired — the response field is not documented for these events

followup_message on stop

Verification status, stated plainly: the Hermes column is exercised end to end on this machine (hermes hooks doctor, hermes hooks test <event> with real Jev answers, and the measurements in hooks/README.md). The Claude Code / Gemini CLI / Cursor columns come from each vendor's hook reference plus the bridge's own offline tests (node hooks/selftest.mjs, 33 cases, every agent's block/allow/context path asserted against a stub MCP server) — I have not run those three apps with the hooks installed, so treat their rows as "documented contract, adapter tested", not as exercised.

License

MIT

Available Tools

6 tools
jev_askAsk Jev many typed questions at onceA
Read-onlyIdempotent

Ask Jev one or more typed questions about a state and get calibrated decisions back. Mixed question types share one request: every question is evaluated against the state in parallel, so extra questions cost a few tokens and almost no latency. Prefer one call with many questions over many calls. Jev decides, it does not generate: every question needs a defined answer space (a label set, a rubric, yes/no), and it cannot summarize, translate, write code or explain its reasoning. Read-only: the request has no side effects.

ParametersJSON Schema
NameRequiredDescriptionDefault
rawNoReturn the raw API result (every field, unformatted) instead of the compact answer set.
modelNoModel override, e.g. jev-latest, or a pinned version such as jev-1.13.0.
stateYesThe material to judge: a string, a JSON object, or an array of text values. Jev reads this once and evaluates every question against it in parallel. Non-text inputs (images, audio, binaries) must be converted to text or structured fields first.
questionsYesQuestions keyed by the name each answer comes back under. Each is one of: {"type":"noul"} (yes/no), {"type":"choice","criteria":{"label":"what it means",...}} (pick one), {"type":"score","criteria":["level 0","level 1",...]} (ordered rubric, at least 2 levels). Instructions and criteria may be strings or structured JSON.
include_usageNoInclude token usage. Default true.
include_legendNoInclude the score rubric legend echoed by the API. Off by default: you already sent the rubric.
confidence_thresholdNoAnswers below this confidence come back flagged (needs_review for choice/score, uncertain for noul). Default 0.6, or JEV_CONFIDENCE_THRESHOLD.
include_probabilitiesNoInclude the full probability table per answer. Off by default — it is the largest part of a response.

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so safety is covered. The description adds valuable behavioral context beyond that: 'every question is evaluated against the state in parallel, so extra questions cost a few tokens and almost no latency' reveals efficiency behavior, and 'Jev decides, it does not generate' plus the explicit list of non-capabilities (summarize, translate, write code, explain reasoning) defines the model's behavioral boundaries. This significantly exceeds what annotations provide.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact (around 120 words) and every sentence earns its place. It front-loads the core purpose in the first sentence, then layers on parallel evaluation efficiency, usage preference, behavioral constraints, and the read-only guarantee. There is no redundancy or fluff; the structure flows logically from what the tool does to how to use it to what it cannot do.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is complex (8 parameters, nested question objects, no output schema), and the description covers the essential usage guidance and behavioral constraints. It does not explain the response structure, but the schema richly documents the response-affecting parameters (raw, include_usage, include_probabilities, confidence_threshold). Since annotations cover safety and the schema covers parameters, the description is largely complete, though a brief note on response shape (e.g., 'returns an object keyed by question name') would elevate it. Given the schema's richness, a 4 is appropriate.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description adds high-level guidance about the 'questions' parameter by stating 'every question needs a defined answer space (a label set, a rubric, yes/no),' which complements the schema's detailed per-type definitions. However, it does not describe the response-format parameters (raw, include_usage, include_probabilities, etc.) or the confidence_threshold behavior, leaving those to the schema. The added context is helpful but not comprehensive, hence a 4.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's function: 'Ask Jev one or more typed questions about a state and get calibrated decisions back.' It uses a specific verb (ask) and resource (Jev), and explicitly distinguishes itself from sibling single-question tools by emphasizing 'mixed question types share one request' and 'prefer one call with many questions over many calls.' It also clarifies what the tool does not do (cannot summarize, translate, write code, or explain reasoning), leaving no ambiguity about its scope.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit usage guidance: 'Prefer one call with many questions over many calls,' directly steering agents toward this tool for batched questions and away from multiple single-question calls. It also states the requirement that 'every question needs a defined answer space' and lists exclusions (cannot summarize, translate, etc.), which implicitly guides when NOT to use it. This is concrete, actionable guidance that distinguishes it from siblings like jev_score or jev_choice.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

jev_choicePick one label from a setA
Read-onlyIdempotent

Ask Jev to pick exactly one label from a defined set. Returns the selected label, the calibrated confidence in it, and — when asked — the probability of every label. Use it for routing, classification, and screening. Read-only: the request has no side effects.

ParametersJSON Schema
NameRequiredDescriptionDefault
rawNoReturn the raw API result (every field, unformatted) instead of the compact answer set.
modelNoModel override, e.g. jev-latest, or a pinned version such as jev-1.13.0.
stateYesThe material to judge: a string, a JSON object, or an array of text values. Jev reads this once and evaluates every question against it in parallel. Non-text inputs (images, audio, binaries) must be converted to text or structured fields first.
optionsYesOption labels mapped to a description of what each label means, or null to leave it undescribed. At least 2 labels.
answer_nameNoKey this answer appears under in the response. Defaults to "answer".
instructionsYesThe question, as a string or structured JSON. Write it as a judgment a knowledgeable person makes in a second, not as a multi-step task.
include_usageNoInclude token usage. Default true.
include_legendNoInclude the score rubric legend echoed by the API. Off by default: you already sent the rubric.
confidence_thresholdNoAnswers below this confidence come back flagged (needs_review for choice/score, uncertain for noul). Default 0.6, or JEV_CONFIDENCE_THRESHOLD.
include_probabilitiesNoInclude the full probability table per answer. Off by default — it is the largest part of a response.

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint. The description adds output behavior details: returns selected label, calibrated confidence, and optionally probabilities. It also reiterates read-only, which is already in annotations, but the output details are new. No contradictions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, each serving a purpose: purpose, return value, and use cases/read-only. Front-loaded with the core action. No fluff.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

While the tool has 10 parameters and complex nested structures, the schema descriptions are comprehensive. The description provides a high-level summary but does not explain the full response structure (no output schema) or nuanced behaviors like parallel evaluation of multiple questions (though that is in the state parameter description). Given the tool's complexity, the description is adequate but not exhaustive.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema descriptions cover 100% of parameters, so baseline is 3. The description does not add parameter-specific guidance beyond the schema, but it does mention 'when asked' for probabilities, indirectly referencing include_probabilities. No additional semantics needed given full schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: 'Ask Jev to pick exactly one label from a defined set.' Clearly distinguishes from sibling scoring tools by focusing on single-label selection. Mentions use cases (routing, classification, screening) which further clarify intent.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit context for when to use: 'Use it for routing, classification, and screening.' However, does not explicitly state when not to use it or name alternative tools, leaving the agent to infer distinctions from the tool name and context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

jev_list_modelsList available Jev modelsA
Read-onlyIdempotent

List the model names this account can send in a model field, with a description and release date each, plus what the aliases jev-latest and jev-preview currently point to. The versioned ID that answered a request is reported in that answer's model field.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and no destructive action. The description adds extra context about the tool's output, specifically the alias mapping and the reporting of the versioned ID in the response's 'model' field. This goes beyond the schematic annotations without conflicting with them.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences, with the primary purpose in the first half and additional details in the second. Every clause earns its place, and there is no redundancy. It is front-loaded with the core action ('List the model names').

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given that the tool has no parameters and annotations cover read-only and idempotency, the description provides sufficient detail for an agent to understand what the tool does and what to expect in the response. It does not mention pagination or response format beyond naming the fields, but that is acceptable for a simple list operation. Overall, it is complete enough for correct invocation and interpretation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so the schema is effectively empty. The description correctly omits any parameter details because there are none to explain. With zero parameters, the baseline is 4, and the description adds no unnecessary parameter information.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('List') and resource ('model names'), with details on what is included (descriptions, release dates, alias mappings). It clearly distinguishes from sibling tools like jev_ask or jev_score, which are action-oriented.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description does not explicitly state when to use this tool versus alternatives. However, it clearly implies its purpose as the listing tool for models, which is distinct from the other operations. No exclusions or comparisons are given, so guidance is implicit rather than explicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

jev_noulYes/no as calibrated P(yes)A
Read-onlyIdempotent

Ask Jev a yes/no question and get back P(yes) as a calibrated probability. There is no separate confidence for a noul answer — the probability is the answer, so treat values near 0.5 as unresolved. Read-only: the request has no side effects.

ParametersJSON Schema
NameRequiredDescriptionDefault
rawNoReturn the raw API result (every field, unformatted) instead of the compact answer set.
modelNoModel override, e.g. jev-latest, or a pinned version such as jev-1.13.0.
stateYesThe material to judge: a string, a JSON object, or an array of text values. Jev reads this once and evaluates every question against it in parallel. Non-text inputs (images, audio, binaries) must be converted to text or structured fields first.
answer_nameNoKey this answer appears under in the response. Defaults to "answer".
no_criteriaNoOptional description of what counts as no.
instructionsYesThe question, as a string or structured JSON. Write it as a judgment a knowledgeable person makes in a second, not as a multi-step task.
yes_criteriaNoOptional description of what counts as yes.
include_usageNoInclude token usage. Default true.
include_legendNoInclude the score rubric legend echoed by the API. Off by default: you already sent the rubric.
confidence_thresholdNoAnswers below this confidence come back flagged (needs_review for choice/score, uncertain for noul). Default 0.6, or JEV_CONFIDENCE_THRESHOLD.
include_probabilitiesNoInclude the full probability table per answer. Off by default — it is the largest part of a response.

TDQS

A4.2/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description adds behavioral context beyond the annotations: it explains that 'there is no separate confidence for a noul answer' and that values near 0.5 should be treated as unresolved. It also states the read-only nature explicitly, aligning with readOnlyHint. It mentions parallel evaluation of state, which is useful execution detail. This exceeds the annotation coverage and provides meaningful interpretation guidance.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is three sentences, front-loaded with the core purpose, then adds the critical interpretation caveat, and finally the read-only note. Every sentence earns its place; there is no filler. It is concise and well-structured.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description explains the primary return value (P(yes)) and its interpretation, which is the most important aspect for an agent. However, with no output schema and complex options (e.g., raw, include_probabilities, include_usage), the description does not outline the full response structure beyond the probability. The schema parameter descriptions help, but a bit more detail on the default response format would improve completeness. Given the tool's complexity, this is a minor gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema already has 100% description coverage for all parameters, so the baseline is 3. The tool description itself does not elaborate on parameters beyond the schema, but it does not need to—the schema covers semantics well. The description's mention of 'calibrated probability' relates to the output, not parameters, so no additional parameter semantics are added.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's function: 'Ask Jev a yes/no question and get back P(yes) as a calibrated probability.' It also explains the key output interpretation ('the probability is the answer'), which distinguishes it from sibling tools like jev_score or jev_choice. This is a specific verb+resource statement that leaves no ambiguity about what the tool does.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies when to use it ('Ask Jev a yes/no question') but does not explicitly compare it to siblings or state when NOT to use it. It does not mention alternatives like jev_score (which likely returns a score) or jev_choice (which chooses among options). The context is clear enough for an agent to infer the use case, but explicit exclusions are missing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

jev_scoreScore against an ordered rubricA
Read-onlyIdempotent

Ask Jev to rate a state against an ordered rubric. Returns the expected score (which may fall between levels), its confidence, and — when asked — the probability of each level. Split a judgment that depends on several factors into one score per factor and combine them in your own code. Read-only: the request has no side effects.

ParametersJSON Schema
NameRequiredDescriptionDefault
rawNoReturn the raw API result (every field, unformatted) instead of the compact answer set.
modelNoModel override, e.g. jev-latest, or a pinned version such as jev-1.13.0.
stateYesThe material to judge: a string, a JSON object, or an array of text values. Jev reads this once and evaluates every question against it in parallel. Non-text inputs (images, audio, binaries) must be converted to text or structured fields first.
levelsYesThe rubric, lowest level first, indexed from 0. Descriptions may be strings or null. At least 2 levels.
answer_nameNoKey this answer appears under in the response. Defaults to "answer".
instructionsYesThe question, as a string or structured JSON. Write it as a judgment a knowledgeable person makes in a second, not as a multi-step task.
include_usageNoInclude token usage. Default true.
include_legendNoInclude the score rubric legend echoed by the API. Off by default: you already sent the rubric.
confidence_thresholdNoAnswers below this confidence come back flagged (needs_review for choice/score, uncertain for noul). Default 0.6, or JEV_CONFIDENCE_THRESHOLD.
include_probabilitiesNoInclude the full probability table per answer. Off by default — it is the largest part of a response.

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already provide readOnly/idempotent/destructive safety hints; the description reinforces this with an explicit 'Read-only: the request has no side effects.' It adds useful behavioral context beyond the annotations, such as the expected score possibly falling between levels and probabilities being returned only when requested. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences deliver purpose, return behavior, and usage guidance without filler. The main action is front-loaded, and every sentence earns its place, including the concise decomposition tip and read-only note.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Despite the absence of an output schema, the description names the central return fields (score, confidence, probabilities) and the side-effect guarantee, which covers the most essential invocation context. Parameter-level details are handled by the schema's thorough descriptions. Minor omissions like error behavior or default model behavior are not critical for a correct call.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

All 10 parameters have descriptions in the schema (100% coverage), so the schema already carries most semantic weight. The description adds high-level context (e.g., ordered rubric, optional probabilities) but does not clarify per-parameter details beyond the schema, so the baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('rate a state') and the resource ('an ordered rubric'), and it names the key outputs (expected score, confidence, probabilities). It does not explicitly differentiate from sibling tools like jev_choice or jev_noul, so the agent must infer distinctions from naming and schema rather than from the description.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives a clear context for use (scoring against an ordered rubric) and offers an implementation guideline: split factor-dependent judgments into separate scores and combine them in code. However, it does not state when to use this tool instead of siblings, nor any exclusion conditions, so the guidance is implied rather than explicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

jev_server_infoShow this server’s configuration and limitsA
Read-onlyIdempotent

Report this server's configuration and safety limits: base URL, default model, whether an API key is present (never the key), the context budget and how an over-budget request is refused, the confidence threshold, how other MCP clients connect, and the tool list. Use it to confirm what an agent is actually connected to.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, openWorldHint, idempotentHint, and destructiveHint=false, so the tool is known to be safe and non-destructive. The description adds valuable context beyond that: it explicitly states it never returns the API key, describes what happens with over-budget requests (refused), and mentions the confidence threshold. This enriches the behavioral understanding beyond the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single sentence but is information-dense, listing all the key items (base URL, model, API key, context budget, threshold, connectivity, tool list) without fluff. It is front-loaded with the main purpose ('Report this server's configuration and safety limits') and ends with a clear usage directive. Every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given that the tool has no parameters, no output schema, and a read-only, idempotent, non-destructive profile, the description is complete. It covers what the tool reports, what it doesn't return (API key), and why to use it. An agent has all necessary information to call it correctly and interpret the result.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema has 100% description coverage and 0 parameters, so the baseline is 4. The description doesn't need to explain parameters because there are none. It does specify what the tool reports, which is effectively the 'return' content, though not structured as parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states a specific verb ('Report') and resource ('this server's configuration and safety limits') and enumerates the exact items covered (base URL, default model, API key presence, context budget, confidence threshold, client connections, tool list). It is distinct from sibling tools like jev_score or jev_ask, which have different purposes, and the description explicitly says to use it to confirm what the agent is connected to.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly tells when to use this tool: 'Use it to confirm what an agent is actually connected to.' This provides clear context and purpose, distinguishing it from alternatives. While it doesn't explicitly say 'when not to use,' the guidance is sufficient for an agent to know this is the go-to for server info, not for scoring or asking questions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

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

  1. 6 tool updatesv0.1.0
    • First observedjev_ask
    • First observedjev_choice
    • First observedjev_list_models
    • First observedjev_noul
    • First observedjev_score
    • First observedjev_server_info

TDQS

A4.1/5.0

Scored across 6 tools

Disambiguation3/5

jev_ask can handle label sets, rubrics, and yes/no questions, so it overlaps with jev_choice, jev_score, and jev_noul for single-question use. The specialized tools are individually clear, but an agent could reasonably hesitate between the generic ask tool and the specialized one.

Naming Consistency4/5

All tools share a consistent jev_ prefix and lowercase snake_case style, with list_models and server_info following a recognizable pattern. The names score, ask, choice are concise, though jev_noul is cryptic and not clearly verb- or noun-shaped.

Tool Count5/5

Six tools is well-scoped for a decision-serving MCP: four distinct question modes plus two informational endpoints. Each tool earns its place, and the count is comfortably inside the expected range.

Completeness5/5

The surface covers all stated capabilities: rubric scoring, label choice, yes/no probability, mixed parallel questions, model metadata, and server configuration. The explicit design limitation that Jev does not generate text explains why generation/rewrite tools are absent, leaving no obvious dead ends.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    B
    maintenance
    Enables frontier coding agents to delegate routine probabilistic judgments to TypeSafe Jev, providing calibrated triage signals for failures, attempts, completion, context ranking, findings, risk, and generic evidence-grounded questions.
    7
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables MCP clients to consult TypeSafe's Jev through a judge tool, answering narrow typed questions with calibrated probabilities instead of prose.
    MIT
  • 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
    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
    1
    AGPL 3.0