@1medium/cli 1.1.0 → 1.3.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/package.json +1 -1
- package/src/api.js +18 -0
- package/src/mcp-server.js +228 -2
package/package.json
CHANGED
package/src/api.js
CHANGED
|
@@ -23,12 +23,30 @@ function getToken() {
|
|
|
23
23
|
return token;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
+
/**
|
|
27
|
+
* Get configured org ID (if any)
|
|
28
|
+
*/
|
|
29
|
+
function getOrgId() {
|
|
30
|
+
return config.get("orgId") || null;
|
|
31
|
+
}
|
|
32
|
+
|
|
26
33
|
/**
|
|
27
34
|
* Make an authenticated API request
|
|
35
|
+
* Automatically includes org_id if configured
|
|
28
36
|
*/
|
|
29
37
|
async function request(method, path, body = null, params = null) {
|
|
30
38
|
const baseUrl = getApiUrl();
|
|
31
39
|
const token = getToken();
|
|
40
|
+
const orgId = getOrgId();
|
|
41
|
+
|
|
42
|
+
// Add org_id to params for GET requests, or to body for POST/PATCH
|
|
43
|
+
if (orgId) {
|
|
44
|
+
if (method === "GET" || method === "DELETE") {
|
|
45
|
+
params = { ...params, org_id: orgId };
|
|
46
|
+
} else if (method === "POST" || method === "PATCH" || method === "PUT") {
|
|
47
|
+
body = { ...(body || {}), org_id: orgId };
|
|
48
|
+
}
|
|
49
|
+
}
|
|
32
50
|
|
|
33
51
|
let url = `${baseUrl}/v1/agent${path}`;
|
|
34
52
|
if (params) {
|
package/src/mcp-server.js
CHANGED
|
@@ -26,6 +26,40 @@ const server = new Server(
|
|
|
26
26
|
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
27
27
|
return {
|
|
28
28
|
tools: [
|
|
29
|
+
{
|
|
30
|
+
name: "org_list",
|
|
31
|
+
description: "List available organizations. Use this to see which orgs you can switch to.",
|
|
32
|
+
inputSchema: {
|
|
33
|
+
type: "object",
|
|
34
|
+
properties: {},
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
name: "org_set",
|
|
39
|
+
description: "Set the active organization for subsequent operations. Use org_list to see available orgs.",
|
|
40
|
+
inputSchema: {
|
|
41
|
+
type: "object",
|
|
42
|
+
properties: {
|
|
43
|
+
id: {
|
|
44
|
+
type: "string",
|
|
45
|
+
description: "Organization ID to set as active",
|
|
46
|
+
},
|
|
47
|
+
name: {
|
|
48
|
+
type: "string",
|
|
49
|
+
description: "Organization name (for display purposes)",
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
required: ["id"],
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
name: "org_get",
|
|
57
|
+
description: "Get the currently active organization",
|
|
58
|
+
inputSchema: {
|
|
59
|
+
type: "object",
|
|
60
|
+
properties: {},
|
|
61
|
+
},
|
|
62
|
+
},
|
|
29
63
|
{
|
|
30
64
|
name: "task_create",
|
|
31
65
|
description: "Create a new task in 1Medium. Use this to track work items, todos, or any actionable items.",
|
|
@@ -169,6 +203,32 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
169
203
|
properties: {},
|
|
170
204
|
},
|
|
171
205
|
},
|
|
206
|
+
{
|
|
207
|
+
name: "space_set",
|
|
208
|
+
description: "Set the active space for subsequent operations. Use space_list to see available spaces.",
|
|
209
|
+
inputSchema: {
|
|
210
|
+
type: "object",
|
|
211
|
+
properties: {
|
|
212
|
+
id: {
|
|
213
|
+
type: "string",
|
|
214
|
+
description: "Space ID to set as active",
|
|
215
|
+
},
|
|
216
|
+
name: {
|
|
217
|
+
type: "string",
|
|
218
|
+
description: "Space name (for display purposes)",
|
|
219
|
+
},
|
|
220
|
+
},
|
|
221
|
+
required: ["id"],
|
|
222
|
+
},
|
|
223
|
+
},
|
|
224
|
+
{
|
|
225
|
+
name: "space_get",
|
|
226
|
+
description: "Get the currently active space",
|
|
227
|
+
inputSchema: {
|
|
228
|
+
type: "object",
|
|
229
|
+
properties: {},
|
|
230
|
+
},
|
|
231
|
+
},
|
|
172
232
|
{
|
|
173
233
|
name: "space_create",
|
|
174
234
|
description: "Create a new space (top-level group) in 1Medium",
|
|
@@ -228,6 +288,32 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
228
288
|
},
|
|
229
289
|
},
|
|
230
290
|
},
|
|
291
|
+
{
|
|
292
|
+
name: "project_set",
|
|
293
|
+
description: "Set the active project for subsequent task operations. New tasks will be created in this project by default.",
|
|
294
|
+
inputSchema: {
|
|
295
|
+
type: "object",
|
|
296
|
+
properties: {
|
|
297
|
+
id: {
|
|
298
|
+
type: "string",
|
|
299
|
+
description: "Project ID to set as active",
|
|
300
|
+
},
|
|
301
|
+
name: {
|
|
302
|
+
type: "string",
|
|
303
|
+
description: "Project name (for display purposes)",
|
|
304
|
+
},
|
|
305
|
+
},
|
|
306
|
+
required: ["id"],
|
|
307
|
+
},
|
|
308
|
+
},
|
|
309
|
+
{
|
|
310
|
+
name: "project_get",
|
|
311
|
+
description: "Get the currently active project",
|
|
312
|
+
inputSchema: {
|
|
313
|
+
type: "object",
|
|
314
|
+
properties: {},
|
|
315
|
+
},
|
|
316
|
+
},
|
|
231
317
|
{
|
|
232
318
|
name: "project_create",
|
|
233
319
|
description: "Create a new project in 1Medium",
|
|
@@ -308,6 +394,70 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
308
394
|
let result;
|
|
309
395
|
|
|
310
396
|
switch (name) {
|
|
397
|
+
case "org_list": {
|
|
398
|
+
result = await api.listOrgs();
|
|
399
|
+
const orgs = result.orgs || [];
|
|
400
|
+
const currentOrgId = config.get("orgId");
|
|
401
|
+
|
|
402
|
+
if (orgs.length === 0) {
|
|
403
|
+
return {
|
|
404
|
+
content: [{ type: "text", text: "No organizations found." }],
|
|
405
|
+
};
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
const orgList = orgs
|
|
409
|
+
.map((o) => {
|
|
410
|
+
const current = o.id === currentOrgId ? " (active)" : "";
|
|
411
|
+
const personal = o.is_personal ? " [personal]" : "";
|
|
412
|
+
return `- ${o.name}${personal}${current}\n ID: ${o.id}`;
|
|
413
|
+
})
|
|
414
|
+
.join("\n\n");
|
|
415
|
+
|
|
416
|
+
return {
|
|
417
|
+
content: [
|
|
418
|
+
{
|
|
419
|
+
type: "text",
|
|
420
|
+
text: `Organizations:\n\n${orgList}`,
|
|
421
|
+
},
|
|
422
|
+
],
|
|
423
|
+
};
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
case "org_set": {
|
|
427
|
+
config.set("orgId", args.id);
|
|
428
|
+
if (args.name) {
|
|
429
|
+
config.set("orgName", args.name);
|
|
430
|
+
}
|
|
431
|
+
return {
|
|
432
|
+
content: [
|
|
433
|
+
{
|
|
434
|
+
type: "text",
|
|
435
|
+
text: `Active organization set:\n ID: ${args.id}${args.name ? `\n Name: ${args.name}` : ""}`,
|
|
436
|
+
},
|
|
437
|
+
],
|
|
438
|
+
};
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
case "org_get": {
|
|
442
|
+
const orgId = config.get("orgId");
|
|
443
|
+
const orgName = config.get("orgName");
|
|
444
|
+
|
|
445
|
+
if (!orgId) {
|
|
446
|
+
return {
|
|
447
|
+
content: [{ type: "text", text: "No active organization set. Use org_list and org_set to configure." }],
|
|
448
|
+
};
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
return {
|
|
452
|
+
content: [
|
|
453
|
+
{
|
|
454
|
+
type: "text",
|
|
455
|
+
text: `Active organization:\n ID: ${orgId}${orgName ? `\n Name: ${orgName}` : ""}`,
|
|
456
|
+
},
|
|
457
|
+
],
|
|
458
|
+
};
|
|
459
|
+
}
|
|
460
|
+
|
|
311
461
|
case "task_create": {
|
|
312
462
|
// Use provided project_id or fall back to configured default
|
|
313
463
|
const projectId = args.project_id || config.get("projectId") || null;
|
|
@@ -436,6 +586,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
436
586
|
case "space_list": {
|
|
437
587
|
result = await api.listSpaces();
|
|
438
588
|
const spaces = result.spaces || [];
|
|
589
|
+
const currentSpaceId = config.get("spaceId");
|
|
439
590
|
|
|
440
591
|
if (spaces.length === 0) {
|
|
441
592
|
return {
|
|
@@ -444,7 +595,10 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
444
595
|
}
|
|
445
596
|
|
|
446
597
|
const spaceList = spaces
|
|
447
|
-
.map((s) =>
|
|
598
|
+
.map((s) => {
|
|
599
|
+
const current = s.id === currentSpaceId ? " (active)" : "";
|
|
600
|
+
return `- ${s.name}${current}\n ID: ${s.id}`;
|
|
601
|
+
})
|
|
448
602
|
.join("\n\n");
|
|
449
603
|
|
|
450
604
|
return {
|
|
@@ -457,12 +611,48 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
457
611
|
};
|
|
458
612
|
}
|
|
459
613
|
|
|
614
|
+
case "space_set": {
|
|
615
|
+
config.set("spaceId", args.id);
|
|
616
|
+
if (args.name) {
|
|
617
|
+
config.set("spaceName", args.name);
|
|
618
|
+
}
|
|
619
|
+
return {
|
|
620
|
+
content: [
|
|
621
|
+
{
|
|
622
|
+
type: "text",
|
|
623
|
+
text: `Active space set:\n ID: ${args.id}${args.name ? `\n Name: ${args.name}` : ""}`,
|
|
624
|
+
},
|
|
625
|
+
],
|
|
626
|
+
};
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
case "space_get": {
|
|
630
|
+
const spaceId = config.get("spaceId");
|
|
631
|
+
const spaceName = config.get("spaceName");
|
|
632
|
+
|
|
633
|
+
if (!spaceId) {
|
|
634
|
+
return {
|
|
635
|
+
content: [{ type: "text", text: "No active space set. Use space_list and space_set to configure." }],
|
|
636
|
+
};
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
return {
|
|
640
|
+
content: [
|
|
641
|
+
{
|
|
642
|
+
type: "text",
|
|
643
|
+
text: `Active space:\n ID: ${spaceId}${spaceName ? `\n Name: ${spaceName}` : ""}`,
|
|
644
|
+
},
|
|
645
|
+
],
|
|
646
|
+
};
|
|
647
|
+
}
|
|
648
|
+
|
|
460
649
|
case "project_list": {
|
|
461
650
|
const params = {};
|
|
462
651
|
if (args.space_id) params.space_id = args.space_id;
|
|
463
652
|
|
|
464
653
|
result = await api.listProjects(params);
|
|
465
654
|
const projects = result.projects || [];
|
|
655
|
+
const currentProjectId = config.get("projectId");
|
|
466
656
|
|
|
467
657
|
if (projects.length === 0) {
|
|
468
658
|
return {
|
|
@@ -472,7 +662,8 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
472
662
|
|
|
473
663
|
const projectList = projects
|
|
474
664
|
.map((p) => {
|
|
475
|
-
|
|
665
|
+
const current = p.id === currentProjectId ? " (active)" : "";
|
|
666
|
+
let text = `- ${p.name}${current}\n ID: ${p.id}`;
|
|
476
667
|
if (p.space_name) {
|
|
477
668
|
text += `\n Space: ${p.space_name}`;
|
|
478
669
|
}
|
|
@@ -490,6 +681,41 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
490
681
|
};
|
|
491
682
|
}
|
|
492
683
|
|
|
684
|
+
case "project_set": {
|
|
685
|
+
config.set("projectId", args.id);
|
|
686
|
+
if (args.name) {
|
|
687
|
+
config.set("projectName", args.name);
|
|
688
|
+
}
|
|
689
|
+
return {
|
|
690
|
+
content: [
|
|
691
|
+
{
|
|
692
|
+
type: "text",
|
|
693
|
+
text: `Active project set:\n ID: ${args.id}${args.name ? `\n Name: ${args.name}` : ""}\n\nNew tasks will be created in this project by default.`,
|
|
694
|
+
},
|
|
695
|
+
],
|
|
696
|
+
};
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
case "project_get": {
|
|
700
|
+
const projectId = config.get("projectId");
|
|
701
|
+
const projectName = config.get("projectName");
|
|
702
|
+
|
|
703
|
+
if (!projectId) {
|
|
704
|
+
return {
|
|
705
|
+
content: [{ type: "text", text: "No active project set. Use project_list and project_set to configure." }],
|
|
706
|
+
};
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
return {
|
|
710
|
+
content: [
|
|
711
|
+
{
|
|
712
|
+
type: "text",
|
|
713
|
+
text: `Active project:\n ID: ${projectId}${projectName ? `\n Name: ${projectName}` : ""}`,
|
|
714
|
+
},
|
|
715
|
+
],
|
|
716
|
+
};
|
|
717
|
+
}
|
|
718
|
+
|
|
493
719
|
case "space_create": {
|
|
494
720
|
result = await api.createSpace({ name: args.name });
|
|
495
721
|
return {
|