mcp-sunsama 0.12.0 → 0.12.1
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/CHANGELOG.md +12 -0
- package/bun.lock +2 -2
- package/dist/main.js +9 -48
- package/dist/schemas.d.ts +9 -12
- package/dist/schemas.d.ts.map +1 -1
- package/dist/schemas.js +1 -2
- package/dist/schemas.test.js +24 -62
- package/package.json +2 -2
- package/src/main.ts +13 -52
- package/src/schemas.test.ts +25 -77
- package/src/schemas.ts +1 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# mcp-sunsama
|
|
2
2
|
|
|
3
|
+
## 0.12.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Update update-task-stream tool to use sunsama-api updateTaskStream method
|
|
8
|
+
|
|
9
|
+
- Replaced direct GraphQL implementation with sunsama-api updateTaskStream method
|
|
10
|
+
- Changed parameter from `streamIds` array to single `streamId` for API compatibility
|
|
11
|
+
- Updated schema validation and tests to match new single stream parameter
|
|
12
|
+
- Removed `recommendedStreamId` parameter as it's not supported by the API method
|
|
13
|
+
- Improved error handling and logging consistency
|
|
14
|
+
|
|
3
15
|
## 0.12.0
|
|
4
16
|
|
|
5
17
|
### Minor Changes
|
package/bun.lock
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"@types/papaparse": "^5.3.16",
|
|
8
8
|
"fastmcp": "3.3.1",
|
|
9
9
|
"papaparse": "^5.5.3",
|
|
10
|
-
"sunsama-api": "0.
|
|
10
|
+
"sunsama-api": "0.11.0",
|
|
11
11
|
"zod": "3.24.4",
|
|
12
12
|
},
|
|
13
13
|
"devDependencies": {
|
|
@@ -430,7 +430,7 @@
|
|
|
430
430
|
|
|
431
431
|
"strtok3": ["strtok3@10.3.1", "", { "dependencies": { "@tokenizer/token": "^0.3.0" } }, "sha512-3JWEZM6mfix/GCJBBUrkA8p2Id2pBkyTkVCJKto55w080QBKZ+8R171fGrbiSp+yMO/u6F8/yUh7K4V9K+YCnw=="],
|
|
432
432
|
|
|
433
|
-
"sunsama-api": ["sunsama-api@0.
|
|
433
|
+
"sunsama-api": ["sunsama-api@0.11.0", "", { "dependencies": { "graphql": "^16.11.0", "graphql-tag": "^2.12.6", "marked": "^14.1.3", "tough-cookie": "^5.1.2", "tslib": "^2.8.1", "turndown": "^7.2.0", "yjs": "^13.6.27", "zod": "^3.25.64" } }, "sha512-dfY6oDReWXnUF5TfMxkWLgebGVoZkru4und17+vq2m0AG3Maxyg9NvdC2DL2TTQpChVOz6xpu7AEgndL3s3Qqg=="],
|
|
434
434
|
|
|
435
435
|
"term-size": ["term-size@2.2.1", "", {}, "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg=="],
|
|
436
436
|
|
package/dist/main.js
CHANGED
|
@@ -16,7 +16,7 @@ if (transportConfig.transportType === "stdio") {
|
|
|
16
16
|
}
|
|
17
17
|
const server = new FastMCP({
|
|
18
18
|
name: "Sunsama API Server",
|
|
19
|
-
version: "0.12.
|
|
19
|
+
version: "0.12.1",
|
|
20
20
|
instructions: `
|
|
21
21
|
This MCP server provides access to the Sunsama API for task and project management.
|
|
22
22
|
|
|
@@ -733,55 +733,19 @@ server.addTool({
|
|
|
733
733
|
execute: async (args, { session, log }) => {
|
|
734
734
|
try {
|
|
735
735
|
// Extract parameters
|
|
736
|
-
const { taskId,
|
|
736
|
+
const { taskId, streamId, limitResponsePayload } = args;
|
|
737
737
|
log.info("Updating task stream assignment", {
|
|
738
738
|
taskId: taskId,
|
|
739
|
-
|
|
740
|
-
recommendedStreamId: recommendedStreamId,
|
|
739
|
+
streamId: streamId,
|
|
741
740
|
limitResponsePayload: limitResponsePayload
|
|
742
741
|
});
|
|
743
742
|
// Get the appropriate client based on transport type
|
|
744
743
|
const sunsamaClient = getSunsamaClient(session);
|
|
745
|
-
//
|
|
746
|
-
const
|
|
747
|
-
mutation updateTaskStream($input: UpdateTaskStreamInput!) {
|
|
748
|
-
updateTaskStream(input: $input) {
|
|
749
|
-
success
|
|
750
|
-
updatedTask {
|
|
751
|
-
_id
|
|
752
|
-
streamIds
|
|
753
|
-
recommendedStreamId
|
|
754
|
-
}
|
|
755
|
-
updatedFields {
|
|
756
|
-
_id
|
|
757
|
-
streamIds
|
|
758
|
-
recommendedStreamId
|
|
759
|
-
}
|
|
760
|
-
}
|
|
761
|
-
}
|
|
762
|
-
`;
|
|
763
|
-
const variables = {
|
|
764
|
-
input: {
|
|
765
|
-
taskId,
|
|
766
|
-
streamIds,
|
|
767
|
-
recommendedStreamId: recommendedStreamId || null,
|
|
768
|
-
limitResponsePayload: limitResponsePayload ?? true,
|
|
769
|
-
},
|
|
770
|
-
};
|
|
771
|
-
// Make the GraphQL request using the client's graphqlRequest method
|
|
772
|
-
const response = await sunsamaClient.graphqlRequest({
|
|
773
|
-
operationName: 'updateTaskStream',
|
|
774
|
-
variables,
|
|
775
|
-
query: updateTaskStreamMutation,
|
|
776
|
-
});
|
|
777
|
-
if (!response.data) {
|
|
778
|
-
throw new Error('No response data received');
|
|
779
|
-
}
|
|
780
|
-
const result = response.data.updateTaskStream;
|
|
744
|
+
// Call the sunsama-api updateTaskStream method
|
|
745
|
+
const result = await sunsamaClient.updateTaskStream(taskId, streamId, limitResponsePayload !== undefined ? limitResponsePayload : true);
|
|
781
746
|
log.info("Successfully updated task stream assignment", {
|
|
782
747
|
taskId: taskId,
|
|
783
|
-
|
|
784
|
-
recommendedStreamId: recommendedStreamId,
|
|
748
|
+
streamId: streamId,
|
|
785
749
|
success: result.success
|
|
786
750
|
});
|
|
787
751
|
return {
|
|
@@ -791,8 +755,7 @@ server.addTool({
|
|
|
791
755
|
text: JSON.stringify({
|
|
792
756
|
success: result.success,
|
|
793
757
|
taskId: taskId,
|
|
794
|
-
|
|
795
|
-
recommendedStreamId: recommendedStreamId,
|
|
758
|
+
streamId: streamId,
|
|
796
759
|
streamUpdated: true,
|
|
797
760
|
updatedFields: result.updatedFields
|
|
798
761
|
})
|
|
@@ -803,8 +766,7 @@ server.addTool({
|
|
|
803
766
|
catch (error) {
|
|
804
767
|
log.error("Failed to update task stream assignment", {
|
|
805
768
|
taskId: args.taskId,
|
|
806
|
-
|
|
807
|
-
recommendedStreamId: args.recommendedStreamId,
|
|
769
|
+
streamId: args.streamId,
|
|
808
770
|
error: error instanceof Error ? error.message : 'Unknown error'
|
|
809
771
|
});
|
|
810
772
|
throw new Error(`Failed to update task stream assignment: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
@@ -968,8 +930,7 @@ Uses HTTP Basic Auth headers (per-request authentication):
|
|
|
968
930
|
- **update-task-stream**: Update the stream/channel assignment for a task
|
|
969
931
|
- Parameters:
|
|
970
932
|
- \`taskId\` (required): The ID of the task to update stream assignment for
|
|
971
|
-
- \`
|
|
972
|
-
- \`recommendedStreamId\` (optional): Recommended stream ID for the task
|
|
933
|
+
- \`streamId\` (required): Stream ID to assign to the task
|
|
973
934
|
- \`limitResponsePayload\` (optional): Whether to limit response size
|
|
974
935
|
- Returns: JSON with update result
|
|
975
936
|
|
package/dist/schemas.d.ts
CHANGED
|
@@ -202,19 +202,16 @@ export declare const updateTaskTextSchema: z.ZodObject<{
|
|
|
202
202
|
}>;
|
|
203
203
|
export declare const updateTaskStreamSchema: z.ZodObject<{
|
|
204
204
|
taskId: z.ZodString;
|
|
205
|
-
|
|
206
|
-
recommendedStreamId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
205
|
+
streamId: z.ZodString;
|
|
207
206
|
limitResponsePayload: z.ZodOptional<z.ZodBoolean>;
|
|
208
207
|
}, "strip", z.ZodTypeAny, {
|
|
209
208
|
taskId: string;
|
|
210
|
-
|
|
209
|
+
streamId: string;
|
|
211
210
|
limitResponsePayload?: boolean | undefined;
|
|
212
|
-
recommendedStreamId?: string | null | undefined;
|
|
213
211
|
}, {
|
|
214
212
|
taskId: string;
|
|
215
|
-
|
|
213
|
+
streamId: string;
|
|
216
214
|
limitResponsePayload?: boolean | undefined;
|
|
217
|
-
recommendedStreamId?: string | null | undefined;
|
|
218
215
|
}>;
|
|
219
216
|
/**
|
|
220
217
|
* Response Type Schemas (for validation and documentation)
|
|
@@ -345,10 +342,10 @@ export declare const taskSchema: z.ZodObject<{
|
|
|
345
342
|
createdAt: string;
|
|
346
343
|
updatedAt: string;
|
|
347
344
|
userId: string;
|
|
345
|
+
streamId?: string | undefined;
|
|
348
346
|
description?: string | undefined;
|
|
349
347
|
scheduledDate?: string | undefined;
|
|
350
348
|
completedAt?: string | undefined;
|
|
351
|
-
streamId?: string | undefined;
|
|
352
349
|
}, {
|
|
353
350
|
status: string;
|
|
354
351
|
_id: string;
|
|
@@ -357,10 +354,10 @@ export declare const taskSchema: z.ZodObject<{
|
|
|
357
354
|
createdAt: string;
|
|
358
355
|
updatedAt: string;
|
|
359
356
|
userId: string;
|
|
357
|
+
streamId?: string | undefined;
|
|
360
358
|
description?: string | undefined;
|
|
361
359
|
scheduledDate?: string | undefined;
|
|
362
360
|
completedAt?: string | undefined;
|
|
363
|
-
streamId?: string | undefined;
|
|
364
361
|
}>;
|
|
365
362
|
export declare const streamSchema: z.ZodObject<{
|
|
366
363
|
_id: z.ZodString;
|
|
@@ -520,10 +517,10 @@ export declare const tasksResponseSchema: z.ZodObject<{
|
|
|
520
517
|
createdAt: string;
|
|
521
518
|
updatedAt: string;
|
|
522
519
|
userId: string;
|
|
520
|
+
streamId?: string | undefined;
|
|
523
521
|
description?: string | undefined;
|
|
524
522
|
scheduledDate?: string | undefined;
|
|
525
523
|
completedAt?: string | undefined;
|
|
526
|
-
streamId?: string | undefined;
|
|
527
524
|
}, {
|
|
528
525
|
status: string;
|
|
529
526
|
_id: string;
|
|
@@ -532,10 +529,10 @@ export declare const tasksResponseSchema: z.ZodObject<{
|
|
|
532
529
|
createdAt: string;
|
|
533
530
|
updatedAt: string;
|
|
534
531
|
userId: string;
|
|
532
|
+
streamId?: string | undefined;
|
|
535
533
|
description?: string | undefined;
|
|
536
534
|
scheduledDate?: string | undefined;
|
|
537
535
|
completedAt?: string | undefined;
|
|
538
|
-
streamId?: string | undefined;
|
|
539
536
|
}>, "many">;
|
|
540
537
|
count: z.ZodNumber;
|
|
541
538
|
}, "strip", z.ZodTypeAny, {
|
|
@@ -547,10 +544,10 @@ export declare const tasksResponseSchema: z.ZodObject<{
|
|
|
547
544
|
createdAt: string;
|
|
548
545
|
updatedAt: string;
|
|
549
546
|
userId: string;
|
|
547
|
+
streamId?: string | undefined;
|
|
550
548
|
description?: string | undefined;
|
|
551
549
|
scheduledDate?: string | undefined;
|
|
552
550
|
completedAt?: string | undefined;
|
|
553
|
-
streamId?: string | undefined;
|
|
554
551
|
}[];
|
|
555
552
|
count: number;
|
|
556
553
|
}, {
|
|
@@ -562,10 +559,10 @@ export declare const tasksResponseSchema: z.ZodObject<{
|
|
|
562
559
|
createdAt: string;
|
|
563
560
|
updatedAt: string;
|
|
564
561
|
userId: string;
|
|
562
|
+
streamId?: string | undefined;
|
|
565
563
|
description?: string | undefined;
|
|
566
564
|
scheduledDate?: string | undefined;
|
|
567
565
|
completedAt?: string | undefined;
|
|
568
|
-
streamId?: string | undefined;
|
|
569
566
|
}[];
|
|
570
567
|
count: number;
|
|
571
568
|
}>;
|
package/dist/schemas.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../src/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;GAEG;AAEH,eAAO,MAAM,gBAAgB,wCAO3B,CAAC;AAEH;;GAEG;AAGH,eAAO,MAAM,sBAAsB,+CAA6C,CAAC;AAGjF,eAAO,MAAM,mBAAmB;;;;;;;;;;;;EAI9B,CAAC;AAGH,eAAO,MAAM,qBAAqB,gDAAe,CAAC;AAGlD,eAAO,MAAM,sBAAsB;;;;;;;;;EAGjC,CAAC;AAGH,eAAO,MAAM,iBAAiB;;;;;;EAE5B,CAAC;AAEH;;GAEG;AAGH,eAAO,MAAM,aAAa,gDAAe,CAAC;AAE1C;;GAEG;AAGH,eAAO,MAAM,gBAAgB,gDAAe,CAAC;AAE7C;;GAEG;AAGH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;EAS3B,CAAC;AAGH,eAAO,MAAM,wBAAwB;;;;;;;;;;;;EAInC,CAAC;AAGH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;EAI3B,CAAC;AAGH,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;EAKrC,CAAC;AAGH,eAAO,MAAM,uBAAuB;;;;;;;;;;;;EAIlC,CAAC;AAGH,eAAO,MAAM,2BAA2B;;;;;;;;;;;;EAItC,CAAC;AAGH,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;EAgBjC,CAAC;AAGF,eAAO,MAAM,uBAAuB;;;;;;;;;;;;EAOlC,CAAC;AAGH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;EAK/B,CAAC;AAGH,eAAO,MAAM,sBAAsB
|
|
1
|
+
{"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../src/schemas.ts"],"names":[],"mappings":"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"}
|
package/dist/schemas.js
CHANGED
|
@@ -122,8 +122,7 @@ export const updateTaskTextSchema = z.object({
|
|
|
122
122
|
// Update task stream parameters
|
|
123
123
|
export const updateTaskStreamSchema = z.object({
|
|
124
124
|
taskId: z.string().min(1, "Task ID is required").describe("The ID of the task to update stream assignment for"),
|
|
125
|
-
|
|
126
|
-
recommendedStreamId: z.string().nullable().optional().describe("Recommended stream ID for the task"),
|
|
125
|
+
streamId: z.string().min(1, "Stream ID is required").describe("Stream ID to assign to the task"),
|
|
127
126
|
limitResponsePayload: z.boolean().optional().describe("Whether to limit the response payload size"),
|
|
128
127
|
});
|
|
129
128
|
/**
|
package/dist/schemas.test.js
CHANGED
|
@@ -425,123 +425,85 @@ describe("Tool Parameter Schemas", () => {
|
|
|
425
425
|
test("should accept valid task stream assignment", () => {
|
|
426
426
|
const validInput = {
|
|
427
427
|
taskId: "task-123",
|
|
428
|
-
|
|
429
|
-
recommendedStreamId: "stream-1",
|
|
428
|
+
streamId: "stream-1",
|
|
430
429
|
limitResponsePayload: true,
|
|
431
430
|
};
|
|
432
431
|
expect(() => updateTaskStreamSchema.parse(validInput)).not.toThrow();
|
|
433
432
|
});
|
|
434
|
-
test("should accept
|
|
435
|
-
const validInput = {
|
|
436
|
-
taskId: "task-123",
|
|
437
|
-
streamIds: [],
|
|
438
|
-
recommendedStreamId: null,
|
|
439
|
-
limitResponsePayload: false,
|
|
440
|
-
};
|
|
441
|
-
expect(() => updateTaskStreamSchema.parse(validInput)).not.toThrow();
|
|
442
|
-
});
|
|
443
|
-
test("should accept single stream ID", () => {
|
|
444
|
-
const validInput = {
|
|
445
|
-
taskId: "task-123",
|
|
446
|
-
streamIds: ["stream-1"],
|
|
447
|
-
recommendedStreamId: "stream-1",
|
|
448
|
-
};
|
|
449
|
-
expect(() => updateTaskStreamSchema.parse(validInput)).not.toThrow();
|
|
450
|
-
});
|
|
451
|
-
test("should accept null recommendedStreamId", () => {
|
|
433
|
+
test("should accept minimal required input", () => {
|
|
452
434
|
const validInput = {
|
|
453
435
|
taskId: "task-123",
|
|
454
|
-
|
|
455
|
-
recommendedStreamId: null,
|
|
436
|
+
streamId: "stream-1",
|
|
456
437
|
};
|
|
457
438
|
expect(() => updateTaskStreamSchema.parse(validInput)).not.toThrow();
|
|
458
439
|
});
|
|
459
|
-
test("should accept
|
|
440
|
+
test("should accept with limitResponsePayload false", () => {
|
|
460
441
|
const validInput = {
|
|
461
442
|
taskId: "task-123",
|
|
462
|
-
|
|
443
|
+
streamId: "stream-1",
|
|
444
|
+
limitResponsePayload: false,
|
|
463
445
|
};
|
|
464
446
|
expect(() => updateTaskStreamSchema.parse(validInput)).not.toThrow();
|
|
465
447
|
});
|
|
466
448
|
test("should reject empty taskId", () => {
|
|
467
449
|
expect(() => updateTaskStreamSchema.parse({
|
|
468
450
|
taskId: "",
|
|
469
|
-
|
|
451
|
+
streamId: "stream-1",
|
|
470
452
|
})).toThrow();
|
|
471
453
|
});
|
|
472
454
|
test("should reject missing taskId", () => {
|
|
473
455
|
expect(() => updateTaskStreamSchema.parse({
|
|
474
|
-
|
|
456
|
+
streamId: "stream-1",
|
|
457
|
+
})).toThrow();
|
|
458
|
+
});
|
|
459
|
+
test("should reject missing streamId", () => {
|
|
460
|
+
expect(() => updateTaskStreamSchema.parse({
|
|
461
|
+
taskId: "task-123",
|
|
475
462
|
})).toThrow();
|
|
476
463
|
});
|
|
477
|
-
test("should reject
|
|
464
|
+
test("should reject empty streamId", () => {
|
|
478
465
|
expect(() => updateTaskStreamSchema.parse({
|
|
479
466
|
taskId: "task-123",
|
|
467
|
+
streamId: "",
|
|
480
468
|
})).toThrow();
|
|
481
469
|
});
|
|
482
470
|
test("should reject non-string task ID", () => {
|
|
483
471
|
expect(() => updateTaskStreamSchema.parse({
|
|
484
472
|
taskId: 123,
|
|
485
|
-
|
|
473
|
+
streamId: "stream-1",
|
|
486
474
|
})).toThrow();
|
|
487
475
|
expect(() => updateTaskStreamSchema.parse({
|
|
488
476
|
taskId: null,
|
|
489
|
-
|
|
477
|
+
streamId: "stream-1",
|
|
490
478
|
})).toThrow();
|
|
491
479
|
expect(() => updateTaskStreamSchema.parse({
|
|
492
480
|
taskId: undefined,
|
|
493
|
-
|
|
481
|
+
streamId: "stream-1",
|
|
494
482
|
})).toThrow();
|
|
495
483
|
});
|
|
496
|
-
test("should reject non-
|
|
484
|
+
test("should reject non-string streamId", () => {
|
|
497
485
|
expect(() => updateTaskStreamSchema.parse({
|
|
498
486
|
taskId: "task-123",
|
|
499
|
-
|
|
487
|
+
streamId: 123,
|
|
500
488
|
})).toThrow();
|
|
501
489
|
expect(() => updateTaskStreamSchema.parse({
|
|
502
490
|
taskId: "task-123",
|
|
503
|
-
|
|
504
|
-
})).toThrow();
|
|
505
|
-
expect(() => updateTaskStreamSchema.parse({
|
|
506
|
-
taskId: "task-123",
|
|
507
|
-
streamIds: undefined,
|
|
508
|
-
})).toThrow();
|
|
509
|
-
});
|
|
510
|
-
test("should reject non-string elements in streamIds array", () => {
|
|
511
|
-
expect(() => updateTaskStreamSchema.parse({
|
|
512
|
-
taskId: "task-123",
|
|
513
|
-
streamIds: [123, "stream-1"],
|
|
514
|
-
})).toThrow();
|
|
515
|
-
expect(() => updateTaskStreamSchema.parse({
|
|
516
|
-
taskId: "task-123",
|
|
517
|
-
streamIds: ["stream-1", null],
|
|
518
|
-
})).toThrow();
|
|
519
|
-
expect(() => updateTaskStreamSchema.parse({
|
|
520
|
-
taskId: "task-123",
|
|
521
|
-
streamIds: ["stream-1", undefined],
|
|
522
|
-
})).toThrow();
|
|
523
|
-
});
|
|
524
|
-
test("should reject non-string, non-null recommendedStreamId", () => {
|
|
525
|
-
expect(() => updateTaskStreamSchema.parse({
|
|
526
|
-
taskId: "task-123",
|
|
527
|
-
streamIds: ["stream-1"],
|
|
528
|
-
recommendedStreamId: 123,
|
|
491
|
+
streamId: null,
|
|
529
492
|
})).toThrow();
|
|
530
493
|
expect(() => updateTaskStreamSchema.parse({
|
|
531
494
|
taskId: "task-123",
|
|
532
|
-
|
|
533
|
-
recommendedStreamId: true,
|
|
495
|
+
streamId: undefined,
|
|
534
496
|
})).toThrow();
|
|
535
497
|
});
|
|
536
498
|
test("should reject non-boolean limitResponsePayload", () => {
|
|
537
499
|
expect(() => updateTaskStreamSchema.parse({
|
|
538
500
|
taskId: "task-123",
|
|
539
|
-
|
|
501
|
+
streamId: "stream-1",
|
|
540
502
|
limitResponsePayload: "true",
|
|
541
503
|
})).toThrow();
|
|
542
504
|
expect(() => updateTaskStreamSchema.parse({
|
|
543
505
|
taskId: "task-123",
|
|
544
|
-
|
|
506
|
+
streamId: "stream-1",
|
|
545
507
|
limitResponsePayload: 1,
|
|
546
508
|
})).toThrow();
|
|
547
509
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mcp-sunsama",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.1",
|
|
4
4
|
"description": "MCP server for Sunsama API integration",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"private": false,
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"@types/papaparse": "^5.3.16",
|
|
27
27
|
"fastmcp": "3.3.1",
|
|
28
28
|
"papaparse": "^5.5.3",
|
|
29
|
-
"sunsama-api": "0.
|
|
29
|
+
"sunsama-api": "0.11.0",
|
|
30
30
|
"zod": "3.24.4"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
package/src/main.ts
CHANGED
|
@@ -38,7 +38,7 @@ if (transportConfig.transportType === "stdio") {
|
|
|
38
38
|
|
|
39
39
|
const server = new FastMCP({
|
|
40
40
|
name: "Sunsama API Server",
|
|
41
|
-
version: "0.12.
|
|
41
|
+
version: "0.12.1",
|
|
42
42
|
instructions: `
|
|
43
43
|
This MCP server provides access to the Sunsama API for task and project management.
|
|
44
44
|
|
|
@@ -897,63 +897,27 @@ server.addTool({
|
|
|
897
897
|
execute: async (args, {session, log}) => {
|
|
898
898
|
try {
|
|
899
899
|
// Extract parameters
|
|
900
|
-
const {taskId,
|
|
900
|
+
const {taskId, streamId, limitResponsePayload} = args;
|
|
901
901
|
|
|
902
902
|
log.info("Updating task stream assignment", {
|
|
903
903
|
taskId: taskId,
|
|
904
|
-
|
|
905
|
-
recommendedStreamId: recommendedStreamId,
|
|
904
|
+
streamId: streamId,
|
|
906
905
|
limitResponsePayload: limitResponsePayload
|
|
907
906
|
});
|
|
908
907
|
|
|
909
908
|
// Get the appropriate client based on transport type
|
|
910
909
|
const sunsamaClient = getSunsamaClient(session as SessionData | null);
|
|
911
910
|
|
|
912
|
-
//
|
|
913
|
-
const
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
_id
|
|
919
|
-
streamIds
|
|
920
|
-
recommendedStreamId
|
|
921
|
-
}
|
|
922
|
-
updatedFields {
|
|
923
|
-
_id
|
|
924
|
-
streamIds
|
|
925
|
-
recommendedStreamId
|
|
926
|
-
}
|
|
927
|
-
}
|
|
928
|
-
}
|
|
929
|
-
`;
|
|
930
|
-
|
|
931
|
-
const variables = {
|
|
932
|
-
input: {
|
|
933
|
-
taskId,
|
|
934
|
-
streamIds,
|
|
935
|
-
recommendedStreamId: recommendedStreamId || null,
|
|
936
|
-
limitResponsePayload: limitResponsePayload ?? true,
|
|
937
|
-
},
|
|
938
|
-
};
|
|
939
|
-
|
|
940
|
-
// Make the GraphQL request using the client's graphqlRequest method
|
|
941
|
-
const response = await (sunsamaClient as any).graphqlRequest({
|
|
942
|
-
operationName: 'updateTaskStream',
|
|
943
|
-
variables,
|
|
944
|
-
query: updateTaskStreamMutation,
|
|
945
|
-
});
|
|
946
|
-
|
|
947
|
-
if (!response.data) {
|
|
948
|
-
throw new Error('No response data received');
|
|
949
|
-
}
|
|
950
|
-
|
|
951
|
-
const result = response.data.updateTaskStream;
|
|
911
|
+
// Call the sunsama-api updateTaskStream method
|
|
912
|
+
const result = await sunsamaClient.updateTaskStream(
|
|
913
|
+
taskId,
|
|
914
|
+
streamId,
|
|
915
|
+
limitResponsePayload !== undefined ? limitResponsePayload : true
|
|
916
|
+
);
|
|
952
917
|
|
|
953
918
|
log.info("Successfully updated task stream assignment", {
|
|
954
919
|
taskId: taskId,
|
|
955
|
-
|
|
956
|
-
recommendedStreamId: recommendedStreamId,
|
|
920
|
+
streamId: streamId,
|
|
957
921
|
success: result.success
|
|
958
922
|
});
|
|
959
923
|
|
|
@@ -964,8 +928,7 @@ server.addTool({
|
|
|
964
928
|
text: JSON.stringify({
|
|
965
929
|
success: result.success,
|
|
966
930
|
taskId: taskId,
|
|
967
|
-
|
|
968
|
-
recommendedStreamId: recommendedStreamId,
|
|
931
|
+
streamId: streamId,
|
|
969
932
|
streamUpdated: true,
|
|
970
933
|
updatedFields: result.updatedFields
|
|
971
934
|
})
|
|
@@ -976,8 +939,7 @@ server.addTool({
|
|
|
976
939
|
} catch (error) {
|
|
977
940
|
log.error("Failed to update task stream assignment", {
|
|
978
941
|
taskId: args.taskId,
|
|
979
|
-
|
|
980
|
-
recommendedStreamId: args.recommendedStreamId,
|
|
942
|
+
streamId: args.streamId,
|
|
981
943
|
error: error instanceof Error ? error.message : 'Unknown error'
|
|
982
944
|
});
|
|
983
945
|
|
|
@@ -1149,8 +1111,7 @@ Uses HTTP Basic Auth headers (per-request authentication):
|
|
|
1149
1111
|
- **update-task-stream**: Update the stream/channel assignment for a task
|
|
1150
1112
|
- Parameters:
|
|
1151
1113
|
- \`taskId\` (required): The ID of the task to update stream assignment for
|
|
1152
|
-
- \`
|
|
1153
|
-
- \`recommendedStreamId\` (optional): Recommended stream ID for the task
|
|
1114
|
+
- \`streamId\` (required): Stream ID to assign to the task
|
|
1154
1115
|
- \`limitResponsePayload\` (optional): Whether to limit response size
|
|
1155
1116
|
- Returns: JSON with update result
|
|
1156
1117
|
|
package/src/schemas.test.ts
CHANGED
|
@@ -586,45 +586,25 @@ describe("Tool Parameter Schemas", () => {
|
|
|
586
586
|
test("should accept valid task stream assignment", () => {
|
|
587
587
|
const validInput = {
|
|
588
588
|
taskId: "task-123",
|
|
589
|
-
|
|
590
|
-
recommendedStreamId: "stream-1",
|
|
589
|
+
streamId: "stream-1",
|
|
591
590
|
limitResponsePayload: true,
|
|
592
591
|
};
|
|
593
592
|
expect(() => updateTaskStreamSchema.parse(validInput)).not.toThrow();
|
|
594
593
|
});
|
|
595
594
|
|
|
596
|
-
test("should accept
|
|
597
|
-
const validInput = {
|
|
598
|
-
taskId: "task-123",
|
|
599
|
-
streamIds: [],
|
|
600
|
-
recommendedStreamId: null,
|
|
601
|
-
limitResponsePayload: false,
|
|
602
|
-
};
|
|
603
|
-
expect(() => updateTaskStreamSchema.parse(validInput)).not.toThrow();
|
|
604
|
-
});
|
|
605
|
-
|
|
606
|
-
test("should accept single stream ID", () => {
|
|
607
|
-
const validInput = {
|
|
608
|
-
taskId: "task-123",
|
|
609
|
-
streamIds: ["stream-1"],
|
|
610
|
-
recommendedStreamId: "stream-1",
|
|
611
|
-
};
|
|
612
|
-
expect(() => updateTaskStreamSchema.parse(validInput)).not.toThrow();
|
|
613
|
-
});
|
|
614
|
-
|
|
615
|
-
test("should accept null recommendedStreamId", () => {
|
|
595
|
+
test("should accept minimal required input", () => {
|
|
616
596
|
const validInput = {
|
|
617
597
|
taskId: "task-123",
|
|
618
|
-
|
|
619
|
-
recommendedStreamId: null,
|
|
598
|
+
streamId: "stream-1",
|
|
620
599
|
};
|
|
621
600
|
expect(() => updateTaskStreamSchema.parse(validInput)).not.toThrow();
|
|
622
601
|
});
|
|
623
602
|
|
|
624
|
-
test("should accept
|
|
603
|
+
test("should accept with limitResponsePayload false", () => {
|
|
625
604
|
const validInput = {
|
|
626
605
|
taskId: "task-123",
|
|
627
|
-
|
|
606
|
+
streamId: "stream-1",
|
|
607
|
+
limitResponsePayload: false,
|
|
628
608
|
};
|
|
629
609
|
expect(() => updateTaskStreamSchema.parse(validInput)).not.toThrow();
|
|
630
610
|
});
|
|
@@ -633,7 +613,7 @@ describe("Tool Parameter Schemas", () => {
|
|
|
633
613
|
expect(() =>
|
|
634
614
|
updateTaskStreamSchema.parse({
|
|
635
615
|
taskId: "",
|
|
636
|
-
|
|
616
|
+
streamId: "stream-1",
|
|
637
617
|
})
|
|
638
618
|
).toThrow();
|
|
639
619
|
});
|
|
@@ -641,12 +621,12 @@ describe("Tool Parameter Schemas", () => {
|
|
|
641
621
|
test("should reject missing taskId", () => {
|
|
642
622
|
expect(() =>
|
|
643
623
|
updateTaskStreamSchema.parse({
|
|
644
|
-
|
|
624
|
+
streamId: "stream-1",
|
|
645
625
|
})
|
|
646
626
|
).toThrow();
|
|
647
627
|
});
|
|
648
628
|
|
|
649
|
-
test("should reject missing
|
|
629
|
+
test("should reject missing streamId", () => {
|
|
650
630
|
expect(() =>
|
|
651
631
|
updateTaskStreamSchema.parse({
|
|
652
632
|
taskId: "task-123",
|
|
@@ -654,89 +634,57 @@ describe("Tool Parameter Schemas", () => {
|
|
|
654
634
|
).toThrow();
|
|
655
635
|
});
|
|
656
636
|
|
|
657
|
-
test("should reject
|
|
637
|
+
test("should reject empty streamId", () => {
|
|
658
638
|
expect(() =>
|
|
659
639
|
updateTaskStreamSchema.parse({
|
|
660
|
-
taskId: 123,
|
|
661
|
-
|
|
662
|
-
})
|
|
663
|
-
).toThrow();
|
|
664
|
-
|
|
665
|
-
expect(() =>
|
|
666
|
-
updateTaskStreamSchema.parse({
|
|
667
|
-
taskId: null,
|
|
668
|
-
streamIds: ["stream-1"],
|
|
669
|
-
})
|
|
670
|
-
).toThrow();
|
|
671
|
-
|
|
672
|
-
expect(() =>
|
|
673
|
-
updateTaskStreamSchema.parse({
|
|
674
|
-
taskId: undefined,
|
|
675
|
-
streamIds: ["stream-1"],
|
|
640
|
+
taskId: "task-123",
|
|
641
|
+
streamId: "",
|
|
676
642
|
})
|
|
677
643
|
).toThrow();
|
|
678
644
|
});
|
|
679
645
|
|
|
680
|
-
test("should reject non-
|
|
646
|
+
test("should reject non-string task ID", () => {
|
|
681
647
|
expect(() =>
|
|
682
648
|
updateTaskStreamSchema.parse({
|
|
683
|
-
taskId:
|
|
684
|
-
|
|
649
|
+
taskId: 123,
|
|
650
|
+
streamId: "stream-1",
|
|
685
651
|
})
|
|
686
652
|
).toThrow();
|
|
687
653
|
|
|
688
654
|
expect(() =>
|
|
689
655
|
updateTaskStreamSchema.parse({
|
|
690
|
-
taskId:
|
|
691
|
-
|
|
656
|
+
taskId: null,
|
|
657
|
+
streamId: "stream-1",
|
|
692
658
|
})
|
|
693
659
|
).toThrow();
|
|
694
660
|
|
|
695
661
|
expect(() =>
|
|
696
662
|
updateTaskStreamSchema.parse({
|
|
697
|
-
taskId:
|
|
698
|
-
|
|
663
|
+
taskId: undefined,
|
|
664
|
+
streamId: "stream-1",
|
|
699
665
|
})
|
|
700
666
|
).toThrow();
|
|
701
667
|
});
|
|
702
668
|
|
|
703
|
-
test("should reject non-string
|
|
704
|
-
expect(() =>
|
|
705
|
-
updateTaskStreamSchema.parse({
|
|
706
|
-
taskId: "task-123",
|
|
707
|
-
streamIds: [123, "stream-1"],
|
|
708
|
-
})
|
|
709
|
-
).toThrow();
|
|
710
|
-
|
|
669
|
+
test("should reject non-string streamId", () => {
|
|
711
670
|
expect(() =>
|
|
712
671
|
updateTaskStreamSchema.parse({
|
|
713
672
|
taskId: "task-123",
|
|
714
|
-
|
|
673
|
+
streamId: 123,
|
|
715
674
|
})
|
|
716
675
|
).toThrow();
|
|
717
676
|
|
|
718
677
|
expect(() =>
|
|
719
678
|
updateTaskStreamSchema.parse({
|
|
720
679
|
taskId: "task-123",
|
|
721
|
-
|
|
722
|
-
})
|
|
723
|
-
).toThrow();
|
|
724
|
-
});
|
|
725
|
-
|
|
726
|
-
test("should reject non-string, non-null recommendedStreamId", () => {
|
|
727
|
-
expect(() =>
|
|
728
|
-
updateTaskStreamSchema.parse({
|
|
729
|
-
taskId: "task-123",
|
|
730
|
-
streamIds: ["stream-1"],
|
|
731
|
-
recommendedStreamId: 123,
|
|
680
|
+
streamId: null,
|
|
732
681
|
})
|
|
733
682
|
).toThrow();
|
|
734
683
|
|
|
735
684
|
expect(() =>
|
|
736
685
|
updateTaskStreamSchema.parse({
|
|
737
686
|
taskId: "task-123",
|
|
738
|
-
|
|
739
|
-
recommendedStreamId: true,
|
|
687
|
+
streamId: undefined,
|
|
740
688
|
})
|
|
741
689
|
).toThrow();
|
|
742
690
|
});
|
|
@@ -745,7 +693,7 @@ describe("Tool Parameter Schemas", () => {
|
|
|
745
693
|
expect(() =>
|
|
746
694
|
updateTaskStreamSchema.parse({
|
|
747
695
|
taskId: "task-123",
|
|
748
|
-
|
|
696
|
+
streamId: "stream-1",
|
|
749
697
|
limitResponsePayload: "true",
|
|
750
698
|
})
|
|
751
699
|
).toThrow();
|
|
@@ -753,7 +701,7 @@ describe("Tool Parameter Schemas", () => {
|
|
|
753
701
|
expect(() =>
|
|
754
702
|
updateTaskStreamSchema.parse({
|
|
755
703
|
taskId: "task-123",
|
|
756
|
-
|
|
704
|
+
streamId: "stream-1",
|
|
757
705
|
limitResponsePayload: 1,
|
|
758
706
|
})
|
|
759
707
|
).toThrow();
|
package/src/schemas.ts
CHANGED
|
@@ -147,8 +147,7 @@ export const updateTaskTextSchema = z.object({
|
|
|
147
147
|
// Update task stream parameters
|
|
148
148
|
export const updateTaskStreamSchema = z.object({
|
|
149
149
|
taskId: z.string().min(1, "Task ID is required").describe("The ID of the task to update stream assignment for"),
|
|
150
|
-
|
|
151
|
-
recommendedStreamId: z.string().nullable().optional().describe("Recommended stream ID for the task"),
|
|
150
|
+
streamId: z.string().min(1, "Stream ID is required").describe("Stream ID to assign to the task"),
|
|
152
151
|
limitResponsePayload: z.boolean().optional().describe("Whether to limit the response payload size"),
|
|
153
152
|
});
|
|
154
153
|
|