mcp-sunsama 0.10.0 → 0.10.2

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 CHANGED
@@ -1,5 +1,23 @@
1
1
  # mcp-sunsama
2
2
 
3
+ ## 0.10.2
4
+
5
+ ### Patch Changes
6
+
7
+ - Upgrades sunsama package to 0.8.1. Fixes create-task tool snooze date
8
+
9
+ ## 0.10.1
10
+
11
+ ### Patch Changes
12
+
13
+ - 002cd07: Fix MCP Inspector compatibility for update-task-notes schema
14
+
15
+ - Replace ZodIntersection (.and()) with single z.object() using .refine() for XOR validation
16
+ - Ensure schema generates proper JSON Schema with "type": "object" for MCP Inspector
17
+ - Add clear parameter descriptions indicating mutual exclusivity
18
+ - Maintain same validation behavior while fixing compatibility issues
19
+ - Update documentation to reflect schema architecture improvements
20
+
3
21
  ## 0.10.0
4
22
 
5
23
  ### Minor Changes
package/CLAUDE.md CHANGED
@@ -66,7 +66,8 @@ All tools use Zod schemas from `schemas.ts`:
66
66
  - Automatic TypeScript inference
67
67
  - Comprehensive parameter documentation
68
68
  - Union types for completion filters
69
- - XOR schema patterns for mutually exclusive parameters (e.g., `update-task-notes` requires either `html` OR `markdown`, but not both)
69
+ - XOR schema patterns for mutually exclusive parameters using `.refine()` for MCP Inspector compatibility
70
+ - Example: `update-task-notes` requires either `html` OR `markdown`, but not both
70
71
 
71
72
  ## Key Patterns
72
73
 
package/README.md CHANGED
@@ -95,7 +95,7 @@ Add this configuration to your Claude Desktop MCP settings:
95
95
  - `get-task-by-id` - Get a specific task by its ID
96
96
  - `update-task-complete` - Mark tasks as complete
97
97
  - `update-task-planned-time` - Update the planned time (time estimate) for tasks
98
- - `update-task-notes` - Update task notes content (requires either `html` or `markdown` parameter)
98
+ - `update-task-notes` - Update task notes content (requires either `html` or `markdown` parameter, mutually exclusive)
99
99
  - `update-task-snooze-date` - Reschedule tasks to different dates
100
100
  - `update-task-backlog` - Move tasks to the backlog
