@damper/mcp 0.1.8 → 0.1.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/README.md +6 -2
- package/dist/index.js +24 -8
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -71,10 +71,10 @@ The AI will see tools from both servers and can distinguish between them:
|
|
|
71
71
|
|
|
72
72
|
| Tool | Description |
|
|
73
73
|
|------|-------------|
|
|
74
|
-
| `list_tasks` | Get roadmap tasks (filter by `status`, `type`) |
|
|
74
|
+
| `list_tasks` | Get roadmap tasks (filter by `status`, `type`, `quarter`) |
|
|
75
75
|
| `get_task` | Task details + subtasks + linked feedback |
|
|
76
76
|
| `create_task` | Create task with type (bug, feature, improvement, task) |
|
|
77
|
-
| `update_task` | Update description, plan, priority, effort, labels |
|
|
77
|
+
| `update_task` | Update description, plan, priority, effort, quarter, labels |
|
|
78
78
|
| `start_task` | Lock and start task (use `force` to take over) |
|
|
79
79
|
| `add_note` | Add progress note |
|
|
80
80
|
| `create_subtask` | Add subtask to a task |
|
|
@@ -102,6 +102,7 @@ Tasks include project management fields visible in `list_tasks` and `get_task`:
|
|
|
102
102
|
|
|
103
103
|
- **Priority**: high 🔴, medium 🟡, low ⚪
|
|
104
104
|
- **Effort**: xs, s, m, l, xl
|
|
105
|
+
- **Quarter**: Target quarter (Q1 2025, Q2 2025, etc.)
|
|
105
106
|
- **Labels**: Custom tags
|
|
106
107
|
- **Due date**: Target completion date
|
|
107
108
|
|
|
@@ -114,6 +115,7 @@ Refine task details as you work:
|
|
|
114
115
|
> Update the implementation plan with what I've learned
|
|
115
116
|
> Add labels: backend, api, auth
|
|
116
117
|
> Set effort to medium
|
|
118
|
+
> Schedule this for Q2 2025
|
|
117
119
|
```
|
|
118
120
|
|
|
119
121
|
### Subtasks
|
|
@@ -148,6 +150,8 @@ When you start a task, it's locked to prevent other agents from working on it si
|
|
|
148
150
|
```
|
|
149
151
|
> What tasks are available?
|
|
150
152
|
> List bugs I can fix
|
|
153
|
+
> Show tasks for Q2 2025
|
|
154
|
+
> What's unscheduled? (quarter: none)
|
|
151
155
|
> Import my TODO.md into Damper
|
|
152
156
|
> Work on the dark mode feature
|
|
153
157
|
> Show me the subtasks for this task
|
package/dist/index.js
CHANGED
|
@@ -34,7 +34,7 @@ async function api(method, path, body) {
|
|
|
34
34
|
// Server
|
|
35
35
|
const server = new McpServer({
|
|
36
36
|
name: 'damper',
|
|
37
|
-
version: '0.1.
|
|
37
|
+
version: '0.1.10',
|
|
38
38
|
});
|
|
39
39
|
// Output schemas
|
|
40
40
|
const SubtaskProgressSchema = z.object({
|
|
@@ -48,6 +48,7 @@ const TaskSummarySchema = z.object({
|
|
|
48
48
|
status: z.string(),
|
|
49
49
|
priority: z.string(),
|
|
50
50
|
effort: z.string().nullable().optional(),
|
|
51
|
+
quarter: z.string().nullable().optional(),
|
|
51
52
|
labels: z.array(z.string()).optional(),
|
|
52
53
|
dueDate: z.string().nullable().optional(),
|
|
53
54
|
feedbackCount: z.number(),
|
|
@@ -68,6 +69,7 @@ const TaskDetailSchema = z.object({
|
|
|
68
69
|
status: z.string(),
|
|
69
70
|
priority: z.string().nullable().optional(),
|
|
70
71
|
effort: z.string().nullable().optional(),
|
|
72
|
+
quarter: z.string().nullable().optional(),
|
|
71
73
|
labels: z.array(z.string()).optional(),
|
|
72
74
|
dueDate: z.string().nullable().optional(),
|
|
73
75
|
voteScore: z.number(),
|
|
@@ -102,10 +104,11 @@ const FeedbackDetailSchema = z.object({
|
|
|
102
104
|
server.registerTool('list_tasks', {
|
|
103
105
|
title: 'List Tasks',
|
|
104
106
|
description: 'Get roadmap tasks. Returns planned/in-progress by default. ' +
|
|
105
|
-
'Filter by type
|
|
107
|
+
'Filter by type, quarter, etc.',
|
|
106
108
|
inputSchema: z.object({
|
|
107
109
|
status: z.enum(['planned', 'in_progress', 'done', 'all']).optional(),
|
|
108
110
|
type: z.enum(['bug', 'feature', 'improvement', 'task']).optional().describe('Filter by task type'),
|
|
111
|
+
quarter: z.string().optional().describe('Filter by quarter (e.g., "Q1 2025") or "none" for unscheduled'),
|
|
109
112
|
limit: z.number().optional(),
|
|
110
113
|
}),
|
|
111
114
|
outputSchema: z.object({
|
|
@@ -118,19 +121,22 @@ server.registerTool('list_tasks', {
|
|
|
118
121
|
idempotentHint: true,
|
|
119
122
|
openWorldHint: false,
|
|
120
123
|
},
|
|
121
|
-
}, async ({ status, type, limit }) => {
|
|
124
|
+
}, async ({ status, type, quarter, limit }) => {
|
|
122
125
|
const params = new URLSearchParams();
|
|
123
126
|
if (status)
|
|
124
127
|
params.set('status', status);
|
|
125
128
|
if (type)
|
|
126
129
|
params.set('type', type);
|
|
130
|
+
if (quarter)
|
|
131
|
+
params.set('quarter', quarter);
|
|
127
132
|
if (limit)
|
|
128
133
|
params.set('limit', String(limit));
|
|
129
134
|
const query = params.toString();
|
|
130
135
|
const data = await api('GET', `/api/agent/tasks${query ? `?${query}` : ''}`);
|
|
131
136
|
if (!data.tasks.length) {
|
|
137
|
+
const filters = [type && `type: ${type}`, quarter && `quarter: ${quarter}`].filter(Boolean).join(', ');
|
|
132
138
|
return {
|
|
133
|
-
content: [{ type: 'text', text: `No tasks in "${data.project.name}"${
|
|
139
|
+
content: [{ type: 'text', text: `No tasks in "${data.project.name}"${filters ? ` (${filters})` : ''}` }],
|
|
134
140
|
structuredContent: { project: data.project.name, tasks: [] },
|
|
135
141
|
};
|
|
136
142
|
}
|
|
@@ -138,7 +144,8 @@ server.registerTool('list_tasks', {
|
|
|
138
144
|
const p = t.priority === 'high' ? '🔴' : t.priority === 'medium' ? '🟡' : '⚪';
|
|
139
145
|
const typeIcon = t.type === 'bug' ? '🐛' : t.type === 'feature' ? '✨' : t.type === 'improvement' ? '💡' : '📌';
|
|
140
146
|
const subtaskInfo = t.subtaskProgress ? ` [${t.subtaskProgress.done}/${t.subtaskProgress.total}]` : '';
|
|
141
|
-
|
|
147
|
+
const quarterInfo = t.quarter ? ` 📅${t.quarter}` : '';
|
|
148
|
+
return `• ${t.id}: ${typeIcon} ${t.title} [${t.status}] ${p}${quarterInfo}${t.hasImplementationPlan ? ' 📋' : ''}${subtaskInfo}`;
|
|
142
149
|
});
|
|
143
150
|
return {
|
|
144
151
|
content: [{ type: 'text', text: `Tasks in "${data.project.name}":\n${lines.join('\n')}` }],
|
|
@@ -166,12 +173,14 @@ server.registerTool('get_task', {
|
|
|
166
173
|
`# ${typeIcon} ${t.title}`,
|
|
167
174
|
`Type: ${t.type} | Status: ${t.status} | Score: ${t.voteScore}`,
|
|
168
175
|
];
|
|
169
|
-
// Add priority/effort/labels if present
|
|
176
|
+
// Add priority/effort/quarter/labels if present
|
|
170
177
|
const meta = [];
|
|
171
178
|
if (t.priority)
|
|
172
179
|
meta.push(`Priority: ${t.priority}`);
|
|
173
180
|
if (t.effort)
|
|
174
181
|
meta.push(`Effort: ${t.effort}`);
|
|
182
|
+
if (t.quarter)
|
|
183
|
+
meta.push(`Quarter: ${t.quarter}`);
|
|
175
184
|
if (t.dueDate)
|
|
176
185
|
meta.push(`Due: ${t.dueDate}`);
|
|
177
186
|
if (t.labels && t.labels.length)
|
|
@@ -202,7 +211,7 @@ server.registerTool('get_task', {
|
|
|
202
211
|
// Tool: Update task
|
|
203
212
|
server.registerTool('update_task', {
|
|
204
213
|
title: 'Update Task',
|
|
205
|
-
description: 'Update task fields like description, implementation plan, priority, effort, or labels. ' +
|
|
214
|
+
description: 'Update task fields like description, implementation plan, priority, effort, quarter, or labels. ' +
|
|
206
215
|
'Useful for refining task details as you learn more about the work.',
|
|
207
216
|
inputSchema: z.object({
|
|
208
217
|
taskId: z.string().describe('Task ID'),
|
|
@@ -210,6 +219,7 @@ server.registerTool('update_task', {
|
|
|
210
219
|
implementationPlan: z.string().optional().describe('Implementation plan (markdown)'),
|
|
211
220
|
priority: z.enum(['high', 'medium', 'low']).nullable().optional().describe('Task priority'),
|
|
212
221
|
effort: z.enum(['xs', 's', 'm', 'l', 'xl']).nullable().optional().describe('Estimated effort'),
|
|
222
|
+
quarter: z.string().nullable().optional().describe('Target quarter (e.g., "Q1 2025", "Q2 2025")'),
|
|
213
223
|
labels: z.array(z.string()).optional().describe('Labels/tags'),
|
|
214
224
|
}),
|
|
215
225
|
outputSchema: z.object({
|
|
@@ -219,6 +229,7 @@ server.registerTool('update_task', {
|
|
|
219
229
|
implementationPlan: z.string().nullable().optional(),
|
|
220
230
|
priority: z.string().nullable().optional(),
|
|
221
231
|
effort: z.string().nullable().optional(),
|
|
232
|
+
quarter: z.string().nullable().optional(),
|
|
222
233
|
labels: z.array(z.string()).optional(),
|
|
223
234
|
}),
|
|
224
235
|
annotations: {
|
|
@@ -227,7 +238,7 @@ server.registerTool('update_task', {
|
|
|
227
238
|
idempotentHint: true,
|
|
228
239
|
openWorldHint: false,
|
|
229
240
|
},
|
|
230
|
-
}, async ({ taskId, description, implementationPlan, priority, effort, labels }) => {
|
|
241
|
+
}, async ({ taskId, description, implementationPlan, priority, effort, quarter, labels }) => {
|
|
231
242
|
const body = {};
|
|
232
243
|
if (description !== undefined)
|
|
233
244
|
body.description = description;
|
|
@@ -237,6 +248,8 @@ server.registerTool('update_task', {
|
|
|
237
248
|
body.priority = priority;
|
|
238
249
|
if (effort !== undefined)
|
|
239
250
|
body.effort = effort;
|
|
251
|
+
if (quarter !== undefined)
|
|
252
|
+
body.quarter = quarter;
|
|
240
253
|
if (labels !== undefined)
|
|
241
254
|
body.labels = labels;
|
|
242
255
|
const result = await api('PATCH', `/api/agent/tasks/${taskId}`, body);
|
|
@@ -249,6 +262,8 @@ server.registerTool('update_task', {
|
|
|
249
262
|
updates.push(`priority=${priority || 'none'}`);
|
|
250
263
|
if (effort !== undefined)
|
|
251
264
|
updates.push(`effort=${effort || 'none'}`);
|
|
265
|
+
if (quarter !== undefined)
|
|
266
|
+
updates.push(`quarter=${quarter || 'none'}`);
|
|
252
267
|
if (labels !== undefined)
|
|
253
268
|
updates.push(`labels=[${labels.join(', ')}]`);
|
|
254
269
|
return {
|
|
@@ -260,6 +275,7 @@ server.registerTool('update_task', {
|
|
|
260
275
|
implementationPlan: result.implementationPlan,
|
|
261
276
|
priority: result.priority,
|
|
262
277
|
effort: result.effort,
|
|
278
|
+
quarter: result.quarter,
|
|
263
279
|
labels: result.labels,
|
|
264
280
|
},
|
|
265
281
|
};
|