Skip to content

Commit aa090e9

Browse files
committed
feat: add listDevlogNotes method and schema for retrieving devlog notes
1 parent 6efad2b commit aa090e9

File tree

4 files changed

+88
-39
lines changed

4 files changed

+88
-39
lines changed

packages/mcp/src/adapters/mcp-adapter.ts

Lines changed: 39 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import type {
1717
GetCurrentProjectArgs,
1818
GetDevlogArgs,
1919
ListDevlogArgs,
20+
ListDevlogNotesArgs,
2021
ListProjectsArgs,
2122
SwitchProjectArgs,
2223
UpdateDevlogArgs,
@@ -197,19 +198,10 @@ export class MCPAdapter {
197198

198199
// Handle update with optional note
199200
if (args.note) {
200-
// Then add the note
201201
await this.apiClient.addDevlogNote(args.id, args.note.content, args.note.category);
202-
203-
return this.toStandardResponse(true, { id: args.id }, `Updated entry ${args.id} with note`);
204-
} else {
205-
// Regular update without note
206-
const entry = await this.apiClient.updateDevlog(args.id, {
207-
status: args.status,
208-
priority: args.priority,
209-
});
210-
211-
return this.toStandardResponse(true, { id: args.id }, `Updated entry ${args.id}`);
212202
}
203+
204+
return this.toStandardResponse(true, { id: args.id }, `Updated entry ${args.id}`);
213205
} catch (error) {
214206
return this.handleError('Failed to update entry', error);
215207
}
@@ -242,22 +234,6 @@ export class MCPAdapter {
242234
}
243235
}
244236

245-
async addDevlogNote(args: AddDevlogNoteArgs): Promise<CallToolResult> {
246-
await this.ensureInitialized();
247-
248-
try {
249-
await this.apiClient.addDevlogNote(args.id, args.content, args.category);
250-
251-
return this.toStandardResponse(
252-
true,
253-
{ id: args.id },
254-
`Added ${args.category} note to entry ${args.id}`,
255-
);
256-
} catch (error) {
257-
return this.handleError('Failed to add note', error);
258-
}
259-
}
260-
261237
async findRelatedDevlogs(args: FindRelatedDevlogsArgs): Promise<CallToolResult> {
262238
await this.ensureInitialized();
263239

@@ -294,6 +270,42 @@ export class MCPAdapter {
294270
}
295271
}
296272

273+
async addDevlogNote(args: AddDevlogNoteArgs): Promise<CallToolResult> {
274+
await this.ensureInitialized();
275+
276+
try {
277+
await this.apiClient.addDevlogNote(args.id, args.content, args.category);
278+
279+
return this.toStandardResponse(
280+
true,
281+
{ id: args.id },
282+
`Added ${args.category} note to entry ${args.id}`,
283+
);
284+
} catch (error) {
285+
return this.handleError('Failed to add note', error);
286+
}
287+
}
288+
289+
async listDevlogNotes(args: ListDevlogNotesArgs): Promise<CallToolResult> {
290+
await this.ensureInitialized();
291+
292+
try {
293+
const result = await this.apiClient.listDevlogNotes(args.id, args.category, args.limit);
294+
295+
return this.toStandardResponse(
296+
true,
297+
{
298+
devlogId: args.id,
299+
total: result.total,
300+
notes: result.notes,
301+
},
302+
`Found ${result.notes.length} notes for devlog ${args.id}`,
303+
);
304+
} catch (error) {
305+
return this.handleError('Failed to list notes', error);
306+
}
307+
}
308+
297309
// === PROJECT OPERATIONS ===
298310

