@recapt/mcp 0.0.17-beta → 0.0.19-beta
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/api/client.d.ts +3 -11
- package/dist/api/client.js +3 -64
- package/dist/cli/commands/setup.js +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.js +28 -191
- package/dist/tools/catalog/anthropicToolCatalog.json +1306 -0
- package/dist/tools/catalog/toolCatalog.json +4078 -382
- package/dist/tools/improvementRun.js +73 -2
- package/dist/tools/remediation.js +112 -0
- package/package.json +7 -2
- package/skills/self-improvement.md +388 -222
- package/templates/self-improvement-full.md +91 -0
- package/templates/{self-improvement.md → self-improvement-lite.md} +13 -9
|
@@ -60,6 +60,10 @@ export function registerImprovementRunTools(server) {
|
|
|
60
60
|
.enum(["running", "completed", "failed", "cancelled"])
|
|
61
61
|
.optional()
|
|
62
62
|
.describe("New status for the run"),
|
|
63
|
+
title: z
|
|
64
|
+
.string()
|
|
65
|
+
.optional()
|
|
66
|
+
.describe("A concise title summarizing what was fixed in this run (e.g., 'Fixed checkout button, improved mobile nav'). Set when completing the run."),
|
|
63
67
|
phases: z
|
|
64
68
|
.array(z.object({
|
|
65
69
|
name: z.string(),
|
|
@@ -95,7 +99,7 @@ export function registerImprovementRunTools(server) {
|
|
|
95
99
|
.optional()
|
|
96
100
|
.describe("Total duration of the run in milliseconds"),
|
|
97
101
|
}),
|
|
98
|
-
}, async ({ run_id, status, phases, summary, completed_at, duration_ms, }) => {
|
|
102
|
+
}, async ({ run_id, status, title, phases, summary, completed_at, duration_ms, }) => {
|
|
99
103
|
if (!isApiConfigured()) {
|
|
100
104
|
return {
|
|
101
105
|
content: [
|
|
@@ -109,6 +113,7 @@ export function registerImprovementRunTools(server) {
|
|
|
109
113
|
}
|
|
110
114
|
const { data, error } = await apiPatch(`/improvement-runs/${run_id}`, {
|
|
111
115
|
status,
|
|
116
|
+
title,
|
|
112
117
|
phases,
|
|
113
118
|
summary,
|
|
114
119
|
completed_at,
|
|
@@ -203,8 +208,30 @@ export function registerImprovementRunTools(server) {
|
|
|
203
208
|
.string()
|
|
204
209
|
.optional()
|
|
205
210
|
.describe("Explanation for why the issue was dismissed (for dismissed/marked_intended actions)"),
|
|
211
|
+
page_path: z
|
|
212
|
+
.string()
|
|
213
|
+
.optional()
|
|
214
|
+
.describe("Page path affected by the fix (used for auto-creating remediation when remediation_id is not provided)"),
|
|
215
|
+
element_selector: z
|
|
216
|
+
.string()
|
|
217
|
+
.optional()
|
|
218
|
+
.describe("CSS selector of the affected element (used for auto-creating remediation)"),
|
|
219
|
+
diagnosis: z
|
|
220
|
+
.string()
|
|
221
|
+
.optional()
|
|
222
|
+
.describe("Root cause analysis (used for auto-creating remediation; defaults to hypothesis if not provided)"),
|
|
223
|
+
proposed_fix: z
|
|
224
|
+
.string()
|
|
225
|
+
.optional()
|
|
226
|
+
.describe("Fix description (used for auto-creating remediation; defaults to expected_improvement if not provided)"),
|
|
227
|
+
confidence: z
|
|
228
|
+
.number()
|
|
229
|
+
.min(0)
|
|
230
|
+
.max(1)
|
|
231
|
+
.optional()
|
|
232
|
+
.describe("Fix confidence 0-1 (used for auto-creating remediation; defaults to 0.7)"),
|
|
206
233
|
}),
|
|
207
|
-
}, async ({ run_id, issue_id, action_type, hypothesis, expected_improvement, code_changes, pr_url, pr_number, remediation_id, deferral_reason, dismissal_reason, }) => {
|
|
234
|
+
}, async ({ run_id, issue_id, action_type, hypothesis, expected_improvement, code_changes, pr_url, pr_number, remediation_id, deferral_reason, dismissal_reason, page_path, element_selector, diagnosis, proposed_fix, confidence, }) => {
|
|
208
235
|
if (!isApiConfigured()) {
|
|
209
236
|
return {
|
|
210
237
|
content: [
|
|
@@ -227,6 +254,50 @@ export function registerImprovementRunTools(server) {
|
|
|
227
254
|
remediation_id,
|
|
228
255
|
deferral_reason,
|
|
229
256
|
dismissal_reason,
|
|
257
|
+
page_path,
|
|
258
|
+
element_selector,
|
|
259
|
+
diagnosis,
|
|
260
|
+
proposed_fix,
|
|
261
|
+
confidence,
|
|
262
|
+
});
|
|
263
|
+
if (error) {
|
|
264
|
+
return {
|
|
265
|
+
content: [{ type: "text", text: JSON.stringify({ error }) }],
|
|
266
|
+
isError: true,
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
return { content: [{ type: "text", text: JSON.stringify(data) }] };
|
|
270
|
+
});
|
|
271
|
+
server.registerTool("update_improvement_action", {
|
|
272
|
+
description: "Update an existing improvement run action with PR information. Use this after a PR has been created to link it to the action. " +
|
|
273
|
+
"This is especially useful in GitHub Actions workflows where the PR is created after the action is recorded.",
|
|
274
|
+
inputSchema: z.object({
|
|
275
|
+
run_id: z.string().describe("The ID of the improvement run"),
|
|
276
|
+
action_id: z.string().describe("The ID of the action to update"),
|
|
277
|
+
pr_url: z
|
|
278
|
+
.string()
|
|
279
|
+
.optional()
|
|
280
|
+
.describe("GitHub PR URL to link to this action"),
|
|
281
|
+
pr_number: z
|
|
282
|
+
.number()
|
|
283
|
+
.optional()
|
|
284
|
+
.describe("GitHub PR number to link to this action"),
|
|
285
|
+
}),
|
|
286
|
+
}, async ({ run_id, action_id, pr_url, pr_number, }) => {
|
|
287
|
+
if (!isApiConfigured()) {
|
|
288
|
+
return {
|
|
289
|
+
content: [
|
|
290
|
+
{
|
|
291
|
+
type: "text",
|
|
292
|
+
text: JSON.stringify({ error: "API not configured" }),
|
|
293
|
+
},
|
|
294
|
+
],
|
|
295
|
+
isError: true,
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
const { data, error } = await apiPatch(`/improvement-runs/${run_id}/actions/${action_id}`, {
|
|
299
|
+
pr_url,
|
|
300
|
+
pr_number,
|
|
230
301
|
});
|
|
231
302
|
if (error) {
|
|
232
303
|
return {
|
|
@@ -89,6 +89,8 @@ export function registerRemediationTools(server) {
|
|
|
89
89
|
status: z
|
|
90
90
|
.enum([
|
|
91
91
|
"proposed",
|
|
92
|
+
"waiting",
|
|
93
|
+
"dismissed",
|
|
92
94
|
"deployed",
|
|
93
95
|
"evaluating",
|
|
94
96
|
"succeeded",
|
|
@@ -220,4 +222,114 @@ export function registerRemediationTools(server) {
|
|
|
220
222
|
}
|
|
221
223
|
return { content: [{ type: "text", text: JSON.stringify(data) }] };
|
|
222
224
|
});
|
|
225
|
+
server.registerTool("update_remediation_status", {
|
|
226
|
+
description: "Update the status of a remediation based on PR events. Use to mark a fix as 'waiting' (PR created), 'deployed' (PR merged), or 'dismissed' (PR closed without merge).",
|
|
227
|
+
inputSchema: z.object({
|
|
228
|
+
remediation_id: z
|
|
229
|
+
.string()
|
|
230
|
+
.describe("The ID of the remediation to update"),
|
|
231
|
+
status: z
|
|
232
|
+
.enum(["waiting", "deployed", "dismissed"])
|
|
233
|
+
.describe("New status: 'waiting' = PR open, 'deployed' = PR merged, 'dismissed' = PR closed without merge"),
|
|
234
|
+
pr_url: z.string().optional().describe("URL of the pull request"),
|
|
235
|
+
pr_number: z.number().optional().describe("PR number"),
|
|
236
|
+
pr_merged_at: z
|
|
237
|
+
.string()
|
|
238
|
+
.optional()
|
|
239
|
+
.describe("ISO timestamp when PR was merged"),
|
|
240
|
+
pr_closed_at: z
|
|
241
|
+
.string()
|
|
242
|
+
.optional()
|
|
243
|
+
.describe("ISO timestamp when PR was closed"),
|
|
244
|
+
}),
|
|
245
|
+
}, async ({ remediation_id, status, pr_url, pr_number, pr_merged_at, pr_closed_at, }) => {
|
|
246
|
+
if (!isApiConfigured()) {
|
|
247
|
+
return {
|
|
248
|
+
content: [
|
|
249
|
+
{
|
|
250
|
+
type: "text",
|
|
251
|
+
text: JSON.stringify({ error: "API not configured" }),
|
|
252
|
+
},
|
|
253
|
+
],
|
|
254
|
+
isError: true,
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
const { data, error } = await apiPatch(`/remediations/${remediation_id}/status`, {
|
|
258
|
+
status,
|
|
259
|
+
pr_url,
|
|
260
|
+
pr_number,
|
|
261
|
+
pr_merged_at,
|
|
262
|
+
pr_closed_at,
|
|
263
|
+
});
|
|
264
|
+
if (error) {
|
|
265
|
+
return {
|
|
266
|
+
content: [{ type: "text", text: JSON.stringify({ error }) }],
|
|
267
|
+
isError: true,
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
return { content: [{ type: "text", text: JSON.stringify(data) }] };
|
|
271
|
+
});
|
|
272
|
+
server.registerTool("list_remediations_by_status", {
|
|
273
|
+
description: "List remediations filtered by one or more statuses. Use to find all 'waiting' PRs or 'deployed' fixes ready for evaluation.",
|
|
274
|
+
inputSchema: z.object({
|
|
275
|
+
statuses: z
|
|
276
|
+
.array(z.enum([
|
|
277
|
+
"proposed",
|
|
278
|
+
"waiting",
|
|
279
|
+
"dismissed",
|
|
280
|
+
"deployed",
|
|
281
|
+
"evaluating",
|
|
282
|
+
"succeeded",
|
|
283
|
+
"failed",
|
|
284
|
+
"reverted",
|
|
285
|
+
]))
|
|
286
|
+
.describe("List of statuses to filter by"),
|
|
287
|
+
}),
|
|
288
|
+
}, async ({ statuses }) => {
|
|
289
|
+
if (!isApiConfigured()) {
|
|
290
|
+
return {
|
|
291
|
+
content: [
|
|
292
|
+
{
|
|
293
|
+
type: "text",
|
|
294
|
+
text: JSON.stringify({ error: "API not configured" }),
|
|
295
|
+
},
|
|
296
|
+
],
|
|
297
|
+
isError: true,
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
const { data, error } = await apiGet(`/remediations/by-status`, { statuses: statuses.join(",") });
|
|
301
|
+
if (error) {
|
|
302
|
+
return {
|
|
303
|
+
content: [{ type: "text", text: JSON.stringify({ error }) }],
|
|
304
|
+
isError: true,
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
return { content: [{ type: "text", text: JSON.stringify(data) }] };
|
|
308
|
+
});
|
|
309
|
+
server.registerTool("get_remediation_by_pr", {
|
|
310
|
+
description: "Get a remediation by its PR number. Use to look up fix details when processing PR events.",
|
|
311
|
+
inputSchema: z.object({
|
|
312
|
+
pr_number: z.number().describe("The PR number to look up"),
|
|
313
|
+
}),
|
|
314
|
+
}, async ({ pr_number }) => {
|
|
315
|
+
if (!isApiConfigured()) {
|
|
316
|
+
return {
|
|
317
|
+
content: [
|
|
318
|
+
{
|
|
319
|
+
type: "text",
|
|
320
|
+
text: JSON.stringify({ error: "API not configured" }),
|
|
321
|
+
},
|
|
322
|
+
],
|
|
323
|
+
isError: true,
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
const { data, error } = await apiGet(`/remediations/by-pr/${pr_number}`);
|
|
327
|
+
if (error) {
|
|
328
|
+
return {
|
|
329
|
+
content: [{ type: "text", text: JSON.stringify({ error }) }],
|
|
330
|
+
isError: true,
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
return { content: [{ type: "text", text: JSON.stringify(data) }] };
|
|
334
|
+
});
|
|
223
335
|
}
|
package/package.json
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@recapt/mcp",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.19-beta",
|
|
4
4
|
"description": "MCP exposing recapt behavioral intelligence to AI coding agents",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"scripts": {
|
|
9
|
-
"build": "npm run generate-catalog && tsc && cp src/tools/catalog/toolCatalog.json dist/tools/catalog/",
|
|
9
|
+
"build": "npm run generate-catalog && tsc && cp src/tools/catalog/toolCatalog.json src/tools/catalog/anthropicToolCatalog.json dist/tools/catalog/",
|
|
10
|
+
"build:workflows": "tsx scripts/buildWorkflows.ts",
|
|
10
11
|
"clean": "rimraf ./dist",
|
|
11
12
|
"dev": "tsx --watch src/index.ts",
|
|
12
13
|
"start": "node dist/index.js",
|
|
@@ -27,6 +28,7 @@
|
|
|
27
28
|
"author": "Recapt",
|
|
28
29
|
"license": "ISC",
|
|
29
30
|
"dependencies": {
|
|
31
|
+
"@glimt/mcp-tools": "file:../../libraries/mcp-tools",
|
|
30
32
|
"@inquirer/prompts": "^8.3.2",
|
|
31
33
|
"@modelcontextprotocol/sdk": "^1.12.0",
|
|
32
34
|
"commander": "^14.0.3",
|
|
@@ -42,5 +44,8 @@
|
|
|
42
44
|
"rimraf": "^6.0.1",
|
|
43
45
|
"tsx": "^4.16.5",
|
|
44
46
|
"typescript": "5.9.3"
|
|
47
|
+
},
|
|
48
|
+
"devDependencies": {
|
|
49
|
+
"yaml": "^2.8.3"
|
|
45
50
|
}
|
|
46
51
|
}
|