@cg3/prior-mcp 0.5.8 → 0.5.10
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/dist/tools.js +35 -12
- package/package.json +1 -1
package/dist/tools.js
CHANGED
|
@@ -15,7 +15,6 @@ const utils_js_1 = require("./utils.js");
|
|
|
15
15
|
/**
|
|
16
16
|
* Coerce a value that might be a string into an array.
|
|
17
17
|
* MCP clients (e.g. Claude Code) sometimes serialize arrays as strings.
|
|
18
|
-
* Call this in the handler, NOT in the Zod schema (z.union breaks JSON Schema generation).
|
|
19
18
|
*/
|
|
20
19
|
function coerceArray(val) {
|
|
21
20
|
if (val == null)
|
|
@@ -36,6 +35,30 @@ function coerceArray(val) {
|
|
|
36
35
|
}
|
|
37
36
|
return undefined;
|
|
38
37
|
}
|
|
38
|
+
/**
|
|
39
|
+
* Zod schema that accepts either a string[] or a JSON-stringified array.
|
|
40
|
+
* Claude Code sometimes sends arrays as strings — this uses z.preprocess
|
|
41
|
+
* to coerce before validation, keeping the JSON Schema output as a simple array type.
|
|
42
|
+
*/
|
|
43
|
+
const flexibleStringArray = zod_1.z.preprocess((val) => {
|
|
44
|
+
if (val == null)
|
|
45
|
+
return val;
|
|
46
|
+
if (Array.isArray(val))
|
|
47
|
+
return val.map(String);
|
|
48
|
+
if (typeof val === "string") {
|
|
49
|
+
const s = val.trim();
|
|
50
|
+
if (s.startsWith("[")) {
|
|
51
|
+
try {
|
|
52
|
+
const parsed = JSON.parse(s);
|
|
53
|
+
if (Array.isArray(parsed))
|
|
54
|
+
return parsed.map(String);
|
|
55
|
+
}
|
|
56
|
+
catch { /* fall through */ }
|
|
57
|
+
}
|
|
58
|
+
return s.split(/[, ]+/).map((t) => t.trim()).filter(Boolean);
|
|
59
|
+
}
|
|
60
|
+
return val;
|
|
61
|
+
}, zod_1.z.array(zod_1.z.string()));
|
|
39
62
|
/**
|
|
40
63
|
* Expand [PRIOR:*] client-side tokens to MCP tool call syntax.
|
|
41
64
|
*/
|
|
@@ -60,11 +83,11 @@ function registerTools(server, { client }) {
|
|
|
60
83
|
// ── prior_search ────────────────────────────────────────────────────
|
|
61
84
|
server.registerTool("prior_search", {
|
|
62
85
|
title: "Search Prior Knowledge Base",
|
|
63
|
-
description: `Search for solutions other agents already discovered.
|
|
86
|
+
description: `Search for solutions other agents already discovered. STOP and search before acting on any error — even mid-task. Do not chain fixes without searching each one.
|
|
64
87
|
|
|
65
|
-
When
|
|
88
|
+
When: Any error, compile failure, stack trace, or unexpected output. Before config, integration, or setup tasks. When a fix attempt just failed — search before trying the next one. Unfamiliar library or framework combination.
|
|
66
89
|
|
|
67
|
-
How:
|
|
90
|
+
How: Paste the exact error message, not your goal. Include framework or language name. Read failedApproaches first to skip dead ends.`,
|
|
68
91
|
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
69
92
|
inputSchema: {
|
|
70
93
|
query: zod_1.z.string().describe("Specific technical query — paste exact error strings for best results"),
|
|
@@ -200,19 +223,19 @@ How: For errors, paste the exact message. For setup or integration, describe the
|
|
|
200
223
|
title: "Contribute to Prior",
|
|
201
224
|
description: `Share a solution. Call after the user confirms they want to contribute.
|
|
202
225
|
|
|
203
|
-
When to prompt the user: After
|
|
226
|
+
When to prompt the user: After each non-trivial fix — not just at end of conversation. If you fixed something by reasoning rather than a known solution, ask inline: "That took some debugging — want me to contribute this to Prior?" Also prompt when the fix differed from what the error suggested, or when a contribution nudge appears in search results.
|
|
204
227
|
|
|
205
228
|
Before submitting, read prior://docs/contributing for field guidance. Scrub file paths, usernames, and keys.`,
|
|
206
229
|
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true },
|
|
207
230
|
inputSchema: {
|
|
208
231
|
title: zod_1.z.string().describe("Concise title (<200 chars) describing the SYMPTOM, not the diagnosis"),
|
|
209
232
|
content: zod_1.z.string().describe("Full description with context and solution (100-10000 chars, markdown)"),
|
|
210
|
-
tags:
|
|
233
|
+
tags: flexibleStringArray.optional().default([]).describe("1-10 lowercase tags (e.g. ['kotlin', 'exposed', 'workaround'])"),
|
|
211
234
|
model: zod_1.z.string().optional().describe("AI model that discovered this (e.g. 'claude-sonnet', 'gpt-4o'). Defaults to 'unknown' if omitted."),
|
|
212
235
|
problem: zod_1.z.string().optional().describe("The symptom or unexpected behavior observed"),
|
|
213
236
|
solution: zod_1.z.string().optional().describe("What actually fixed it"),
|
|
214
|
-
errorMessages:
|
|
215
|
-
failedApproaches:
|
|
237
|
+
errorMessages: flexibleStringArray.optional().describe("Exact error text, or describe the symptom if there was no error message"),
|
|
238
|
+
failedApproaches: flexibleStringArray.optional().describe("What you tried that didn't work — saves others from dead ends"),
|
|
216
239
|
environment: zod_1.z.object({
|
|
217
240
|
language: zod_1.z.string().optional(),
|
|
218
241
|
languageVersion: zod_1.z.string().optional(),
|
|
@@ -236,15 +259,15 @@ Before submitting, read prior://docs/contributing for field guidance. Scrub file
|
|
|
236
259
|
creditsEarned: zod_1.z.number().optional(),
|
|
237
260
|
},
|
|
238
261
|
}, async ({ title, content, tags, model, problem, solution, errorMessages, failedApproaches, environment, effort, ttl }) => {
|
|
239
|
-
const body = { title, content, tags:
|
|
262
|
+
const body = { title, content, tags: tags || [], model: model || "unknown" };
|
|
240
263
|
if (problem)
|
|
241
264
|
body.problem = problem;
|
|
242
265
|
if (solution)
|
|
243
266
|
body.solution = solution;
|
|
244
267
|
if (errorMessages)
|
|
245
|
-
body.errorMessages =
|
|
268
|
+
body.errorMessages = errorMessages;
|
|
246
269
|
if (failedApproaches)
|
|
247
|
-
body.failedApproaches =
|
|
270
|
+
body.failedApproaches = failedApproaches;
|
|
248
271
|
if (environment)
|
|
249
272
|
body.environment = environment;
|
|
250
273
|
if (effort)
|
|
@@ -282,7 +305,7 @@ When: After trying a search result (useful or not_useful), or immediately if a r
|
|
|
282
305
|
correction: zod_1.z.object({
|
|
283
306
|
content: zod_1.z.string().describe("Corrected content (100-10000 chars)"),
|
|
284
307
|
title: zod_1.z.string().optional(),
|
|
285
|
-
tags:
|
|
308
|
+
tags: flexibleStringArray.optional(),
|
|
286
309
|
}).optional().describe("Submit a correction if you found the real fix"),
|
|
287
310
|
},
|
|
288
311
|
outputSchema: {
|
package/package.json
CHANGED