mcp-task-server 0.3.0 → 1.0.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/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env node
2
+ import { existsSync } from "fs";
2
3
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";
3
4
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
5
  import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
@@ -6,7 +7,7 @@ import { getConfig, getWorkspace } from "./config.js";
6
7
  import * as tools from "./tools.js";
7
8
  import { loadSharedContext, getWritingPreferences, getUserIdentity, getWorkflowPreferences, clearContextCache, upsertMemory, upsertMemoryByTitle, deleteMemory, generateMemoryId, } from "./context.js";
8
9
  // Version constant - update with each release
9
- const VERSION = "0.3.0";
10
+ const VERSION = "1.0.0";
10
11
  const config = getConfig();
11
12
  // Always log workspace info on startup for debugging
12
13
  console.error(`[mcp-task-server v${VERSION}] Workspace: ${config.workspaceRoot}`);
@@ -25,385 +26,412 @@ const server = new Server({
25
26
  // ============================================================================
26
27
  // Tool Definitions
27
28
  // ============================================================================
28
- server.setRequestHandler(ListToolsRequestSchema, async () => {
29
- return {
30
- tools: [
31
- // Core Tools
32
- {
33
- name: "list_tasks",
34
- description: "List all tasks, optionally filtered by status or assignee",
35
- inputSchema: {
36
- type: "object",
37
- properties: {
38
- status: {
39
- type: "string",
40
- enum: ["pending", "claimed", "in_progress", "review", "approved", "rejected", "completed", "cancelled", "done", "deprecated"],
41
- description: "Filter tasks by status",
42
- },
43
- assigned_to: {
44
- type: "string",
45
- description: "Filter tasks by assigned agent",
46
- },
47
- agent_id: { type: "string", description: "ID of the calling agent (for multi-agent mode)" },
48
- role: { type: "string", enum: ["planner", "worker", "judge"], description: "Role of the calling agent" },
49
- },
29
+ const TOOL_DEFINITIONS = [
30
+ // Help (first for discoverability)
31
+ {
32
+ name: "help",
33
+ description: "List all available MCP task server tools with descriptions and parameters. Use to discover commands.",
34
+ inputSchema: {
35
+ type: "object",
36
+ properties: {
37
+ tool: {
38
+ type: "string",
39
+ description: "Show details for a specific tool (optional)",
50
40
  },
51
41
  },
52
- {
53
- name: "get_task",
54
- description: "Get a specific task by ID, including its subtasks",
55
- inputSchema: {
56
- type: "object",
57
- properties: {
58
- task_id: { type: "string", description: "ID of the task to retrieve" },
59
- agent_id: { type: "string", description: "ID of the calling agent" },
60
- role: { type: "string", enum: ["planner", "worker", "judge"] },
61
- },
62
- required: ["task_id"],
42
+ },
43
+ },
44
+ // Core Tools
45
+ {
46
+ name: "list_tasks",
47
+ description: "List all tasks, optionally filtered by status or assignee",
48
+ inputSchema: {
49
+ type: "object",
50
+ properties: {
51
+ status: {
52
+ type: "string",
53
+ enum: ["pending", "claimed", "in_progress", "review", "approved", "rejected", "completed", "cancelled", "done", "deprecated"],
54
+ description: "Filter tasks by status",
63
55
  },
64
- },
65
- {
66
- name: "add_task",
67
- description: "Create a new top-level task (Planner role in multi-agent mode)",
68
- inputSchema: {
69
- type: "object",
70
- properties: {
71
- title: { type: "string", description: "Task title/name" },
72
- content: { type: "string", description: "Task title (legacy, use 'title' instead)" },
73
- description: { type: "string", description: "Detailed task description" },
74
- details: { type: "string", description: "Implementation details" },
75
- testStrategy: { type: "string", description: "How to verify the task is complete" },
76
- priority: { type: "string", enum: ["low", "medium", "high", "critical"], default: "medium" },
77
- dependencies: { type: "array", items: { type: "string" }, description: "IDs of tasks this depends on" },
78
- agent_id: { type: "string" },
79
- role: { type: "string", enum: ["planner", "worker", "judge"] },
80
- },
56
+ assigned_to: {
57
+ type: "string",
58
+ description: "Filter tasks by assigned agent",
81
59
  },
60
+ agent_id: { type: "string", description: "ID of the calling agent (for multi-agent mode)" },
61
+ role: { type: "string", enum: ["planner", "worker", "judge"], description: "Role of the calling agent" },
82
62
  },
83
- {
84
- name: "update_task",
85
- description: "Update a task's title, description, status, priority, or metadata",
86
- inputSchema: {
87
- type: "object",
88
- properties: {
89
- task_id: { type: "string", description: "ID of the task to update" },
90
- title: { type: "string", description: "New task title" },
91
- content: { type: "string", description: "Task title (legacy, use 'title' instead)" },
92
- description: { type: "string", description: "Detailed task description" },
93
- details: { type: "string", description: "Implementation details" },
94
- testStrategy: { type: "string", description: "How to verify the task is complete" },
95
- status: { type: "string", enum: ["pending", "claimed", "in_progress", "review", "approved", "rejected", "completed", "cancelled", "done", "deprecated"] },
96
- priority: { type: "string", enum: ["low", "medium", "high", "critical"] },
97
- metadata: { type: "object", description: "Additional metadata to store" },
98
- agent_id: { type: "string" },
99
- role: { type: "string", enum: ["planner", "worker", "judge"] },
100
- },
101
- required: ["task_id"],
102
- },
63
+ },
64
+ },
65
+ {
66
+ name: "get_task",
67
+ description: "Get a specific task by ID, including its subtasks",
68
+ inputSchema: {
69
+ type: "object",
70
+ properties: {
71
+ task_id: { type: "string", description: "ID of the task to retrieve" },
72
+ agent_id: { type: "string", description: "ID of the calling agent" },
73
+ role: { type: "string", enum: ["planner", "worker", "judge"] },
103
74
  },
104
- {
105
- name: "complete_task",
106
- description: "Mark a task as completed",
107
- inputSchema: {
108
- type: "object",
109
- properties: {
110
- task_id: { type: "string", description: "ID of the task to complete" },
111
- agent_id: { type: "string" },
112
- role: { type: "string", enum: ["planner", "worker", "judge"] },
113
- },
114
- required: ["task_id"],
115
- },
75
+ required: ["task_id"],
76
+ },
77
+ },
78
+ {
79
+ name: "add_task",
80
+ description: "Create a new top-level task (Planner role in multi-agent mode)",
81
+ inputSchema: {
82
+ type: "object",
83
+ properties: {
84
+ title: { type: "string", description: "Task title/name" },
85
+ content: { type: "string", description: "Task title (legacy, use 'title' instead)" },
86
+ description: { type: "string", description: "Detailed task description" },
87
+ details: { type: "string", description: "Implementation details" },
88
+ testStrategy: { type: "string", description: "How to verify the task is complete" },
89
+ priority: { type: "string", enum: ["low", "medium", "high", "critical"], default: "medium" },
90
+ dependencies: { type: "array", items: { type: "string" }, description: "IDs of tasks this depends on" },
91
+ agent_id: { type: "string" },
92
+ role: { type: "string", enum: ["planner", "worker", "judge"] },
116
93
  },
117
- {
118
- name: "next_task",
119
- description: "Get the next recommended task based on priority and dependencies",
120
- inputSchema: {
121
- type: "object",
122
- properties: {
123
- agent_id: { type: "string" },
124
- role: { type: "string", enum: ["planner", "worker", "judge"] },
125
- },
126
- },
94
+ },
95
+ },
96
+ {
97
+ name: "update_task",
98
+ description: "Update a task's title, description, status, priority, or metadata",
99
+ inputSchema: {
100
+ type: "object",
101
+ properties: {
102
+ task_id: { type: "string", description: "ID of the task to update" },
103
+ title: { type: "string", description: "New task title" },
104
+ content: { type: "string", description: "Task title (legacy, use 'title' instead)" },
105
+ description: { type: "string", description: "Detailed task description" },
106
+ details: { type: "string", description: "Implementation details" },
107
+ testStrategy: { type: "string", description: "How to verify the task is complete" },
108
+ status: { type: "string", enum: ["pending", "claimed", "in_progress", "review", "approved", "rejected", "completed", "cancelled", "done", "deprecated"] },
109
+ priority: { type: "string", enum: ["low", "medium", "high", "critical"] },
110
+ metadata: { type: "object", description: "Additional metadata to store" },
111
+ agent_id: { type: "string" },
112
+ role: { type: "string", enum: ["planner", "worker", "judge"] },
127
113
  },
128
- // Multi-Agent Coordination Tools
129
- {
130
- name: "claim_task",
131
- description: "Claim a task for the calling agent to work on",
132
- inputSchema: {
133
- type: "object",
134
- properties: {
135
- task_id: { type: "string", description: "ID of the task to claim" },
136
- agent_id: { type: "string", description: "ID of the agent claiming the task" },
137
- role: { type: "string", enum: ["planner", "worker", "judge"] },
138
- },
139
- required: ["task_id"],
140
- },
114
+ required: ["task_id"],
115
+ },
116
+ },
117
+ {
118
+ name: "complete_task",
119
+ description: "Mark a task as completed",
120
+ inputSchema: {
121
+ type: "object",
122
+ properties: {
123
+ task_id: { type: "string", description: "ID of the task to complete" },
124
+ agent_id: { type: "string" },
125
+ role: { type: "string", enum: ["planner", "worker", "judge"] },
141
126
  },
142
- {
143
- name: "release_task",
144
- description: "Release a claimed task so others can work on it",
145
- inputSchema: {
146
- type: "object",
147
- properties: {
148
- task_id: { type: "string", description: "ID of the task to release" },
149
- agent_id: { type: "string" },
150
- role: { type: "string", enum: ["planner", "worker", "judge"] },
151
- },
152
- required: ["task_id"],
153
- },
127
+ required: ["task_id"],
128
+ },
129
+ },
130
+ {
131
+ name: "next_task",
132
+ description: "Get the next recommended task based on priority and dependencies",
133
+ inputSchema: {
134
+ type: "object",
135
+ properties: {
136
+ agent_id: { type: "string" },
137
+ role: { type: "string", enum: ["planner", "worker", "judge"] },
154
138
  },
155
- {
156
- name: "handoff_task",
157
- description: "Hand off a task to another role (e.g., Worker to Judge for review)",
158
- inputSchema: {
159
- type: "object",
160
- properties: {
161
- task_id: { type: "string", description: "ID of the task to hand off" },
162
- to_role: { type: "string", enum: ["planner", "worker", "judge"], description: "Role to hand off to" },
163
- notes: { type: "string", description: "Notes for the receiving role" },
164
- agent_id: { type: "string" },
165
- role: { type: "string", enum: ["planner", "worker", "judge"] },
166
- },
167
- required: ["task_id", "to_role"],
168
- },
139
+ },
140
+ },
141
+ // Multi-Agent Coordination Tools
142
+ {
143
+ name: "claim_task",
144
+ description: "Claim a task for the calling agent to work on",
145
+ inputSchema: {
146
+ type: "object",
147
+ properties: {
148
+ task_id: { type: "string", description: "ID of the task to claim" },
149
+ agent_id: { type: "string", description: "ID of the agent claiming the task" },
150
+ role: { type: "string", enum: ["planner", "worker", "judge"] },
169
151
  },
170
- {
171
- name: "review_task",
172
- description: "Review a task that has been handed off (Judge role)",
173
- inputSchema: {
174
- type: "object",
175
- properties: {
176
- task_id: { type: "string", description: "ID of the task to review" },
177
- agent_id: { type: "string" },
178
- role: { type: "string", enum: ["planner", "worker", "judge"] },
179
- },
180
- required: ["task_id"],
181
- },
152
+ required: ["task_id"],
153
+ },
154
+ },
155
+ {
156
+ name: "release_task",
157
+ description: "Release a claimed task so others can work on it",
158
+ inputSchema: {
159
+ type: "object",
160
+ properties: {
161
+ task_id: { type: "string", description: "ID of the task to release" },
162
+ agent_id: { type: "string" },
163
+ role: { type: "string", enum: ["planner", "worker", "judge"] },
182
164
  },
183
- {
184
- name: "approve_task",
185
- description: "Approve a completed task (Judge role)",
186
- inputSchema: {
187
- type: "object",
188
- properties: {
189
- task_id: { type: "string", description: "ID of the task to approve" },
190
- notes: { type: "string", description: "Approval notes" },
191
- agent_id: { type: "string" },
192
- role: { type: "string", enum: ["planner", "worker", "judge"] },
193
- },
194
- required: ["task_id"],
195
- },
165
+ required: ["task_id"],
166
+ },
167
+ },
168
+ {
169
+ name: "handoff_task",
170
+ description: "Hand off a task to another role (e.g., Worker to Judge for review)",
171
+ inputSchema: {
172
+ type: "object",
173
+ properties: {
174
+ task_id: { type: "string", description: "ID of the task to hand off" },
175
+ to_role: { type: "string", enum: ["planner", "worker", "judge"], description: "Role to hand off to" },
176
+ notes: { type: "string", description: "Notes for the receiving role" },
177
+ agent_id: { type: "string" },
178
+ role: { type: "string", enum: ["planner", "worker", "judge"] },
196
179
  },
197
- {
198
- name: "reject_task",
199
- description: "Reject a task with feedback (Judge role)",
200
- inputSchema: {
201
- type: "object",
202
- properties: {
203
- task_id: { type: "string", description: "ID of the task to reject" },
204
- feedback: { type: "string", description: "Feedback explaining why the task was rejected" },
205
- agent_id: { type: "string" },
206
- role: { type: "string", enum: ["planner", "worker", "judge"] },
207
- },
208
- required: ["task_id", "feedback"],
209
- },
180
+ required: ["task_id", "to_role"],
181
+ },
182
+ },
183
+ {
184
+ name: "review_task",
185
+ description: "Review a task that has been handed off (Judge role)",
186
+ inputSchema: {
187
+ type: "object",
188
+ properties: {
189
+ task_id: { type: "string", description: "ID of the task to review" },
190
+ agent_id: { type: "string" },
191
+ role: { type: "string", enum: ["planner", "worker", "judge"] },
210
192
  },
211
- // Task Breakdown Tools
212
- {
213
- name: "expand_task",
214
- description: "Get a prompt to break down a task into subtasks (Planner role)",
215
- inputSchema: {
216
- type: "object",
217
- properties: {
218
- task_id: { type: "string", description: "ID of the task to expand" },
219
- agent_id: { type: "string" },
220
- role: { type: "string", enum: ["planner", "worker", "judge"] },
221
- },
222
- required: ["task_id"],
223
- },
193
+ required: ["task_id"],
194
+ },
195
+ },
196
+ {
197
+ name: "approve_task",
198
+ description: "Approve a completed task (Judge role)",
199
+ inputSchema: {
200
+ type: "object",
201
+ properties: {
202
+ task_id: { type: "string", description: "ID of the task to approve" },
203
+ notes: { type: "string", description: "Approval notes" },
204
+ agent_id: { type: "string" },
205
+ role: { type: "string", enum: ["planner", "worker", "judge"] },
224
206
  },
225
- {
226
- name: "add_subtask",
227
- description: "Add a subtask to an existing task",
228
- inputSchema: {
229
- type: "object",
230
- properties: {
231
- parent_id: { type: "string", description: "ID of the parent task" },
232
- title: { type: "string", description: "Subtask title/name" },
233
- content: { type: "string", description: "Subtask title (legacy, use 'title' instead)" },
234
- description: { type: "string", description: "Detailed subtask description" },
235
- details: { type: "string", description: "Implementation details" },
236
- dependencies: { type: "array", items: { type: "number" }, description: "IDs of sibling subtasks this depends on" },
237
- agent_id: { type: "string" },
238
- role: { type: "string", enum: ["planner", "worker", "judge"] },
239
- },
240
- required: ["parent_id"],
241
- },
207
+ required: ["task_id"],
208
+ },
209
+ },
210
+ {
211
+ name: "reject_task",
212
+ description: "Reject a task with feedback (Judge role)",
213
+ inputSchema: {
214
+ type: "object",
215
+ properties: {
216
+ task_id: { type: "string", description: "ID of the task to reject" },
217
+ feedback: { type: "string", description: "Feedback explaining why the task was rejected" },
218
+ agent_id: { type: "string" },
219
+ role: { type: "string", enum: ["planner", "worker", "judge"] },
242
220
  },
243
- {
244
- name: "set_dependencies",
245
- description: "Set task dependencies (Planner role)",
246
- inputSchema: {
247
- type: "object",
248
- properties: {
249
- task_id: { type: "string", description: "ID of the task" },
250
- dependencies: { type: "array", items: { type: "string" }, description: "IDs of dependency tasks" },
251
- agent_id: { type: "string" },
252
- role: { type: "string", enum: ["planner", "worker", "judge"] },
253
- },
254
- required: ["task_id", "dependencies"],
255
- },
221
+ required: ["task_id", "feedback"],
222
+ },
223
+ },
224
+ // Task Breakdown Tools
225
+ {
226
+ name: "expand_task",
227
+ description: "Get a prompt to break down a task into subtasks (Planner role)",
228
+ inputSchema: {
229
+ type: "object",
230
+ properties: {
231
+ task_id: { type: "string", description: "ID of the task to expand" },
232
+ agent_id: { type: "string" },
233
+ role: { type: "string", enum: ["planner", "worker", "judge"] },
256
234
  },
257
- {
258
- name: "remove_task",
259
- description: "Remove a task and clean up dependencies",
260
- inputSchema: {
261
- type: "object",
262
- properties: {
263
- task_id: { type: "string", description: "ID of the task to remove" },
264
- agent_id: { type: "string" },
265
- role: { type: "string", enum: ["planner", "worker", "judge"] },
266
- },
267
- required: ["task_id"],
268
- },
235
+ required: ["task_id"],
236
+ },
237
+ },
238
+ {
239
+ name: "add_subtask",
240
+ description: "Add a subtask to an existing task",
241
+ inputSchema: {
242
+ type: "object",
243
+ properties: {
244
+ parent_id: { type: "string", description: "ID of the parent task" },
245
+ title: { type: "string", description: "Subtask title/name" },
246
+ content: { type: "string", description: "Subtask title (legacy, use 'title' instead)" },
247
+ description: { type: "string", description: "Detailed subtask description" },
248
+ details: { type: "string", description: "Implementation details" },
249
+ dependencies: { type: "array", items: { type: "number" }, description: "IDs of sibling subtasks this depends on" },
250
+ agent_id: { type: "string" },
251
+ role: { type: "string", enum: ["planner", "worker", "judge"] },
269
252
  },
270
- // Prompt-Based Tools
271
- {
272
- name: "parse_prd",
273
- description: "Get a prompt to parse a PRD into tasks (Planner role)",
274
- inputSchema: {
275
- type: "object",
276
- properties: {
277
- prd_content: { type: "string", description: "The PRD content to parse" },
278
- agent_id: { type: "string" },
279
- role: { type: "string", enum: ["planner", "worker", "judge"] },
280
- },
281
- required: ["prd_content"],
282
- },
253
+ required: ["parent_id"],
254
+ },
255
+ },
256
+ {
257
+ name: "set_dependencies",
258
+ description: "Set task dependencies (Planner role)",
259
+ inputSchema: {
260
+ type: "object",
261
+ properties: {
262
+ task_id: { type: "string", description: "ID of the task" },
263
+ dependencies: { type: "array", items: { type: "string" }, description: "IDs of dependency tasks" },
264
+ agent_id: { type: "string" },
265
+ role: { type: "string", enum: ["planner", "worker", "judge"] },
283
266
  },
284
- {
285
- name: "research_task",
286
- description: "Get a prompt to research a task (Worker role)",
287
- inputSchema: {
288
- type: "object",
289
- properties: {
290
- task_id: { type: "string", description: "ID of the task to research" },
291
- topic: { type: "string", description: "Specific topic to research (optional)" },
292
- agent_id: { type: "string" },
293
- role: { type: "string", enum: ["planner", "worker", "judge"] },
294
- },
295
- required: ["task_id"],
296
- },
267
+ required: ["task_id", "dependencies"],
268
+ },
269
+ },
270
+ {
271
+ name: "remove_task",
272
+ description: "Remove a task and clean up dependencies",
273
+ inputSchema: {
274
+ type: "object",
275
+ properties: {
276
+ task_id: { type: "string", description: "ID of the task to remove" },
277
+ agent_id: { type: "string" },
278
+ role: { type: "string", enum: ["planner", "worker", "judge"] },
297
279
  },
298
- {
299
- name: "analyse_complexity",
300
- description: "Get a prompt to analyse task complexity (Planner role)",
301
- inputSchema: {
302
- type: "object",
303
- properties: {
304
- task_id: { type: "string", description: "ID of the task to analyse" },
305
- agent_id: { type: "string" },
306
- role: { type: "string", enum: ["planner", "worker", "judge"] },
307
- },
308
- required: ["task_id"],
309
- },
280
+ required: ["task_id"],
281
+ },
282
+ },
283
+ // Prompt-Based Tools
284
+ {
285
+ name: "parse_prd",
286
+ description: "Get a prompt to parse a PRD into tasks (Planner role)",
287
+ inputSchema: {
288
+ type: "object",
289
+ properties: {
290
+ prd_content: { type: "string", description: "The PRD content to parse" },
291
+ agent_id: { type: "string" },
292
+ role: { type: "string", enum: ["planner", "worker", "judge"] },
310
293
  },
311
- {
312
- name: "check_compliance",
313
- description: "Check if a file or folder complies with user preferences from shared context. Returns a prompt to review and optionally fix issues.",
314
- inputSchema: {
315
- type: "object",
316
- properties: {
317
- path: { type: "string", description: "File or folder path to check (relative to workspace)" },
318
- fix: { type: "boolean", description: "If true, prompt will instruct to fix issues. If false, review only.", default: false },
319
- agent_id: { type: "string" },
320
- role: { type: "string", enum: ["planner", "worker", "judge"] },
321
- },
322
- required: ["path"],
323
- },
294
+ required: ["prd_content"],
295
+ },
296
+ },
297
+ {
298
+ name: "research_task",
299
+ description: "Get a prompt to research a task (Worker role)",
300
+ inputSchema: {
301
+ type: "object",
302
+ properties: {
303
+ task_id: { type: "string", description: "ID of the task to research" },
304
+ topic: { type: "string", description: "Specific topic to research (optional)" },
305
+ agent_id: { type: "string" },
306
+ role: { type: "string", enum: ["planner", "worker", "judge"] },
324
307
  },
325
- // Project Initialisation
326
- {
327
- name: "init_project",
328
- description: "Initialise a project with agent-kit, memory_bank, and cursor rules. Creates directory structure and template files. Safe to run on existing projects (will not overwrite files with content unless force: true).",
329
- inputSchema: {
330
- type: "object",
331
- properties: {
332
- project_name: { type: "string", description: "Project name for placeholders in templates (defaults to workspace folder name)" },
333
- force: { type: "boolean", description: "If true, overwrite existing files. Default: false (skip existing files)", default: false },
334
- },
335
- },
308
+ required: ["task_id"],
309
+ },
310
+ },
311
+ {
312
+ name: "analyse_complexity",
313
+ description: "Get a prompt to analyse task complexity (Planner role)",
314
+ inputSchema: {
315
+ type: "object",
316
+ properties: {
317
+ task_id: { type: "string", description: "ID of the task to analyse" },
318
+ agent_id: { type: "string" },
319
+ role: { type: "string", enum: ["planner", "worker", "judge"] },
320
+ },
321
+ required: ["task_id"],
322
+ },
323
+ },
324
+ {
325
+ name: "check_compliance",
326
+ description: "Check if a file or folder complies with user preferences from shared context. Returns a prompt to review and optionally fix issues.",
327
+ inputSchema: {
328
+ type: "object",
329
+ properties: {
330
+ path: { type: "string", description: "File or folder path to check (relative to workspace)" },
331
+ fix: { type: "boolean", description: "If true, prompt will instruct to fix issues. If false, review only.", default: false },
332
+ agent_id: { type: "string" },
333
+ role: { type: "string", enum: ["planner", "worker", "judge"] },
336
334
  },
337
- // Utility Tools
338
- {
339
- name: "get_version",
340
- description: "Get the current version of the MCP task server",
341
- inputSchema: {
342
- type: "object",
343
- properties: {},
335
+ required: ["path"],
336
+ },
337
+ },
338
+ // Project Initialisation
339
+ {
340
+ name: "init_project",
341
+ description: "Initialise a project with agent-kit, memory_bank, and cursor rules. Creates directory structure and template files. Safe to run on existing projects (will not overwrite files with content unless force: true).",
342
+ inputSchema: {
343
+ type: "object",
344
+ properties: {
345
+ project_name: { type: "string", description: "Project name for placeholders in templates (defaults to workspace folder name)" },
346
+ force: { type: "boolean", description: "If true, overwrite existing files. Default: false (skip existing files)", default: false },
347
+ },
348
+ },
349
+ },
350
+ // Utility Tools
351
+ {
352
+ name: "get_version",
353
+ description: "Get the MCP task server version and workspace detection info. Use this to verify which project directory the server is using.",
354
+ inputSchema: {
355
+ type: "object",
356
+ properties: {},
357
+ },
358
+ },
359
+ {
360
+ name: "diagnose",
361
+ description: "Diagnose MCP task server configuration. Shows workspace detection, available paths, and verifies the server is working correctly for this project.",
362
+ inputSchema: {
363
+ type: "object",
364
+ properties: {
365
+ verbose: {
366
+ type: "boolean",
367
+ description: "Show detailed detection info",
368
+ default: false,
344
369
  },
345
370
  },
346
- {
347
- name: "show_memory",
348
- description: "Show shared context memories from ~/.cursor/shared-context.json. Displays all memories or filter by search term.",
349
- inputSchema: {
350
- type: "object",
351
- properties: {
352
- search: {
353
- type: "string",
354
- description: "Optional search term to filter memories by title",
355
- },
356
- reload: {
357
- type: "boolean",
358
- description: "Force reload from file (clears cache)",
359
- default: false,
360
- },
361
- },
371
+ },
372
+ },
373
+ {
374
+ name: "show_memory",
375
+ description: "Show shared context memories from ~/.cursor/shared-context.json. Displays all memories or filter by search term.",
376
+ inputSchema: {
377
+ type: "object",
378
+ properties: {
379
+ search: {
380
+ type: "string",
381
+ description: "Optional search term to filter memories by title",
382
+ },
383
+ reload: {
384
+ type: "boolean",
385
+ description: "Force reload from file (clears cache)",
386
+ default: false,
362
387
  },
363
388
  },
364
- {
365
- name: "update_memory",
366
- description: "Create, update, sync, or delete a memory in ~/.cursor/shared-context.json. Use 'sync' to find by title and create or update automatically.",
367
- inputSchema: {
368
- type: "object",
369
- properties: {
370
- action: {
371
- type: "string",
372
- enum: ["create", "update", "delete", "sync"],
373
- description: "Action: create (new), update (by ID), delete (by ID), sync (find by title, create or update)",
374
- },
375
- id: {
376
- type: "string",
377
- description: "Memory ID (required for update/delete, auto-generated for create/sync)",
378
- },
379
- title: {
380
- type: "string",
381
- description: "Memory title (required for create/update/sync)",
382
- },
383
- content: {
384
- type: "string",
385
- description: "Memory content (required for create/update/sync)",
386
- },
387
- },
388
- required: ["action"],
389
+ },
390
+ },
391
+ {
392
+ name: "update_memory",
393
+ description: "Create, update, sync, or delete a memory in ~/.cursor/shared-context.json. Use 'sync' with the Cursor memory ID to keep IDs consistent.",
394
+ inputSchema: {
395
+ type: "object",
396
+ properties: {
397
+ action: {
398
+ type: "string",
399
+ enum: ["create", "update", "delete", "sync"],
400
+ description: "Action: create (new), update (by ID), delete (by ID), sync (upsert by title with optional Cursor ID)",
401
+ },
402
+ id: {
403
+ type: "string",
404
+ description: "Memory ID - for sync, use the Cursor memory ID (e.g. '13502615') to preserve consistency",
405
+ },
406
+ title: {
407
+ type: "string",
408
+ description: "Memory title (required for create/update/sync)",
409
+ },
410
+ content: {
411
+ type: "string",
412
+ description: "Memory content (required for create/update/sync)",
389
413
  },
390
414
  },
391
- {
392
- name: "analyse_project",
393
- description: "Analyse the project structure and generate suggestions for memory_bank files. Scans the codebase and returns a prompt with suggested updates for brief.md, tech.md, active.md, etc.",
394
- inputSchema: {
395
- type: "object",
396
- properties: {
397
- focus: {
398
- type: "string",
399
- enum: ["all", "brief", "tech", "architecture", "active"],
400
- description: "Which memory_bank area to focus on (default: all)",
401
- },
402
- },
415
+ required: ["action"],
416
+ },
417
+ },
418
+ {
419
+ name: "analyse_project",
420
+ description: "Analyse the project structure and generate suggestions for memory_bank files. Scans the codebase and returns a prompt with suggested updates for brief.md, tech.md, active.md, etc.",
421
+ inputSchema: {
422
+ type: "object",
423
+ properties: {
424
+ focus: {
425
+ type: "string",
426
+ enum: ["all", "brief", "tech", "architecture", "active"],
427
+ description: "Which memory_bank area to focus on (default: all)",
403
428
  },
404
429
  },
405
- ],
406
- };
430
+ },
431
+ },
432
+ ];
433
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
434
+ return { tools: TOOL_DEFINITIONS };
407
435
  });
408
436
  // ============================================================================
409
437
  // Tool Handler
@@ -462,6 +490,68 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
462
490
  case "analyse_project":
463
491
  return tools.analyseProject(config, tools.AnalyseProjectSchema.parse(args));
464
492
  // Utility Tools
493
+ case "help": {
494
+ const { tool: toolName } = args;
495
+ if (toolName) {
496
+ // Find specific tool
497
+ const toolDef = TOOL_DEFINITIONS.find(t => t.name === toolName);
498
+ if (!toolDef) {
499
+ return {
500
+ content: [
501
+ {
502
+ type: "text",
503
+ text: JSON.stringify({
504
+ status: "error",
505
+ message: `Tool '${toolName}' not found`,
506
+ available_tools: TOOL_DEFINITIONS.map(t => t.name),
507
+ }, null, 2),
508
+ },
509
+ ],
510
+ };
511
+ }
512
+ // Format parameters from inputSchema
513
+ const params = {};
514
+ const schema = toolDef.inputSchema;
515
+ if (schema.properties) {
516
+ for (const [key, value] of Object.entries(schema.properties)) {
517
+ params[key] = {
518
+ type: value.type || "unknown",
519
+ required: schema.required?.includes(key) || false,
520
+ description: value.description || "",
521
+ };
522
+ }
523
+ }
524
+ return {
525
+ content: [
526
+ {
527
+ type: "text",
528
+ text: JSON.stringify({
529
+ name: toolDef.name,
530
+ description: toolDef.description,
531
+ parameters: Object.keys(params).length > 0 ? params : "none",
532
+ }, null, 2),
533
+ },
534
+ ],
535
+ };
536
+ }
537
+ // Return summary of all tools
538
+ return {
539
+ content: [
540
+ {
541
+ type: "text",
542
+ text: JSON.stringify({
543
+ server: "mcp-task-server",
544
+ version: VERSION,
545
+ tool_count: TOOL_DEFINITIONS.length,
546
+ tools: TOOL_DEFINITIONS.map(t => ({
547
+ name: t.name,
548
+ description: t.description,
549
+ })),
550
+ }, null, 2),
551
+ },
552
+ ],
553
+ };
554
+ }
465
555
  case "get_version": {
466
556
  const workspace = getWorkspace();
467
557
  return {
@@ -481,6 +571,45 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
481
571
  ],
482
572
  };
483
573
  }
574
+ case "diagnose": {
575
+ const workspace = getWorkspace();
576
+ const { verbose } = args;
577
+ const diagnosis = {
578
+ status: "ok",
579
+ version: VERSION,
580
+ workspace: {
581
+ detected_root: workspace.root,
582
+ detection_method: workspace.source,
583
+ },
584
+ paths: {
585
+ tasks_json: `${workspace.root}/${config.jsonPath}`,
586
+ progress_md: `${workspace.root}/${config.markdownPath}`,
587
+ tasks_dir: `${workspace.root}/${config.tasksDir}`,
588
+ },
589
+ };
590
+ if (verbose) {
591
+ diagnosis.environment = {
592
+ TASK_WORKSPACE: process.env.TASK_WORKSPACE || "(not set)",
593
+ WORKSPACE_FOLDER_PATHS: process.env.WORKSPACE_FOLDER_PATHS || "(not set)",
594
+ cwd: process.cwd(),
595
+ };
596
+ diagnosis.files_exist = {
597
+ tasks_json: existsSync(`${workspace.root}/${config.jsonPath}`),
598
+ progress_md: existsSync(`${workspace.root}/${config.markdownPath}`),
599
+ tasks_dir: existsSync(`${workspace.root}/${config.tasksDir}`),
600
+ memory_bank: existsSync(`${workspace.root}/memory_bank`),
601
+ agent_kit: existsSync(`${workspace.root}/agent-kit`),
602
+ };
603
+ }
604
+ return {
605
+ content: [
606
+ {
607
+ type: "text",
608
+ text: JSON.stringify(diagnosis, null, 2),
609
+ },
610
+ ],
611
+ };
612
+ }
484
613
  case "show_memory": {
485
614
  const { search, reload } = args;
486
615
  // Clear cache if reload requested
@@ -587,7 +716,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
587
716
  ],
588
717
  };
589
718
  }
590
- const { memory: syncedMemory, wasUpdated } = upsertMemoryByTitle(title, content);
719
+ const { memory: syncedMemory, wasUpdated } = upsertMemoryByTitle(title, content, id);
591
720
  const ctx = loadSharedContext();
592
721
  return {
593
722
  content: [