@damper/mcp 0.3.19 → 0.3.21

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/index.js +18 -6
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -111,16 +111,20 @@ server.registerTool('list_tasks', {
111
111
  title: 'List Tasks',
112
112
  description: 'Get roadmap tasks. Returns planned/in-progress by default. ' +
113
113
  'Filter by type, quarter, etc.\n\n' +
114
+ 'Returns up to 20 tasks by default. Response includes `total` count. ' +
115
+ 'If total > returned tasks, paginate with offset (e.g. offset=20 for page 2).\n\n' +
114
116
  '**Recommended:** Call `get_project_context` before starting work to understand codebase patterns.',
115
117
  inputSchema: z.object({
116
118
  status: z.enum(['planned', 'in_progress', 'done', 'all']).optional(),
117
119
  type: z.enum(['bug', 'feature', 'improvement', 'task']).optional().describe('Filter by task type'),
118
120
  quarter: z.string().optional().describe('Filter by quarter (e.g., "Q1 2025") or "none" for unscheduled'),
119
121
  sort: z.enum(['importance', 'newest', 'votes']).optional().describe('Sort order: importance (priority+votes, default), newest, or votes'),
120
- limit: z.number().optional(),
122
+ limit: z.number().optional().describe('Max tasks to return (default: 20)'),
123
+ offset: z.number().optional().describe('Skip first N tasks for pagination (default: 0)'),
121
124
  }),
122
125
  outputSchema: z.object({
123
126
  project: z.string(),
127
+ total: z.number(),
124
128
  tasks: z.array(TaskSummarySchema),
125
129
  }),
126
130
  annotations: {
@@ -129,7 +133,7 @@ server.registerTool('list_tasks', {
129
133
  idempotentHint: true,
130
134
  openWorldHint: false,
131
135
  },
132
- }, async ({ status, type, quarter, sort, limit }) => {
136
+ }, async ({ status, type, quarter, sort, limit, offset }) => {
133
137
  const params = new URLSearchParams();
134
138
  if (status)
135
139
  params.set('status', status);
@@ -141,13 +145,15 @@ server.registerTool('list_tasks', {
141
145
  params.set('sort', sort);
142
146
  if (limit)
143
147
  params.set('limit', String(limit));
148
+ if (offset)
149
+ params.set('offset', String(offset));
144
150
  const query = params.toString();
145
151
  const data = await api('GET', `/api/agent/tasks${query ? `?${query}` : ''}`);
146
152
  if (!data.tasks.length) {
147
153
  const filters = [type && `type: ${type}`, quarter && `quarter: ${quarter}`].filter(Boolean).join(', ');
148
154
  return {
149
155
  content: [{ type: 'text', text: `No tasks in "${data.project.name}"${filters ? ` (${filters})` : ''}` }],
150
- structuredContent: { project: data.project.name, tasks: [] },
156
+ structuredContent: { project: data.project.name, total: 0, tasks: [] },
151
157
  };
152
158
  }
153
159
  const lines = data.tasks.map((t) => {
@@ -157,15 +163,20 @@ server.registerTool('list_tasks', {
157
163
  const quarterInfo = t.quarter ? ` šŸ“…${t.quarter}` : '';
158
164
  return `• ${t.id}: ${typeIcon} ${t.title} [${t.status}] ${p}${quarterInfo}${t.hasImplementationPlan ? ' šŸ“‹' : ''}${subtaskInfo}`;
159
165
  });
166
+ const currentOffset = offset || 0;
167
+ const paginationInfo = data.total > currentOffset + data.tasks.length
168
+ ? `\nšŸ“„ Showing ${currentOffset + 1}–${currentOffset + data.tasks.length} of ${data.total}. Use offset=${currentOffset + data.tasks.length} to see more.`
169
+ : '';
160
170
  const output = [
161
- `Tasks in "${data.project.name}":`,
171
+ `Tasks in "${data.project.name}" (${data.total} total):`,
162
172
  lines.join('\n'),
173
+ paginationInfo,
163
174
  '',
164
175
  'šŸ’” **Tip:** Run `get_project_context` first to understand codebase patterns before starting work.',
165
176
  ].join('\n');
166
177
  return {
167
178
  content: [{ type: 'text', text: output }],
168
- structuredContent: { project: data.project.name, tasks: data.tasks },
179
+ structuredContent: { project: data.project.name, total: data.total, tasks: data.tasks },
169
180
  };
170
181
  });
171
182
  // Tool: Get task
@@ -326,7 +337,8 @@ server.registerTool('create_task', {
326
337
  title: 'Create Task',
327
338
  description: 'Create a new roadmap task. Use for importing from TODO files or creating work items.',
328
339
  inputSchema: z.object({
329
- title: z.string(),
340
+ title: z.string().describe('Task title. Use verb prefix matching the type: ' +
341
+ 'bug → "Fix …", feature → "Add …", improvement → "Improve …", task → "Set up …" / "Update …"'),
330
342
  description: z.string().optional(),
331
343
  type: z.enum(['bug', 'feature', 'improvement', 'task']).optional().describe('Task type (default: feature)'),
332
344
  status: z.enum(['planned', 'in_progress', 'done']).optional(),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@damper/mcp",
3
- "version": "0.3.19",
3
+ "version": "0.3.21",
4
4
  "description": "MCP server for Damper task management",
5
5
  "author": "Damper <hello@usedamper.com>",
6
6
  "repository": {