101
101
  - `delete-task` - Delete tasks permanently
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.8.0",
10
+ "sunsama-api": "0.8.1",
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.8.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-EiUqEc2OIDsmfCHQX54Pu+xZDfJBTMjHAcwhWqHVIWTp2emMyitUuSDvABEqupoXrzITZw+XW0lxNZUQaW4lqQ=="],
433
+ "sunsama-api": ["sunsama-api@0.8.1", "", { "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-CcLyMwrUnpQi9GmRrNqgqb0A7f2Ba5qxaI1uJdAivcqZQRNfg+g5V9RFzh64mGrN/7M3v+Meiv+Ev6AsiSAz3A=="],
434
434
 
435
435
  "term-size": ["term-size@2.2.1", "", {}, "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg=="],
436
436
 
@@ -0,0 +1,11 @@
1
+ {
2
+ "data": {
3
+ "updateTaskText": {
4
+ "updatedTask": null,
5
+ "updatedFields": null,
6
+ "success": true,
7
+ "skipped": null,
8
+ "__typename": "UpdateTaskPayload"
9
+ }
10
+ }
11
+ }
@@ -0,0 +1,20 @@
1
+ curl 'https://api.sunsama.com/graphql' \
2
+ -H 'accept: */*' \
3
+ -H 'accept-language: en-US,en;q=0.5' \
4
+ -H 'content-type: application/json' \
5
+ -b 'intercom-device-id-bneprukf=cb3bdbde-e6f5-452f-860a-3d9af07d287f; sunsamaSession=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiI2NjM2N2MzZjMzNzEzMzAwMDEwODEyNjAiLCJzZXNzaW9uSWQiOiI2OTcxMmYyOS1jZDZiLTQzNjgtODFmYS1iNTg3ZmQ0NGVlZWYiLCJzZXNzaW9uTm9uY2UiOiIwYjAyZWJlNC0yMzNlLTRhMjYtYTQ1Ni1hNmJhMzA2YTJhZTQiLCJncm91cElkIjoiNjYzNjdjNDMzMzcxMzMwMDAxMDgxMjYyIiwiZ3JvdXBVcmxQYXRoIjoiMTcxNDg0Njc4NzkzNDI0NzQiLCJpYXQiOjE3NTA1MTEzNzgsImV4cCI6MTc1MzEwMzM3OH0.rzteDU3SQfOPiZc9I71jVIfc78ocxh3MGEBeNqzDLJM; intercom-session-bneprukf=NnRmSnl1ZmJCb0V1RGhnb1prdWx5LzJkTGxUNFFORkUvSkNZWVRSY205MlVkVG11TUtYdithSXRRWlVmTXRwai9MaXVPSXl2QkJYZTRGM2N4MCtrVjg0NUNSblRKUWxRK2lHdzBjNjdMTlk9LS1VUmc1c1NzVkpGZ1V0eElLMnlOL29nPT0=--54db2c84e7f41fb661fae4a1650446aaf046bf1e' \
6
+ -H 'origin: https://app.sunsama.com' \
7
+ -H 'priority: u=1, i' \
8
+ -H 'referer: https://app.sunsama.com/' \
9
+ -H 'sec-ch-ua: "Brave";v="137", "Chromium";v="137", "Not/A)Brand";v="24"' \
10
+ -H 'sec-ch-ua-mobile: ?0' \
11
+ -H 'sec-ch-ua-platform: "macOS"' \
12
+ -H 'sec-fetch-dest: empty' \
13
+ -H 'sec-fetch-mode: cors' \
14
+ -H 'sec-fetch-site: same-site' \
15
+ -H 'sec-gpc: 1' \
16
+ -H 'traceparent: 00-e604d5f85432b50fe3b7d5bf8fc2775b-2ef7c8c51cf75623-01' \
17
+ -H 'user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36' \
18
+ -H 'x-gql-operation-name: updateTaskText' \
19
+ -H 'x-pusher-socket-id: 73411.8251716' \
20
+ --data-raw $'{"operationName":"updateTaskText","variables":{"input":{"taskId":"685693f91f41775b0458892f","text":"Try out FOSS AI browser ","recommendedStreamId":null,"limitResponsePayload":true}},"query":"mutation updateTaskText($input: UpdateTaskTextInput\u0021) {\\n updateTaskText(input: $input) {\\n ...UpdateTaskPayload\\n __typename\\n }\\n}\\n\\nfragment UpdateTaskPayload on UpdateTaskPayload {\\n updatedTask {\\n ...Task\\n __typename\\n }\\n updatedFields {\\n ...PartialTask\\n __typename\\n }\\n success\\n skipped\\n __typename\\n}\\n\\nfragment Task on Task {\\n _id\\n groupId\\n taskType\\n streamIds\\n recommendedStreamId\\n eventInfo {\\n eventId\\n clone\\n __typename\\n }\\n seededEventIds\\n private\\n assigneeId\\n createdBy\\n integration {\\n ...TaskIntegration\\n __typename\\n }\\n deleted\\n text\\n notes\\n notesMarkdown\\n notesChecksum\\n editorVersion\\n collabSnapshot\\n completed\\n completedBy\\n completeDate\\n completeOn\\n archivedAt\\n duration\\n runDate {\\n startDate\\n endDate\\n __typename\\n }\\n snooze {\\n userId\\n date\\n until\\n __typename\\n }\\n timeHorizon {\\n type\\n relativeTo\\n __typename\\n }\\n dueDate\\n comments {\\n userId\\n text\\n markdown\\n editorVersion\\n groupId\\n createdAt\\n editedAt\\n deleted\\n file\\n fileMetadata {\\n url\\n filename\\n mimetype\\n size\\n width\\n height\\n __typename\\n }\\n __typename\\n }\\n orderings {\\n ordinal\\n panelDate\\n channelId\\n userId\\n __typename\\n }\\n backlogOrderings {\\n horizonType\\n position\\n streamId\\n __typename\\n }\\n subtasks {\\n _id\\n title\\n completedDate\\n completedBy\\n timeEstimate\\n actualTime {\\n ...TaskActualTime\\n __typename\\n }\\n snooze {\\n userId\\n date\\n until\\n __typename\\n }\\n scheduledTime {\\n ...TaskScheduledTime\\n __typename\\n }\\n integration {\\n ...TaskIntegration\\n __typename\\n }\\n mergedTaskId\\n recommendedTimeEstimate\\n __typename\\n }\\n subtasksCollapsed\\n sequence {\\n date\\n id\\n expiresDate\\n ruleString\\n searchable\\n forked\\n final\\n estimatedStart {\\n hour\\n minute\\n __typename\\n }\\n master\\n finalDate\\n template {\\n streamIds\\n private\\n text\\n notes\\n notesMarkdown\\n notesChecksum\\n editorVersion\\n subtasks {\\n _id\\n title\\n completedDate\\n completedBy\\n timeEstimate\\n actualTime {\\n ...TaskActualTime\\n __typename\\n }\\n __typename\\n }\\n timeEstimate\\n assigneeId\\n __typename\\n }\\n __typename\\n }\\n followers\\n recommendedTimeEstimate\\n timeEstimate\\n actualTime {\\n ...TaskActualTime\\n __typename\\n }\\n scheduledTime {\\n ...TaskScheduledTime\\n __typename\\n }\\n createdAt\\n lastModified\\n objectiveId\\n ritual {\\n id\\n period {\\n interval\\n startCalendarDay\\n endCalendarDay\\n __typename\\n }\\n __typename\\n }\\n __typename\\n}\\n\\nfragment TaskActualTime on TaskActualTime {\\n userId\\n startDate\\n endDate\\n duration\\n isTimerEntry\\n __typename\\n}\\n\\nfragment TaskScheduledTime on TaskScheduledTime {\\n eventId\\n serviceIds {\\n google\\n microsoft\\n microsoftUniqueId\\n apple\\n appleRecurrenceId\\n sunsama\\n __typename\\n }\\n calendarId\\n userId\\n startDate\\n endDate\\n isAllDay\\n importedFromCalendar\\n __typename\\n}\\n\\nfragment TaskIntegration on TaskIntegration {\\n ... on TaskAsanaIntegration {\\n service\\n identifier {\\n id\\n url\\n accountId\\n __typename\\n }\\n __typename\\n }\\n ... on TaskTrelloIntegration {\\n service\\n identifier {\\n id\\n url\\n accountId\\n __typename\\n }\\n __typename\\n }\\n ... on TaskJiraIntegration {\\n service\\n identifier {\\n id\\n cloudId\\n accountId\\n url\\n __typename\\n }\\n __typename\\n }\\n ... on TaskGithubIntegration {\\n service\\n identifier {\\n id\\n repositoryOwnerLogin\\n repositoryName\\n number\\n type\\n url\\n __typename\\n }\\n __typename\\n }\\n ... on TaskTodoistIntegration {\\n service\\n identifier {\\n id\\n url\\n deepUrl\\n __typename\\n }\\n __typename\\n }\\n ... on TaskGoogleCalendarIntegration {\\n service\\n identifier {\\n sunsamaId\\n __typename\\n }\\n __typename\\n }\\n ... on TaskOutlookCalendarIntegration {\\n service\\n identifier {\\n sunsamaId\\n __typename\\n }\\n __typename\\n }\\n ... on TaskAppleCalendarIntegration {\\n service\\n identifier {\\n sunsamaId\\n __typename\\n }\\n __typename\\n }\\n ... on TaskSunsamaCalendarIntegration {\\n service\\n identifier {\\n sunsamaId\\n __typename\\n }\\n __typename\\n }\\n ... on TaskGmailIntegration {\\n service\\n identifier {\\n id\\n messageId\\n accountId\\n url\\n __typename\\n }\\n __typename\\n }\\n ... on TaskOutlookIntegration {\\n service\\n identifier {\\n id\\n internetMessageId\\n conversationId\\n accountId\\n url\\n __typename\\n }\\n __typename\\n }\\n ... on TaskSlackIntegration {\\n service\\n identifier {\\n permalink\\n notesMarkdown\\n __typename\\n }\\n __typename\\n }\\n ... on TaskNotionIntegration {\\n service\\n identifier {\\n id\\n workspaceId\\n url\\n deepUrl\\n __typename\\n }\\n __typename\\n }\\n ... on TaskClickUpIntegration {\\n service\\n identifier {\\n id\\n userId\\n teamId\\n url\\n __typename\\n }\\n __typename\\n }\\n ... on TaskGitlabIntegration {\\n service\\n identifier {\\n id\\n __typename\\n }\\n __typename\\n }\\n ... on TaskEmailIntegration {\\n service\\n identifier {\\n id\\n __typename\\n }\\n content {\\n subject\\n text\\n html\\n from {\\n name\\n email\\n __typename\\n }\\n date\\n __typename\\n }\\n __typename\\n }\\n ... on TaskLinearIntegration {\\n service\\n identifier {\\n id\\n url\\n identifier\\n linearUserId\\n linearOrganizationId\\n number\\n _version\\n __typename\\n }\\n __typename\\n }\\n ... on TaskMondayIntegration {\\n service\\n identifier {\\n id\\n boardId\\n mondayAccountId\\n url\\n __typename\\n }\\n __typename\\n }\\n ... on TaskWebsiteIntegration {\\n service\\n identifier {\\n url\\n private\\n canonicalUrl\\n description\\n faviconUrl\\n imageUrl\\n siteName\\n title\\n __typename\\n }\\n __typename\\n }\\n ... on TaskLoomVideoIntegration {\\n service\\n identifier {\\n url\\n videoId\\n title\\n description\\n thumbnail {\\n width\\n height\\n url\\n __typename\\n }\\n __typename\\n }\\n __typename\\n }\\n ... on TaskMicrosoftTeamsIntegration {\\n service\\n identifier {\\n permalink\\n notesMarkdown\\n __typename\\n }\\n __typename\\n }\\n ... on TaskAppleRemindersIntegration {\\n service\\n identifier {\\n id\\n listId\\n autoImported\\n __typename\\n }\\n __typename\\n }\\n ... on TaskGoogleTasksIntegration {\\n service\\n identifier {\\n id\\n listId\\n accountId\\n __typename\\n }\\n __typename\\n }\\n ... on TaskMicrosoftToDoIntegration {\\n service\\n identifier {\\n id\\n listId\\n accountId\\n parentTaskId\\n __typename\\n }\\n __typename\\n }\\n ... on TaskSunsamaTaskIntegration {\\n service\\n identifier {\\n taskId\\n groupId\\n sunsamaUserId\\n __typename\\n }\\n __typename\\n }\\n __typename\\n}\\n\\nfragment PartialTask on PartialTask {\\n _id\\n recommendedStreamId\\n streamIds\\n recommendedTimeEstimate\\n subtasks {\\n _id\\n title\\n completedDate\\n completedBy\\n timeEstimate\\n actualTime {\\n ...TaskActualTime\\n __typename\\n }\\n snooze {\\n userId\\n date\\n until\\n __typename\\n }\\n scheduledTime {\\n ...TaskScheduledTime\\n __typename\\n }\\n integration {\\n ...TaskIntegration\\n __typename\\n }\\n mergedTaskId\\n recommendedTimeEstimate\\n __typename\\n }\\n __typename\\n}"}'
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.10.0",
19
+ version: "0.10.2",
20
20
  instructions: `
21
21
  This MCP server provides access to the Sunsama API for task and project management.
22
22
 
package/dist/schemas.d.ts CHANGED
@@ -145,34 +145,32 @@ export declare const updateTaskPlannedTimeSchema: z.ZodObject<{
145
145
  timeEstimateMinutes: number;
146
146
  limitResponsePayload?: boolean | undefined;
147
147
  }>;
148
- export declare const updateTaskNotesSchema: z.ZodIntersection<z.ZodObject<{
148
+ export declare const updateTaskNotesSchema: z.ZodEffects<z.ZodObject<{
149
149
  taskId: z.ZodString;
150
+ html: z.ZodOptional<z.ZodString>;
151
+ markdown: z.ZodOptional<z.ZodString>;
150
152
  limitResponsePayload: z.ZodOptional<z.ZodBoolean>;
151
153
  }, "strip", z.ZodTypeAny, {
152
154
  taskId: string;
153
155
  limitResponsePayload?: boolean | undefined;
156
+ html?: string | undefined;
157
+ markdown?: string | undefined;
154
158
  }, {
155
159
  taskId: string;
156
160
  limitResponsePayload?: boolean | undefined;
157
- }>, z.ZodUnion<[z.ZodObject<{
158
- html: z.ZodString;
159
- markdown: z.ZodOptional<z.ZodNever>;
160
- }, "strip", z.ZodTypeAny, {
161
- html: string;
162
- markdown?: undefined;
163
- }, {
164
- html: string;
165
- markdown?: undefined;
166
- }>, z.ZodObject<{
167
- markdown: z.ZodString;
168
- html: z.ZodOptional<z.ZodNever>;
169
- }, "strip", z.ZodTypeAny, {
170
- markdown: string;
171
- html?: undefined;
161
+ html?: string | undefined;
162
+ markdown?: string | undefined;
163
+ }>, {
164
+ taskId: string;
165
+ limitResponsePayload?: boolean | undefined;
166
+ html?: string | undefined;
167
+ markdown?: string | undefined;
172
168
  }, {
173
- markdown: string;
174
- html?: undefined;
175
- }>]>>;
169
+ taskId: string;
170
+ limitResponsePayload?: boolean | undefined;
171
+ html?: string | undefined;
172
+ markdown?: string | undefined;
173
+ }>;
176
174
  /**
177
175
  * Response Type Schemas (for validation and documentation)
178
176
  */
@@ -1 +1 @@
1
- {"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../src/schemas.ts"],"names":[],"mappings":"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"}
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;AAEF;;GAEG;AAGH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;EAO5B,CAAC;AAGH,eAAO,MAAM,WAAW;;;;;;;;;;;;EAItB,CAAC;AAGH,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAKrB,CAAC;AAGH,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAYrB,CAAC;AAGH,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;EAQvB,CAAC;AAEH;;GAEG;AAGH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAE7B,CAAC;AAGH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAG9B,CAAC;AAGH,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAGhC,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;EAI9B,CAAC;AAEH;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEtE,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AACrE,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AACzE,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAC3E,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AACjE,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AACzD,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE/D,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAC/D,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAC/E,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAC/D,MAAM,MAAM,yBAAyB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AACnF,MAAM,MAAM,0BAA0B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAC;AACrF,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEzE,MAAM,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAC;AAC9C,MAAM,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAC;AAC9C,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAClD,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAC9D,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAChE,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AACpE,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC"}
package/dist/schemas.js CHANGED
@@ -88,22 +88,21 @@ export const updateTaskPlannedTimeSchema = z.object({
88
88
  timeEstimateMinutes: z.number().int().min(0).describe("Time estimate in minutes (use 0 to clear the time estimate)"),
89
89
  limitResponsePayload: z.boolean().optional().describe("Whether to limit the response payload size"),
90
90
  });
91
- // Update task notes base parameters (without content)
92
- const updateTaskNotesBaseSchema = z.object({
91
+ // Update task notes parameters with XOR content validation
92
+ export const updateTaskNotesSchema = z.object({
93
93
  taskId: z.string().min(1, "Task ID is required").describe("The ID of the task to update notes for"),
94
+ html: z.string().optional().describe("HTML content for the task notes (mutually exclusive with markdown)"),
95
+ markdown: z.string().optional().describe("Markdown content for the task notes (mutually exclusive with html)"),
94
96
  limitResponsePayload: z.boolean().optional().describe("Whether to limit the response payload size (defaults to true)"),
97
+ }).refine((data) => {
98
+ // Exactly one of html or markdown must be provided
99
+ const hasHtml = data.html !== undefined;
100
+ const hasMarkdown = data.markdown !== undefined;
101
+ return hasHtml !== hasMarkdown; // XOR: exactly one must be true
102
+ }, {
103
+ message: "Exactly one of 'html' or 'markdown' must be provided",
104
+ path: [], // This will show the error at the root level
95
105
  });
96
- // Update task notes parameters with XOR content
97
- export const updateTaskNotesSchema = updateTaskNotesBaseSchema.and(z.union([
98
- z.object({
99
- html: z.string().describe("HTML content for the task notes"),
100
- markdown: z.never().optional()
101
- }),
102
- z.object({
103
- markdown: z.string().describe("Markdown content for the task notes"),
104
- html: z.never().optional()
105
- })
106
- ]));
107
106
  /**
108
107
  * Response Type Schemas (for validation and documentation)
109
108
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mcp-sunsama",
3
- "version": "0.10.0",
3
+ "version": "0.10.2",
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.8.0",
29
+ "sunsama-api": "0.8.1",
30
30
  "zod": "3.24.4"
31
31
  },
32
32
  "devDependencies": {
package/src/main.ts CHANGED
@@ -35,7 +35,7 @@ if (transportConfig.transportType === "stdio") {
35
35
 
36
36
  const server = new FastMCP({
37
37
  name: "Sunsama API Server",
38
- version: "0.10.0",
38
+ version: "0.10.2",
39
39
  instructions: `
40
40
  This MCP server provides access to the Sunsama API for task and project management.
41
41
 
package/src/schemas.ts CHANGED
@@ -107,24 +107,23 @@ export const updateTaskPlannedTimeSchema = z.object({
107
107
  limitResponsePayload: z.boolean().optional().describe("Whether to limit the response payload size"),
108
108
  });
109
109
 
110
- // Update task notes base parameters (without content)
111
- const updateTaskNotesBaseSchema = z.object({
110
+ // Update task notes parameters with XOR content validation
111
+ export const updateTaskNotesSchema = z.object({
112
112
  taskId: z.string().min(1, "Task ID is required").describe("The ID of the task to update notes for"),
113
+ html: z.string().optional().describe("HTML content for the task notes (mutually exclusive with markdown)"),
114
+ markdown: z.string().optional().describe("Markdown content for the task notes (mutually exclusive with html)"),
113
115
  limitResponsePayload: z.boolean().optional().describe("Whether to limit the response payload size (defaults to true)"),
114
- });
115
-
116
- // Update task notes parameters with XOR content
117
- export const updateTaskNotesSchema = updateTaskNotesBaseSchema.and(
118
- z.union([
119
- z.object({
120
- html: z.string().describe("HTML content for the task notes"),
121
- markdown: z.never().optional()
122
- }),
123
- z.object({
124
- markdown: z.string().describe("Markdown content for the task notes"),
125
- html: z.never().optional()
126
- })
127
- ])
116
+ }).refine(
117
+ (data) => {
118
+ // Exactly one of html or markdown must be provided
119
+ const hasHtml = data.html !== undefined;
120
+ const hasMarkdown = data.markdown !== undefined;
121
+ return hasHtml !== hasMarkdown; // XOR: exactly one must be true
122
+ },
123
+ {
124
+ message: "Exactly one of 'html' or 'markdown' must be provided",
125
+ path: [], // This will show the error at the root level
126
+ }
128
127
  );
129
128
 
130
129
  /**