mcp-jev 1.0.0 → 1.1.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/README.md +23 -1
- package/dist/index.js +73 -116
- package/dist/index.js.map +1 -1
- package/dist/lib.d.ts +173 -0
- package/dist/lib.d.ts.map +1 -0
- package/dist/lib.js +104 -0
- package/dist/lib.js.map +1 -0
- package/package.json +8 -5
package/README.md
CHANGED
|
@@ -69,7 +69,7 @@ Gửi state + typed questions → nhận calibrated probabilities. Không sinh t
|
|
|
69
69
|
},
|
|
70
70
|
"frustration": {
|
|
71
71
|
"score": 2.04,
|
|
72
|
-
"legend": "Rất bực bội",
|
|
72
|
+
"legend": { "0": "Bình thường", "1": "Hơi khó chịu", "2": "Rất bực bội" },
|
|
73
73
|
"probabilities": { "Bình thường": 0.05, "Hơi khó chịu": 0.18, "Rất bực bội": 0.77 },
|
|
74
74
|
"confidence": 0.77
|
|
75
75
|
}
|
|
@@ -188,3 +188,25 @@ Rate limits hiện tại: 250,000 tokens/s · 1,200 requests/min.
|
|
|
188
188
|
- Choice tối đa 255 options; Score 2–10 levels
|
|
189
189
|
- Không thể dùng cho System 2 tasks (lập luận đa bước, sinh code, giải thích)
|
|
190
190
|
- Model hiện tại: `jev-1.13.0` / alias `jev-latest`
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
## npx (khuyến nghị)
|
|
195
|
+
|
|
196
|
+
Không cần clone repo — dùng trực tiếp từ npm:
|
|
197
|
+
|
|
198
|
+
```json
|
|
199
|
+
{
|
|
200
|
+
"mcpServers": {
|
|
201
|
+
"jev": {
|
|
202
|
+
"command": "npx",
|
|
203
|
+
"args": ["-y", "mcp-jev"],
|
|
204
|
+
"env": {
|
|
205
|
+
"TYPESAFE_API_KEY": "your_key_here"
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
Source: [github.com/mndpjm/mcp-jev](https://github.com/mndpjm/mcp-jev)
|
package/dist/index.js
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
14
14
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
15
15
|
import { z } from "zod";
|
|
16
|
+
import { ERROR_BODY_MAX_CHARS, MAX_CHOICE_OPTIONS, MIN_SCORE_LEVELS, MAX_SCORE_LEVELS, MAX_STATE_STRING_CHARS, MAX_QUESTIONS, truncate, fetchWithRetry, parseModelEntries, JevResponseSchema, JevModelsResponseSchema, } from "./lib.js";
|
|
16
17
|
// ─── Config ─────────────────────────────────────────────────────────────────
|
|
17
18
|
const API_KEY = process.env.TYPESAFE_API_KEY;
|
|
18
19
|
const BASE_URL = process.env.TYPESAFE_BASE_URL?.replace(/\/$/, "") ??
|
|
@@ -21,38 +22,15 @@ if (!API_KEY) {
|
|
|
21
22
|
process.stderr.write("[mcp-jev] FATAL: TYPESAFE_API_KEY environment variable is not set.\n");
|
|
22
23
|
process.exit(1);
|
|
23
24
|
}
|
|
24
|
-
// ───
|
|
25
|
+
// ─── Internal API helpers ────────────────────────────────────────────────────
|
|
25
26
|
/**
|
|
26
|
-
*
|
|
27
|
-
*
|
|
27
|
+
* Read response body and throw a standardized API error.
|
|
28
|
+
* Truncates body to prevent log bloat (F14, F15).
|
|
28
29
|
*/
|
|
29
|
-
async function
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
let lastError;
|
|
33
|
-
for (let attempt = 1; attempt <= attempts; attempt++) {
|
|
34
|
-
const resp = await fetch(url, init);
|
|
35
|
-
if (resp.status !== 429 && resp.status !== 529) {
|
|
36
|
-
return resp; // success or non-retryable error
|
|
37
|
-
}
|
|
38
|
-
// Respect Retry-After header if present (guard against NaN/negative)
|
|
39
|
-
const retryAfter = resp.headers.get("Retry-After");
|
|
40
|
-
const parsed = retryAfter ? parseInt(retryAfter, 10) : NaN;
|
|
41
|
-
const waitMs = !isNaN(parsed) && parsed > 0
|
|
42
|
-
? parsed * 1000
|
|
43
|
-
: delayMs * Math.pow(2, attempt - 1); // true exponential: 1s, 2s, 4s
|
|
44
|
-
// Read body for error context before discarding the response
|
|
45
|
-
const body = await resp.text().catch(() => "");
|
|
46
|
-
if (attempt < attempts) {
|
|
47
|
-
await new Promise((r) => setTimeout(r, waitMs));
|
|
48
|
-
}
|
|
49
|
-
else {
|
|
50
|
-
lastError = new Error(`HTTP ${resp.status} after ${attempts} attempts — rate limited or overloaded. Response: ${body}`);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
throw lastError ?? new Error("fetchWithRetry: unexpected loop exit");
|
|
30
|
+
async function throwApiError(resp, context) {
|
|
31
|
+
const raw = await resp.text().catch(() => "");
|
|
32
|
+
throw new Error(`Jev API error ${resp.status} (${context}): ${truncate(raw, ERROR_BODY_MAX_CHARS)}`);
|
|
54
33
|
}
|
|
55
|
-
// ─── Jev API helpers ────────────────────────────────────────────────────────
|
|
56
34
|
async function callSystemOne(body) {
|
|
57
35
|
const resp = await fetchWithRetry(`${BASE_URL}/v1/systemone`, {
|
|
58
36
|
method: "POST",
|
|
@@ -63,15 +41,21 @@ async function callSystemOne(body) {
|
|
|
63
41
|
body: JSON.stringify(body),
|
|
64
42
|
});
|
|
65
43
|
if (!resp.ok) {
|
|
66
|
-
|
|
67
|
-
throw new Error(`Jev API error ${resp.status}: ${text}`);
|
|
44
|
+
await throwApiError(resp, "systemone");
|
|
68
45
|
}
|
|
46
|
+
let raw;
|
|
69
47
|
try {
|
|
70
|
-
|
|
48
|
+
raw = await resp.json();
|
|
71
49
|
}
|
|
72
50
|
catch (e) {
|
|
73
51
|
throw new Error(`Failed to parse Jev API response as JSON: ${e instanceof Error ? e.message : String(e)}`);
|
|
74
52
|
}
|
|
53
|
+
// Runtime validation — catches API contract changes early (F01)
|
|
54
|
+
const parsed = JevResponseSchema.safeParse(raw);
|
|
55
|
+
if (!parsed.success) {
|
|
56
|
+
throw new Error(`Jev API response shape unexpected: ${parsed.error.message}`);
|
|
57
|
+
}
|
|
58
|
+
return parsed.data;
|
|
75
59
|
}
|
|
76
60
|
async function listModels() {
|
|
77
61
|
const resp = await fetchWithRetry(`${BASE_URL}/v1/models`, {
|
|
@@ -79,11 +63,8 @@ async function listModels() {
|
|
|
79
63
|
headers: { Authorization: `Bearer ${API_KEY}` },
|
|
80
64
|
});
|
|
81
65
|
if (!resp.ok) {
|
|
82
|
-
|
|
83
|
-
throw new Error(`Jev API error ${resp.status}: ${text}`);
|
|
66
|
+
await throwApiError(resp, "models");
|
|
84
67
|
}
|
|
85
|
-
// Official docs: response has a "models" array (not "data")
|
|
86
|
-
// Each entry has: id, description, release_date (for aliases)
|
|
87
68
|
let raw;
|
|
88
69
|
try {
|
|
89
70
|
raw = await resp.json();
|
|
@@ -91,16 +72,17 @@ async function listModels() {
|
|
|
91
72
|
catch (e) {
|
|
92
73
|
throw new Error(`Failed to parse Jev models response as JSON: ${e instanceof Error ? e.message : String(e)}`);
|
|
93
74
|
}
|
|
94
|
-
|
|
75
|
+
// Runtime shape validation (F01)
|
|
76
|
+
const envelope = JevModelsResponseSchema.safeParse(raw);
|
|
77
|
+
if (!envelope.success) {
|
|
78
|
+
throw new Error(`Unexpected Jev models response shape: ${envelope.error.message}`);
|
|
79
|
+
}
|
|
80
|
+
const entries = envelope.data.models ?? envelope.data.data ?? [];
|
|
95
81
|
if (!Array.isArray(entries)) {
|
|
96
82
|
throw new Error("Unexpected Jev models response shape — expected array");
|
|
97
83
|
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
...(m.description ? { description: m.description } : {}),
|
|
101
|
-
...(m.release_date ? { release_date: m.release_date } : {}),
|
|
102
|
-
...(m.aliases ? { aliases: m.aliases } : {}),
|
|
103
|
-
}));
|
|
84
|
+
// Filter and validate each model entry — skip entries missing id (F03)
|
|
85
|
+
return parseModelEntries(entries);
|
|
104
86
|
}
|
|
105
87
|
// ─── MCP server ─────────────────────────────────────────────────────────────
|
|
106
88
|
const server = new McpServer({
|
|
@@ -108,15 +90,6 @@ const server = new McpServer({
|
|
|
108
90
|
version: "1.0.0",
|
|
109
91
|
});
|
|
110
92
|
// ── Tool 1: jev_decide ──────────────────────────────────────────────────────
|
|
111
|
-
/**
|
|
112
|
-
* QuestionSchema covers all three Jev primitives: noul, choice, score.
|
|
113
|
-
*
|
|
114
|
-
* Per official TypeSafe docs:
|
|
115
|
-
* - instructions: string | object | array
|
|
116
|
-
* - choice criteria values: string | object | array | null (max 255 options)
|
|
117
|
-
* - score criteria levels: string | object | array per level (2–10 levels)
|
|
118
|
-
* - noul criteria: string (optional clarification only)
|
|
119
|
-
*/
|
|
120
93
|
const InstructionsSchema = z
|
|
121
94
|
.union([z.string(), z.record(z.unknown()), z.array(z.unknown())])
|
|
122
95
|
.describe([
|
|
@@ -126,56 +99,43 @@ const InstructionsSchema = z
|
|
|
126
99
|
" - An array: ordered list of instruction parts",
|
|
127
100
|
"Reference state fields with backtick paths, e.g. `message` or `order.id`.",
|
|
128
101
|
].join("\n"));
|
|
129
|
-
/** Value for a single Choice option or Score level — string, object, array, or null */
|
|
130
102
|
const CriteriaValueSchema = z
|
|
131
103
|
.union([z.string(), z.record(z.unknown()), z.array(z.unknown()), z.null()])
|
|
132
104
|
.describe("Description for this option/level. Use null for options that need no extra detail.");
|
|
133
105
|
const QuestionSchema = z.discriminatedUnion("type", [
|
|
134
106
|
z.object({
|
|
135
|
-
id: z
|
|
136
|
-
.string()
|
|
137
|
-
.min(1)
|
|
138
|
-
.describe("Unique key for this question. Used to look up the answer in the response."),
|
|
107
|
+
id: z.string().min(1).describe("Unique key for this question. Used to look up the answer in the response."),
|
|
139
108
|
type: z.literal("noul").describe("True/false probability question."),
|
|
140
109
|
instructions: InstructionsSchema,
|
|
141
|
-
criteria: z
|
|
142
|
-
.string()
|
|
143
|
-
.optional()
|
|
144
|
-
.describe("Optional extra clarification string for the model."),
|
|
110
|
+
criteria: z.string().optional().describe("Optional extra clarification string for the model."),
|
|
145
111
|
}),
|
|
146
112
|
z.object({
|
|
147
|
-
id: z
|
|
148
|
-
.string()
|
|
149
|
-
.min(1)
|
|
150
|
-
.describe("Unique key for this question. Used to look up the answer in the response."),
|
|
113
|
+
id: z.string().min(1).describe("Unique key for this question. Used to look up the answer in the response."),
|
|
151
114
|
type: z.literal("choice").describe("Pick one from a named list of options."),
|
|
152
115
|
instructions: InstructionsSchema,
|
|
153
116
|
criteria: z
|
|
154
117
|
.record(CriteriaValueSchema)
|
|
155
|
-
.refine((obj) => Object.keys(obj).length <=
|
|
156
|
-
message:
|
|
118
|
+
.refine((obj) => Object.keys(obj).length <= MAX_CHOICE_OPTIONS, {
|
|
119
|
+
message: `Choice criteria cannot exceed ${MAX_CHOICE_OPTIONS} options`,
|
|
157
120
|
})
|
|
158
121
|
.describe([
|
|
159
|
-
|
|
160
|
-
"Each value can be: string, object
|
|
122
|
+
`Map of option key → description (max ${MAX_CHOICE_OPTIONS} options).`,
|
|
123
|
+
"Each value can be: string, object, array, or null.",
|
|
161
124
|
'Use null for options that need no extra detail, e.g. {"other": null}.',
|
|
162
125
|
].join("\n")),
|
|
163
126
|
}),
|
|
164
127
|
z.object({
|
|
165
|
-
id: z
|
|
166
|
-
.string()
|
|
167
|
-
.min(1)
|
|
168
|
-
.describe("Unique key for this question. Used to look up the answer in the response."),
|
|
128
|
+
id: z.string().min(1).describe("Unique key for this question. Used to look up the answer in the response."),
|
|
169
129
|
type: z.literal("score").describe("Rate on an ordered scale of 2–10 levels."),
|
|
170
130
|
instructions: InstructionsSchema,
|
|
171
131
|
criteria: z
|
|
172
132
|
.array(CriteriaValueSchema)
|
|
173
|
-
.min(
|
|
174
|
-
.max(
|
|
133
|
+
.min(MIN_SCORE_LEVELS)
|
|
134
|
+
.max(MAX_SCORE_LEVELS)
|
|
175
135
|
.describe([
|
|
176
|
-
|
|
177
|
-
"Each level can be: string, object
|
|
178
|
-
'e.g. ["calm", "frustrated", "very angry"]
|
|
136
|
+
`Ordered list of level descriptions from lowest to highest (${MIN_SCORE_LEVELS}–${MAX_SCORE_LEVELS} levels).`,
|
|
137
|
+
"Each level can be: string, object, or array.",
|
|
138
|
+
'e.g. ["calm", "frustrated", "very angry"]',
|
|
179
139
|
].join("\n")),
|
|
180
140
|
}),
|
|
181
141
|
]);
|
|
@@ -192,24 +152,36 @@ server.tool("jev_decide", [
|
|
|
192
152
|
" - Run multiple of the above on the same content in one call",
|
|
193
153
|
"",
|
|
194
154
|
"Question types:",
|
|
195
|
-
" - noul: yes/no probability (0–1)
|
|
196
|
-
" - choice: pick one of N options
|
|
197
|
-
" - score: rate on ordered rubric
|
|
155
|
+
" - noul: yes/no probability (0–1)",
|
|
156
|
+
" - choice: pick one of N options",
|
|
157
|
+
" - score: rate on ordered rubric (2–10 levels)",
|
|
198
158
|
"",
|
|
199
|
-
"
|
|
200
|
-
"
|
|
159
|
+
"Example — triage a support message:",
|
|
160
|
+
" state: { \"message\": \"My payout failed 3 days ago, need urgent help!\" }",
|
|
161
|
+
" questions:",
|
|
162
|
+
" - { id: \"is_urgent\", type: \"noul\",",
|
|
163
|
+
" instructions: \"Does the user in `message` need urgent support?\" }",
|
|
164
|
+
" - { id: \"dept\", type: \"choice\",",
|
|
165
|
+
" instructions: \"Which department should handle `message`?\",",
|
|
166
|
+
" criteria: { billing: \"Payments/refunds\", technical: \"API errors\", general: null } }",
|
|
167
|
+
" - { id: \"frustration\", type: \"score\",",
|
|
168
|
+
" instructions: \"How frustrated is the user in `message`?\",",
|
|
169
|
+
" criteria: [\"calm\", \"annoyed\", \"very frustrated\"] }",
|
|
170
|
+
" → answers: { is_urgent: { noul: 0.95 },",
|
|
171
|
+
" dept: { choice: \"billing\", probabilities: {...}, confidence: 0.82 },",
|
|
172
|
+
" frustration: { score: 2.04, legend: {\"0\":\"calm\",\"2\":\"very frustrated\"}, ... } }",
|
|
201
173
|
"",
|
|
202
174
|
"Tip: send only the state fields each question needs. Extra context degrades accuracy.",
|
|
203
175
|
].join("\n"), {
|
|
204
176
|
state: z
|
|
205
177
|
.union([
|
|
206
|
-
z.string(),
|
|
178
|
+
z.string().max(MAX_STATE_STRING_CHARS), // (F05) size limit for string state
|
|
207
179
|
z.record(z.unknown()),
|
|
208
180
|
z.array(z.unknown()),
|
|
209
181
|
])
|
|
210
182
|
.describe([
|
|
211
183
|
"The content Jev evaluates. Can be:",
|
|
212
|
-
|
|
184
|
+
` - A plain string (max ${MAX_STATE_STRING_CHARS.toLocaleString()} chars): \"My card was charged twice.\"`,
|
|
213
185
|
" - An object with named fields: {\"message\": \"...\", \"order_id\": \"A-104\"}",
|
|
214
186
|
" - An array of records (for batches or conversation turns)",
|
|
215
187
|
"Include only what the questions need — extra content lowers accuracy.",
|
|
@@ -217,8 +189,9 @@ server.tool("jev_decide", [
|
|
|
217
189
|
questions: z
|
|
218
190
|
.array(QuestionSchema)
|
|
219
191
|
.min(1)
|
|
192
|
+
.max(MAX_QUESTIONS) // (F06) prevent upstream 422 on massive payloads
|
|
220
193
|
.describe([
|
|
221
|
-
|
|
194
|
+
`List of questions to evaluate (max ${MAX_QUESTIONS}). Each has:`,
|
|
222
195
|
" id — key used in the response answers map",
|
|
223
196
|
" type — \"noul\" | \"choice\" | \"score\"",
|
|
224
197
|
" instructions — full question text, may reference state fields in backticks",
|
|
@@ -227,14 +200,18 @@ server.tool("jev_decide", [
|
|
|
227
200
|
model: z
|
|
228
201
|
.string()
|
|
229
202
|
.default("jev-latest")
|
|
230
|
-
.describe("Model alias or versioned ID
|
|
203
|
+
.describe("Model alias or versioned ID (default: jev-latest). Use \"jev-preview\" for cutting edge. Call jev_list_models to see available IDs."),
|
|
231
204
|
}, async ({ state, questions, model }) => {
|
|
232
|
-
// Build the questions object (Record<id, JevQuestion>) from the array
|
|
233
205
|
const questionsMap = {};
|
|
234
206
|
for (const q of questions) {
|
|
235
207
|
if (q.id in questionsMap) {
|
|
236
208
|
return {
|
|
237
|
-
content: [
|
|
209
|
+
content: [
|
|
210
|
+
{
|
|
211
|
+
type: "text",
|
|
212
|
+
text: `Error: duplicate question id '${q.id}' — each question must have a unique id. Rename one of them (e.g. '${q.id}_2').`,
|
|
213
|
+
},
|
|
214
|
+
],
|
|
238
215
|
isError: true,
|
|
239
216
|
};
|
|
240
217
|
}
|
|
@@ -246,36 +223,19 @@ server.tool("jev_decide", [
|
|
|
246
223
|
};
|
|
247
224
|
}
|
|
248
225
|
else if (q.type === "choice") {
|
|
249
|
-
questionsMap[q.id] = {
|
|
250
|
-
type: "choice",
|
|
251
|
-
instructions: q.instructions,
|
|
252
|
-
criteria: q.criteria,
|
|
253
|
-
};
|
|
226
|
+
questionsMap[q.id] = { type: "choice", instructions: q.instructions, criteria: q.criteria };
|
|
254
227
|
}
|
|
255
228
|
else {
|
|
256
|
-
|
|
257
|
-
questionsMap[q.id] = {
|
|
258
|
-
type: "score",
|
|
259
|
-
instructions: q.instructions,
|
|
260
|
-
criteria: q.criteria,
|
|
261
|
-
};
|
|
229
|
+
questionsMap[q.id] = { type: "score", instructions: q.instructions, criteria: q.criteria };
|
|
262
230
|
}
|
|
263
231
|
}
|
|
264
232
|
try {
|
|
265
|
-
const result = await callSystemOne({
|
|
266
|
-
model,
|
|
267
|
-
state,
|
|
268
|
-
questions: questionsMap,
|
|
269
|
-
});
|
|
233
|
+
const result = await callSystemOne({ model, state, questions: questionsMap });
|
|
270
234
|
return {
|
|
271
235
|
content: [
|
|
272
236
|
{
|
|
273
237
|
type: "text",
|
|
274
|
-
text: JSON.stringify({
|
|
275
|
-
answers: result.answers,
|
|
276
|
-
model: result.model,
|
|
277
|
-
usage: result.usage,
|
|
278
|
-
}, null, 2),
|
|
238
|
+
text: JSON.stringify({ answers: result.answers, model: result.model, usage: result.usage }, null, 2),
|
|
279
239
|
},
|
|
280
240
|
],
|
|
281
241
|
};
|
|
@@ -300,12 +260,7 @@ server.tool("jev_list_models", [
|
|
|
300
260
|
try {
|
|
301
261
|
const models = await listModels();
|
|
302
262
|
return {
|
|
303
|
-
content: [
|
|
304
|
-
{
|
|
305
|
-
type: "text",
|
|
306
|
-
text: JSON.stringify(models, null, 2),
|
|
307
|
-
},
|
|
308
|
-
],
|
|
263
|
+
content: [{ type: "text", text: JSON.stringify(models, null, 2) }],
|
|
309
264
|
};
|
|
310
265
|
}
|
|
311
266
|
catch (e) {
|
|
@@ -317,6 +272,8 @@ server.tool("jev_list_models", [
|
|
|
317
272
|
}
|
|
318
273
|
});
|
|
319
274
|
// ─── Start ───────────────────────────────────────────────────────────────────
|
|
275
|
+
process.stderr.write("[mcp-jev] Server starting…\n");
|
|
320
276
|
const transport = new StdioServerTransport();
|
|
321
277
|
await server.connect(transport);
|
|
278
|
+
process.stderr.write("[mcp-jev] Server ready.\n");
|
|
322
279
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/lib.d.ts
ADDED
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Exported utilities for testing.
|
|
3
|
+
* index.ts re-exports from here — only import from lib.ts in tests.
|
|
4
|
+
*/
|
|
5
|
+
export declare const FETCH_TIMEOUT_MS = 30000;
|
|
6
|
+
export declare const MAX_RETRY_WAIT_MS = 60000;
|
|
7
|
+
export declare const ERROR_BODY_MAX_CHARS = 500;
|
|
8
|
+
export declare const MAX_CHOICE_OPTIONS = 255;
|
|
9
|
+
export declare const MIN_SCORE_LEVELS = 2;
|
|
10
|
+
export declare const MAX_SCORE_LEVELS = 10;
|
|
11
|
+
export declare const MAX_STATE_STRING_CHARS = 200000;
|
|
12
|
+
export declare const MAX_QUESTIONS = 100;
|
|
13
|
+
/** Truncate a string to maxChars, appending "…" if cut */
|
|
14
|
+
export declare function truncate(text: string, maxChars: number): string;
|
|
15
|
+
import { z } from "zod";
|
|
16
|
+
export declare const NoulAnswerSchema: z.ZodObject<{
|
|
17
|
+
noul: z.ZodNumber;
|
|
18
|
+
}, "strip", z.ZodTypeAny, {
|
|
19
|
+
noul: number;
|
|
20
|
+
}, {
|
|
21
|
+
noul: number;
|
|
22
|
+
}>;
|
|
23
|
+
export declare const ChoiceAnswerSchema: z.ZodObject<{
|
|
24
|
+
choice: z.ZodString;
|
|
25
|
+
probabilities: z.ZodRecord<z.ZodString, z.ZodNumber>;
|
|
26
|
+
confidence: z.ZodNumber;
|
|
27
|
+
}, "strip", z.ZodTypeAny, {
|
|
28
|
+
choice: string;
|
|
29
|
+
probabilities: Record<string, number>;
|
|
30
|
+
confidence: number;
|
|
31
|
+
}, {
|
|
32
|
+
choice: string;
|
|
33
|
+
probabilities: Record<string, number>;
|
|
34
|
+
confidence: number;
|
|
35
|
+
}>;
|
|
36
|
+
export declare const ScoreAnswerSchema: z.ZodObject<{
|
|
37
|
+
score: z.ZodNumber;
|
|
38
|
+
legend: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
39
|
+
probabilities: z.ZodRecord<z.ZodString, z.ZodNumber>;
|
|
40
|
+
confidence: z.ZodNumber;
|
|
41
|
+
}, "strip", z.ZodTypeAny, {
|
|
42
|
+
probabilities: Record<string, number>;
|
|
43
|
+
confidence: number;
|
|
44
|
+
score: number;
|
|
45
|
+
legend: Record<string, string>;
|
|
46
|
+
}, {
|
|
47
|
+
probabilities: Record<string, number>;
|
|
48
|
+
confidence: number;
|
|
49
|
+
score: number;
|
|
50
|
+
legend: Record<string, string>;
|
|
51
|
+
}>;
|
|
52
|
+
export declare const JevResponseSchema: z.ZodObject<{
|
|
53
|
+
answers: z.ZodRecord<z.ZodString, z.ZodUnion<[z.ZodObject<{
|
|
54
|
+
noul: z.ZodNumber;
|
|
55
|
+
}, "strip", z.ZodTypeAny, {
|
|
56
|
+
noul: number;
|
|
57
|
+
}, {
|
|
58
|
+
noul: number;
|
|
59
|
+
}>, z.ZodObject<{
|
|
60
|
+
choice: z.ZodString;
|
|
61
|
+
probabilities: z.ZodRecord<z.ZodString, z.ZodNumber>;
|
|
62
|
+
confidence: z.ZodNumber;
|
|
63
|
+
}, "strip", z.ZodTypeAny, {
|
|
64
|
+
choice: string;
|
|
65
|
+
probabilities: Record<string, number>;
|
|
66
|
+
confidence: number;
|
|
67
|
+
}, {
|
|
68
|
+
choice: string;
|
|
69
|
+
probabilities: Record<string, number>;
|
|
70
|
+
confidence: number;
|
|
71
|
+
}>, z.ZodObject<{
|
|
72
|
+
score: z.ZodNumber;
|
|
73
|
+
legend: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
74
|
+
probabilities: z.ZodRecord<z.ZodString, z.ZodNumber>;
|
|
75
|
+
confidence: z.ZodNumber;
|
|
76
|
+
}, "strip", z.ZodTypeAny, {
|
|
77
|
+
probabilities: Record<string, number>;
|
|
78
|
+
confidence: number;
|
|
79
|
+
score: number;
|
|
80
|
+
legend: Record<string, string>;
|
|
81
|
+
}, {
|
|
82
|
+
probabilities: Record<string, number>;
|
|
83
|
+
confidence: number;
|
|
84
|
+
score: number;
|
|
85
|
+
legend: Record<string, string>;
|
|
86
|
+
}>]>>;
|
|
87
|
+
model: z.ZodString;
|
|
88
|
+
usage: z.ZodObject<{
|
|
89
|
+
input_tokens: z.ZodNumber;
|
|
90
|
+
output_tokens: z.ZodNumber;
|
|
91
|
+
}, "strip", z.ZodTypeAny, {
|
|
92
|
+
input_tokens: number;
|
|
93
|
+
output_tokens: number;
|
|
94
|
+
}, {
|
|
95
|
+
input_tokens: number;
|
|
96
|
+
output_tokens: number;
|
|
97
|
+
}>;
|
|
98
|
+
}, "strip", z.ZodTypeAny, {
|
|
99
|
+
answers: Record<string, {
|
|
100
|
+
noul: number;
|
|
101
|
+
} | {
|
|
102
|
+
choice: string;
|
|
103
|
+
probabilities: Record<string, number>;
|
|
104
|
+
confidence: number;
|
|
105
|
+
} | {
|
|
106
|
+
probabilities: Record<string, number>;
|
|
107
|
+
confidence: number;
|
|
108
|
+
score: number;
|
|
109
|
+
legend: Record<string, string>;
|
|
110
|
+
}>;
|
|
111
|
+
model: string;
|
|
112
|
+
usage: {
|
|
113
|
+
input_tokens: number;
|
|
114
|
+
output_tokens: number;
|
|
115
|
+
};
|
|
116
|
+
}, {
|
|
117
|
+
answers: Record<string, {
|
|
118
|
+
noul: number;
|
|
119
|
+
} | {
|
|
120
|
+
choice: string;
|
|
121
|
+
probabilities: Record<string, number>;
|
|
122
|
+
confidence: number;
|
|
123
|
+
} | {
|
|
124
|
+
probabilities: Record<string, number>;
|
|
125
|
+
confidence: number;
|
|
126
|
+
score: number;
|
|
127
|
+
legend: Record<string, string>;
|
|
128
|
+
}>;
|
|
129
|
+
model: string;
|
|
130
|
+
usage: {
|
|
131
|
+
input_tokens: number;
|
|
132
|
+
output_tokens: number;
|
|
133
|
+
};
|
|
134
|
+
}>;
|
|
135
|
+
export declare const JevModelSchema: z.ZodObject<{
|
|
136
|
+
id: z.ZodString;
|
|
137
|
+
description: z.ZodOptional<z.ZodString>;
|
|
138
|
+
release_date: z.ZodOptional<z.ZodString>;
|
|
139
|
+
aliases: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
140
|
+
}, "strip", z.ZodTypeAny, {
|
|
141
|
+
id: string;
|
|
142
|
+
description?: string | undefined;
|
|
143
|
+
release_date?: string | undefined;
|
|
144
|
+
aliases?: string[] | undefined;
|
|
145
|
+
}, {
|
|
146
|
+
id: string;
|
|
147
|
+
description?: string | undefined;
|
|
148
|
+
release_date?: string | undefined;
|
|
149
|
+
aliases?: string[] | undefined;
|
|
150
|
+
}>;
|
|
151
|
+
export declare const JevModelsResponseSchema: z.ZodObject<{
|
|
152
|
+
models: z.ZodOptional<z.ZodArray<z.ZodUnknown, "many">>;
|
|
153
|
+
data: z.ZodOptional<z.ZodArray<z.ZodUnknown, "many">>;
|
|
154
|
+
}, "strip", z.ZodTypeAny, {
|
|
155
|
+
models?: unknown[] | undefined;
|
|
156
|
+
data?: unknown[] | undefined;
|
|
157
|
+
}, {
|
|
158
|
+
models?: unknown[] | undefined;
|
|
159
|
+
data?: unknown[] | undefined;
|
|
160
|
+
}>;
|
|
161
|
+
export interface FetchLike {
|
|
162
|
+
(url: string, init?: RequestInit & {
|
|
163
|
+
signal?: AbortSignal;
|
|
164
|
+
}): Promise<Response>;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Fetch with exponential back-off for 429/529 and per-request timeout.
|
|
168
|
+
* Accepts an injectable fetch function for testing.
|
|
169
|
+
*/
|
|
170
|
+
export declare function fetchWithRetry(url: string, init: RequestInit, attempts?: number, delayMs?: number, fetchFn?: FetchLike): Promise<Response>;
|
|
171
|
+
/** Parse and filter model entries — skips entries missing id (F03) */
|
|
172
|
+
export declare function parseModelEntries(entries: unknown[]): z.infer<typeof JevModelSchema>[];
|
|
173
|
+
//# sourceMappingURL=lib.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lib.d.ts","sourceRoot":"","sources":["../src/lib.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,eAAO,MAAM,gBAAgB,QAAS,CAAC;AACvC,eAAO,MAAM,iBAAiB,QAAS,CAAC;AACxC,eAAO,MAAM,oBAAoB,MAAM,CAAC;AACxC,eAAO,MAAM,kBAAkB,MAAM,CAAC;AACtC,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAClC,eAAO,MAAM,gBAAgB,KAAK,CAAC;AACnC,eAAO,MAAM,sBAAsB,SAAU,CAAC;AAC9C,eAAO,MAAM,aAAa,MAAM,CAAC;AAIjC,0DAA0D;AAC1D,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE/D;AAID,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,gBAAgB;;;;;;EAE3B,CAAC;AAEH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;EAI7B,CAAC;AAEH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;EAK5B,CAAC;AAEH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAS5B,CAAC;AAEH,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;EAKzB,CAAC;AAEH,eAAO,MAAM,uBAAuB;;;;;;;;;EAGlC,CAAC;AAIH,MAAM,WAAW,SAAS;IACxB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG;QAAE,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;CACjF;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAClC,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,WAAW,EACjB,QAAQ,SAAI,EACZ,OAAO,SAAO,EACd,OAAO,GAAE,SAAiB,GACzB,OAAO,CAAC,QAAQ,CAAC,CA+CnB;AAID,sEAAsE;AACtE,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,EAAE,CAQtF"}
|
package/dist/lib.js
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Exported utilities for testing.
|
|
3
|
+
* index.ts re-exports from here — only import from lib.ts in tests.
|
|
4
|
+
*/
|
|
5
|
+
// ─── Constants ────────────────────────────────────────────────────────────────
|
|
6
|
+
export const FETCH_TIMEOUT_MS = 30_000;
|
|
7
|
+
export const MAX_RETRY_WAIT_MS = 60_000;
|
|
8
|
+
export const ERROR_BODY_MAX_CHARS = 500;
|
|
9
|
+
export const MAX_CHOICE_OPTIONS = 255;
|
|
10
|
+
export const MIN_SCORE_LEVELS = 2;
|
|
11
|
+
export const MAX_SCORE_LEVELS = 10;
|
|
12
|
+
export const MAX_STATE_STRING_CHARS = 200_000;
|
|
13
|
+
export const MAX_QUESTIONS = 100;
|
|
14
|
+
// ─── Helpers ──────────────────────────────────────────────────────────────────
|
|
15
|
+
/** Truncate a string to maxChars, appending "…" if cut */
|
|
16
|
+
export function truncate(text, maxChars) {
|
|
17
|
+
return text.length <= maxChars ? text : text.slice(0, maxChars) + "…";
|
|
18
|
+
}
|
|
19
|
+
// ─── Zod response schemas ────────────────────────────────────────────────────
|
|
20
|
+
import { z } from "zod";
|
|
21
|
+
export const NoulAnswerSchema = z.object({
|
|
22
|
+
noul: z.number(),
|
|
23
|
+
});
|
|
24
|
+
export const ChoiceAnswerSchema = z.object({
|
|
25
|
+
choice: z.string(),
|
|
26
|
+
probabilities: z.record(z.number()),
|
|
27
|
+
confidence: z.number(),
|
|
28
|
+
});
|
|
29
|
+
export const ScoreAnswerSchema = z.object({
|
|
30
|
+
score: z.number(),
|
|
31
|
+
legend: z.record(z.string()),
|
|
32
|
+
probabilities: z.record(z.number()),
|
|
33
|
+
confidence: z.number(),
|
|
34
|
+
});
|
|
35
|
+
export const JevResponseSchema = z.object({
|
|
36
|
+
answers: z.record(z.union([NoulAnswerSchema, ChoiceAnswerSchema, ScoreAnswerSchema])),
|
|
37
|
+
model: z.string(),
|
|
38
|
+
usage: z.object({
|
|
39
|
+
input_tokens: z.number(),
|
|
40
|
+
output_tokens: z.number(),
|
|
41
|
+
}),
|
|
42
|
+
});
|
|
43
|
+
export const JevModelSchema = z.object({
|
|
44
|
+
id: z.string(),
|
|
45
|
+
description: z.string().optional(),
|
|
46
|
+
release_date: z.string().optional(),
|
|
47
|
+
aliases: z.array(z.string()).optional(),
|
|
48
|
+
});
|
|
49
|
+
export const JevModelsResponseSchema = z.object({
|
|
50
|
+
models: z.array(z.unknown()).optional(),
|
|
51
|
+
data: z.array(z.unknown()).optional(),
|
|
52
|
+
});
|
|
53
|
+
/**
|
|
54
|
+
* Fetch with exponential back-off for 429/529 and per-request timeout.
|
|
55
|
+
* Accepts an injectable fetch function for testing.
|
|
56
|
+
*/
|
|
57
|
+
export async function fetchWithRetry(url, init, attempts = 3, delayMs = 1000, fetchFn = fetch) {
|
|
58
|
+
if (attempts < 1)
|
|
59
|
+
throw new Error("fetchWithRetry: attempts must be >= 1");
|
|
60
|
+
let lastError;
|
|
61
|
+
for (let attempt = 1; attempt <= attempts; attempt++) {
|
|
62
|
+
const controller = new AbortController();
|
|
63
|
+
const timeoutId = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);
|
|
64
|
+
let resp;
|
|
65
|
+
try {
|
|
66
|
+
resp = await fetchFn(url, { ...init, signal: controller.signal });
|
|
67
|
+
}
|
|
68
|
+
catch (e) {
|
|
69
|
+
clearTimeout(timeoutId);
|
|
70
|
+
if (e instanceof Error && e.name === "AbortError") {
|
|
71
|
+
throw new Error(`Jev API request timed out after ${FETCH_TIMEOUT_MS / 1000}s`);
|
|
72
|
+
}
|
|
73
|
+
throw e;
|
|
74
|
+
}
|
|
75
|
+
clearTimeout(timeoutId);
|
|
76
|
+
if (resp.status !== 429 && resp.status !== 529) {
|
|
77
|
+
return resp;
|
|
78
|
+
}
|
|
79
|
+
const retryAfter = resp.headers.get("Retry-After");
|
|
80
|
+
const parsed = retryAfter ? parseInt(retryAfter, 10) : NaN;
|
|
81
|
+
const rawWait = !isNaN(parsed) && parsed > 0
|
|
82
|
+
? parsed * 1000
|
|
83
|
+
: delayMs * Math.pow(2, attempt - 1);
|
|
84
|
+
const waitMs = Math.min(rawWait, MAX_RETRY_WAIT_MS);
|
|
85
|
+
const body = await resp.text().catch(() => "");
|
|
86
|
+
if (attempt < attempts) {
|
|
87
|
+
await new Promise((r) => setTimeout(r, waitMs));
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
lastError = new Error(`HTTP ${resp.status} after ${attempts} attempts — rate limited or overloaded. ` +
|
|
91
|
+
`Response: ${truncate(body, ERROR_BODY_MAX_CHARS)}`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
throw lastError ?? new Error("fetchWithRetry: unexpected loop exit");
|
|
95
|
+
}
|
|
96
|
+
// ─── listModels entries filter ────────────────────────────────────────────────
|
|
97
|
+
/** Parse and filter model entries — skips entries missing id (F03) */
|
|
98
|
+
export function parseModelEntries(entries) {
|
|
99
|
+
return entries
|
|
100
|
+
.map((e) => JevModelSchema.safeParse(e))
|
|
101
|
+
.filter((r) => r.success && typeof r.data.id === "string")
|
|
102
|
+
.map((r) => r.data);
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=lib.js.map
|
package/dist/lib.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lib.js","sourceRoot":"","sources":["../src/lib.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mcp-jev",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "MCP server for TypeSafe Jev — System One Model. Two tools: jev_decide (noul/choice/score) and jev_list_models.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -12,7 +12,9 @@
|
|
|
12
12
|
"dev": "tsx src/index.ts",
|
|
13
13
|
"typecheck": "tsc --noEmit",
|
|
14
14
|
"start": "node dist/index.js",
|
|
15
|
-
"prepare": "tsc"
|
|
15
|
+
"prepare": "tsc",
|
|
16
|
+
"test": "vitest run",
|
|
17
|
+
"test:watch": "vitest"
|
|
16
18
|
},
|
|
17
19
|
"files": [
|
|
18
20
|
"dist",
|
|
@@ -32,9 +34,9 @@
|
|
|
32
34
|
"license": "MIT",
|
|
33
35
|
"repository": {
|
|
34
36
|
"type": "git",
|
|
35
|
-
"url": "https://github.com/
|
|
37
|
+
"url": "https://github.com/mndpjm/mcp-jev"
|
|
36
38
|
},
|
|
37
|
-
"homepage": "https://github.com/
|
|
39
|
+
"homepage": "https://github.com/mndpjm/mcp-jev#readme",
|
|
38
40
|
"dependencies": {
|
|
39
41
|
"@modelcontextprotocol/sdk": "^1.16.0",
|
|
40
42
|
"zod": "^3.23.8"
|
|
@@ -42,7 +44,8 @@
|
|
|
42
44
|
"devDependencies": {
|
|
43
45
|
"@types/node": "^22.9.0",
|
|
44
46
|
"tsx": "^4.19.0",
|
|
45
|
-
"typescript": "^5.6.3"
|
|
47
|
+
"typescript": "^5.6.3",
|
|
48
|
+
"vitest": "^2.1.0"
|
|
46
49
|
},
|
|
47
50
|
"engines": {
|
|
48
51
|
"node": ">=20"
|