@jkudish/jev-mcp 0.10.1 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.12.0
4
+
5
+ - Side-effect-free imports: the package root and `/server` export `createServer()` without starting a transport; the CLI stays unchanged. The new exports map replaces `dist/*` deep imports. Requested in [#49](https://github.com/jkudish/jev-mcp/issues/49) by [@deadczarvc](https://github.com/deadczarvc).
6
+ - Opt-in `/mcp/<token>` authentication for HTTP clients that cannot send bearer headers, with URL-safe token validation and token stripping after authentication. Via [#50](https://github.com/jkudish/jev-mcp/pull/50).
7
+ - TypeSafe requests retry transient HTTP failures, honor bounded `Retry-After`, and report the effective model through `jev-agent-tools` 0.1.4; exhausted rate limits and server failures remain tool errors rather than invalid judgments. Reported in [jev-agent-tools#5](https://github.com/jkudish/jev-agent-tools/issues/5) by [@deadczarvc](https://github.com/deadczarvc).
8
+
9
+ ## 0.11.0
10
+
11
+ - New `jev_audit` tool: a max-gated failure-mode battery (hallucinated, off-target, incomplete, wrong format) plus an omission check, auditing extracted values against their source before they're trusted. Via [#48](https://github.com/jkudish/jev-mcp/pull/48) by Rex-Gao, prompted by [#45](https://github.com/jkudish/jev-mcp/issues/45).
12
+ - `jev_decide`: names `contradicted_requirements` on the recommendation, and opt-in `escalate_on_contradiction` withdraws a contradicted pick in addition to the warning; no silent re-selection. Via [#46](https://github.com/jkudish/jev-mcp/pull/46) by Rex-Gao, prompted by [#43](https://github.com/jkudish/jev-mcp/issues/43); the structural-field idea from [#44](https://github.com/jkudish/jev-mcp/pull/44) by xujiantop-crypto.
13
+ - `jev_review` / `jev_gate`: optional per-file review mode — one request, composed auto/mean/min/limiting, combined request+tests+diffs budget, per-file truncation. Via [#47](https://github.com/jkudish/jev-mcp/pull/47) by Rex-Gao, prompted by [#42](https://github.com/jkudish/jev-mcp/issues/42).
14
+ - Docs: runnable Exa search → classification example. Via [#41](https://github.com/jkudish/jev-mcp/pull/41) by RogueTex.
15
+
3
16
  ## 0.10.1
4
17
 
5
18
  - `--http` advertises a static tool list and refuses `subscriptions/listen` in-band: previously a client that opened a listener parked an idle stream on a concurrency slot for its lifetime, and enough listeners could starve the server of slots. Slot accounting no longer leaks on a rejected handler either.
package/README.md CHANGED
@@ -9,7 +9,7 @@
9
9
 
10
10
  Fast, cheap, typed judgments from TypeSafe's Jev model, as MCP tools.
11
11
 
12
- Give your agent eleven judgment tools:
12
+ Give your agent twelve judgment tools:
13
13
 
14
14
  - `jev_verify` checks claims against evidence.
15
15
  - `jev_screen` judges content before it enters context.
@@ -20,6 +20,7 @@ Give your agent eleven judgment tools:
20
20
  - `jev_decide` settles bounded alternatives.
21
21
  - `jev_compare` judges how two passages relate.
22
22
  - `jev_extract` pulls field values with regex plus judgment.
23
+ - `jev_audit` audits extracted values against their source before they are trusted.
23
24
  - `jev_review` scores a proposed diff before the task is called done.
24
25
  - `jev_gate` reviews a patch and verifies completion claims in one call.
25
26
 
@@ -142,8 +143,18 @@ It listens on `PORT` (default `8080`) and serves MCP at `/mcp`, with a health ch
142
143
  claude mcp add --transport http jev https://jev.example.com/mcp --header "Authorization: Bearer $JEV_MCP_AUTH_TOKEN"
143
144
  ```
144
145
 
146
+ Some clients can only be configured with a URL and cannot send headers, such as claude.ai custom connectors. For those, set `JEV_MCP_PATH_TOKEN=1` and give the client `https://jev.example.com/mcp/<token>`; the segment is compared raw, in constant time, against `JEV_MCP_AUTH_TOKEN`, and the server refuses to start unless the token is URL-safe (letters, digits, `.` `_` `-` `~`). Use a dedicated high-entropy token for this form (for example `openssl rand -hex 32`), serve it over HTTPS only, and treat the whole URL as the secret: redact full paths from proxy and access logs, keep the URL out of shared configs, and avoid redirects of it. Rotate the token if it escapes. It is off by default because a URL is easier to leak than a header. The header form keeps working alongside it.
147
+
145
148
  The server itself speaks plain HTTP: terminate TLS at a reverse proxy or load balancer before exposing it beyond loopback, and put connection limits and request rate limits at that ingress. The process bounds admitted `/mcp` requests (`JEV_MCP_MAX_CONCURRENCY`, default 16; excess shed with `429`) and caps request bodies at 4 MiB, but it does not limit sockets waiting to finish headers or repeatedly rejected requests. The tool list is static: the server advertises no `listChanged` capability and refuses `subscriptions/listen` requests, so an idle listener cannot hold one of the concurrency slots. Clients that never open a listener, the common case, see no difference.
146
149
 
150
+ ### Embedding
151
+
152
+ The `jev-mcp` bin boots a transport when run; importing the package never does. To run the tools in-process (an agent hook, a larger server, a test harness):
153
+
154
+ - `import { createServer } from "@jkudish/jev-mcp"` — side-effect-free: it registers the tools and exports a `createServer()` that returns a fresh `McpServer` wired with all twelve, without starting stdio or HTTP. Connect your own transport to it; the stateless HTTP path in this package uses the same factory. `@jkudish/jev-mcp/server` is an explicit alias for the same entry.
155
+ - `MODEL` is exported alongside it, resolved from `JEV_MCP_MODEL` at import time (default `jev-latest`), so embedders report the same model the CLI serves.
156
+ - The package now declares `exports`, so deep imports like `@jkudish/jev-mcp/dist/index.js` no longer resolve. Before the exports map, importing that path booted a transport inside the importer's process — the trap `/server` and the safe root entry replace. `dist/index.js` remains the bin and still boots when executed.
157
+
147
158
  ### Agent skill
148
159
 
149
160
  The package ships an agent skill (`skills/jev/`) that teaches coding agents when to reach for each tool instead of answering from their own reading: the difference between tools that sit registered-but-unused and tools that get called. Copy it into your client's skills directory:
@@ -186,7 +197,7 @@ Check each claim in a report, PR description, or agent brief against the sources
186
197
  }
187
198
  ```
188
199
 
189
- Malformed or missing relation answers fail closed per claim (other valid claims are preserved). A missing, null, or non-object `answers` envelope invalidates every claim:
200
+ A malformed or missing relation answer fails closed per claim:
190
201
 
191
202
  ```jsonc
192
203
  // invalid result entry; tool/model/provider/auto_accept/summary/results/usage remain
@@ -197,6 +208,7 @@ Malformed or missing relation answers fail closed per claim (other valid claims
197
208
  }
198
209
  ```
199
210
 
211
+ - A malformed or missing relation answer fails closed for that claim; other valid claims are preserved. A missing, null, or non-object `answers` envelope invalidates every claim.
200
212
  - Relation choices must belong to the requested set and be a maximum-probability option. Distributions must contain exactly all relation keys, with finite probabilities in `[0,1]` summing to 1 within `0.01`.
201
213
  - Missing or null confidence stays `null` and requires `review`, even with `auto_accept: 0`. Non-number, non-finite, or out-of-range confidence invalidates the claim and is returned as `null`; numeric zero is valid.
202
214
  - With multiple evidence items, each claim also gets the id of the evidence it rests on. These source answers are optional auxiliary information; missing sources yield `supporting_evidence: null` without invalidating a valid relation. A present source must be a well-formed choice over the evidence ids plus `none`; anything else yields `null`.
@@ -234,8 +246,9 @@ Missing or malformed required answers return an error branch:
234
246
  }
235
247
  ```
236
248
 
237
- All requested probabilities must be finite numbers in `[0,1]`; zero is valid. Invalid or missing probabilities become `null`, while valid values are retained. Relevance is required only when a non-empty purpose is supplied; otherwise it is `null`. A missing, null, or non-object `answers` envelope also takes this error branch.
238
-
249
+ - All requested probabilities must be finite numbers in `[0,1]`; zero is valid. Invalid or missing probabilities become `null`, while valid values are retained.
250
+ - Relevance is required only when a non-empty `purpose` is supplied; otherwise it is `null`.
251
+ - A missing, null, or non-object `answers` envelope also takes this error branch.
239
252
  - The recommendation is advisory: `pass`, `review`, `block`, or `skip`. The server never blocks on its own; enforcement stays with the calling agent.
240
253
  - Low substance or relevance yields `skip`: the page is not worth reading.
241
254
  - `block_at` (default `0.75`) and `review_at` (default `0.25`) are thresholds on the injection probability. Both are parameters.
@@ -289,8 +302,9 @@ Missing or malformed `exists` or `best` answers return an error branch:
289
302
  }
290
303
  ```
291
304
 
292
- `exists` must be a finite number in `[0,1]`; zero validly means `absent`. On failure, a valid `exists` value is retained; an invalid or missing value becomes `null`. The best distribution must contain exactly all candidate ids, finite probabilities in `[0,1]` summing to 1 within `0.01`, and a string choice tied for the maximum probability. Missing, null, or non-object `answers` also returns this error branch. Protocol failure is reported only in `status`; `exists_verdict` is `null` on failure.
293
-
305
+ - `exists` must be a finite number in `[0,1]`; zero validly means `absent`. On failure, a valid `exists` value is retained; an invalid or missing value becomes `null`. Protocol failure is reported only in `status`; `exists_verdict` is `null` on failure.
306
+ - The best distribution must contain exactly all candidate ids, finite probabilities in `[0,1]` summing to 1 within `0.01`, and a string choice tied for the maximum probability.
307
+ - A missing, null, or non-object `answers` envelope also returns this error branch.
294
308
  - On successful responses, ranking always returns a winner, because Choice probabilities sum to 1. A top hit can masquerade as an answer when none is present; the exists check catches that. `exists_verdict` is `answered`, `partial`, or `absent`.
295
309
  - Up to 250 candidates per call. Candidate texts are truncated at 2,000 characters.
296
310
  - Pattern from the [semantic-find cookbook](https://docs.typesafe.ai/cookbooks/semantic_find).
@@ -329,6 +343,7 @@ Assign each item to one class from a shared catalog, in one batched request: the
329
343
  - Class descriptions carry the decision. Strong ones state a precise definition, what belongs, what does not, precedence over overlapping classes, and a short example.
330
344
  - Up to 250 classes and 64 items per call, with an 8,000 item-class budget per batch (split larger waves into multiple calls); item text is truncated at 2,000 characters.
331
345
  - A malformed or incomplete model response is reported as `status: invalid_response` on that item, never as model uncertainty. The chosen class must have the maximum probability (ties and differences within `1e-9` are accepted); otherwise that item returns `invalid_response`.
346
+ - For a runnable Exa search → classification pipeline with preserved source URLs and review routing, see the [Exa classification example](examples/exa-classify.md).
332
347
 
333
348
  ### jev_decide
334
349
 
@@ -352,14 +367,16 @@ One bounded decision, 2-6 candidates, evidence, and explicit priorities. Jev ret
352
367
  // live result, abridged
353
368
  {
354
369
  "recommendation": { "selected": "poll", "escaped": false, "confidence": 1,
355
- "probabilities": { "poll": 1, "push": 0, "ask_user": 0 } },
370
+ "probabilities": { "poll": 1, "push": 0, "ask_user": 0 },
371
+ "contradicted_requirements": [] },
356
372
  "checks": [ { "candidate": "poll", "requirement": 0, "answer": "supported" },
357
373
  { "candidate": "push", "requirement": 0, "answer": "contradicted" } ]
358
374
  }
359
375
  ```
360
376
 
361
377
  - Escape hatches (`ask_user`, `investigate`, `none`) let the model decline to rank when a preference or fact is missing; `escaped: true` in the result marks it. Disable with `escape_hatches: false` for closed-world choices.
362
- - Requirement checks run as independent questions in the same request and may disagree with the recommendation; a contradiction on the recommended candidate surfaces as a warning.
378
+ - Requirement checks run as independent questions in the same request and may disagree with the recommendation; `recommendation.contradicted_requirements` names the zero-based requirement indexes whose checks came back `contradicted` for the selected candidate, and a contradiction also surfaces as a warning.
379
+ - Pass `escalate_on_contradiction: true` to withdraw a contradicted recommendation in addition to the warning: the result comes back `selected: null` with `status: "escalate"` (the `jev_verify` vocabulary), probabilities and `contradicted_requirements` intact. The indexes describe the recommended candidate before withdrawal — `selected` is null afterward. The default keeps the recommendation and warns. No re-selection: a withdrawn recommendation is never silently replaced by the runner-up.
363
380
  - One call per unchanged decision. Repeat only with materially new evidence or criteria.
364
381
 
365
382
  <sub>Pattern credit: [thesammykins/jev_ampcode](https://github.com/thesammykins/jev_ampcode).</sub>
@@ -400,8 +417,8 @@ Score every candidate's relevance to a query and get them back sorted. You bring
400
417
  }
401
418
  ```
402
419
 
403
- Each candidate is a file: `id` is any handle you choose, echoed back verbatim, and `text` is the file's contents (truncated at 2,000 characters). No candidate contains the words bandwidth or triple. A shorter CDN TTL means more origin fetches, so `src/cache.ts` ranks first on meaning alone; the always-on VMs are cloud spend too, just not bandwidth.
404
-
420
+ - Why `src/cache.ts` ranks first: no candidate contains the words bandwidth or triple. A shorter CDN TTL means more origin fetches, so it wins on meaning alone; the always-on VMs are cloud spend too, just not bandwidth.
421
+ - Each candidate is a file: `id` is any handle you choose, echoed back verbatim, and `text` is the file's contents (truncated at 2,000 characters).
405
422
  - One relevance probability per candidate, all in a single request; cost scales with the number of candidates, not with candidate-pairs.
406
423
  - Candidate ids are preserved verbatim. If any answer comes back malformed, the whole ranking is reported `invalid_response` rather than sorting a missing score as a confident zero.
407
424
  - Up to 250 candidates and a 100,000-character aggregate budget; split larger batches.
@@ -471,6 +488,55 @@ Pull structured fields out of a document with your regex and Jev's judgment. You
471
488
  - Invalid patterns and regexes that time out (they run in a sandboxed worker with a 1-second deadline, so a pathological pattern cannot hang the server) return `invalid_pattern` with the error instead of failing the whole call.
472
489
  - Up to 32 fields per call and 20 candidate matches per field, judged in one request. The document is capped at 50,000 characters, and the candidate match text at 50,000 characters in aggregate.
473
490
 
491
+ ### jev_audit
492
+
493
+ Audit extracted values against the text they claim to come from, before the values are trusted. For each value, one request carries a failure-mode battery — hallucinated, off-target, incomplete, wrong format — each a yes/no question framed so that yes means something is wrong, plus a dedicated omission check for values that came back empty. A value's `p_wrong` is the maximum over its checks; any value at or above `wrong_at` (default 0.7) escalates the whole audit. Max-gated, never averaged: one fired flag cannot be diluted by clean siblings.
494
+
495
+ ```jsonc
496
+ // arguments
497
+ {
498
+ "source": "Invoice INV-7734. Total $1,240.00. Due 2026-10-15. Late fee 1.5% per month.",
499
+ "records": [
500
+ { "id": "total", "request": "The invoice total amount", "value": "$1,240.00" },
501
+ { "id": "due_date", "request": "The due date in YYYY-MM-DD", "value": "2026-10-15" },
502
+ { "id": "currency", "request": "The billing currency", "value": "EUR" }
503
+ ]
504
+ }
505
+ ```
506
+
507
+ ```jsonc
508
+ // live result, abridged
509
+ {
510
+ "action": "escalate",
511
+ "wrong_at": 0.7,
512
+ "summary": { "records": 3, "flagged": 1, "invalid": 0 },
513
+ "records": [
514
+ { "id": "total", "value": "$1,240.00", "action": "ok", "p_wrong": 0.02,
515
+ "checks": { "hallucinated": 0.02, "off_target": 0.01, "incomplete": 0.01, "format": 0.01 } },
516
+ { "id": "due_date", "value": "2026-10-15", "action": "ok", "p_wrong": 0.03, "checks": { "…": "…" } },
517
+ { "id": "currency", "value": "EUR", "action": "wrong", "p_wrong": 0.91,
518
+ "checks": { "hallucinated": 0.91, "off_target": 0.4, "incomplete": 0.05, "format": 0.2 } }
519
+ ]
520
+ }
521
+ ```
522
+
523
+ - Here the currency was fabricated — the invoice never states one — and the `hallucinated` check catches what a schema-valid extraction would happily pass through.
524
+ - The framing discipline is the point: every check asks "is something wrong", so one threshold routes the record. The battery, the omission special case, and the max gate come from TypeSafe's SDE cascade cookbook, where this verifier is what catches a schema-valid fabrication.
525
+ - An empty value gets only the omission check: wrong when the source supports a value the extractor missed, correct when returning nothing was right.
526
+ - Malformed answers mark the record `invalid_response` and escalate: a protocol failure is never a clean pass. A truncated `source` (over 50,000 characters) demotes `pass` to `review`, never keeps it.
527
+ - Up to 32 records per call, judged in one request; each request line is capped at 500 characters, each value at 2,000.
528
+
529
+ #### Multimodal intake
530
+
531
+ Jev reads text only — its state is a string, JSON object, or array, and images, audio, and video are not supported (pre-process to text first, per the TypeSafe docs). Multimodal judgment therefore lands as a cascade, with the text artifacts cross-checked by the text-only judge:
532
+
533
+ 1. **Extract** with your host model: a vision or ASR model produces a dense transcript of the image, scan, or recording, plus the structured values you want.
534
+ 2. **Screen** the transcript with `jev_screen`: transcripts of fetched content are untrusted text and get the injection screen before anything else. The screen is advice you enforce — honor `block` and `review` before passing the transcript onward. It protects what enters your context, not the vision or ASR model, which has already consumed the untrusted material.
535
+ 3. **Audit** the values against the transcript with `jev_audit`. This is a cross-check between two text artifacts, not verification of the original: when the original text exists (a document, a page), audit against it directly. For vision or ASR output, one host model usually produces both the transcript and the values, so the same misreading can appear in both and pass the audit — producing the two separately, or with independent models, makes the cross-check stronger. `pass` means no check crossed the threshold, never that the values were verified against the pixels or audio.
536
+ 4. **Judge** with the existing tools — verify claims, classify, review — over the audited text, keeping the provenance in state so downstream judgments know they read an extraction, not the original.
537
+
538
+ <sub>Question design adapted from the TypeSafe [SDE cascade cookbook](https://docs.typesafe.ai/cookbooks/sde_cascade) (see [#45](https://github.com/jkudish/jev-mcp/issues/45)).</sub>
539
+
474
540
  ### jev_review
475
541
 
476
542
  Score a proposed diff against the request before the task is called done. Jev answers four rubric questions, correctness, spec match, test gap, and blast radius, each 0..2, plus one safe-to-apply probability; the server combines them into a weighted composite and one action: `auto`, `review`, or `escalate`. It judges what you hand it. It never runs tests and never applies the patch.
@@ -505,14 +571,18 @@ Score a proposed diff against the request before the task is called done. Jev an
505
571
  }
506
572
  ```
507
573
 
508
- Here the composite clears the floor, but the failing test drags `safe_to_apply` to 0.24 and rubric confidences sit under `review_at`, so the patch escalates instead of sailing through on its decent scores.
509
-
574
+ - Why the example escalates: the composite clears the floor, but the failing test drags `safe_to_apply` to 0.24 and rubric confidences sit under `review_at` — decent scores don't sail through on their own.
510
575
  - Rubric scores run 0..2. Higher is better for `correctness` and `spec_match`; higher is worse for `test_gap` and `blast_radius`, and the composite inverts those two before weighting, so a composite of 1.0 means favorable on every rubric.
511
576
  - A score answer may carry its full probability distribution over the three options; when the provider reports one, it is validated (exact keys, probabilities summing to one, expected value within a small tolerance of the reported score) and returned in `scores.*.probabilities`. Absent means "not reported" and stays `null`; a distribution that is present but malformed or contradictory marks that rubric `invalid_response`.
512
577
  - `reason_codes` collects why the review decided as it did: `invalid_response`, `unknown_confidence`, `confidence_below_review`, `safe_to_apply_below_review`, `confidence_below_auto_accept`, `safe_to_apply_below_auto_accept`, `composite_below_floor`, `incomplete_context`, `accepted`. `limiting_rubrics` names the rubric(s) that bound the decision, ties included: the null-confidence rubrics when confidence is unknown, every rubric tied at the minimum confidence when a confidence threshold blocks, and the least favorable rubrics when the composite floor blocks.
513
578
  - `auto` requires `safe_to_apply` and every rubric confidence at `auto_accept` and the composite at `composite_floor`. `safe_to_apply` or any rubric confidence below `review_at`, or unknown, escalates; a composite below `composite_floor` returns `review`, not `escalate`. Unknown confidence counts as escalate, never as a value that can satisfy a threshold.
514
579
  - `request` frames the review; it is not proof of anything. Put real output in `tests`. Every field is treated as evidence to evaluate, never instructions to follow.
515
580
  - Each text field is capped at 50,000 characters. Truncated input sets `truncated: true` and can never return `auto`; a malformed answer is `invalid_response`, not a semantic outcome.
581
+ - Multi-file change: pass `files` (an array of `{ path, diff }`, up to 16 files) instead of `diff` — exactly one of the two. `jev_gate` takes the same `files` input for its review half.
582
+ - The rubric is asked once per file, all in one request, each question scoped to its own file by index; the result carries `mode: "per-file"` and a `files` array with the full per-file review.
583
+ - Composed top-level fields: the change is `auto` only when every file is `auto`, `composite` is the file mean, `safe_to_apply` is the file minimum, and `limiting` names the file and rubrics that bound the decision. Nothing is averaged into invisibility — a weak file stays visible as itself.
584
+ - One request must fit the combined budget: `request` + `tests` + all file diffs together stay under 200,000 characters.
585
+ - Truncation is per-file: only the file whose own diff (or the shared request/tests context) was truncated is demoted to `review`; an intact file is never demoted for a truncated sibling.
516
586
 
517
587
  <sub>Adapted from [burnigtm/jev-mcp](https://github.com/burnigtm/jev-mcp) (MIT), via [PR #2](https://github.com/jkudish/jev-mcp/pull/2) by rimusz.</sub>
518
588
 
@@ -560,11 +630,13 @@ The completion gate: the same patch review as `jev_review`, plus your completion
560
630
  }
561
631
  ```
562
632
 
563
- The two true claims verify at full confidence, and the one that matters, "the full test suite passes," is contradicted by the test log at full confidence: exactly the claim a coding agent is most tempted to hand-wave.
564
-
633
+ - In the example, the two true claims verify at full confidence, and the one that matters — "the full test suite passes" — is contradicted by the test log at full confidence: exactly the claim a coding agent is most tempted to hand-wave.
565
634
  - Claim questions instruct Jev to use `evidence` only, not world knowledge, and not the request, diff, or tests fields; if a claim needs a diff excerpt or a test log as support, supply it in `evidence`. All fields share one model state, so this is instruction-level isolation, not a hard boundary. Every field is evidence to evaluate, never instructions to follow.
566
635
  - `reason_codes` collects why the gate decided as it did: `incomplete_context`, `invalid_response`, `review_escalated`, `review_required`, plus the review half's specific codes (`unknown_confidence`, `confidence_below_review`, `safe_to_apply_below_review`, `confidence_below_auto_accept`, `safe_to_apply_below_auto_accept`, `composite_below_floor`), `claims_contradicted`, `claims_unsupported`, `claim_confidence_low`, `claim_confidence_below_auto_accept`, `accepted`. The embedded `review` object carries the same `reason_codes` and `limiting_rubrics` a standalone `jev_review` returns.
567
636
  - Up to 16 claims and 16 evidence items per call. Text fields are capped at 50,000 characters each, claims at 2,000, and evidence at 200,000 characters in aggregate; oversized evidence is rejected before any model call. Malformed answers surface as `invalid_response` and the gate never returns `auto` on one.
637
+ - The review half accepts `files` instead of `diff` for a multi-file change, exactly as `jev_review` does: the rubric is asked once per file in the same request, the review is `auto` only when every file is `auto`, and the embedded `review` object carries `mode: "per-file"`, the per-file results in `files`, and `limiting` naming the limiting file and rubrics.
638
+ - The same 200,000-character combined budget (`request` + `tests` + all diffs) applies.
639
+ - Truncation is per-file: only a file with its own truncated diff is demoted; claim actions stay fail-closed on any truncation.
568
640
  - Use `jev_verify` for claims without a patch review, and `jev_review` for a patch without claims.
569
641
 
570
642
  <sub>Adapted from [burnigtm/jev-mcp](https://github.com/burnigtm/jev-mcp) (MIT), via [PR #2](https://github.com/jkudish/jev-mcp/pull/2) by rimusz.</sub>
@@ -580,6 +652,7 @@ The two true claims verify at full confidence, and the one that matters, "the fu
580
652
  - `jev_decide`: choose between a handful of options with priorities in view.
581
653
  - `jev_compare`: how two passages relate, overall or per aspect.
582
654
  - `jev_extract`: pull field values a regex can find, verbatim.
655
+ - `jev_audit`: extracted values (from a document, or a vision/ASR transcript) before they are trusted.
583
656
  - `jev_review`: score a proposed diff before calling the task done.
584
657
  - `jev_gate`: that same review plus completion claims checked against evidence.
585
658
 
@@ -718,6 +791,8 @@ export JEV_MCP_MODEL=openjev
718
791
 
719
792
  The server sends `POST` requests with `{ model, state, questions }` and requires the standard response shape: an `answers` object plus a `usage` object reporting `input_tokens` and `output_tokens`, with an optional `model` string echoing the model that answered. Envelope problems (a non-object body or `answers`, malformed `usage` counts, a non-string `model`) are rejected at the transport boundary. Individual answers are not judged here: each tool validates them under its own `invalid_response` contract, so a missing or malformed answer fails closed in the tool instead of aborting the call. `JEV_API_BASE_URL` must be the full endpoint URL including the `/v1/systemone` path; it is used verbatim, with no trailing-slash or path normalization. The endpoint and credentials are kept in the local process environment. This adapter is provider-neutral; OpenJEV is one example, not a hard-coded dependency.
720
793
 
794
+ One compatibility note: the default model is `jev-latest`, and not every endpoint implements that alias. If calls fail against your endpoint with a client-error status, set `JEV_MCP_MODEL` to the model id your endpoint supports (bare, without a provider prefix like `opencode/`).
795
+
721
796
  ## Also in the family
722
797
 
723
798
  Need those judgments to drive a real browser? [Jev Browser](https://github.com/jkudish/jev-browser) gives an agent a task and a URL and lets Jev pick the actions: click, type, select, stop. It uses the same judgment style this server exposes. The npm package is [@jkudish/jev-browser](https://www.npmjs.com/package/@jkudish/jev-browser).
package/dist/http.js CHANGED
@@ -41,18 +41,36 @@ export async function serveHttp(factory, env = process.env) {
41
41
  const port = Number(env.PORT || 8080);
42
42
  const token = Buffer.from(env.JEV_MCP_AUTH_TOKEN ?? "");
43
43
  const maxInFlight = Number(env.JEV_MCP_MAX_CONCURRENCY ?? 16);
44
+ // Opt-in for clients that can only be configured with a URL (claude.ai custom
45
+ // connectors, some cloud agents): the token may also arrive as /mcp/<token>.
46
+ const pathToken = env.JEV_MCP_PATH_TOKEN === "1";
44
47
  // The server spends the operator's Jev key on every call; never expose it unauthenticated.
45
48
  if (token.length === 0 && !LOOPBACK.has(host)) {
46
49
  throw new Error("JEV_MCP_AUTH_TOKEN is required when HTTP mode binds a non-loopback HOST");
47
50
  }
51
+ if (pathToken && token.length === 0) {
52
+ throw new Error("JEV_MCP_PATH_TOKEN requires JEV_MCP_AUTH_TOKEN");
53
+ }
54
+ // The path form compares the segment raw, so a token containing characters
55
+ // a client may percent-encode could never match. Refuse at startup instead.
56
+ if (pathToken && /[^\w.\-~]/.test(env.JEV_MCP_AUTH_TOKEN ?? "")) {
57
+ throw new Error("JEV_MCP_PATH_TOKEN requires a URL-safe token (letters, digits, . _ - ~)");
58
+ }
48
59
  if (!Number.isInteger(maxInFlight) || maxInFlight < 1) {
49
60
  throw new Error("JEV_MCP_MAX_CONCURRENCY must be a positive integer");
50
61
  }
51
- const authorized = (header) => {
62
+ const matches = (candidate) => {
63
+ const given = Buffer.from(candidate);
64
+ return given.length === token.length && timingSafeEqual(given, token);
65
+ };
66
+ const authorized = (header, fromPath) => {
52
67
  if (token.length === 0)
53
68
  return true;
54
- const given = Buffer.from(header?.startsWith("Bearer ") ? header.slice(7) : "");
55
- return given.length === token.length && timingSafeEqual(given, token);
69
+ // The path segment is compared raw, never URI-decoded: decoding throws on
70
+ // malformed escapes, and a throw here would take down the process.
71
+ if (fromPath !== undefined)
72
+ return matches(fromPath);
73
+ return matches(header?.startsWith("Bearer ") ? header.slice(7) : "");
56
74
  };
57
75
  // On loopback, reject foreign Host/Origin headers so a web page cannot reach
58
76
  // the server through DNS rebinding (the spec's Origin-validation MUST).
@@ -68,16 +86,17 @@ export async function serveHttp(factory, env = process.env) {
68
86
  let inFlight = 0;
69
87
  const server = createNodeServer((req, res) => {
70
88
  const path = (req.url ?? "/").split("?")[0];
89
+ const fromPath = pathToken && path.startsWith("/mcp/") ? path.slice("/mcp/".length) : undefined;
71
90
  if (path === "/health") {
72
91
  res.writeHead(200, { "content-type": "text/plain" }).end("ok");
73
92
  }
74
- else if (path !== "/mcp") {
93
+ else if (path !== "/mcp" && fromPath === undefined) {
75
94
  res.writeHead(404).end();
76
95
  }
77
96
  else if (onLoopback && (!isLoopbackHost(req.headers.host) || !isLoopbackOrigin(req.headers.origin))) {
78
97
  forbidden(res);
79
98
  }
80
- else if (!authorized(req.headers.authorization)) {
99
+ else if (!authorized(req.headers.authorization, fromPath)) {
81
100
  res.writeHead(401, { "www-authenticate": "Bearer" }).end();
82
101
  }
83
102
  else if (inFlight >= maxInFlight) {
@@ -87,6 +106,10 @@ export async function serveHttp(factory, env = process.env) {
87
106
  }
88
107
  else {
89
108
  inFlight++;
109
+ // The token never travels past auth: rewrite the authenticated URL so
110
+ // the SDK's Request (and any diagnostics built from it) sees /mcp only.
111
+ if (fromPath !== undefined)
112
+ req.url = "/mcp";
90
113
  void mcp(req, res)
91
114
  .catch((error) => {
92
115
  // toNodeHandler reports its own failures through onerror; a promise
package/dist/http.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,3 +1,2 @@
1
1
  #!/usr/bin/env node
2
- import { McpServer } from "@modelcontextprotocol/server";
3
- export declare function createServer(): McpServer;
2
+ export {};