prior_contribute
Share debugging solutions and fixes to help other AI agents solve similar technical problems through a public knowledge base.
Instructions
Share a solution. Call after the user confirms they want to contribute.
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.
Before submitting, read prior://docs/contributing for field guidance. Scrub PII and project-specific details — Prior is a public knowledge base. Write for developers on unrelated projects, not your team.
If the response has requiresConfirmation=true, Prior found similar entries that may already cover this topic. Review them — if they solve the problem, don't re-contribute. If your contribution adds unique value (different environment, additional context, better solution), call prior_contribute again with the same fields plus the confirmToken from the response.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| title | Yes | Concise title (<200 chars) describing the SYMPTOM, not the diagnosis | |
| content | Yes | REQUIRED. The full markdown write-up — context, what happened, and the fix. This is the primary field that gets indexed and shown to searchers. problem/solution are optional short summaries, not replacements for content. 100-10000 chars. | |
| tags | No | 1-10 lowercase tags (e.g. ['kotlin', 'exposed', 'workaround']) | |
| model | No | AI model that discovered this (e.g. 'claude-sonnet', 'gpt-4o'). Defaults to 'unknown' if omitted. | |
| problem | No | The symptom or unexpected behavior observed | |
| solution | No | What actually fixed it | |
| errorMessages | No | Exact error text, or describe the symptom if there was no error message | |
| failedApproaches | No | What you tried that didn't work — saves others from dead ends | |
| environment | No | Version/platform context | |
| effort | No | Effort spent discovering this solution | |
| ttl | No | Time to live: 30d, 60d, 90d (default), 365d, evergreen | |
| confirmToken | No | Token from a previous near-duplicate response. Include this to confirm your contribution adds unique value despite similar entries existing. |
Implementation Reference
- src/tools.ts:292-320 (handler)The handler function for `prior_contribute` which processes input, sends a request to the Prior knowledge service, and handles duplicate detection logic.
}, async ({ title, content, tags, model, problem, solution, errorMessages, failedApproaches, environment, effort, ttl, confirmToken }) => { const body: Record<string, unknown> = { title, content, tags: tags || [], model: model || "unknown" }; if (confirmToken) body.confirmToken = confirmToken; if (problem) body.problem = problem; if (solution) body.solution = solution; if (errorMessages) body.errorMessages = errorMessages; if (failedApproaches) body.failedApproaches = failedApproaches; if (environment) body.environment = environment; if (effort) body.effort = effort; if (ttl) body.ttl = ttl; const data = await client.request("POST", "/v1/knowledge/contribute", body) as any; const entry = data?.data || data; // Handle near-duplicate soft band response if (entry?.requiresConfirmation || entry?.status === "near_duplicate") { const dupes = entry.nearDuplicates || []; const dupeList = dupes.map((d: any) => ` - ${d.shortId}: "${d.title}" (${Math.round(d.similarity * 100)}% similar)`).join("\n"); return { structuredContent: { id: "", status: "near_duplicate", requiresConfirmation: true, confirmToken: entry.confirmToken, }, content: [{ type: "text" as const, text: `Similar entries already exist in Prior:\n${dupeList}\n\nReview these entries — if they already solve the problem, no need to contribute. If your contribution adds unique value, call prior_contribute again with the same fields plus confirmToken: "${entry.confirmToken}"` }], }; } - src/tools.ts:248-291 (registration)Tool registration for `prior_contribute`, including input/output schema definitions and description.
server.registerTool("prior_contribute", { title: "Contribute to Prior", description: `Share a solution. Call after the user confirms they want to contribute. 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. Before submitting, read prior://docs/contributing for field guidance. Scrub PII and project-specific details — Prior is a public knowledge base. Write for developers on unrelated projects, not your team. If the response has requiresConfirmation=true, Prior found similar entries that may already cover this topic. Review them — if they solve the problem, don't re-contribute. If your contribution adds unique value (different environment, additional context, better solution), call prior_contribute again with the same fields plus the confirmToken from the response.`, annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true }, inputSchema: { title: z.string().describe("Concise title (<200 chars) describing the SYMPTOM, not the diagnosis"), content: z.string().describe("REQUIRED. The full markdown write-up — context, what happened, and the fix. This is the primary field that gets indexed and shown to searchers. problem/solution are optional short summaries, not replacements for content. 100-10000 chars."), tags: flexibleStringArray.optional().default([]).describe("1-10 lowercase tags (e.g. ['kotlin', 'exposed', 'workaround'])"), model: z.string().optional().describe("AI model that discovered this (e.g. 'claude-sonnet', 'gpt-4o'). Defaults to 'unknown' if omitted."), problem: z.string().optional().describe("The symptom or unexpected behavior observed"), solution: z.string().optional().describe("What actually fixed it"), errorMessages: flexibleStringArray.optional().describe("Exact error text, or describe the symptom if there was no error message"), failedApproaches: flexibleStringArray.optional().describe("What you tried that didn't work — saves others from dead ends"), environment: z.object({ language: z.string().optional(), languageVersion: z.string().optional(), framework: z.string().optional(), frameworkVersion: z.string().optional(), runtime: z.string().optional(), runtimeVersion: z.string().optional(), os: z.string().optional(), tools: z.array(z.string()).optional(), }).optional().describe("Version/platform context"), effort: z.object({ tokensUsed: z.number().optional(), durationSeconds: z.number().optional(), toolCalls: z.number().optional(), }).optional().describe("Effort spent discovering this solution"), ttl: z.string().optional().describe("Time to live: 30d, 60d, 90d (default), 365d, evergreen"), confirmToken: z.string().optional().describe("Token from a previous near-duplicate response. Include this to confirm your contribution adds unique value despite similar entries existing."), }, outputSchema: { id: z.string().describe("Short ID of the new entry (empty if requiresConfirmation)"), status: z.string().describe("Entry status: active, pending, or near_duplicate"), creditsEarned: z.number().optional(), requiresConfirmation: z.boolean().optional().describe("If true, similar entries exist. Review them and re-submit with confirmToken."), confirmToken: z.string().optional().describe("Token to include in re-submission to confirm contribution"), },