@damper/mcp 0.3.10 → 0.3.12
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 +225 -7
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -644,6 +644,7 @@ server.registerTool('get_agent_instructions', {
|
|
|
644
644
|
outputSchema: z.object({
|
|
645
645
|
format: z.enum(['markdown', 'section']),
|
|
646
646
|
content: z.string(),
|
|
647
|
+
lastModified: z.string().describe('ISO date when instructions were last updated'),
|
|
647
648
|
}),
|
|
648
649
|
annotations: {
|
|
649
650
|
readOnlyHint: true,
|
|
@@ -652,8 +653,11 @@ server.registerTool('get_agent_instructions', {
|
|
|
652
653
|
openWorldHint: false,
|
|
653
654
|
},
|
|
654
655
|
}, async ({ format = 'section' }) => {
|
|
656
|
+
const lastModified = '2025-02-04';
|
|
655
657
|
const section = `## Task Management with Damper MCP
|
|
656
658
|
|
|
659
|
+
> Last updated: ${lastModified}
|
|
660
|
+
|
|
657
661
|
This project uses Damper MCP for task tracking. **You MUST follow this workflow.**
|
|
658
662
|
|
|
659
663
|
### At Session Start (MANDATORY)
|
|
@@ -668,6 +672,13 @@ This project uses Damper MCP for task tracking. **You MUST follow this workflow.
|
|
|
668
672
|
- \`update_subtask\` to mark subtask progress
|
|
669
673
|
- **Follow patterns from project context** - Don't reinvent; use existing conventions
|
|
670
674
|
|
|
675
|
+
### Feedback & Changelog Integration
|
|
676
|
+
- \`link_feedback_to_task\` - Link user feedback IDs to your task (helps track what customer requests led to the feature)
|
|
677
|
+
- When completing a **public** task, it auto-adds to the project's draft changelog
|
|
678
|
+
- \`list_changelogs\` - View existing changelogs and drafts
|
|
679
|
+
- \`create_changelog\` / \`update_changelog\` - Create or edit changelog entries
|
|
680
|
+
- \`add_to_changelog\` - Manually add completed tasks to a changelog
|
|
681
|
+
|
|
671
682
|
### At Session End (MANDATORY)
|
|
672
683
|
- ALWAYS call \`add_note\` with session summary before stopping
|
|
673
684
|
- ALWAYS call \`complete_task\` (if done) or \`abandon_task\` (if stopping early)
|
|
@@ -678,16 +689,17 @@ This project uses Damper MCP for task tracking. **You MUST follow this workflow.
|
|
|
678
689
|
- **Project context prevents mistakes** - Contains architecture decisions, gotchas, and patterns
|
|
679
690
|
- Locked tasks block other agents from working on them
|
|
680
691
|
- Commits and notes help the next agent continue the work
|
|
681
|
-
- Updating context saves future agents from re-analyzing the codebase
|
|
692
|
+
- Updating context saves future agents from re-analyzing the codebase
|
|
693
|
+
- Linking feedback connects customer requests to shipped features`;
|
|
682
694
|
if (format === 'markdown') {
|
|
683
695
|
return {
|
|
684
696
|
content: [{ type: 'text', text: `# CLAUDE.md\n\n${section}` }],
|
|
685
|
-
structuredContent: { format: 'markdown', content: `# CLAUDE.md\n\n${section}
|
|
697
|
+
structuredContent: { format: 'markdown', content: `# CLAUDE.md\n\n${section}`, lastModified },
|
|
686
698
|
};
|
|
687
699
|
}
|
|
688
700
|
return {
|
|
689
701
|
content: [{ type: 'text', text: section }],
|
|
690
|
-
structuredContent: { format: 'section', content: section },
|
|
702
|
+
structuredContent: { format: 'section', content: section, lastModified },
|
|
691
703
|
};
|
|
692
704
|
});
|
|
693
705
|
// ==================== Context Tools ====================
|
|
@@ -767,9 +779,12 @@ server.registerTool('get_context_section', {
|
|
|
767
779
|
openWorldHint: false,
|
|
768
780
|
},
|
|
769
781
|
}, async ({ section }) => {
|
|
770
|
-
// Encode
|
|
771
|
-
// issues with some proxies/CDNs that interpret * as a wildcard
|
|
772
|
-
const encodedSection =
|
|
782
|
+
// Encode each path segment individually but preserve slashes for hierarchical sections
|
|
783
|
+
// Also encode * which can cause issues with some proxies/CDNs that interpret * as a wildcard
|
|
784
|
+
const encodedSection = section
|
|
785
|
+
.split('/')
|
|
786
|
+
.map(part => encodeURIComponent(part).replace(/\*/g, '%2A'))
|
|
787
|
+
.join('/');
|
|
773
788
|
const data = await api('GET', `/api/agent/context/${encodedSection}`);
|
|
774
789
|
// Handle glob pattern response (multiple sections)
|
|
775
790
|
if (data.pattern && data.sections) {
|
|
@@ -859,7 +874,11 @@ server.registerTool('delete_context_section', {
|
|
|
859
874
|
openWorldHint: false,
|
|
860
875
|
},
|
|
861
876
|
}, async ({ section }) => {
|
|
862
|
-
|
|
877
|
+
// Encode each path segment individually but preserve slashes
|
|
878
|
+
const encodedSection = section
|
|
879
|
+
.split('/')
|
|
880
|
+
.map(part => encodeURIComponent(part).replace(/\*/g, '%2A'))
|
|
881
|
+
.join('/');
|
|
863
882
|
const result = await api('DELETE', `/api/agent/context/${encodedSection}`);
|
|
864
883
|
return {
|
|
865
884
|
content: [{ type: 'text', text: `🗑️ Deleted context section: ${result.section}` }],
|
|
@@ -1366,6 +1385,205 @@ server.registerTool('sync_modules', {
|
|
|
1366
1385
|
structuredContent: result,
|
|
1367
1386
|
};
|
|
1368
1387
|
});
|
|
1388
|
+
// ==================== Changelog Tools ====================
|
|
1389
|
+
// Tool: Link feedback to task
|
|
1390
|
+
server.registerTool('link_feedback_to_task', {
|
|
1391
|
+
title: 'Link Feedback to Task',
|
|
1392
|
+
description: 'Link feedback items to a roadmap task. Links the specified feedback IDs to the task.\n\n' +
|
|
1393
|
+
'**When to use:**\n' +
|
|
1394
|
+
'- After seeing relevant feedback in `list_feedback`\n' +
|
|
1395
|
+
'- When user mentions feedback that should be tracked with a task',
|
|
1396
|
+
inputSchema: z.object({
|
|
1397
|
+
taskId: z.string().describe('Task ID to link feedback to'),
|
|
1398
|
+
feedbackIds: z.array(z.string()).describe('Feedback IDs to link'),
|
|
1399
|
+
}),
|
|
1400
|
+
outputSchema: z.object({
|
|
1401
|
+
taskId: z.string(),
|
|
1402
|
+
linkedFeedbackIds: z.array(z.string()),
|
|
1403
|
+
totalLinkedFeedback: z.number(),
|
|
1404
|
+
feedbackTitles: z.array(z.string()),
|
|
1405
|
+
}),
|
|
1406
|
+
annotations: {
|
|
1407
|
+
readOnlyHint: false,
|
|
1408
|
+
destructiveHint: false,
|
|
1409
|
+
idempotentHint: true,
|
|
1410
|
+
openWorldHint: false,
|
|
1411
|
+
},
|
|
1412
|
+
}, async ({ taskId, feedbackIds }) => {
|
|
1413
|
+
const result = await api('POST', `/api/agent/tasks/${taskId}/feedback`, { feedbackIds });
|
|
1414
|
+
const linkedCount = result.linkedFeedbackIds.length;
|
|
1415
|
+
if (linkedCount === 0) {
|
|
1416
|
+
return {
|
|
1417
|
+
content: [{ type: 'text', text: `No new feedback linked (already linked or not found)` }],
|
|
1418
|
+
structuredContent: result,
|
|
1419
|
+
};
|
|
1420
|
+
}
|
|
1421
|
+
return {
|
|
1422
|
+
content: [{ type: 'text', text: `🔗 Linked ${linkedCount} feedback to task: ${result.feedbackTitles.join(', ')}` }],
|
|
1423
|
+
structuredContent: result,
|
|
1424
|
+
};
|
|
1425
|
+
});
|
|
1426
|
+
// Tool: List changelogs
|
|
1427
|
+
server.registerTool('list_changelogs', {
|
|
1428
|
+
title: 'List Changelogs',
|
|
1429
|
+
description: 'List changelogs for the project. Filter by status (draft, published).\n\n' +
|
|
1430
|
+
'**Draft changelogs:** Automatically created when completing public roadmap items. ' +
|
|
1431
|
+
'Review and publish them to announce releases.',
|
|
1432
|
+
inputSchema: z.object({
|
|
1433
|
+
status: z.enum(['draft', 'published']).optional().describe('Filter by status'),
|
|
1434
|
+
limit: z.number().optional(),
|
|
1435
|
+
}),
|
|
1436
|
+
outputSchema: z.object({
|
|
1437
|
+
changelogs: z.array(z.object({
|
|
1438
|
+
id: z.string(),
|
|
1439
|
+
title: z.string(),
|
|
1440
|
+
version: z.string().nullable().optional(),
|
|
1441
|
+
status: z.string(),
|
|
1442
|
+
publishedAt: z.string().nullable().optional(),
|
|
1443
|
+
roadmapItemCount: z.number(),
|
|
1444
|
+
contentPreview: z.string(),
|
|
1445
|
+
})),
|
|
1446
|
+
}),
|
|
1447
|
+
annotations: {
|
|
1448
|
+
readOnlyHint: true,
|
|
1449
|
+
destructiveHint: false,
|
|
1450
|
+
idempotentHint: true,
|
|
1451
|
+
openWorldHint: false,
|
|
1452
|
+
},
|
|
1453
|
+
}, async ({ status, limit }) => {
|
|
1454
|
+
const params = new URLSearchParams();
|
|
1455
|
+
if (status)
|
|
1456
|
+
params.set('status', status);
|
|
1457
|
+
if (limit)
|
|
1458
|
+
params.set('limit', String(limit));
|
|
1459
|
+
const query = params.toString();
|
|
1460
|
+
const data = await api('GET', `/api/agent/changelogs${query ? `?${query}` : ''}`);
|
|
1461
|
+
if (!data.changelogs.length) {
|
|
1462
|
+
return {
|
|
1463
|
+
content: [{ type: 'text', text: 'No changelogs found' }],
|
|
1464
|
+
structuredContent: { changelogs: [] },
|
|
1465
|
+
};
|
|
1466
|
+
}
|
|
1467
|
+
const lines = data.changelogs.map((c) => {
|
|
1468
|
+
const status = c.status === 'draft' ? '📝' : '✅';
|
|
1469
|
+
const version = c.version ? ` v${c.version}` : '';
|
|
1470
|
+
const items = c.roadmapItemCount > 0 ? ` (${c.roadmapItemCount} items)` : '';
|
|
1471
|
+
return `• ${c.id}: ${status} ${c.title}${version}${items}`;
|
|
1472
|
+
});
|
|
1473
|
+
return {
|
|
1474
|
+
content: [{ type: 'text', text: `Changelogs:\n${lines.join('\n')}` }],
|
|
1475
|
+
structuredContent: data,
|
|
1476
|
+
};
|
|
1477
|
+
});
|
|
1478
|
+
// Tool: Create changelog
|
|
1479
|
+
server.registerTool('create_changelog', {
|
|
1480
|
+
title: 'Create Changelog',
|
|
1481
|
+
description: 'Create a new changelog entry. Usually starts as draft.\n\n' +
|
|
1482
|
+
'**Note:** Draft changelogs are auto-created when completing public roadmap items. ' +
|
|
1483
|
+
'Use this to create additional changelogs if needed.',
|
|
1484
|
+
inputSchema: z.object({
|
|
1485
|
+
title: z.string().describe('Changelog title (e.g., "v2.1.0" or "January 2025 Release")'),
|
|
1486
|
+
content: z.string().optional().describe('Initial changelog content (markdown)'),
|
|
1487
|
+
version: z.string().optional().describe('Version number'),
|
|
1488
|
+
status: z.enum(['draft', 'published']).optional().describe('Status (default: draft)'),
|
|
1489
|
+
}),
|
|
1490
|
+
outputSchema: z.object({
|
|
1491
|
+
id: z.string(),
|
|
1492
|
+
title: z.string(),
|
|
1493
|
+
version: z.string().nullable().optional(),
|
|
1494
|
+
status: z.string(),
|
|
1495
|
+
}),
|
|
1496
|
+
annotations: {
|
|
1497
|
+
readOnlyHint: false,
|
|
1498
|
+
destructiveHint: false,
|
|
1499
|
+
idempotentHint: false,
|
|
1500
|
+
openWorldHint: false,
|
|
1501
|
+
},
|
|
1502
|
+
}, async (args) => {
|
|
1503
|
+
const result = await api('POST', '/api/agent/changelogs', args);
|
|
1504
|
+
const status = result.status === 'draft' ? '📝' : '✅';
|
|
1505
|
+
return {
|
|
1506
|
+
content: [{ type: 'text', text: `${status} Created changelog: ${result.id} "${result.title}"` }],
|
|
1507
|
+
structuredContent: result,
|
|
1508
|
+
};
|
|
1509
|
+
});
|
|
1510
|
+
// Tool: Update changelog
|
|
1511
|
+
server.registerTool('update_changelog', {
|
|
1512
|
+
title: 'Update Changelog',
|
|
1513
|
+
description: 'Update a changelog entry. Can update title, content, version, or status.\n\n' +
|
|
1514
|
+
'**Publishing:** Set status to "published" to make the changelog public.',
|
|
1515
|
+
inputSchema: z.object({
|
|
1516
|
+
changelogId: z.string().describe('Changelog ID'),
|
|
1517
|
+
title: z.string().optional().describe('New title'),
|
|
1518
|
+
content: z.string().optional().describe('New content (markdown)'),
|
|
1519
|
+
version: z.string().optional().describe('Version number'),
|
|
1520
|
+
status: z.enum(['draft', 'published']).optional().describe('Status'),
|
|
1521
|
+
}),
|
|
1522
|
+
outputSchema: z.object({
|
|
1523
|
+
id: z.string(),
|
|
1524
|
+
title: z.string(),
|
|
1525
|
+
version: z.string().nullable().optional(),
|
|
1526
|
+
status: z.string(),
|
|
1527
|
+
publishedAt: z.string().nullable().optional(),
|
|
1528
|
+
}),
|
|
1529
|
+
annotations: {
|
|
1530
|
+
readOnlyHint: false,
|
|
1531
|
+
destructiveHint: false,
|
|
1532
|
+
idempotentHint: true,
|
|
1533
|
+
openWorldHint: false,
|
|
1534
|
+
},
|
|
1535
|
+
}, async ({ changelogId, title, content, version, status }) => {
|
|
1536
|
+
const body = {};
|
|
1537
|
+
if (title !== undefined)
|
|
1538
|
+
body.title = title;
|
|
1539
|
+
if (content !== undefined)
|
|
1540
|
+
body.content = content;
|
|
1541
|
+
if (version !== undefined)
|
|
1542
|
+
body.version = version;
|
|
1543
|
+
if (status !== undefined)
|
|
1544
|
+
body.status = status;
|
|
1545
|
+
const result = await api('PATCH', `/api/agent/changelogs/${changelogId}`, body);
|
|
1546
|
+
const statusIcon = result.status === 'published' ? '✅' : '📝';
|
|
1547
|
+
const published = result.status === 'published' && result.publishedAt ? ' (just published)' : '';
|
|
1548
|
+
return {
|
|
1549
|
+
content: [{ type: 'text', text: `${statusIcon} Updated changelog: "${result.title}"${published}` }],
|
|
1550
|
+
structuredContent: result,
|
|
1551
|
+
};
|
|
1552
|
+
});
|
|
1553
|
+
// Tool: Add roadmap items to changelog
|
|
1554
|
+
server.registerTool('add_to_changelog', {
|
|
1555
|
+
title: 'Add to Changelog',
|
|
1556
|
+
description: 'Add completed roadmap items to a changelog. Links the items and appends formatted entries to content.\n\n' +
|
|
1557
|
+
'**When to use:**\n' +
|
|
1558
|
+
'- After completing multiple items that should be in one release\n' +
|
|
1559
|
+
'- To manually add items to a draft changelog',
|
|
1560
|
+
inputSchema: z.object({
|
|
1561
|
+
changelogId: z.string().describe('Changelog ID'),
|
|
1562
|
+
roadmapItemIds: z.array(z.string()).describe('Roadmap item IDs to add'),
|
|
1563
|
+
}),
|
|
1564
|
+
outputSchema: z.object({
|
|
1565
|
+
id: z.string(),
|
|
1566
|
+
title: z.string(),
|
|
1567
|
+
roadmapItemCount: z.number(),
|
|
1568
|
+
addedItems: z.array(z.object({
|
|
1569
|
+
id: z.string(),
|
|
1570
|
+
title: z.string(),
|
|
1571
|
+
})),
|
|
1572
|
+
}),
|
|
1573
|
+
annotations: {
|
|
1574
|
+
readOnlyHint: false,
|
|
1575
|
+
destructiveHint: false,
|
|
1576
|
+
idempotentHint: true,
|
|
1577
|
+
openWorldHint: false,
|
|
1578
|
+
},
|
|
1579
|
+
}, async ({ changelogId, roadmapItemIds }) => {
|
|
1580
|
+
const result = await api('POST', `/api/agent/changelogs/${changelogId}/items`, { roadmapItemIds });
|
|
1581
|
+
const addedTitles = result.addedItems.map((i) => i.title).join(', ');
|
|
1582
|
+
return {
|
|
1583
|
+
content: [{ type: 'text', text: `📋 Added ${result.addedItems.length} items to "${result.title}": ${addedTitles}` }],
|
|
1584
|
+
structuredContent: result,
|
|
1585
|
+
};
|
|
1586
|
+
});
|
|
1369
1587
|
// Start
|
|
1370
1588
|
async function main() {
|
|
1371
1589
|
const transport = new StdioServerTransport();
|