299311
async listProjects(args: ListProjectsArgs): Promise<CallToolResult> {

packages/mcp/src/api/devlog-api-client.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import type {
77
CreateDevlogRequest,
88
DevlogEntry,
99
DevlogFilter,
10+
DevlogNote,
11+
DevlogNoteCategory,
1012
PaginatedResult,
1113
PaginationMeta,
1214
SortOptions,
@@ -286,6 +288,23 @@ export class DevlogApiClient {
286288
return this.unwrapApiResponse<DevlogEntry>(response);
287289
}
288290

291+
async listDevlogNotes(
292+
devlogId: number,
293+
category?: DevlogNoteCategory,
294+
limit?: number,
295+
): Promise<{ devlogId: number; total: number; notes: DevlogNote[] }> {
296+
const params = new URLSearchParams();
297+
298+
if (category) params.append('category', category);
299+
if (limit) params.append('limit', limit.toString());
300+
301+
const query = params.toString() ? `?${params.toString()}` : '';
302+
const response = await this.get(
303+
`${this.getProjectEndpoint()}/devlogs/${devlogId}/notes${query}`,
304+
);
305+
return this.unwrapApiResponse(response);
306+
}
307+
289308
// Health check
290309
async healthCheck(): Promise<{ status: string; timestamp: string }> {
291310
try {

packages/mcp/src/handlers/tool-handlers.ts

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ import {
1616
type GetDevlogArgs,
1717
GetDevlogSchema,
1818
type ListDevlogArgs,
19+
ListDevlogNotesArgs,
20+
ListDevlogNotesSchema,
1921
ListDevlogSchema,
2022
type ListProjectsArgs,
2123
ListProjectsSchema,
@@ -75,6 +77,14 @@ export const toolHandlers = {
7577
adapter.listDevlogs(validArgs),
7678
),
7779

80+
find_related_devlogs: (adapter: MCPAdapter, args: unknown) =>
81+
validateAndHandle<FindRelatedDevlogsArgs>(
82+
FindRelatedDevlogsSchema,
83+
args,
84+
'find_related_devlogs',
85+
(validArgs) => adapter.findRelatedDevlogs(validArgs),
86+
),
87+
7888
add_devlog_note: (adapter: MCPAdapter, args: unknown) =>
7989
validateAndHandle<AddDevlogNoteArgs>(
8090
AddDevlogNoteSchema,
@@ -83,12 +93,12 @@ export const toolHandlers = {
8393
(validArgs) => adapter.addDevlogNote(validArgs),
8494
),
8595

86-
find_related_devlogs: (adapter: MCPAdapter, args: unknown) =>
87-
validateAndHandle<FindRelatedDevlogsArgs>(
88-
FindRelatedDevlogsSchema,
96+
list_devlog_notes: (adapter: MCPAdapter, args: unknown) =>
97+
validateAndHandle<ListDevlogNotesArgs>(
98+
ListDevlogNotesSchema,
8999
args,
90-
'find_related_devlogs',
91-
(validArgs) => adapter.findRelatedDevlogs(validArgs),
100+
'list_devlog_notes',
101+
(validArgs) => adapter.listDevlogNotes(validArgs),
92102
),
93103

94104
// Project operations

packages/mcp/src/schemas/devlog-schemas.ts

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ export const UpdateDevlogSchema = z.object({
5454
.optional(),
5555
});
5656

57-
// === LIST/SEARCH DEVLOGS ===
57+
// === LIST DEVLOGS ===
5858
export const ListDevlogSchema = z.object({
5959
status: DevlogStatusSchema.optional(),
6060
type: DevlogTypeSchema.optional(),
@@ -65,18 +65,25 @@ export const ListDevlogSchema = z.object({
6565
sortOrder: SortOrderSchema,
6666
});
6767

68+
// === FIND RELATED DEVLOGS ===
69+
export const FindRelatedDevlogsSchema = z.object({
70+
description: DescriptionSchema,
71+
type: DevlogTypeSchema.optional(),
72+
keywords: KeywordsSchema,
73+
limit: LimitSchema,
74+
});
75+
6876
// === ADD DEVLOG NOTE ===
6977
export const AddDevlogNoteSchema = z.object({
7078
id: DevlogIdSchema,
7179
content: DevlogNoteContentSchema,
7280
category: DevlogNoteCategorySchema,
7381
});
7482

75-
// === FIND RELATED DEVLOGS ===
76-
export const FindRelatedDevlogsSchema = z.object({
77-
description: DescriptionSchema,
78-
type: DevlogTypeSchema.optional(),
79-
keywords: KeywordsSchema,
83+
// === LIST DEVLOG NOTES ===
84+
export const ListDevlogNotesSchema = z.object({
85+
id: DevlogIdSchema,
86+
category: DevlogNoteCategorySchema,
8087
limit: LimitSchema,
8188
});
8289

@@ -85,5 +92,6 @@ export type CreateDevlogArgs = z.infer<typeof CreateDevlogSchema>;
8592
export type GetDevlogArgs = z.infer<typeof GetDevlogSchema>;
8693
export type UpdateDevlogArgs = z.infer<typeof UpdateDevlogSchema>;
8794
export type ListDevlogArgs = z.infer<typeof ListDevlogSchema>;
88-
export type AddDevlogNoteArgs = z.infer<typeof AddDevlogNoteSchema>;
8995
export type FindRelatedDevlogsArgs = z.infer<typeof FindRelatedDevlogsSchema>;
96+
export type AddDevlogNoteArgs = z.infer<typeof AddDevlogNoteSchema>;
97+
export type ListDevlogNotesArgs = z.infer<typeof ListDevlogNotesSchema>;

0 commit comments

Comments
 (0)