@damper/mcp 0.3.18 ā 0.3.20
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/index.js +65 -15
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -117,10 +117,12 @@ server.registerTool('list_tasks', {
|
|
|
117
117
|
type: z.enum(['bug', 'feature', 'improvement', 'task']).optional().describe('Filter by task type'),
|
|
118
118
|
quarter: z.string().optional().describe('Filter by quarter (e.g., "Q1 2025") or "none" for unscheduled'),
|
|
119
119
|
sort: z.enum(['importance', 'newest', 'votes']).optional().describe('Sort order: importance (priority+votes, default), newest, or votes'),
|
|
120
|
-
limit: z.number().optional(),
|
|
120
|
+
limit: z.number().optional().describe('Max tasks to return (default: 20)'),
|
|
121
|
+
offset: z.number().optional().describe('Skip first N tasks for pagination (default: 0)'),
|
|
121
122
|
}),
|
|
122
123
|
outputSchema: z.object({
|
|
123
124
|
project: z.string(),
|
|
125
|
+
total: z.number(),
|
|
124
126
|
tasks: z.array(TaskSummarySchema),
|
|
125
127
|
}),
|
|
126
128
|
annotations: {
|
|
@@ -129,7 +131,7 @@ server.registerTool('list_tasks', {
|
|
|
129
131
|
idempotentHint: true,
|
|
130
132
|
openWorldHint: false,
|
|
131
133
|
},
|
|
132
|
-
}, async ({ status, type, quarter, sort, limit }) => {
|
|
134
|
+
}, async ({ status, type, quarter, sort, limit, offset }) => {
|
|
133
135
|
const params = new URLSearchParams();
|
|
134
136
|
if (status)
|
|
135
137
|
params.set('status', status);
|
|
@@ -141,13 +143,15 @@ server.registerTool('list_tasks', {
|
|
|
141
143
|
params.set('sort', sort);
|
|
142
144
|
if (limit)
|
|
143
145
|
params.set('limit', String(limit));
|
|
146
|
+
if (offset)
|
|
147
|
+
params.set('offset', String(offset));
|
|
144
148
|
const query = params.toString();
|
|
145
149
|
const data = await api('GET', `/api/agent/tasks${query ? `?${query}` : ''}`);
|
|
146
150
|
if (!data.tasks.length) {
|
|
147
151
|
const filters = [type && `type: ${type}`, quarter && `quarter: ${quarter}`].filter(Boolean).join(', ');
|
|
148
152
|
return {
|
|
149
153
|
content: [{ type: 'text', text: `No tasks in "${data.project.name}"${filters ? ` (${filters})` : ''}` }],
|
|
150
|
-
structuredContent: { project: data.project.name, tasks: [] },
|
|
154
|
+
structuredContent: { project: data.project.name, total: 0, tasks: [] },
|
|
151
155
|
};
|
|
152
156
|
}
|
|
153
157
|
const lines = data.tasks.map((t) => {
|
|
@@ -157,15 +161,20 @@ server.registerTool('list_tasks', {
|
|
|
157
161
|
const quarterInfo = t.quarter ? ` š
${t.quarter}` : '';
|
|
158
162
|
return `⢠${t.id}: ${typeIcon} ${t.title} [${t.status}] ${p}${quarterInfo}${t.hasImplementationPlan ? ' š' : ''}${subtaskInfo}`;
|
|
159
163
|
});
|
|
164
|
+
const currentOffset = offset || 0;
|
|
165
|
+
const paginationInfo = data.total > currentOffset + data.tasks.length
|
|
166
|
+
? `\nš Showing ${currentOffset + 1}ā${currentOffset + data.tasks.length} of ${data.total}. Use offset=${currentOffset + data.tasks.length} to see more.`
|
|
167
|
+
: '';
|
|
160
168
|
const output = [
|
|
161
|
-
`Tasks in "${data.project.name}":`,
|
|
169
|
+
`Tasks in "${data.project.name}" (${data.total} total):`,
|
|
162
170
|
lines.join('\n'),
|
|
171
|
+
paginationInfo,
|
|
163
172
|
'',
|
|
164
173
|
'š” **Tip:** Run `get_project_context` first to understand codebase patterns before starting work.',
|
|
165
174
|
].join('\n');
|
|
166
175
|
return {
|
|
167
176
|
content: [{ type: 'text', text: output }],
|
|
168
|
-
structuredContent: { project: data.project.name, tasks: data.tasks },
|
|
177
|
+
structuredContent: { project: data.project.name, total: data.total, tasks: data.tasks },
|
|
169
178
|
};
|
|
170
179
|
});
|
|
171
180
|
// Tool: Get task
|
|
@@ -244,6 +253,7 @@ server.registerTool('update_task', {
|
|
|
244
253
|
'Useful for refining task details as you learn more about the work.',
|
|
245
254
|
inputSchema: z.object({
|
|
246
255
|
taskId: z.string().describe('Task ID'),
|
|
256
|
+
title: z.string().optional().describe('Task title'),
|
|
247
257
|
description: z.string().optional().describe('Task description'),
|
|
248
258
|
implementationPlan: z.string().optional().describe('Implementation plan (markdown)'),
|
|
249
259
|
priority: z.enum(['high', 'medium', 'low']).nullable().optional().describe('Task priority'),
|
|
@@ -269,8 +279,10 @@ server.registerTool('update_task', {
|
|
|
269
279
|
idempotentHint: true,
|
|
270
280
|
openWorldHint: false,
|
|
271
281
|
},
|
|
272
|
-
}, async ({ taskId, description, implementationPlan, priority, effort, quarter, labels, isPublic }) => {
|
|
282
|
+
}, async ({ taskId, title, description, implementationPlan, priority, effort, quarter, labels, isPublic }) => {
|
|
273
283
|
const body = {};
|
|
284
|
+
if (title !== undefined)
|
|
285
|
+
body.title = title;
|
|
274
286
|
if (description !== undefined)
|
|
275
287
|
body.description = description;
|
|
276
288
|
if (implementationPlan !== undefined)
|
|
@@ -287,6 +299,8 @@ server.registerTool('update_task', {
|
|
|
287
299
|
body.isPublic = isPublic;
|
|
288
300
|
const result = await api('PATCH', `/api/agent/tasks/${taskId}`, body);
|
|
289
301
|
const updates = [];
|
|
302
|
+
if (title !== undefined)
|
|
303
|
+
updates.push(`title="${title}"`);
|
|
290
304
|
if (description !== undefined)
|
|
291
305
|
updates.push('description');
|
|
292
306
|
if (implementationPlan !== undefined)
|
|
@@ -321,10 +335,12 @@ server.registerTool('create_task', {
|
|
|
321
335
|
title: 'Create Task',
|
|
322
336
|
description: 'Create a new roadmap task. Use for importing from TODO files or creating work items.',
|
|
323
337
|
inputSchema: z.object({
|
|
324
|
-
title: z.string()
|
|
338
|
+
title: z.string().describe('Task title. Use verb prefix matching the type: ' +
|
|
339
|
+
'bug ā "Fix ā¦", feature ā "Add ā¦", improvement ā "Improve ā¦", task ā "Set up ā¦" / "Update ā¦"'),
|
|
325
340
|
description: z.string().optional(),
|
|
326
341
|
type: z.enum(['bug', 'feature', 'improvement', 'task']).optional().describe('Task type (default: feature)'),
|
|
327
|
-
status: z.enum(['planned', 'in_progress']).optional(),
|
|
342
|
+
status: z.enum(['planned', 'in_progress', 'done']).optional(),
|
|
343
|
+
priority: z.enum(['high', 'medium', 'low']).optional().describe('Task priority'),
|
|
328
344
|
implementationPlan: z.string().optional(),
|
|
329
345
|
isPublic: z.boolean().optional().describe('Whether task is visible on public roadmap (default: true)'),
|
|
330
346
|
}),
|
|
@@ -1160,6 +1176,40 @@ server.registerTool('get_feedback', {
|
|
|
1160
1176
|
structuredContent: f,
|
|
1161
1177
|
};
|
|
1162
1178
|
});
|
|
1179
|
+
// Tool: Update feedback
|
|
1180
|
+
server.registerTool('update_feedback', {
|
|
1181
|
+
title: 'Update Feedback',
|
|
1182
|
+
description: 'Update feedback status. Use to triage, close, or mark feedback as done.',
|
|
1183
|
+
inputSchema: z.object({
|
|
1184
|
+
feedbackId: z.string().describe('Feedback ID'),
|
|
1185
|
+
status: z
|
|
1186
|
+
.enum(['new', 'under_review', 'planned', 'in_progress', 'done', 'closed'])
|
|
1187
|
+
.describe('New status'),
|
|
1188
|
+
}),
|
|
1189
|
+
outputSchema: z.object({
|
|
1190
|
+
id: z.string(),
|
|
1191
|
+
title: z.string(),
|
|
1192
|
+
status: z.string(),
|
|
1193
|
+
type: z.string(),
|
|
1194
|
+
}),
|
|
1195
|
+
annotations: {
|
|
1196
|
+
readOnlyHint: false,
|
|
1197
|
+
destructiveHint: false,
|
|
1198
|
+
idempotentHint: true,
|
|
1199
|
+
openWorldHint: false,
|
|
1200
|
+
},
|
|
1201
|
+
}, async ({ feedbackId, status }) => {
|
|
1202
|
+
const result = await api('PATCH', `/api/agent/feedback/${feedbackId}`, { status });
|
|
1203
|
+
return {
|
|
1204
|
+
content: [
|
|
1205
|
+
{
|
|
1206
|
+
type: 'text',
|
|
1207
|
+
text: `Updated feedback "${result.title}" ā ${result.status}`,
|
|
1208
|
+
},
|
|
1209
|
+
],
|
|
1210
|
+
structuredContent: result,
|
|
1211
|
+
};
|
|
1212
|
+
});
|
|
1163
1213
|
// ==================== Issue Reporting ====================
|
|
1164
1214
|
// Tool: Report issue
|
|
1165
1215
|
server.registerTool('report_issue', {
|
|
@@ -1658,16 +1708,16 @@ server.registerTool('update_changelog', {
|
|
|
1658
1708
|
structuredContent: result,
|
|
1659
1709
|
};
|
|
1660
1710
|
});
|
|
1661
|
-
// Tool: Add
|
|
1711
|
+
// Tool: Add tasks to changelog
|
|
1662
1712
|
server.registerTool('add_to_changelog', {
|
|
1663
1713
|
title: 'Add to Changelog',
|
|
1664
|
-
description: 'Add completed
|
|
1714
|
+
description: 'Add completed tasks to a changelog. Links the tasks and appends formatted entries to content.\n\n' +
|
|
1665
1715
|
'**When to use:**\n' +
|
|
1666
|
-
'- After completing multiple
|
|
1667
|
-
'- To manually add
|
|
1716
|
+
'- After completing multiple tasks that should be in one release\n' +
|
|
1717
|
+
'- To manually add tasks to a draft changelog',
|
|
1668
1718
|
inputSchema: z.object({
|
|
1669
1719
|
changelogId: z.string().describe('Changelog ID'),
|
|
1670
|
-
|
|
1720
|
+
taskIds: z.array(z.string()).describe('Task IDs to add'),
|
|
1671
1721
|
}),
|
|
1672
1722
|
outputSchema: z.object({
|
|
1673
1723
|
id: z.string(),
|
|
@@ -1684,8 +1734,8 @@ server.registerTool('add_to_changelog', {
|
|
|
1684
1734
|
idempotentHint: true,
|
|
1685
1735
|
openWorldHint: false,
|
|
1686
1736
|
},
|
|
1687
|
-
}, async ({ changelogId,
|
|
1688
|
-
const result = await api('POST', `/api/agent/changelogs/${changelogId}/items`, { roadmapItemIds });
|
|
1737
|
+
}, async ({ changelogId, taskIds }) => {
|
|
1738
|
+
const result = await api('POST', `/api/agent/changelogs/${changelogId}/items`, { roadmapItemIds: taskIds });
|
|
1689
1739
|
const addedTitles = result.addedItems.map((i) => i.title).join(', ');
|
|
1690
1740
|
return {
|
|
1691
1741
|
content: [{ type: 'text', text: `š Added ${result.addedItems.length} items to "${result.title}": ${addedTitles}` }],
|