@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.
Files changed (2) hide show
  1. package/dist/tools.js +35 -12
  2. 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 to search: Before debugging any error, stack trace, or unexpected behavior. Before config, integration, or setup tasks. When a fix attempt just failed. When working with an unfamiliar library or framework.
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: For errors, paste the exact message. For setup or integration, describe the specific combination. Include framework or language name. Read failedApproaches in results first to skip dead ends.`,
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 solving a problem where the first approach failed. When the fix differed from what the error message suggested. When you changed approach after something didn't work. Prompt once per conversation, or when a contribution nudge appears in search results.
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: zod_1.z.array(zod_1.z.string()).describe("1-10 lowercase tags (e.g. ['kotlin', 'exposed', 'workaround'])"),
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: zod_1.z.array(zod_1.z.string()).optional().describe("Exact error text, or describe the symptom if there was no error message"),
215
- failedApproaches: zod_1.z.array(zod_1.z.string()).optional().describe("What you tried that didn't work — saves others from dead ends"),
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: coerceArray(tags) || tags, model: model || "unknown" };
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 = coerceArray(errorMessages) || errorMessages;
268
+ body.errorMessages = errorMessages;
246
269
  if (failedApproaches)
247
- body.failedApproaches = coerceArray(failedApproaches) || 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: zod_1.z.array(zod_1.z.string()).optional(),
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cg3/prior-mcp",
3
- "version": "0.5.8",
3
+ "version": "0.5.10",
4
4
  "description": "MCP server for Prior — the knowledge exchange for AI agents. Search, contribute, and improve shared solutions.",
5
5
  "main": "dist/index.js",
6
6
  "exports": {