Skip to main content
Glama
Ahesui
by Ahesui
README.md
# vercel-jev-mcp

A local stdio MCP server that gives Cursor, Codex, and other MCP clients typed [TypeSafe Jev](https://docs.typesafe.ai/introduction.md) judgments **over the [Vercel AI Gateway](https://vercel.com/docs/ai-gateway)**. Jev returns Choice, Score, and Noul answers; the host agent still edits files and runs commands.

One key, one endpoint, one bill: `AI_GATEWAY_API_KEY` and `POST https://ai-gateway.vercel.sh/v1/evaluate` with model `typesafe-ai/jev`.

## Tools

| Tool | Purpose |
| --- | --- |
| `jev_step` | Route the next step and select a prepared call in one request |
| `jev_coding_loop` | Route the next step and decide whether a partner model is needed |
| `jev_tool_route` | Select an exact host-prepared tool call without generating arguments |
| `jev_review` | Assess a proposed patch |
| `jev_verify` | Check claims against supplied evidence |
| `jev_gate` | Combine patch review and claim verification in one upstream call |
| `jev_screen` | Screen untrusted content before the host reads it |
| `jev_rank` | Rank candidates supplied by the host |
| `jev_evaluate` | Ask custom, atomic typed questions |

Results include typed answers, token usage, and an `action`: `auto`, `review`, or `escalate`. Confidence measures model certainty, not factual truth. Incomplete context never permits `auto`; reduce the input and submit it again for a complete judgment.

Question packs are MCP resources at `jev://packs/{coding-loop,tool-route,step,review,verify,screen,rank,gate}`.

## Why the AI Gateway route

The judgment engine, the question packs, and the typed policy layer are unchanged. What the gateway adds:

- **One credential and one bill.** `AI_GATEWAY_API_KEY` replaces a provider-specific key; model choice, routing, and fallbacks are gateway configuration, and the same key serves every other model you already route there.
- **Real per-call accounting.** Each response carries gateway `marketCost`, a `generationId`, and token `usage`. The `eval` CLI and `doctor` surface them, so a Jev swarm is measurable instead of estimated.
- **Deadline-aware retry.** Transient gateway failures (408, 429, 5xx, connection drops) are retried with exponential backoff, honouring `Retry-After`, and never past the tool deadline — the same shared budget that already covers ranking rounds.
- **No vendor SDK.** The transport is a typed `fetch` call against the documented wire contract; the internal domain model in [`src/jev-types.ts`](src/jev-types.ts) stays the single source of truth for what the tools see.

## Coding with fewer partner-model turns

`jev_step` answers the whole loop turn in one request: it routes the step and, when the host supplies prepared calls, selects among them. A host that would otherwise call `jev_coding_loop` and then `jev_tool_route` spends one MCP round-trip instead of two, so it spends one host-model turn instead of two. Both original tools remain available.

Let host code execute known steps and prepare exact tool calls from an existing plan. When a semantic choice is needed, pass those calls to `jev_step` or `jev_tool_route`; either returns an executable `call` only for a confident, suitable selection with complete context and validated host facts. The host executes that call and routes again using the new observation. Jev never invents arguments or executes tools.

When a new plan or code may be needed, use `jev_coding_loop` with trusted `execution` facts. Its `handoff` distinguishes tool use, context gathering, review, user input, stopping, and a partner model. Invoke a generative partner only when `partner_model.required` is `true`; the legacy `model_tier` answer alone does not request a model turn. Uncertainty and escalation do not automatically spend a partner turn.

The prepared-call router accepts at most 32 candidates. Empty or wholly ineligible lists return locally with zero Jev usage. Other routing calls use Jev; this reduces unnecessary generative handoffs by policy, but live quality and cost savings have not been measured. See [the tool contracts](docs/tools.md) and [host workflow](skills/vercel-jev-mcp/SKILL.md).

## Quick start

Install Node 20+ and run from a checkout:

```bash
npm ci
npm run build
```

Set an [AI Gateway API key](https://vercel.com/docs/ai-gateway/manage-api-keys/api-key-management) in your shell, then run diagnostics:

```bash
export AI_GATEWAY_API_KEY=vck_...
node dist/index.js doctor
node dist/index.js doctor --json
```

PowerShell:

```powershell
$env:AI_GATEWAY_API_KEY = 'vck_...'
node dist/index.js doctor --json
```

For a deterministic local demo, set `JEV_MCP_MOCK=1` instead. Mock mode is for tests and demos, not production decisions. Neither the CLI nor MCP automatically reads `.env`; see [configuration](docs/configuration.md) for explicit environment-file use.

**Cursor:** copy [the MCP example](examples/cursor.mcp.json) into `.cursor/mcp.json`, replace its argument with the absolute path to this checkout's `dist/index.js`, and set the key in `env`.

**Codex:** register the absolute path:

```bash
codex mcp add jev --env AI_GATEWAY_API_KEY=vck_... -- node /absolute/path/to/vercel-jev-mcp/dist/index.js
```

Copy [the agent skill](skills/vercel-jev-mcp/SKILL.md) into the project so the host knows when to call these tools. Detailed setup is in [installation](docs/install.md).

## CLI

```bash
node dist/index.js                       # stdio MCP
node dist/index.js doctor                # human-readable diagnostics on stderr
node dist/index.js doctor --json         # structured diagnostics on stdout
node dist/index.js eval --stdin < request.json
```

An evaluation request contains `state` and a `questions` map:

```json
{
  "state": "Production payouts are failing. Urgent.",
  "questions": {
    "urgent": { "type": "noul", "instructions": "Is this urgent?" }
  }
}
```

`eval` prints the typed answers plus `usage` and, on a live call, the gateway's `provider` block (`cost_usd`, `generation_id`):

```json
{
  "answers": { "urgent": { "type": "noul", "noul": 0.92 } },
  "usage": { "input_tokens": 407, "output_tokens": 70 },
  "provider": { "cost_usd": 0.000011592, "generation_id": "gen_01M2YEY6S02VMFPV8BMED0PX0G" }
}
```

Diagnostics do not log request content or API keys. Calls have a 30-second total deadline by default, configurable with `JEV_MCP_TIMEOUT_MS`; transient gateway failures retry inside that deadline. API failures and invalid responses return typed errors rather than fabricated judgments.

## Limits and policy

State plus questions must fit the estimated 64,000-token total budget and the 32,000-token state-plus-longest-question budget. State may be shortened; results expose incomplete coverage and cannot automatically accept a judgment based on omitted context. Questions alone that exceed the budget are rejected. State is sent to the gateway as text, so a truncated evaluation truncates *what Jev reads*, not just what you see.

Rank accepts unique candidate IDs and at most 5,000 supplied candidates, with at most 250 options per upstream call. Larger lists use repeated reduction rounds; each candidate text is capped at 2,000 characters. Verify and gate accept at most 1,000 claims. A Score question takes 2 to 10 levels, which is the gateway's own limit and is enforced before any request. It ranks supplied candidates and does not index your repository. Arithmetic and date calculations belong in host code.

All nine tools expose an MCP output schema and return the same successful payload through both `structuredContent` and the JSON text content. Tool-route and fused-step judgments receive sanitized candidate descriptions and argument shapes; raw host arguments are retained only for the selected, locally validated call.

## Development

```bash
npm test
npm run typecheck
npm run build
npm run test:package
npm run benchmark
```

The regular suite runs without a key; the live test is skipped unless `AI_GATEWAY_API_KEY` is present and mock mode is disabled. Package smoke testing builds and packs the project, installs the tarball into an isolated directory with `npm --offline`, then runs its shipped CLI. `npm run benchmark` builds the compiled server and measures the real MCP stdio transport in deterministic mock mode: sequential and concurrent calls, payload-size scaling, and candidate-count scaling. Use `npm run benchmark:ci` to apply broad sanity budgets; set `JEV_BENCH_ITERATIONS`, `JEV_BENCH_CONCURRENCY`, `JEV_BENCH_MAX_P95_MS`, or `JEV_BENCH_MIN_RPS` to tune a run. Run `npm ci` first to populate the dependency cache. No test publishes the package.

`npm pack` and `npm publish` build automatically through `prepack`. CI checks Node 20 and 22 on Windows and Linux, including the offline packed-install smoke test, entirely offline and in mock mode.

## Documentation

| Document | Contents |
| --- | --- |
| [Changelog](docs/changelog.md) | Unreleased changes, compatibility notes, and validation |
| [Architecture](docs/architecture.md) | Request path, gateway transport, policy, limits, and errors |
| [Tools](docs/tools.md) | Arguments and outputs for all nine tools |
| [Install](docs/install.md) | Host configuration for Cursor, Codex, and other MCP clients |
| [Configuration](docs/configuration.md) | Environment, thresholds, diagnostics, tests |
| [Agent skill](skills/vercel-jev-mcp/SKILL.md) | Calling guidance for the host |
| [AGENTS.md](AGENTS.md) | Short project guidance |

TDQS

A4/5.0

Scored across 9 tools

Disambiguation3/5

The tools are largely distinct, but a few are deliberately composite or overlapping: jev_step is effectively jev_coding_loop plus jev_tool_route, and jev_gate bundles jev_review and jev_verify. An agent must read the long descriptions carefully to select the right orchestration recipe, so misselection is possible despite the clear use-case notes.

Naming Consistency4/5

All tools share the consistent jev_ prefix and lowercase snake_case style, which makes the set feel predictable. However, the suffix pattern is mixed: verb-style names like jev_review, jev_verify, and jev_rank sit alongside noun-style names like jev_gate, jev_step, and jev_coding_loop, plus the compound noun jev_tool_route.

Tool Count5/5

Nine tools is a well-scoped count for this kind of workflow server, and each tool maps to a recognizable phase: screening, ranking, evaluation, routing, stepping, review, verification, and final gating. None of the tools feel like filler, and the set is large enough to cover meaningful decisions without becoming unwieldy.

Completeness5/5

The toolset covers the full intended lifecycle for a decision/review server: untrusted text screening, candidate ranking, arbitrary typed evaluation, tool/step routing, next-action loop decisions, diff review, claim verification, and a combined final gate. The deliberate exclusion of file edits/execution is consistent with the stated purpose, and jev_evaluate acts as an escape hatch to prevent dead ends.

Maintenance

ActivityMaintained
ResponsivenessNo issues