gyrus 0.1.0
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/LICENSE +21 -0
- package/README.md +273 -0
- package/package.json +78 -0
- package/src/commands/adr.ts +482 -0
- package/src/commands/doctor.ts +263 -0
- package/src/commands/init.ts +293 -0
- package/src/commands/knowledge.ts +446 -0
- package/src/commands/list.ts +51 -0
- package/src/commands/mcp.ts +94 -0
- package/src/commands/use.ts +65 -0
- package/src/config/index.ts +262 -0
- package/src/config/schema.ts +139 -0
- package/src/formatters/adr.ts +295 -0
- package/src/formatters/index.ts +44 -0
- package/src/formatters/knowledge.ts +282 -0
- package/src/formatters/workspace.ts +149 -0
- package/src/index.ts +153 -0
- package/src/operations/adr.ts +312 -0
- package/src/operations/index.ts +58 -0
- package/src/operations/knowledge.ts +324 -0
- package/src/operations/types.ts +199 -0
- package/src/operations/workspace.ts +108 -0
- package/src/server/mcp-stdio.ts +526 -0
- package/src/services/adr.ts +511 -0
- package/src/services/knowledge.ts +516 -0
- package/src/services/markdown.ts +155 -0
- package/src/services/workspace.ts +377 -0
- package/src/templates/knowledge/README.md +199 -0
- package/src/tools/adr-create.ts +99 -0
- package/src/tools/adr-list.ts +72 -0
- package/src/tools/adr-read.ts +54 -0
- package/src/tools/adr-search.ts +79 -0
- package/src/tools/adr-update.ts +95 -0
- package/src/tools/gyrus-list.ts +41 -0
- package/src/tools/gyrus-switch.ts +45 -0
- package/src/tools/index.ts +91 -0
- package/src/tools/knowledge-create.ts +75 -0
- package/src/tools/knowledge-list.ts +60 -0
- package/src/tools/knowledge-read.ts +62 -0
- package/src/tools/knowledge-search.ts +65 -0
- package/src/tools/knowledge-update.ts +76 -0
- package/src/types/index.ts +343 -0
- package/tsconfig.json +26 -0
|
@@ -0,0 +1,526 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Server configuration and setup
|
|
3
|
+
* Creates the MCP server instance with stdio transport
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
7
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
8
|
+
import { z } from "zod";
|
|
9
|
+
import { WorkspaceManager } from "../services/workspace.ts";
|
|
10
|
+
import {
|
|
11
|
+
gyrusListTool,
|
|
12
|
+
gyrusListSchema,
|
|
13
|
+
executeGyrusList,
|
|
14
|
+
gyrusSwitchTool,
|
|
15
|
+
gyrusSwitchSchema,
|
|
16
|
+
executeGyrusSwitch,
|
|
17
|
+
knowledgeListTool,
|
|
18
|
+
knowledgeListSchema,
|
|
19
|
+
executeKnowledgeList,
|
|
20
|
+
knowledgeReadTool,
|
|
21
|
+
knowledgeReadSchema,
|
|
22
|
+
executeKnowledgeRead,
|
|
23
|
+
knowledgeSearchTool,
|
|
24
|
+
knowledgeSearchSchema,
|
|
25
|
+
executeKnowledgeSearch,
|
|
26
|
+
knowledgeCreateTool,
|
|
27
|
+
knowledgeCreateSchema,
|
|
28
|
+
executeKnowledgeCreate,
|
|
29
|
+
knowledgeUpdateTool,
|
|
30
|
+
knowledgeUpdateSchema,
|
|
31
|
+
executeKnowledgeUpdate,
|
|
32
|
+
adrListTool,
|
|
33
|
+
adrListSchema,
|
|
34
|
+
executeAdrList,
|
|
35
|
+
adrReadTool,
|
|
36
|
+
adrReadSchema,
|
|
37
|
+
executeAdrRead,
|
|
38
|
+
adrSearchTool,
|
|
39
|
+
adrSearchSchema,
|
|
40
|
+
executeAdrSearch,
|
|
41
|
+
adrCreateTool,
|
|
42
|
+
adrCreateSchema,
|
|
43
|
+
executeAdrCreate,
|
|
44
|
+
adrUpdateTool,
|
|
45
|
+
adrUpdateSchema,
|
|
46
|
+
executeAdrUpdate,
|
|
47
|
+
} from "../tools/index.ts";
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Create and configure the MCP server
|
|
51
|
+
*/
|
|
52
|
+
export function createServer(manager: WorkspaceManager): McpServer {
|
|
53
|
+
const server = new McpServer({
|
|
54
|
+
name: "gyrus",
|
|
55
|
+
version: "0.1.0",
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
// =============================================================================
|
|
59
|
+
// Gyrus Workspace Tools
|
|
60
|
+
// =============================================================================
|
|
61
|
+
|
|
62
|
+
// Register gyrus_list tool
|
|
63
|
+
server.tool(gyrusListTool.name, gyrusListTool.description, {}, async () => {
|
|
64
|
+
const result = await executeGyrusList(manager, {});
|
|
65
|
+
return {
|
|
66
|
+
content: [{ type: "text", text: result }],
|
|
67
|
+
};
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
// Register gyrus_switch tool
|
|
71
|
+
server.tool(
|
|
72
|
+
gyrusSwitchTool.name,
|
|
73
|
+
gyrusSwitchTool.description,
|
|
74
|
+
{
|
|
75
|
+
name: z.string().describe("The name of the workspace to switch to"),
|
|
76
|
+
},
|
|
77
|
+
async (args) => {
|
|
78
|
+
const input = gyrusSwitchSchema.parse(args);
|
|
79
|
+
const result = await executeGyrusSwitch(manager, input);
|
|
80
|
+
return {
|
|
81
|
+
content: [{ type: "text", text: result }],
|
|
82
|
+
};
|
|
83
|
+
},
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
// =============================================================================
|
|
87
|
+
// Knowledge Tools
|
|
88
|
+
// =============================================================================
|
|
89
|
+
|
|
90
|
+
// Register knowledge_list tool
|
|
91
|
+
server.tool(
|
|
92
|
+
knowledgeListTool.name,
|
|
93
|
+
knowledgeListTool.description,
|
|
94
|
+
{
|
|
95
|
+
workspace: z
|
|
96
|
+
.string()
|
|
97
|
+
.optional()
|
|
98
|
+
.describe(
|
|
99
|
+
"Target workspace name. If not provided, uses the active workspace.",
|
|
100
|
+
),
|
|
101
|
+
category: z
|
|
102
|
+
.enum(["projects", "patterns", "tools", "gotchas", "decisions"])
|
|
103
|
+
.optional()
|
|
104
|
+
.describe("Filter by category folder"),
|
|
105
|
+
tags: z
|
|
106
|
+
.array(z.string())
|
|
107
|
+
.optional()
|
|
108
|
+
.describe("Filter by tags (matches notes with any of these tags)"),
|
|
109
|
+
},
|
|
110
|
+
async (args) => {
|
|
111
|
+
const input = knowledgeListSchema.parse(args);
|
|
112
|
+
const result = await executeKnowledgeList(manager, input);
|
|
113
|
+
return {
|
|
114
|
+
content: [{ type: "text", text: result }],
|
|
115
|
+
};
|
|
116
|
+
},
|
|
117
|
+
);
|
|
118
|
+
|
|
119
|
+
// Register knowledge_read tool
|
|
120
|
+
server.tool(
|
|
121
|
+
knowledgeReadTool.name,
|
|
122
|
+
knowledgeReadTool.description,
|
|
123
|
+
{
|
|
124
|
+
workspace: z
|
|
125
|
+
.string()
|
|
126
|
+
.optional()
|
|
127
|
+
.describe(
|
|
128
|
+
"Target workspace name. If not provided, uses the active workspace.",
|
|
129
|
+
),
|
|
130
|
+
id: z
|
|
131
|
+
.string()
|
|
132
|
+
.optional()
|
|
133
|
+
.describe("The unique ID of the note to read (from frontmatter)"),
|
|
134
|
+
path: z
|
|
135
|
+
.string()
|
|
136
|
+
.optional()
|
|
137
|
+
.describe(
|
|
138
|
+
"The relative path of the note (e.g., 'patterns/pattern-retry-with-backoff.md')",
|
|
139
|
+
),
|
|
140
|
+
},
|
|
141
|
+
async (args) => {
|
|
142
|
+
const input = knowledgeReadSchema.parse(args);
|
|
143
|
+
const result = await executeKnowledgeRead(manager, input);
|
|
144
|
+
return {
|
|
145
|
+
content: [{ type: "text", text: result }],
|
|
146
|
+
};
|
|
147
|
+
},
|
|
148
|
+
);
|
|
149
|
+
|
|
150
|
+
// Register knowledge_search tool
|
|
151
|
+
server.tool(
|
|
152
|
+
knowledgeSearchTool.name,
|
|
153
|
+
knowledgeSearchTool.description,
|
|
154
|
+
{
|
|
155
|
+
workspace: z
|
|
156
|
+
.string()
|
|
157
|
+
.optional()
|
|
158
|
+
.describe(
|
|
159
|
+
"Target workspace name. If not provided, uses the active workspace.",
|
|
160
|
+
),
|
|
161
|
+
query: z
|
|
162
|
+
.string()
|
|
163
|
+
.optional()
|
|
164
|
+
.describe(
|
|
165
|
+
"Text to search for in note titles, content, and descriptions",
|
|
166
|
+
),
|
|
167
|
+
tags: z
|
|
168
|
+
.array(z.string())
|
|
169
|
+
.optional()
|
|
170
|
+
.describe("Filter by tags (matches notes with any of these tags)"),
|
|
171
|
+
category: z
|
|
172
|
+
.enum(["projects", "patterns", "tools", "gotchas", "decisions"])
|
|
173
|
+
.optional()
|
|
174
|
+
.describe("Filter by category folder"),
|
|
175
|
+
},
|
|
176
|
+
async (args) => {
|
|
177
|
+
const input = knowledgeSearchSchema.parse(args);
|
|
178
|
+
const result = await executeKnowledgeSearch(manager, input);
|
|
179
|
+
return {
|
|
180
|
+
content: [{ type: "text", text: result }],
|
|
181
|
+
};
|
|
182
|
+
},
|
|
183
|
+
);
|
|
184
|
+
|
|
185
|
+
// Register knowledge_create tool
|
|
186
|
+
server.tool(
|
|
187
|
+
knowledgeCreateTool.name,
|
|
188
|
+
knowledgeCreateTool.description,
|
|
189
|
+
{
|
|
190
|
+
workspace: z
|
|
191
|
+
.string()
|
|
192
|
+
.optional()
|
|
193
|
+
.describe(
|
|
194
|
+
"Target workspace name. If not provided, uses the active workspace.",
|
|
195
|
+
),
|
|
196
|
+
id: z
|
|
197
|
+
.string()
|
|
198
|
+
.describe(
|
|
199
|
+
"Unique identifier for the note in kebab-case (e.g., 'pattern-retry-with-backoff')",
|
|
200
|
+
),
|
|
201
|
+
title: z.string().describe("Human-readable title for the note"),
|
|
202
|
+
category: z
|
|
203
|
+
.enum(["projects", "patterns", "tools", "gotchas", "decisions"])
|
|
204
|
+
.describe("Category folder to place the note in"),
|
|
205
|
+
content: z
|
|
206
|
+
.string()
|
|
207
|
+
.describe("Markdown content for the note (without frontmatter)"),
|
|
208
|
+
tags: z.array(z.string()).optional().describe("Tags for categorization"),
|
|
209
|
+
related: z
|
|
210
|
+
.array(z.string())
|
|
211
|
+
.optional()
|
|
212
|
+
.describe("IDs of related notes for cross-referencing"),
|
|
213
|
+
description: z
|
|
214
|
+
.string()
|
|
215
|
+
.optional()
|
|
216
|
+
.describe("Brief description of the note"),
|
|
217
|
+
},
|
|
218
|
+
async (args) => {
|
|
219
|
+
const input = knowledgeCreateSchema.parse(args);
|
|
220
|
+
const result = await executeKnowledgeCreate(manager, input);
|
|
221
|
+
return {
|
|
222
|
+
content: [{ type: "text", text: result }],
|
|
223
|
+
};
|
|
224
|
+
},
|
|
225
|
+
);
|
|
226
|
+
|
|
227
|
+
// Register knowledge_update tool
|
|
228
|
+
server.tool(
|
|
229
|
+
knowledgeUpdateTool.name,
|
|
230
|
+
knowledgeUpdateTool.description,
|
|
231
|
+
{
|
|
232
|
+
workspace: z
|
|
233
|
+
.string()
|
|
234
|
+
.optional()
|
|
235
|
+
.describe(
|
|
236
|
+
"Target workspace name. If not provided, uses the active workspace.",
|
|
237
|
+
),
|
|
238
|
+
id: z.string().describe("The unique ID of the note to update"),
|
|
239
|
+
title: z
|
|
240
|
+
.string()
|
|
241
|
+
.optional()
|
|
242
|
+
.describe("New title for the note (optional)"),
|
|
243
|
+
content: z
|
|
244
|
+
.string()
|
|
245
|
+
.optional()
|
|
246
|
+
.describe(
|
|
247
|
+
"New markdown content for the note (optional, replaces existing content)",
|
|
248
|
+
),
|
|
249
|
+
tags: z
|
|
250
|
+
.array(z.string())
|
|
251
|
+
.optional()
|
|
252
|
+
.describe("New tags for the note (optional, replaces existing tags)"),
|
|
253
|
+
related: z
|
|
254
|
+
.array(z.string())
|
|
255
|
+
.optional()
|
|
256
|
+
.describe("New related note IDs (optional, replaces existing related)"),
|
|
257
|
+
description: z
|
|
258
|
+
.string()
|
|
259
|
+
.optional()
|
|
260
|
+
.describe("New description for the note (optional)"),
|
|
261
|
+
},
|
|
262
|
+
async (args) => {
|
|
263
|
+
const input = knowledgeUpdateSchema.parse(args);
|
|
264
|
+
const result = await executeKnowledgeUpdate(manager, input);
|
|
265
|
+
return {
|
|
266
|
+
content: [{ type: "text", text: result }],
|
|
267
|
+
};
|
|
268
|
+
},
|
|
269
|
+
);
|
|
270
|
+
|
|
271
|
+
// =============================================================================
|
|
272
|
+
// ADR Tools
|
|
273
|
+
// =============================================================================
|
|
274
|
+
|
|
275
|
+
// Register adr_list tool
|
|
276
|
+
server.tool(
|
|
277
|
+
adrListTool.name,
|
|
278
|
+
adrListTool.description,
|
|
279
|
+
{
|
|
280
|
+
workspace: z
|
|
281
|
+
.string()
|
|
282
|
+
.optional()
|
|
283
|
+
.describe(
|
|
284
|
+
"Target workspace name. If not provided, uses the active workspace.",
|
|
285
|
+
),
|
|
286
|
+
status: z
|
|
287
|
+
.enum([
|
|
288
|
+
"todo",
|
|
289
|
+
"in-progress",
|
|
290
|
+
"in-review",
|
|
291
|
+
"blocked",
|
|
292
|
+
"completed",
|
|
293
|
+
"deprecated",
|
|
294
|
+
])
|
|
295
|
+
.optional()
|
|
296
|
+
.describe("Filter by ADR status"),
|
|
297
|
+
type: z
|
|
298
|
+
.enum(["enhancement", "debug", "research"])
|
|
299
|
+
.optional()
|
|
300
|
+
.describe("Filter by ADR type"),
|
|
301
|
+
tags: z
|
|
302
|
+
.array(z.string())
|
|
303
|
+
.optional()
|
|
304
|
+
.describe("Filter by tags (matches ADRs with any of these tags)"),
|
|
305
|
+
},
|
|
306
|
+
async (args) => {
|
|
307
|
+
const input = adrListSchema.parse(args);
|
|
308
|
+
const result = await executeAdrList(manager, input);
|
|
309
|
+
return {
|
|
310
|
+
content: [{ type: "text", text: result }],
|
|
311
|
+
};
|
|
312
|
+
},
|
|
313
|
+
);
|
|
314
|
+
|
|
315
|
+
// Register adr_read tool
|
|
316
|
+
server.tool(
|
|
317
|
+
adrReadTool.name,
|
|
318
|
+
adrReadTool.description,
|
|
319
|
+
{
|
|
320
|
+
workspace: z
|
|
321
|
+
.string()
|
|
322
|
+
.optional()
|
|
323
|
+
.describe(
|
|
324
|
+
"Target workspace name. If not provided, uses the active workspace.",
|
|
325
|
+
),
|
|
326
|
+
name: z
|
|
327
|
+
.string()
|
|
328
|
+
.describe(
|
|
329
|
+
"The ADR name (filename without .md) or partial match to find",
|
|
330
|
+
),
|
|
331
|
+
},
|
|
332
|
+
async (args) => {
|
|
333
|
+
const input = adrReadSchema.parse(args);
|
|
334
|
+
const result = await executeAdrRead(manager, input);
|
|
335
|
+
return {
|
|
336
|
+
content: [{ type: "text", text: result }],
|
|
337
|
+
};
|
|
338
|
+
},
|
|
339
|
+
);
|
|
340
|
+
|
|
341
|
+
// Register adr_search tool
|
|
342
|
+
server.tool(
|
|
343
|
+
adrSearchTool.name,
|
|
344
|
+
adrSearchTool.description,
|
|
345
|
+
{
|
|
346
|
+
workspace: z
|
|
347
|
+
.string()
|
|
348
|
+
.optional()
|
|
349
|
+
.describe(
|
|
350
|
+
"Target workspace name. If not provided, uses the active workspace.",
|
|
351
|
+
),
|
|
352
|
+
query: z
|
|
353
|
+
.string()
|
|
354
|
+
.optional()
|
|
355
|
+
.describe(
|
|
356
|
+
"Text to search for in ADR titles, descriptions, names, and content",
|
|
357
|
+
),
|
|
358
|
+
status: z
|
|
359
|
+
.enum([
|
|
360
|
+
"todo",
|
|
361
|
+
"in-progress",
|
|
362
|
+
"in-review",
|
|
363
|
+
"blocked",
|
|
364
|
+
"completed",
|
|
365
|
+
"deprecated",
|
|
366
|
+
])
|
|
367
|
+
.optional()
|
|
368
|
+
.describe("Filter by ADR status"),
|
|
369
|
+
type: z
|
|
370
|
+
.enum(["enhancement", "debug", "research"])
|
|
371
|
+
.optional()
|
|
372
|
+
.describe("Filter by ADR type"),
|
|
373
|
+
tags: z
|
|
374
|
+
.array(z.string())
|
|
375
|
+
.optional()
|
|
376
|
+
.describe("Filter by tags (matches ADRs with any of these tags)"),
|
|
377
|
+
},
|
|
378
|
+
async (args) => {
|
|
379
|
+
const input = adrSearchSchema.parse(args);
|
|
380
|
+
const result = await executeAdrSearch(manager, input);
|
|
381
|
+
return {
|
|
382
|
+
content: [{ type: "text", text: result }],
|
|
383
|
+
};
|
|
384
|
+
},
|
|
385
|
+
);
|
|
386
|
+
|
|
387
|
+
// Register adr_create tool
|
|
388
|
+
server.tool(
|
|
389
|
+
adrCreateTool.name,
|
|
390
|
+
adrCreateTool.description,
|
|
391
|
+
{
|
|
392
|
+
workspace: z
|
|
393
|
+
.string()
|
|
394
|
+
.optional()
|
|
395
|
+
.describe(
|
|
396
|
+
"Target workspace name. If not provided, uses the active workspace.",
|
|
397
|
+
),
|
|
398
|
+
title: z
|
|
399
|
+
.string()
|
|
400
|
+
.describe(
|
|
401
|
+
"Human-readable title for the ADR (e.g., 'Cloud Deployment Feature')",
|
|
402
|
+
),
|
|
403
|
+
type: z
|
|
404
|
+
.enum(["enhancement", "debug", "research"])
|
|
405
|
+
.describe(
|
|
406
|
+
"ADR type: enhancement (new feature), debug (bug fix), or research (exploration)",
|
|
407
|
+
),
|
|
408
|
+
workingFolder: z
|
|
409
|
+
.string()
|
|
410
|
+
.describe(
|
|
411
|
+
"Full path to the project working folder (e.g., '/Users/name/project')",
|
|
412
|
+
),
|
|
413
|
+
description: z
|
|
414
|
+
.string()
|
|
415
|
+
.optional()
|
|
416
|
+
.describe("Brief one-line description of what this ADR covers"),
|
|
417
|
+
tags: z
|
|
418
|
+
.array(z.string())
|
|
419
|
+
.optional()
|
|
420
|
+
.describe(
|
|
421
|
+
"Tags for categorization (e.g., ['frontend', 'api', 'performance'])",
|
|
422
|
+
),
|
|
423
|
+
status: z
|
|
424
|
+
.enum([
|
|
425
|
+
"todo",
|
|
426
|
+
"in-progress",
|
|
427
|
+
"in-review",
|
|
428
|
+
"blocked",
|
|
429
|
+
"completed",
|
|
430
|
+
"deprecated",
|
|
431
|
+
])
|
|
432
|
+
.optional()
|
|
433
|
+
.describe("Initial status (defaults to 'todo')"),
|
|
434
|
+
content: z
|
|
435
|
+
.string()
|
|
436
|
+
.optional()
|
|
437
|
+
.describe(
|
|
438
|
+
"Optional custom content (without frontmatter). If not provided, uses default template.",
|
|
439
|
+
),
|
|
440
|
+
},
|
|
441
|
+
async (args) => {
|
|
442
|
+
const input = adrCreateSchema.parse(args);
|
|
443
|
+
const result = await executeAdrCreate(manager, input);
|
|
444
|
+
return {
|
|
445
|
+
content: [{ type: "text", text: result }],
|
|
446
|
+
};
|
|
447
|
+
},
|
|
448
|
+
);
|
|
449
|
+
|
|
450
|
+
// Register adr_update tool
|
|
451
|
+
server.tool(
|
|
452
|
+
adrUpdateTool.name,
|
|
453
|
+
adrUpdateTool.description,
|
|
454
|
+
{
|
|
455
|
+
workspace: z
|
|
456
|
+
.string()
|
|
457
|
+
.optional()
|
|
458
|
+
.describe(
|
|
459
|
+
"Target workspace name. If not provided, uses the active workspace.",
|
|
460
|
+
),
|
|
461
|
+
name: z
|
|
462
|
+
.string()
|
|
463
|
+
.describe(
|
|
464
|
+
"The ADR name (filename without .md) or partial match to find",
|
|
465
|
+
),
|
|
466
|
+
title: z.string().optional().describe("New title for the ADR (optional)"),
|
|
467
|
+
description: z
|
|
468
|
+
.string()
|
|
469
|
+
.optional()
|
|
470
|
+
.describe("New description for the ADR (optional)"),
|
|
471
|
+
status: z
|
|
472
|
+
.enum([
|
|
473
|
+
"todo",
|
|
474
|
+
"in-progress",
|
|
475
|
+
"in-review",
|
|
476
|
+
"blocked",
|
|
477
|
+
"completed",
|
|
478
|
+
"deprecated",
|
|
479
|
+
])
|
|
480
|
+
.optional()
|
|
481
|
+
.describe("New status for the ADR (optional)"),
|
|
482
|
+
type: z
|
|
483
|
+
.enum(["enhancement", "debug", "research"])
|
|
484
|
+
.optional()
|
|
485
|
+
.describe("New type for the ADR (optional)"),
|
|
486
|
+
tags: z
|
|
487
|
+
.array(z.string())
|
|
488
|
+
.optional()
|
|
489
|
+
.describe("New tags for the ADR (optional, replaces existing tags)"),
|
|
490
|
+
content: z
|
|
491
|
+
.string()
|
|
492
|
+
.optional()
|
|
493
|
+
.describe(
|
|
494
|
+
"New markdown content for the ADR (optional, replaces existing content)",
|
|
495
|
+
),
|
|
496
|
+
workingFolder: z
|
|
497
|
+
.string()
|
|
498
|
+
.optional()
|
|
499
|
+
.describe("New working folder path (optional)"),
|
|
500
|
+
},
|
|
501
|
+
async (args) => {
|
|
502
|
+
const input = adrUpdateSchema.parse(args);
|
|
503
|
+
const result = await executeAdrUpdate(manager, input);
|
|
504
|
+
return {
|
|
505
|
+
content: [{ type: "text", text: result }],
|
|
506
|
+
};
|
|
507
|
+
},
|
|
508
|
+
);
|
|
509
|
+
|
|
510
|
+
return server;
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
/**
|
|
514
|
+
* Create and start the server with stdio transport
|
|
515
|
+
*/
|
|
516
|
+
export async function startStdioServer(
|
|
517
|
+
manager: WorkspaceManager,
|
|
518
|
+
): Promise<void> {
|
|
519
|
+
const server = createServer(manager);
|
|
520
|
+
const transport = new StdioServerTransport();
|
|
521
|
+
|
|
522
|
+
await server.connect(transport);
|
|
523
|
+
|
|
524
|
+
// Log to stderr (not stdout, as stdout is used for MCP protocol)
|
|
525
|
+
console.error(" Server connected via stdio");
|
|
526
|
+
}
|