jev-mcp-server 0.1.0__tar.gz

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.
@@ -0,0 +1,21 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+
8
+ jobs:
9
+ test:
10
+ runs-on: ubuntu-latest
11
+ strategy:
12
+ matrix:
13
+ python-version: ["3.10", "3.12", "3.13"]
14
+ steps:
15
+ - uses: actions/checkout@v4
16
+ - uses: astral-sh/setup-uv@v5
17
+ with:
18
+ python-version: ${{ matrix.python-version }}
19
+ - run: uv sync --dev
20
+ - run: uv run ruff check .
21
+ - run: uv run pytest -q
@@ -0,0 +1,23 @@
1
+ name: Publish to PyPI
2
+
3
+ # Requires a PYPI_API_TOKEN secret (pypi.org -> account settings -> API tokens),
4
+ # or configure trusted publishing for this project on PyPI and remove the
5
+ # `with: password:` block below.
6
+
7
+ on:
8
+ push:
9
+ tags: ["v*"]
10
+
11
+ jobs:
12
+ publish:
13
+ runs-on: ubuntu-latest
14
+ permissions:
15
+ id-token: write
16
+ contents: read
17
+ steps:
18
+ - uses: actions/checkout@v4
19
+ - uses: astral-sh/setup-uv@v5
20
+ - run: uv build
21
+ - uses: pypa/gh-action-pypi-publish@release/v1
22
+ with:
23
+ password: ${{ secrets.PYPI_API_TOKEN }}
@@ -0,0 +1,8 @@
1
+ .venv/
2
+ __pycache__/
3
+ *.pyc
4
+ .pytest_cache/
5
+ .ruff_cache/
6
+ dist/
7
+ build/
8
+ *.egg-info/
@@ -0,0 +1,16 @@
1
+ # Changelog
2
+
3
+ ## 0.1.0 — 2026-09-22
4
+
5
+ Initial release.
6
+
7
+ - Tools mapping 1:1 to the official System One question types:
8
+ - `choice` — pick ONE of 2-100 mutually exclusive options with calibrated probabilities.
9
+ - `score` — grade on an ordered rubric of 2-8 levels (fractional index + per-level probabilities).
10
+ - `noul` — yes/no question with a 0-1 degree.
11
+ - `classify` — batch-classify up to 100 items against one shared category set.
12
+ - `setup` — one-time API key onboarding: live verification, then stored with 0600 permissions.
13
+ - Optional response cache (off by default, `JEVMCP_CACHE=1`).
14
+ - Response validation (probabilities sum, winner consistency, bounds), retry on 429/503/529.
15
+ - Bilingual documentation (English / 简体中文).
16
+ - Config snippets for Claude Code, Codex, OpenCode, pi, and generic stdio clients.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 wangkuangkuang
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,213 @@
1
+ Metadata-Version: 2.5
2
+ Name: jev-mcp-server
3
+ Version: 0.1.0
4
+ Summary: Faithful MCP server for Jev (TypeSafe System One): the three official question types — choice, score, noul — plus batch classify. Calibrated probabilities for coding agents.
5
+ Project-URL: Homepage, https://github.com/wangkuangkuang/jev-mcp-server
6
+ Project-URL: Repository, https://github.com/wangkuangkuang/jev-mcp-server
7
+ Project-URL: Issues, https://github.com/wangkuangkuang/jev-mcp-server/issues
8
+ Project-URL: Changelog, https://github.com/wangkuangkuang/jev-mcp-server/blob/main/CHANGELOG.md
9
+ Author: wangkuangkuang
10
+ License: MIT
11
+ License-File: LICENSE
12
+ Keywords: classifier,decision,jev,llm,mcp,model-context-protocol,routing,system-one,typesafe
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
22
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
23
+ Requires-Python: >=3.10
24
+ Requires-Dist: httpx[http2]>=0.27
25
+ Requires-Dist: mcp<2,>=1.9
26
+ Description-Content-Type: text/markdown
27
+
28
+ [English](README.md) | [简体中文](README.zh-CN.md)
29
+
30
+ # jev-mcp-server
31
+
32
+ [![CI](https://github.com/wangkuangkuang/jev-mcp-server/actions/workflows/ci.yml/badge.svg)](https://github.com/wangkuangkuang/jev-mcp-server/actions/workflows/ci.yml)
33
+ [![PyPI](https://img.shields.io/pypi/v/jev-mcp-server)](https://pypi.org/project/jev-mcp-server/)
34
+ [![Python](https://img.shields.io/badge/python-3.10%2B-blue)](https://pypi.org/project/jev-mcp-server/)
35
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
36
+
37
+ **MCP server for [Jev](https://typesafe.ai) (TypeSafe System One) — a faithful mapping of the three official question types, plus batch classify.**
38
+
39
+ When your coding agent needs a judgment — which log line is the root cause, how risky is this diff, is this change breaking — it usually burns a frontier LLM call and gets prose back. Jev answers with a **typed decision and calibrated probabilities** in a fraction of a second, for a fraction of a cent:
40
+
41
+ | Question type | Tool | Returns | Measured* |
42
+ |---|---|---|---|
43
+ | `choice` | pick 1 of 2-100 options | winner + probabilities over ALL options + confidence | ~0.6 s, ~$0.00002 |
44
+ | `score` | grade on a rubric of 2-8 levels | fractional index + per-level probabilities | ~0.5 s, ~$0.00002 |
45
+ | `noul` | yes / no | 0-1 degree | ~0.4 s, ~$0.00001 |
46
+ | `classify` | label up to 100 items | per-item choice + aggregate summary | ~0.5 s × items |
47
+
48
+ \* Measured against `jev-1.13.0`, 2026-09, from real sessions (see [Benchmarks](#benchmarks)).
49
+
50
+ ## Why this one
51
+
52
+ - **1:1 with the official API.** Tool names match the System One question types (`choice` / `score` / `noul`), so anything you learn from [TypeSafe's docs](https://typesafe.ai) transfers directly. No invented abstractions.
53
+ - **Decisions, not explanations.** Jev never returns reasons — any "why" your assistant writes is its own interpretation of the probability distribution. The README (and the tool docs) say so explicitly, so reports built on top stay honest.
54
+ - **Batch `classify`** for routing/labeling workflows, with per-item caching.
55
+ - **One-time `setup` tool**: paste your API key once in chat; it's verified live, stored with `0600` permissions, and never echoed back.
56
+ - **Bilingual docs** (English / 简体中文), configs for Claude Code, Codex, OpenCode, pi, and any stdio MCP client.
57
+ - Offline-tested (no network in CI), retries on 429/503/529, response validation (probabilities sum to 1, winner is the max), optional response cache.
58
+
59
+ ## Quickstart
60
+
61
+ 1. Get a TypeSafe API key at [console.typesafe.ai/settings/keys](https://console.typesafe.ai/settings/keys).
62
+ 2. Register the server with your client (pick one below).
63
+ 3. Either export `TYPESAFE_API_KEY`, or just ask your agent: *"run the jev setup tool with key `tsk_...`"*.
64
+
65
+ ### Claude Code
66
+
67
+ ```bash
68
+ claude mcp add jev --env TYPESAFE_API_KEY=YOUR_KEY -- uvx jev-mcp-server
69
+ ```
70
+
71
+ ### Codex (`~/.codex/config.toml`)
72
+
73
+ ```toml
74
+ [mcp_servers.jev]
75
+ command = "uvx"
76
+ args = ["jev-mcp-server"]
77
+ env = { TYPESAFE_API_KEY = "YOUR_KEY" }
78
+ ```
79
+
80
+ ### OpenCode (`~/.config/opencode/opencode.json`)
81
+
82
+ ```json
83
+ {
84
+ "mcp": {
85
+ "jev": { "type": "local", "command": ["uvx", "jev-mcp-server"], "enabled": true }
86
+ }
87
+ }
88
+ ```
89
+
90
+ ### pi (`~/.pi/agent/mcp.json`)
91
+
92
+ ```json
93
+ {
94
+ "mcpServers": {
95
+ "jev": { "command": "uvx", "args": ["jev-mcp-server"], "lifecycle": "lazy" }
96
+ }
97
+ }
98
+ ```
99
+
100
+ ### Any stdio MCP client
101
+
102
+ ```json
103
+ { "command": "uvx", "args": ["jev-mcp-server"] }
104
+ ```
105
+
106
+ ### From source (this repo)
107
+
108
+ ```json
109
+ { "command": "uv", "args": ["run", "--directory", "/path/to/jev-mcp-server", "jev-mcp-server"] }
110
+ ```
111
+
112
+ ## Tools
113
+
114
+ ### `choice(question, options, context="")`
115
+
116
+ Pick ONE of 2-100 mutually exclusive options. Returns probabilities over all options (near-ties are visible), confidence, and the runner-up.
117
+
118
+ ```json
119
+ {"choice": "E1", "confidence": 0.67,
120
+ "probabilities": {"E1": 0.72, "E6": 0.2, "E5": 0.05, "E2": 0.01, "E3": 0.01, "E4": 0.01},
121
+ "runner_up": "E6", "model": "jev-1.13.0", "latency_ms": 678,
122
+ "usage": {"input_tokens": 1677, "output_tokens": 66}}
123
+ ```
124
+
125
+ ### `score(question, levels, context="")`
126
+
127
+ Grade on an ordered rubric of 2-8 levels. `score` is a fractional 0-based index: `2.22` with levels `["minor","moderate","severe","critical"]` means *severe, leaning critical*.
128
+
129
+ ```json
130
+ {"score": 2.22, "nearest_level": "severe", "confidence": 0.59,
131
+ "probabilities": {"severe": 0.6, "critical": 0.2, "moderate": 0.2}, "...": "..."}
132
+ ```
133
+
134
+ ### `noul(question, context="")`
135
+
136
+ Yes/no with a 0-1 degree (`>= 0.5` leans yes). No probability list — the degree is the answer.
137
+
138
+ ```json
139
+ {"noul": 0.76, "verdict": "yes", "model": "jev-1.13.0", "latency_ms": 402, "usage": {"...": "..."}}
140
+ ```
141
+
142
+ ### `classify(items, options, question=..., context="")`
143
+
144
+ Batch-label up to 100 items against one shared category set. One `choice` call per item, aggregated:
145
+
146
+ ```json
147
+ {"results": [{"item": "ticket #1", "choice": "billing", "confidence": 0.81, "probabilities": {"...": "..."}}],
148
+ "summary": {"billing": 12, "bug": 7, "howto": 3},
149
+ "usage": {"input_tokens": 8210, "output_tokens": 210, "calls": 22, "cached_calls": 0}}
150
+ ```
151
+
152
+ ### `setup(api_key)`
153
+
154
+ One-time onboarding: verifies the key with a live call, stores it at `~/.config/jev-mcp/key` (0600), never echoes it. An env var `TYPESAFE_API_KEY` always wins over the stored file.
155
+
156
+ ## Caching (off by default)
157
+
158
+ Set `JEVMCP_CACHE=1` to enable. The cache key is the SHA-256 of the exact question payload, so:
159
+
160
+ - Identical repeated decisions (retries, re-runs, deterministic pipelines) return in ~0 ms at **zero API cost**; `usage` then reports `{"cached": true}`.
161
+ - `classify` benefits automatically: duplicate items inside one batch are single-billed.
162
+
163
+ Keep it **off** when decisions must stay fresh (live triage of changing data). Cache files live in `~/.cache/jev-mcp/` (override with `JEVMCP_CACHE_DIR`); delete them anytime.
164
+
165
+ ## Configuration
166
+
167
+ | Variable | Default | Purpose |
168
+ |---|---|---|
169
+ | `TYPESAFE_API_KEY` | — | API key (env wins over the file written by `setup`) |
170
+ | `JEVMCP_MODEL` | `jev-latest` | Model name sent to the API |
171
+ | `JEVMCP_BASE_URL` | `https://api.typesafe.ai/v1/systemone` | Point at a compatible gateway (experimental) |
172
+ | `JEVMCP_CACHE` | off | `1`/`true` enables the response cache |
173
+ | `JEVMCP_CACHE_DIR` | `~/.cache/jev-mcp` | Cache location |
174
+ | `JEVMCP_CONFIG_DIR` | `~/.config/jev-mcp` | Where `setup` stores the key |
175
+
176
+ > **Note on OpenRouter**: Jev was announced for OpenRouter (`~typesafe/jev-latest`), but at publish time it does **not** appear in OpenRouter's public model catalog, and we could not verify a compatible call shape. If you route Jev through a gateway, set `JEVMCP_BASE_URL` accordingly and please open an issue with your findings.
177
+
178
+ ## Decisions, not explanations
179
+
180
+ Jev's contract is: a decision, calibrated probabilities, and nothing else — no rationale text. That is why it is fast and cheap. When your assistant narrates *"jev chose E1 because..."*, that explanation is the assistant's **interpretation** of the numbers, not Jev's output. For formal reports (root-cause analyses, review verdicts), either let the LLM reason itself, or use the two-step pattern — Jev decides, LLM explains, clearly labeled.
181
+
182
+ ## Benchmarks
183
+
184
+ Measured 2026-09 against `jev-1.13.0`, single questions, real sessions:
185
+
186
+ | Call | Latency | Input tokens | Output tokens |
187
+ |---|---|---|---|
188
+ | `choice`, 6 options | 615-678 ms | 344-1677 | 31-66 |
189
+ | `score`, 3 levels | ~500 ms | ~350 | ~30 |
190
+ | `noul` | ~400 ms | ~300 | ~25 |
191
+
192
+ At [$42 / 1B input tokens](https://typesafe.ai) a typical call costs ≈ $0.00002 — roughly two orders of magnitude below a frontier-LLM judgment call.
193
+
194
+ ## Alternatives (fair and square)
195
+
196
+ - [jkudish/jev-mcp](https://github.com/jkudish/jev-mcp) — Node/npm, ten opinionated workflow tools (verify, screen, rerank, gate...). Pick it if you want ready-made agent-safety workflows.
197
+ - [itsmostafa/typesafe-mcp](https://github.com/itsmostafa/typesafe-mcp) — Go binary, one generic `evaluate` tool, one-command client setup.
198
+
199
+ `jev-mcp-server` is the close-to-the-metal option: the three official question types, named exactly as TypeSafe names them, with batch classify, bilingual docs, and measured numbers. Pick whichever fits your taste — they're all MIT.
200
+
201
+ ## Development
202
+
203
+ ```bash
204
+ uv sync
205
+ uv run ruff check .
206
+ uv run pytest -q
207
+ ```
208
+
209
+ Tests are fully offline (the HTTP layer is mocked; CI never spends API credits).
210
+
211
+ ## License
212
+
213
+ [MIT](LICENSE)
@@ -0,0 +1,186 @@
1
+ [English](README.md) | [简体中文](README.zh-CN.md)
2
+
3
+ # jev-mcp-server
4
+
5
+ [![CI](https://github.com/wangkuangkuang/jev-mcp-server/actions/workflows/ci.yml/badge.svg)](https://github.com/wangkuangkuang/jev-mcp-server/actions/workflows/ci.yml)
6
+ [![PyPI](https://img.shields.io/pypi/v/jev-mcp-server)](https://pypi.org/project/jev-mcp-server/)
7
+ [![Python](https://img.shields.io/badge/python-3.10%2B-blue)](https://pypi.org/project/jev-mcp-server/)
8
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
9
+
10
+ **MCP server for [Jev](https://typesafe.ai) (TypeSafe System One) — a faithful mapping of the three official question types, plus batch classify.**
11
+
12
+ When your coding agent needs a judgment — which log line is the root cause, how risky is this diff, is this change breaking — it usually burns a frontier LLM call and gets prose back. Jev answers with a **typed decision and calibrated probabilities** in a fraction of a second, for a fraction of a cent:
13
+
14
+ | Question type | Tool | Returns | Measured* |
15
+ |---|---|---|---|
16
+ | `choice` | pick 1 of 2-100 options | winner + probabilities over ALL options + confidence | ~0.6 s, ~$0.00002 |
17
+ | `score` | grade on a rubric of 2-8 levels | fractional index + per-level probabilities | ~0.5 s, ~$0.00002 |
18
+ | `noul` | yes / no | 0-1 degree | ~0.4 s, ~$0.00001 |
19
+ | `classify` | label up to 100 items | per-item choice + aggregate summary | ~0.5 s × items |
20
+
21
+ \* Measured against `jev-1.13.0`, 2026-09, from real sessions (see [Benchmarks](#benchmarks)).
22
+
23
+ ## Why this one
24
+
25
+ - **1:1 with the official API.** Tool names match the System One question types (`choice` / `score` / `noul`), so anything you learn from [TypeSafe's docs](https://typesafe.ai) transfers directly. No invented abstractions.
26
+ - **Decisions, not explanations.** Jev never returns reasons — any "why" your assistant writes is its own interpretation of the probability distribution. The README (and the tool docs) say so explicitly, so reports built on top stay honest.
27
+ - **Batch `classify`** for routing/labeling workflows, with per-item caching.
28
+ - **One-time `setup` tool**: paste your API key once in chat; it's verified live, stored with `0600` permissions, and never echoed back.
29
+ - **Bilingual docs** (English / 简体中文), configs for Claude Code, Codex, OpenCode, pi, and any stdio MCP client.
30
+ - Offline-tested (no network in CI), retries on 429/503/529, response validation (probabilities sum to 1, winner is the max), optional response cache.
31
+
32
+ ## Quickstart
33
+
34
+ 1. Get a TypeSafe API key at [console.typesafe.ai/settings/keys](https://console.typesafe.ai/settings/keys).
35
+ 2. Register the server with your client (pick one below).
36
+ 3. Either export `TYPESAFE_API_KEY`, or just ask your agent: *"run the jev setup tool with key `tsk_...`"*.
37
+
38
+ ### Claude Code
39
+
40
+ ```bash
41
+ claude mcp add jev --env TYPESAFE_API_KEY=YOUR_KEY -- uvx jev-mcp-server
42
+ ```
43
+
44
+ ### Codex (`~/.codex/config.toml`)
45
+
46
+ ```toml
47
+ [mcp_servers.jev]
48
+ command = "uvx"
49
+ args = ["jev-mcp-server"]
50
+ env = { TYPESAFE_API_KEY = "YOUR_KEY" }
51
+ ```
52
+
53
+ ### OpenCode (`~/.config/opencode/opencode.json`)
54
+
55
+ ```json
56
+ {
57
+ "mcp": {
58
+ "jev": { "type": "local", "command": ["uvx", "jev-mcp-server"], "enabled": true }
59
+ }
60
+ }
61
+ ```
62
+
63
+ ### pi (`~/.pi/agent/mcp.json`)
64
+
65
+ ```json
66
+ {
67
+ "mcpServers": {
68
+ "jev": { "command": "uvx", "args": ["jev-mcp-server"], "lifecycle": "lazy" }
69
+ }
70
+ }
71
+ ```
72
+
73
+ ### Any stdio MCP client
74
+
75
+ ```json
76
+ { "command": "uvx", "args": ["jev-mcp-server"] }
77
+ ```
78
+
79
+ ### From source (this repo)
80
+
81
+ ```json
82
+ { "command": "uv", "args": ["run", "--directory", "/path/to/jev-mcp-server", "jev-mcp-server"] }
83
+ ```
84
+
85
+ ## Tools
86
+
87
+ ### `choice(question, options, context="")`
88
+
89
+ Pick ONE of 2-100 mutually exclusive options. Returns probabilities over all options (near-ties are visible), confidence, and the runner-up.
90
+
91
+ ```json
92
+ {"choice": "E1", "confidence": 0.67,
93
+ "probabilities": {"E1": 0.72, "E6": 0.2, "E5": 0.05, "E2": 0.01, "E3": 0.01, "E4": 0.01},
94
+ "runner_up": "E6", "model": "jev-1.13.0", "latency_ms": 678,
95
+ "usage": {"input_tokens": 1677, "output_tokens": 66}}
96
+ ```
97
+
98
+ ### `score(question, levels, context="")`
99
+
100
+ Grade on an ordered rubric of 2-8 levels. `score` is a fractional 0-based index: `2.22` with levels `["minor","moderate","severe","critical"]` means *severe, leaning critical*.
101
+
102
+ ```json
103
+ {"score": 2.22, "nearest_level": "severe", "confidence": 0.59,
104
+ "probabilities": {"severe": 0.6, "critical": 0.2, "moderate": 0.2}, "...": "..."}
105
+ ```
106
+
107
+ ### `noul(question, context="")`
108
+
109
+ Yes/no with a 0-1 degree (`>= 0.5` leans yes). No probability list — the degree is the answer.
110
+
111
+ ```json
112
+ {"noul": 0.76, "verdict": "yes", "model": "jev-1.13.0", "latency_ms": 402, "usage": {"...": "..."}}
113
+ ```
114
+
115
+ ### `classify(items, options, question=..., context="")`
116
+
117
+ Batch-label up to 100 items against one shared category set. One `choice` call per item, aggregated:
118
+
119
+ ```json
120
+ {"results": [{"item": "ticket #1", "choice": "billing", "confidence": 0.81, "probabilities": {"...": "..."}}],
121
+ "summary": {"billing": 12, "bug": 7, "howto": 3},
122
+ "usage": {"input_tokens": 8210, "output_tokens": 210, "calls": 22, "cached_calls": 0}}
123
+ ```
124
+
125
+ ### `setup(api_key)`
126
+
127
+ One-time onboarding: verifies the key with a live call, stores it at `~/.config/jev-mcp/key` (0600), never echoes it. An env var `TYPESAFE_API_KEY` always wins over the stored file.
128
+
129
+ ## Caching (off by default)
130
+
131
+ Set `JEVMCP_CACHE=1` to enable. The cache key is the SHA-256 of the exact question payload, so:
132
+
133
+ - Identical repeated decisions (retries, re-runs, deterministic pipelines) return in ~0 ms at **zero API cost**; `usage` then reports `{"cached": true}`.
134
+ - `classify` benefits automatically: duplicate items inside one batch are single-billed.
135
+
136
+ Keep it **off** when decisions must stay fresh (live triage of changing data). Cache files live in `~/.cache/jev-mcp/` (override with `JEVMCP_CACHE_DIR`); delete them anytime.
137
+
138
+ ## Configuration
139
+
140
+ | Variable | Default | Purpose |
141
+ |---|---|---|
142
+ | `TYPESAFE_API_KEY` | — | API key (env wins over the file written by `setup`) |
143
+ | `JEVMCP_MODEL` | `jev-latest` | Model name sent to the API |
144
+ | `JEVMCP_BASE_URL` | `https://api.typesafe.ai/v1/systemone` | Point at a compatible gateway (experimental) |
145
+ | `JEVMCP_CACHE` | off | `1`/`true` enables the response cache |
146
+ | `JEVMCP_CACHE_DIR` | `~/.cache/jev-mcp` | Cache location |
147
+ | `JEVMCP_CONFIG_DIR` | `~/.config/jev-mcp` | Where `setup` stores the key |
148
+
149
+ > **Note on OpenRouter**: Jev was announced for OpenRouter (`~typesafe/jev-latest`), but at publish time it does **not** appear in OpenRouter's public model catalog, and we could not verify a compatible call shape. If you route Jev through a gateway, set `JEVMCP_BASE_URL` accordingly and please open an issue with your findings.
150
+
151
+ ## Decisions, not explanations
152
+
153
+ Jev's contract is: a decision, calibrated probabilities, and nothing else — no rationale text. That is why it is fast and cheap. When your assistant narrates *"jev chose E1 because..."*, that explanation is the assistant's **interpretation** of the numbers, not Jev's output. For formal reports (root-cause analyses, review verdicts), either let the LLM reason itself, or use the two-step pattern — Jev decides, LLM explains, clearly labeled.
154
+
155
+ ## Benchmarks
156
+
157
+ Measured 2026-09 against `jev-1.13.0`, single questions, real sessions:
158
+
159
+ | Call | Latency | Input tokens | Output tokens |
160
+ |---|---|---|---|
161
+ | `choice`, 6 options | 615-678 ms | 344-1677 | 31-66 |
162
+ | `score`, 3 levels | ~500 ms | ~350 | ~30 |
163
+ | `noul` | ~400 ms | ~300 | ~25 |
164
+
165
+ At [$42 / 1B input tokens](https://typesafe.ai) a typical call costs ≈ $0.00002 — roughly two orders of magnitude below a frontier-LLM judgment call.
166
+
167
+ ## Alternatives (fair and square)
168
+
169
+ - [jkudish/jev-mcp](https://github.com/jkudish/jev-mcp) — Node/npm, ten opinionated workflow tools (verify, screen, rerank, gate...). Pick it if you want ready-made agent-safety workflows.
170
+ - [itsmostafa/typesafe-mcp](https://github.com/itsmostafa/typesafe-mcp) — Go binary, one generic `evaluate` tool, one-command client setup.
171
+
172
+ `jev-mcp-server` is the close-to-the-metal option: the three official question types, named exactly as TypeSafe names them, with batch classify, bilingual docs, and measured numbers. Pick whichever fits your taste — they're all MIT.
173
+
174
+ ## Development
175
+
176
+ ```bash
177
+ uv sync
178
+ uv run ruff check .
179
+ uv run pytest -q
180
+ ```
181
+
182
+ Tests are fully offline (the HTTP layer is mocked; CI never spends API credits).
183
+
184
+ ## License
185
+
186
+ [MIT](LICENSE)