@chorus-aidlc/chorus-openclaw-plugin 0.3.0 → 0.4.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.
@@ -1,10 +1,15 @@
1
1
  import type { ChorusMcpClient } from "../mcp-client.js";
2
2
 
3
+ function toolResult(result: unknown) {
4
+ return { content: [{ type: "text" as const, text: JSON.stringify(result, null, 2) }], details: result };
5
+ }
6
+
3
7
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
4
8
  export function registerPmTools(api: any, mcpClient: ChorusMcpClient) {
5
9
  // 1. chorus_claim_idea
6
10
  api.registerTool({
7
11
  name: "chorus_claim_idea",
12
+ label: "Claim Idea",
8
13
  description: "Claim an open Idea for elaboration (open -> elaborating). After claiming, start elaboration or create a proposal directly.",
9
14
  parameters: {
10
15
  type: "object",
@@ -16,13 +21,14 @@ export function registerPmTools(api: any, mcpClient: ChorusMcpClient) {
16
21
  },
17
22
  async execute(_id: string, { ideaUuid }: { ideaUuid: string }) {
18
23
  const result = await mcpClient.callTool("chorus_claim_idea", { ideaUuid });
19
- return JSON.stringify(result, null, 2);
24
+ return toolResult(result);
20
25
  },
21
26
  });
22
27
 
23
28
  // 2. chorus_start_elaboration
24
29
  api.registerTool({
25
30
  name: "chorus_start_elaboration",
31
+ label: "Start Elaboration",
26
32
  description: "Start an elaboration round for an Idea. Creates structured questions for the stakeholder to answer before proposal creation.",
27
33
  parameters: {
28
34
  type: "object",
@@ -41,13 +47,14 @@ export function registerPmTools(api: any, mcpClient: ChorusMcpClient) {
41
47
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
42
48
  async execute(_id: string, { ideaUuid, depth, questions }: { ideaUuid: string; depth: string; questions: any[] }) {
43
49
  const result = await mcpClient.callTool("chorus_pm_start_elaboration", { ideaUuid, depth, questions });
44
- return JSON.stringify(result, null, 2);
50
+ return toolResult(result);
45
51
  },
46
52
  });
47
53
 
48
54
  // 3. chorus_answer_elaboration
49
55
  api.registerTool({
50
56
  name: "chorus_answer_elaboration",
57
+ label: "Answer Elaboration",
51
58
  description: "Answer elaboration questions for an Idea. Submits answers for a specific elaboration round.",
52
59
  parameters: {
53
60
  type: "object",
@@ -66,13 +73,14 @@ export function registerPmTools(api: any, mcpClient: ChorusMcpClient) {
66
73
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
67
74
  async execute(_id: string, { ideaUuid, roundUuid, answers }: { ideaUuid: string; roundUuid: string; answers: any[] }) {
68
75
  const result = await mcpClient.callTool("chorus_answer_elaboration", { ideaUuid, roundUuid, answers });
69
- return JSON.stringify(result, null, 2);
76
+ return toolResult(result);
70
77
  },
71
78
  });
72
79
 
73
80
  // 4. chorus_validate_elaboration
74
81
  api.registerTool({
75
82
  name: "chorus_validate_elaboration",
83
+ label: "Validate Elaboration",
76
84
  description: "Validate answers from an elaboration round. Empty issues array = all valid, marks elaboration as resolved.",
77
85
  parameters: {
78
86
  type: "object",
@@ -91,13 +99,14 @@ export function registerPmTools(api: any, mcpClient: ChorusMcpClient) {
91
99
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
92
100
  async execute(_id: string, { ideaUuid, roundUuid, issues }: { ideaUuid: string; roundUuid: string; issues: any[] }) {
93
101
  const result = await mcpClient.callTool("chorus_pm_validate_elaboration", { ideaUuid, roundUuid, issues });
94
- return JSON.stringify(result, null, 2);
102
+ return toolResult(result);
95
103
  },
96
104
  });
97
105
 
98
106
  // 5. chorus_create_proposal
99
107
  api.registerTool({
100
108
  name: "chorus_create_proposal",
109
+ label: "Create Proposal",
101
110
  description: "Create an empty Proposal container. Use chorus_add_document_draft and chorus_add_task_draft to populate it afterwards.",
102
111
  parameters: {
103
112
  type: "object",
@@ -117,13 +126,14 @@ export function registerPmTools(api: any, mcpClient: ChorusMcpClient) {
117
126
  const args: Record<string, any> = { projectUuid, title, inputType, inputUuids };
118
127
  if (description !== undefined) args.description = description;
119
128
  const result = await mcpClient.callTool("chorus_pm_create_proposal", args);
120
- return JSON.stringify(result, null, 2);
129
+ return toolResult(result);
121
130
  },
122
131
  });
123
132
 
124
133
  // 6. chorus_add_document_draft
125
134
  api.registerTool({
126
135
  name: "chorus_add_document_draft",
136
+ label: "Add Doc Draft",
127
137
  description: "Add a document draft to a pending Proposal container.",
128
138
  parameters: {
129
139
  type: "object",
@@ -138,13 +148,14 @@ export function registerPmTools(api: any, mcpClient: ChorusMcpClient) {
138
148
  },
139
149
  async execute(_id: string, { proposalUuid, type, title, content }: { proposalUuid: string; type: string; title: string; content: string }) {
140
150
  const result = await mcpClient.callTool("chorus_pm_add_document_draft", { proposalUuid, type, title, content });
141
- return JSON.stringify(result, null, 2);
151
+ return toolResult(result);
142
152
  },
143
153
  });
144
154
 
145
155
  // 7. chorus_add_task_draft
146
156
  api.registerTool({
147
157
  name: "chorus_add_task_draft",
158
+ label: "Add Task Draft",
148
159
  description: "Add a task draft to a pending Proposal container.",
149
160
  parameters: {
150
161
  type: "object",
@@ -170,13 +181,14 @@ export function registerPmTools(api: any, mcpClient: ChorusMcpClient) {
170
181
  if (acceptanceCriteriaItems !== undefined) args.acceptanceCriteriaItems = acceptanceCriteriaItems;
171
182
  if (dependsOnDraftUuids !== undefined) args.dependsOnDraftUuids = dependsOnDraftUuids;
172
183
  const result = await mcpClient.callTool("chorus_pm_add_task_draft", args);
173
- return JSON.stringify(result, null, 2);
184
+ return toolResult(result);
174
185
  },
175
186
  });
176
187
 
177
188
  // 8. chorus_get_proposal — View full proposal with all drafts
178
189
  api.registerTool({
179
190
  name: "chorus_get_proposal",
191
+ label: "Get Proposal",
180
192
  description: "Get detailed information for a Proposal, including all document drafts and task drafts with their UUIDs. Use this to inspect proposal contents before modifying or submitting.",
181
193
  parameters: {
182
194
  type: "object",
@@ -188,13 +200,14 @@ export function registerPmTools(api: any, mcpClient: ChorusMcpClient) {
188
200
  },
189
201
  async execute(_id: string, { proposalUuid }: { proposalUuid: string }) {
190
202
  const result = await mcpClient.callTool("chorus_get_proposal", { proposalUuid });
191
- return JSON.stringify(result, null, 2);
203
+ return toolResult(result);
192
204
  },
193
205
  });
194
206
 
195
207
  // 9. chorus_update_document_draft — Modify an existing document draft
196
208
  api.registerTool({
197
209
  name: "chorus_update_document_draft",
210
+ label: "Update Doc Draft",
198
211
  description: "Update a document draft in a Proposal. Can change title, type, or content.",
199
212
  parameters: {
200
213
  type: "object",
@@ -216,13 +229,14 @@ export function registerPmTools(api: any, mcpClient: ChorusMcpClient) {
216
229
  if (type !== undefined) args.type = type;
217
230
  if (content !== undefined) args.content = content;
218
231
  const result = await mcpClient.callTool("chorus_pm_update_document_draft", args);
219
- return JSON.stringify(result, null, 2);
232
+ return toolResult(result);
220
233
  },
221
234
  });
222
235
 
223
236
  // 10. chorus_update_task_draft — Modify an existing task draft (including dependencies)
224
237
  api.registerTool({
225
238
  name: "chorus_update_task_draft",
239
+ label: "Update Task Draft",
226
240
  description: "Update a task draft in a Proposal. Use this to fix validation issues, add dependencies (dependsOnDraftUuids), change priority, etc.",
227
241
  parameters: {
228
242
  type: "object",
@@ -250,13 +264,14 @@ export function registerPmTools(api: any, mcpClient: ChorusMcpClient) {
250
264
  if (acceptanceCriteriaItems !== undefined) args.acceptanceCriteriaItems = acceptanceCriteriaItems;
251
265
  if (dependsOnDraftUuids !== undefined) args.dependsOnDraftUuids = dependsOnDraftUuids;
252
266
  const result = await mcpClient.callTool("chorus_pm_update_task_draft", args);
253
- return JSON.stringify(result, null, 2);
267
+ return toolResult(result);
254
268
  },
255
269
  });
256
270
 
257
271
  // 11. chorus_remove_document_draft
258
272
  api.registerTool({
259
273
  name: "chorus_remove_document_draft",
274
+ label: "Remove Doc Draft",
260
275
  description: "Remove a document draft from a Proposal.",
261
276
  parameters: {
262
277
  type: "object",
@@ -269,13 +284,14 @@ export function registerPmTools(api: any, mcpClient: ChorusMcpClient) {
269
284
  },
270
285
  async execute(_id: string, { proposalUuid, draftUuid }: { proposalUuid: string; draftUuid: string }) {
271
286
  const result = await mcpClient.callTool("chorus_pm_remove_document_draft", { proposalUuid, draftUuid });
272
- return JSON.stringify(result, null, 2);
287
+ return toolResult(result);
273
288
  },
274
289
  });
275
290
 
276
291
  // 12. chorus_remove_task_draft
277
292
  api.registerTool({
278
293
  name: "chorus_remove_task_draft",
294
+ label: "Remove Task Draft",
279
295
  description: "Remove a task draft from a Proposal.",
280
296
  parameters: {
281
297
  type: "object",
@@ -288,13 +304,14 @@ export function registerPmTools(api: any, mcpClient: ChorusMcpClient) {
288
304
  },
289
305
  async execute(_id: string, { proposalUuid, draftUuid }: { proposalUuid: string; draftUuid: string }) {
290
306
  const result = await mcpClient.callTool("chorus_pm_remove_task_draft", { proposalUuid, draftUuid });
291
- return JSON.stringify(result, null, 2);
307
+ return toolResult(result);
292
308
  },
293
309
  });
294
310
 
295
311
  // 13. chorus_validate_proposal
296
312
  api.registerTool({
297
313
  name: "chorus_validate_proposal",
314
+ label: "Validate Proposal",
298
315
  description: "Validate a Proposal's completeness before submission. Returns errors (block submit), warnings, and info. ALWAYS call this before chorus_submit_proposal. If errors exist, use chorus_update_task_draft / chorus_update_document_draft to fix them, then validate again.",
299
316
  parameters: {
300
317
  type: "object",
@@ -306,13 +323,14 @@ export function registerPmTools(api: any, mcpClient: ChorusMcpClient) {
306
323
  },
307
324
  async execute(_id: string, { proposalUuid }: { proposalUuid: string }) {
308
325
  const result = await mcpClient.callTool("chorus_pm_validate_proposal", { proposalUuid });
309
- return JSON.stringify(result, null, 2);
326
+ return toolResult(result);
310
327
  },
311
328
  });
312
329
 
313
330
  // 9. chorus_submit_proposal
314
331
  api.registerTool({
315
332
  name: "chorus_submit_proposal",
333
+ label: "Submit Proposal",
316
334
  description: "Submit a Proposal for approval (draft -> pending). Requires all input Ideas to have elaboration resolved.",
317
335
  parameters: {
318
336
  type: "object",
@@ -324,13 +342,14 @@ export function registerPmTools(api: any, mcpClient: ChorusMcpClient) {
324
342
  },
325
343
  async execute(_id: string, { proposalUuid }: { proposalUuid: string }) {
326
344
  const result = await mcpClient.callTool("chorus_pm_submit_proposal", { proposalUuid });
327
- return JSON.stringify(result, null, 2);
345
+ return toolResult(result);
328
346
  },
329
347
  });
330
348
 
331
349
  // 15. chorus_pm_assign_task
332
350
  api.registerTool({
333
351
  name: "chorus_pm_assign_task",
352
+ label: "Assign Task",
334
353
  description: "Assign a task to a specified Developer Agent. The task must be in open or assigned status. Use chorus_search_mentionables to find the agent UUID.",
335
354
  parameters: {
336
355
  type: "object",
@@ -343,13 +362,14 @@ export function registerPmTools(api: any, mcpClient: ChorusMcpClient) {
343
362
  },
344
363
  async execute(_id: string, { taskUuid, agentUuid }: { taskUuid: string; agentUuid: string }) {
345
364
  const result = await mcpClient.callTool("chorus_pm_assign_task", { taskUuid, agentUuid });
346
- return JSON.stringify(result, null, 2);
365
+ return toolResult(result);
347
366
  },
348
367
  });
349
368
 
350
369
  // 16. chorus_move_idea
351
370
  api.registerTool({
352
371
  name: "chorus_move_idea",
372
+ label: "Move Idea",
353
373
  description: "Move an Idea to a different project within the same company. Also moves linked draft/pending Proposals.",
354
374
  parameters: {
355
375
  type: "object",
@@ -362,13 +382,14 @@ export function registerPmTools(api: any, mcpClient: ChorusMcpClient) {
362
382
  },
363
383
  async execute(_id: string, { ideaUuid, targetProjectUuid }: { ideaUuid: string; targetProjectUuid: string }) {
364
384
  const result = await mcpClient.callTool("chorus_move_idea", { ideaUuid, targetProjectUuid });
365
- return JSON.stringify(result, null, 2);
385
+ return toolResult(result);
366
386
  },
367
387
  });
368
388
 
369
389
  // 17. chorus_pm_create_idea
370
390
  api.registerTool({
371
391
  name: "chorus_pm_create_idea",
392
+ label: "Create Idea",
372
393
  description: "Create a new Idea in a project. Use this when you discover a requirement, want to propose work, or record a user request.",
373
394
  parameters: {
374
395
  type: "object",
@@ -384,7 +405,7 @@ export function registerPmTools(api: any, mcpClient: ChorusMcpClient) {
384
405
  const args: Record<string, unknown> = { projectUuid, title };
385
406
  if (content) args.content = content;
386
407
  const result = await mcpClient.callTool("chorus_pm_create_idea", args);
387
- return JSON.stringify(result, null, 2);
408
+ return toolResult(result);
388
409
  },
389
410
  });
390
411
  }