mcp-sunsama 0.15.4 → 0.16.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/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # mcp-sunsama
2
2
 
3
+ ## 0.16.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 56872df: Add GitHub and Gmail integration support to create-task tool
8
+
9
+ This minor release adds support for creating Sunsama tasks with GitHub and Gmail integrations, enabling users to convert GitHub issues/PRs and Gmail emails into tasks with proper linking and metadata.
10
+
11
+ **New Features:**
12
+
13
+ - Added `TaskGithubIntegration` schema with all required fields (id, repositoryOwnerLogin, repositoryName, number, type, url)
14
+ - Added `TaskGmailIntegration` schema with all required fields (id, messageId, accountId, url)
15
+ - Updated `create-task` tool to accept optional `integration` parameter
16
+ - Implemented discriminated union pattern for type-safe integration handling
17
+ - Full TypeScript support with Zod schema validation
18
+
19
+ **Migration:**
20
+ No breaking changes. This is a purely additive feature that extends existing functionality. The integration parameter is optional, so existing code will continue to work without modifications.
21
+
3
22
  ## 0.15.4
4
23
 
5
24
  ### Patch Changes
package/CLAUDE.md CHANGED
@@ -89,6 +89,14 @@ All tools use Zod schemas from `schemas.ts`:
89
89
  - Union types for completion filters
90
90
  - XOR schema patterns for mutually exclusive parameters using `.refine()` for MCP Inspector compatibility
91
91
  - Example: `update-task-notes` requires either `html` OR `markdown`, but not both
92
+ - Discriminated unions for task integrations (GitHub, Gmail)
93
+
94
+ ### Integration Support
95
+ The `create-task` tool supports external integrations:
96
+ - **GitHub Integration**: Link tasks to GitHub issues or pull requests
97
+ - **Gmail Integration**: Link tasks to Gmail emails
98
+ - Uses discriminated union pattern for type-safe integration handling
99
+ - Integration parameter is optional to maintain backward compatibility
92
100
 
93
101
  ## Key Patterns
94
102
 
@@ -149,7 +157,7 @@ src/
149
157
  ├── tools/
150
158
  │ ├── shared.ts # Common utilities and tool wrapper patterns
151
159
  │ ├── user-tools.ts # User operations (get-user)
152
- │ ├── task-tools.ts # Task operations (14 tools)
160
+ │ ├── task-tools.ts # Task operations (15 tools)
153
161
  │ ├── stream-tools.ts # Stream operations (get-streams)
154
162
  │ └── index.ts # Export all tools
155
163
  ├── resources/
@@ -193,7 +201,7 @@ __tests__/
193
201
 
194
202
  **Resource-Based Organization**:
195
203
  - **User Tools**: Single tool for user operations
196
- - **Task Tools**: 14 tools organized by function (query, lifecycle, update)
204
+ - **Task Tools**: 15 tools organized by function (query, lifecycle, update)
197
205
  - **Stream Tools**: Single tool for stream operations
198
206
 
199
207
  **Type Safety Improvements**:
@@ -244,7 +252,7 @@ Optional:
244
252
  ### Task Operations
245
253
  Full CRUD support:
246
254
  - **Read**: `get-tasks-by-day`, `get-tasks-backlog`, `get-archived-tasks`, `get-task-by-id`, `get-streams`
247
- - **Write**: `create-task`, `update-task-complete`, `update-task-planned-time`, `update-task-notes`, `update-task-snooze-date`, `update-task-backlog`, `update-task-stream`, `delete-task`
255
+ - **Write**: `create-task` (with GitHub/Gmail integration support), `update-task-complete`, `update-task-planned-time`, `update-task-notes`, `update-task-snooze-date`, `update-task-backlog`, `update-task-stream`, `update-task-text`, `update-task-due-date`, `delete-task`
248
256
 
249
257
  Task read operations support response trimming. `get-tasks-by-day` includes completion filtering. `get-archived-tasks` includes enhanced pagination with hasMore flag for LLM decision-making.
250
258
 
package/CONTRIBUTING.md CHANGED
@@ -55,12 +55,24 @@ Example: `feat/add-task-labels`
55
55
  bun run build
56
56
  ```
57
57
 
58
- 5. Create a changeset for your changes:
58
+ 5. Create a changeset for your changes (if needed):
59
59
  ```bash
60
60
  bun run changeset
61
61
  ```
62
62
  Follow the prompts to describe your changes.
63
63
 
64
+ **When to create a changeset:**
65
+ - ✅ New user-facing features or tools
66
+ - ✅ Bug fixes that affect npm package users
67
+ - ✅ API changes or breaking changes
68
+ - ✅ Dependency updates that change behavior
69
+
70
+ **When NOT to create a changeset:**
71
+ - ❌ Infrastructure/deployment changes (CI/CD, Docker, Smithery config)
72
+ - ❌ Internal refactoring with no behavior changes
73
+ - ❌ Documentation updates
74
+ - ❌ Development tooling changes
75
+
64
76
  6. Commit your changes using conventional commit format:
65
77
  ```bash
66
78
  git add .
@@ -155,11 +167,9 @@ This project uses [changesets](https://github.com/changesets/changesets) for ver
155
167
  bun run version # Apply changesets and update package.json
156
168
  ```
157
169
 
158
- **IMPORTANT**: After running this command, manually update the MCP server version in `src/main.ts` (line ~19) to match the new version in `package.json`:
170
+ **IMPORTANT**: After this command, manually update the version in `src/constants.ts` to match `package.json`:
159
171
  ```typescript
160
- const server = new FastMCP({
161
- name: "Sunsama API Server",
162
- version: "X.Y.Z", // <-- Update this to match package.json
172
+ export const VERSION = "X.Y.Z"; // <-- Update to match package.json
163
173
  ```
164
174
 
165
175
  3. **Pre-Release Validation**
@@ -177,7 +187,6 @@ This project uses [changesets](https://github.com/changesets/changesets) for ver
177
187
  Verify the commit includes:
178
188
  - `package.json` - version bump
179
189
  - `CHANGELOG.md` - generated changelog
180
- - `src/main.ts` - MCP server version update
181
190
  - Removed changeset files from `.changeset/`
182
191
 
183
192
  5. **Publish to NPM**
@@ -199,7 +208,11 @@ This project uses [changesets](https://github.com/changesets/changesets) for ver
199
208
 
200
209
  #### Version Synchronization
201
210
 
202
- The MCP server version in `src/main.ts` must always match the version in `package.json`. This ensures clients receive accurate version information during the MCP handshake.
211
+ **IMPORTANT**: When updating the version, you must update it in TWO places:
212
+ 1. `package.json` - The npm package version
213
+ 2. `src/constants.ts` - The `VERSION` constant
214
+
215
+ This ensures the MCP server reports the correct version to clients during the handshake.
203
216
 
204
217
  #### Troubleshooting Releases
205
218
 
package/README.md CHANGED
@@ -2,10 +2,14 @@
2
2
 
3
3
  A Model Context Protocol (MCP) server that provides comprehensive task management capabilities through the Sunsama API. This server enables AI assistants to access Sunsama tasks, create new tasks, mark tasks complete, and manage your productivity workflow.
4
4
 
5
+ <a href="https://glama.ai/mcp/servers/@robertn702/mcp-sunsama">
6
+ <img width="380" height="200" src="https://glama.ai/mcp/servers/@robertn702/mcp-sunsama/badge" />
7
+ </a>
8
+
5
9
  ## Features
6
10
 
7
11
  ### Task Management
8
- - **Create Tasks** - Create new tasks with notes, time estimates, due dates, and stream assignments
12
+ - **Create Tasks** - Create new tasks with notes, time estimates, due dates, stream assignments, and GitHub/Gmail integrations
9
13
  - **Read Tasks** - Get tasks by day with completion filtering, access backlog tasks, retrieve archived task history
10
14
  - **Update Tasks** - Mark tasks as complete with custom timestamps, reschedule tasks or move to backlog
11
15
  - **Delete Tasks** - Permanently remove tasks from your workspace
@@ -110,7 +114,7 @@ Add this configuration to your Claude Desktop MCP settings:
110
114
  ## API Tools
111
115
 
112
116
  ### Task Management
113
- - `create-task` - Create new tasks with optional properties
117
+ - `create-task` - Create new tasks with optional properties including GitHub issue/PR and Gmail integration
114
118
  - `get-tasks-by-day` - Get tasks for a specific day with completion filtering
115
119
  - `get-tasks-backlog` - Get backlog tasks
116
120
  - `get-archived-tasks` - Get archived tasks with pagination (includes hasMore flag for LLM context)
@@ -129,6 +133,74 @@ Add this configuration to your Claude Desktop MCP settings:
129
133
  - `get-user` - Get current user information
130
134
  - `get-streams` - Get streams/channels for project organization
131
135
 
136
+ ### Integration Examples
137
+
138
+ The `create-task` tool supports linking tasks to external services like GitHub and Gmail.
139
+
140
+ #### GitHub Integration
141
+
142
+ Link a task to a GitHub issue:
143
+ ```json
144
+ {
145
+ "text": "Fix authentication bug",
146
+ "integration": {
147
+ "service": "github",
148
+ "identifier": {
149
+ "id": "I_kwDOO4SCuM7VTB4n",
150
+ "repositoryOwnerLogin": "robertn702",
151
+ "repositoryName": "mcp-sunsama",
152
+ "number": 42,
153
+ "type": "Issue",
154
+ "url": "https://github.com/robertn702/mcp-sunsama/issues/42",
155
+ "__typename": "TaskGithubIntegrationIdentifier"
156
+ },
157
+ "__typename": "TaskGithubIntegration"
158
+ }
159
+ }
160
+ ```
161
+
162
+ Link a task to a GitHub pull request:
163
+ ```json
164
+ {
165
+ "text": "Review API refactoring PR",
166
+ "integration": {
167
+ "service": "github",
168
+ "identifier": {
169
+ "id": "PR_kwDOO4SCuM7VTB5o",
170
+ "repositoryOwnerLogin": "robertn702",
171
+ "repositoryName": "mcp-sunsama",
172
+ "number": 15,
173
+ "type": "PullRequest",
174
+ "url": "https://github.com/robertn702/mcp-sunsama/pull/15",
175
+ "__typename": "TaskGithubIntegrationIdentifier"
176
+ },
177
+ "__typename": "TaskGithubIntegration"
178
+ }
179
+ }
180
+ ```
181
+
182
+ #### Gmail Integration
183
+
184
+ Link a task to a Gmail email:
185
+ ```json
186
+ {
187
+ "text": "Respond to project update email",
188
+ "integration": {
189
+ "service": "gmail",
190
+ "identifier": {
191
+ "id": "19a830b40fd7ab7d",
192
+ "messageId": "19a830b40fd7ab7d",
193
+ "accountId": "user@example.com",
194
+ "url": "https://mail.google.com/mail/u/user@example.com/#inbox/19a830b40fd7ab7d",
195
+ "__typename": "TaskGmailIntegrationIdentifier"
196
+ },
197
+ "__typename": "TaskGmailIntegration"
198
+ }
199
+ }
200
+ ```
201
+
202
+ **Note**: All integration parameters are optional. Tasks can be created without integrations for standard task management.
203
+
132
204
  ## Development
133
205
 
134
206
  ### Running in Development
@@ -171,7 +243,7 @@ src/
171
243
  ├── tools/
172
244
  │ ├── shared.ts # Common utilities and patterns
173
245
  │ ├── user-tools.ts # User operations (get-user)
174
- │ ├── task-tools.ts # Task operations (14 tools)
246
+ │ ├── task-tools.ts # Task operations (15 tools)
175
247
  │ ├── stream-tools.ts # Stream operations (get-streams)
176
248
  │ └── index.ts # Export all tools
177
249
  ├── resources/
package/bun.lock CHANGED
@@ -9,7 +9,7 @@
9
9
  "cors": "^2.8.5",
10
10
  "express": "^5.1.0",
11
11
  "papaparse": "^5.5.3",
12
- "sunsama-api": "0.11.2",
12
+ "sunsama-api": "0.12.0",
13
13
  "zod": "3.24.4",
14
14
  },
15
15
  "devDependencies": {
@@ -396,7 +396,7 @@
396
396
 
397
397
  "strip-bom": ["strip-bom@3.0.0", "", {}, "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA=="],
398
398
 
399
- "sunsama-api": ["sunsama-api@0.11.2", "", { "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-tyBrCai6Z0jEmRXkwGY+0PlXJTAwE3IJXXRCDcGFwpFPxFO5fyxw6mqM/RhYu7OGhP3AF7w4CikvEOBDaFXvKA=="],
399
+ "sunsama-api": ["sunsama-api@0.12.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-J2nXZAlYnlA567fmfpwWAOqZnOO0FLVfRwskJQ+gngrjpq26E5TamGSQZ4317/UdJ3U87ZnJdyoHnBRjjBdtvA=="],
400
400
 
401
401
  "term-size": ["term-size@2.2.1", "", {}, "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg=="],
402
402
 
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Application constants
3
+ *
4
+ * IMPORTANT: Keep VERSION in sync with package.json version
5
+ */
6
+ export declare const VERSION = "0.16.0";
7
+ export declare const SERVER_NAME = "Sunsama API Server";
8
+ export declare const PACKAGE_NAME = "mcp-sunsama";
9
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,eAAO,MAAM,OAAO,WAAW,CAAC;AAChC,eAAO,MAAM,WAAW,uBAAuB,CAAC;AAChD,eAAO,MAAM,YAAY,gBAAgB,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Application constants
3
+ *
4
+ * IMPORTANT: Keep VERSION in sync with package.json version
5
+ */
6
+ export const VERSION = "0.16.0";
7
+ export const SERVER_NAME = "Sunsama API Server";
8
+ export const PACKAGE_NAME = "mcp-sunsama";
package/dist/main.js CHANGED
@@ -5,11 +5,12 @@ import { setupStdioTransport } from "./transports/stdio.js";
5
5
  import { setupHttpTransport } from "./transports/http.js";
6
6
  import { allTools } from "./tools/index.js";
7
7
  import { apiDocumentationResource } from "./resources/index.js";
8
+ import { VERSION, SERVER_NAME } from "./constants.js";
8
9
  // Async IIFE for top-level await and error handling
9
10
  (async () => {
10
11
  const server = new McpServer({
11
- name: "Sunsama API Server",
12
- version: "0.15.4",
12
+ name: SERVER_NAME,
13
+ version: VERSION,
13
14
  instructions: `
14
15
  This MCP server provides access to the Sunsama API for task and project management.
15
16
 
package/dist/schemas.d.ts CHANGED
@@ -54,6 +54,101 @@ export declare const createTaskSchema: z.ZodObject<{
54
54
  snoozeUntil: z.ZodOptional<z.ZodString>;
55
55
  private: z.ZodOptional<z.ZodBoolean>;
56
56
  taskId: z.ZodOptional<z.ZodString>;
57
+ integration: z.ZodOptional<z.ZodDiscriminatedUnion<"service", [z.ZodObject<{
58
+ service: z.ZodLiteral<"github">;
59
+ identifier: z.ZodObject<{
60
+ id: z.ZodString;
61
+ repositoryOwnerLogin: z.ZodString;
62
+ repositoryName: z.ZodString;
63
+ number: z.ZodNumber;
64
+ type: z.ZodEnum<["Issue", "PullRequest"]>;
65
+ url: z.ZodString;
66
+ __typename: z.ZodLiteral<"TaskGithubIntegrationIdentifier">;
67
+ }, "strip", z.ZodTypeAny, {
68
+ number: number;
69
+ type: "Issue" | "PullRequest";
70
+ id: string;
71
+ url: string;
72
+ repositoryOwnerLogin: string;
73
+ repositoryName: string;
74
+ __typename: "TaskGithubIntegrationIdentifier";
75
+ }, {
76
+ number: number;
77
+ type: "Issue" | "PullRequest";
78
+ id: string;
79
+ url: string;
80
+ repositoryOwnerLogin: string;
81
+ repositoryName: string;
82
+ __typename: "TaskGithubIntegrationIdentifier";
83
+ }>;
84
+ __typename: z.ZodLiteral<"TaskGithubIntegration">;
85
+ }, "strip", z.ZodTypeAny, {
86
+ __typename: "TaskGithubIntegration";
87
+ service: "github";
88
+ identifier: {
89
+ number: number;
90
+ type: "Issue" | "PullRequest";
91
+ id: string;
92
+ url: string;
93
+ repositoryOwnerLogin: string;
94
+ repositoryName: string;
95
+ __typename: "TaskGithubIntegrationIdentifier";
96
+ };
97
+ }, {
98
+ __typename: "TaskGithubIntegration";
99
+ service: "github";
100
+ identifier: {
101
+ number: number;
102
+ type: "Issue" | "PullRequest";
103
+ id: string;
104
+ url: string;
105
+ repositoryOwnerLogin: string;
106
+ repositoryName: string;
107
+ __typename: "TaskGithubIntegrationIdentifier";
108
+ };
109
+ }>, z.ZodObject<{
110
+ service: z.ZodLiteral<"gmail">;
111
+ identifier: z.ZodObject<{
112
+ id: z.ZodString;
113
+ messageId: z.ZodString;
114
+ accountId: z.ZodString;
115
+ url: z.ZodString;
116
+ __typename: z.ZodLiteral<"TaskGmailIntegrationIdentifier">;
117
+ }, "strip", z.ZodTypeAny, {
118
+ id: string;
119
+ url: string;
120
+ __typename: "TaskGmailIntegrationIdentifier";
121
+ messageId: string;
122
+ accountId: string;
123
+ }, {
124
+ id: string;
125
+ url: string;
126
+ __typename: "TaskGmailIntegrationIdentifier";
127
+ messageId: string;
128
+ accountId: string;
129
+ }>;
130
+ __typename: z.ZodLiteral<"TaskGmailIntegration">;
131
+ }, "strip", z.ZodTypeAny, {
132
+ __typename: "TaskGmailIntegration";
133
+ service: "gmail";
134
+ identifier: {
135
+ id: string;
136
+ url: string;
137
+ __typename: "TaskGmailIntegrationIdentifier";
138
+ messageId: string;
139
+ accountId: string;
140
+ };
141
+ }, {
142
+ __typename: "TaskGmailIntegration";
143
+ service: "gmail";
144
+ identifier: {
145
+ id: string;
146
+ url: string;
147
+ __typename: "TaskGmailIntegrationIdentifier";
148
+ messageId: string;
149
+ accountId: string;
150
+ };
151
+ }>]>>;
57
152
  }, "strip", z.ZodTypeAny, {
58
153
  text: string;
59
154
  taskId?: string | undefined;
@@ -63,6 +158,29 @@ export declare const createTaskSchema: z.ZodObject<{
63
158
  dueDate?: string | undefined;
64
159
  snoozeUntil?: string | undefined;
65
160
  private?: boolean | undefined;
161
+ integration?: {
162
+ __typename: "TaskGithubIntegration";
163
+ service: "github";
164
+ identifier: {
165
+ number: number;
166
+ type: "Issue" | "PullRequest";
167
+ id: string;
168
+ url: string;
169
+ repositoryOwnerLogin: string;
170
+ repositoryName: string;
171
+ __typename: "TaskGithubIntegrationIdentifier";
172
+ };
173
+ } | {
174
+ __typename: "TaskGmailIntegration";
175
+ service: "gmail";
176
+ identifier: {
177
+ id: string;
178
+ url: string;
179
+ __typename: "TaskGmailIntegrationIdentifier";
180
+ messageId: string;
181
+ accountId: string;
182
+ };
183
+ } | undefined;
66
184
  }, {
67
185
  text: string;
68
186
  taskId?: string | undefined;
@@ -72,6 +190,29 @@ export declare const createTaskSchema: z.ZodObject<{
72
190
  dueDate?: string | undefined;
73
191
  snoozeUntil?: string | undefined;
74
192
  private?: boolean | undefined;
193
+ integration?: {
194
+ __typename: "TaskGithubIntegration";
195
+ service: "github";
196
+ identifier: {
197
+ number: number;
198
+ type: "Issue" | "PullRequest";
199
+ id: string;
200
+ url: string;
201
+ repositoryOwnerLogin: string;
202
+ repositoryName: string;
203
+ __typename: "TaskGithubIntegrationIdentifier";
204
+ };
205
+ } | {
206
+ __typename: "TaskGmailIntegration";
207
+ service: "gmail";
208
+ identifier: {
209
+ id: string;
210
+ url: string;
211
+ __typename: "TaskGmailIntegrationIdentifier";
212
+ messageId: string;
213
+ accountId: string;
214
+ };
215
+ } | undefined;
75
216
  }>;
76
217
  export declare const updateTaskCompleteSchema: z.ZodObject<{
77
218
  taskId: z.ZodString;
@@ -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":"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"}
package/dist/schemas.js CHANGED
@@ -35,6 +35,44 @@ export const getUserSchema = z.object({});
35
35
  */
36
36
  // Get streams parameters (no parameters needed, uses cached group ID)
37
37
  export const getStreamsSchema = z.object({});
38
+ /**
39
+ * Task Integration Schemas
40
+ */
41
+ // GitHub integration identifier schema
42
+ const githubIntegrationIdentifierSchema = z.object({
43
+ id: z.string().describe("GitHub issue or PR ID"),
44
+ repositoryOwnerLogin: z.string().describe("GitHub repository owner login"),
45
+ repositoryName: z.string().describe("GitHub repository name"),
46
+ number: z.number().int().describe("GitHub issue or PR number"),
47
+ type: z.enum(["Issue", "PullRequest"]).describe("Type of GitHub item"),
48
+ url: z.string().url().describe("URL to the GitHub issue or PR"),
49
+ __typename: z.literal("TaskGithubIntegrationIdentifier"),
50
+ });
51
+ // GitHub integration schema
52
+ const githubIntegrationSchema = z.object({
53
+ service: z.literal("github"),
54
+ identifier: githubIntegrationIdentifierSchema,
55
+ __typename: z.literal("TaskGithubIntegration"),
56
+ });
57
+ // Gmail integration identifier schema
58
+ const gmailIntegrationIdentifierSchema = z.object({
59
+ id: z.string().describe("Gmail message ID"),
60
+ messageId: z.string().describe("Gmail message ID (duplicate of id)"),
61
+ accountId: z.string().describe("Gmail account ID"),
62
+ url: z.string().url().describe("URL to the Gmail message"),
63
+ __typename: z.literal("TaskGmailIntegrationIdentifier"),
64
+ });
65
+ // Gmail integration schema
66
+ const gmailIntegrationSchema = z.object({
67
+ service: z.literal("gmail"),
68
+ identifier: gmailIntegrationIdentifierSchema,
69
+ __typename: z.literal("TaskGmailIntegration"),
70
+ });
71
+ // Union schema for all task integrations
72
+ const taskIntegrationSchema = z.discriminatedUnion("service", [
73
+ githubIntegrationSchema,
74
+ gmailIntegrationSchema,
75
+ ]);
38
76
  /**
39
77
  * Task Mutation Operation Schemas
40
78
  */
@@ -48,6 +86,7 @@ export const createTaskSchema = z.object({
48
86
  snoozeUntil: z.string().optional().describe("Snooze until date string (ISO format) - the date the task is scheduled for"),
49
87
  private: z.boolean().optional().describe("Whether the task is private"),
50
88
  taskId: z.string().optional().describe("Custom task ID (auto-generated if not provided)"),
89
+ integration: taskIntegrationSchema.optional().describe("Integration information for linking task to external services (GitHub, Gmail, etc.)"),
51
90
  });
52
91
  // Update task complete parameters
53
92
  export const updateTaskCompleteSchema = z.object({
@@ -1 +1 @@
1
- {"version":3,"file":"task-tools.d.ts","sourceRoot":"","sources":["../../src/tools/task-tools.ts"],"names":[],"mappings":"AA0CA,eAAO,MAAM,mBAAmB;;;;;CAU9B,CAAC;AAEH,eAAO,MAAM,iBAAiB;;;;;CAqB5B,CAAC;AAEH,eAAO,MAAM,oBAAoB;;;;;CA2B/B,CAAC;AAEH,eAAO,MAAM,eAAe;;;;;CAS1B,CAAC;AAGH,eAAO,MAAM,cAAc;;;;;CAoCzB,CAAC;AAEH,eAAO,MAAM,cAAc;;;;;CAqBzB,CAAC;AAGH,eAAO,MAAM,sBAAsB;;;;;CAqBjC,CAAC;AAEH,eAAO,MAAM,wBAAwB;;;;;CA6BnC,CAAC;AAEH,eAAO,MAAM,qBAAqB;;;;;CA2BhC,CAAC;AAEH,eAAO,MAAM,yBAAyB;;;;;CAsBpC,CAAC;AAEH,eAAO,MAAM,mBAAmB;;;;;CAiC9B,CAAC;AAEH,eAAO,MAAM,qBAAqB;;;;;CAsBhC,CAAC;AAEH,eAAO,MAAM,kBAAkB;;;;;CA8B7B,CAAC;AAEH,eAAO,MAAM,oBAAoB;;;;;CAsB/B,CAAC;AAGH,eAAO,MAAM,SAAS;;;;;GAoBrB,CAAC"}
1
+ {"version":3,"file":"task-tools.d.ts","sourceRoot":"","sources":["../../src/tools/task-tools.ts"],"names":[],"mappings":"AA0CA,eAAO,MAAM,mBAAmB;;;;;CAU9B,CAAC;AAEH,eAAO,MAAM,iBAAiB;;;;;CAqB5B,CAAC;AAEH,eAAO,MAAM,oBAAoB;;;;;CA2B/B,CAAC;AAEH,eAAO,MAAM,eAAe;;;;;CAS1B,CAAC;AAGH,eAAO,MAAM,cAAc;;;;;CAsCzB,CAAC;AAEH,eAAO,MAAM,cAAc;;;;;CAqBzB,CAAC;AAGH,eAAO,MAAM,sBAAsB;;;;;CAqBjC,CAAC;AAEH,eAAO,MAAM,wBAAwB;;;;;CA6BnC,CAAC;AAEH,eAAO,MAAM,qBAAqB;;;;;CA2BhC,CAAC;AAEH,eAAO,MAAM,yBAAyB;;;;;CAsBpC,CAAC;AAEH,eAAO,MAAM,mBAAmB;;;;;CAiC9B,CAAC;AAEH,eAAO,MAAM,qBAAqB;;;;;CAsBhC,CAAC;AAEH,eAAO,MAAM,kBAAkB;;;;;CA8B7B,CAAC;AAEH,eAAO,MAAM,oBAAoB;;;;;CAsB/B,CAAC;AAGH,eAAO,MAAM,SAAS;;;;;GAoBrB,CAAC"}
@@ -64,7 +64,7 @@ export const createTaskTool = withTransportClient({
64
64
  name: "create-task",
65
65
  description: "Create a new task with optional properties",
66
66
  parameters: createTaskSchema,
67
- execute: async ({ text, notes, streamIds, timeEstimate, dueDate, snoozeUntil, private: isPrivate, taskId, }, context) => {
67
+ execute: async ({ text, notes, streamIds, timeEstimate, dueDate, snoozeUntil, private: isPrivate, taskId, integration, }, context) => {
68
68
  const options = {};
69
69
  if (notes)
70
70
  options.notes = notes;
@@ -80,6 +80,8 @@ export const createTaskTool = withTransportClient({
80
80
  options.private = isPrivate;
81
81
  if (taskId)
82
82
  options.taskId = taskId;
83
+ if (integration)
84
+ options.integration = integration;
83
85
  const result = await context.client.createTask(text, options);
84
86
  return formatJsonResponse({
85
87
  success: result.success,
@@ -1 +1 @@
1
- {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/transports/http.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AASpE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAE9D,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAI/D,eAAO,MAAM,cAAc,gBAAuB,CAAC;AAgCnD,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,SAAS,EACjB,MAAM,EAAE,OAAO,CAAC,eAAe,EAAE;IAAE,aAAa,EAAE,MAAM,CAAA;CAAE,CAAC,iBA4O5D"}
1
+ {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/transports/http.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAcpE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAE9D,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAG/D,eAAO,MAAM,cAAc,gBAAuB,CAAC;AAgCnD,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,SAAS,EACjB,MAAM,EAAE,OAAO,CAAC,eAAe,EAAE;IAAE,aAAa,EAAE,MAAM,CAAA;CAAE,CAAC,iBA4O5D"}
@@ -1,12 +1,13 @@
1
- import express from "express";
2
- import cors from "cors";
3
- import { randomUUID } from "node:crypto";
4
1
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
5
2
  import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
6
3
  import { isInitializeRequest } from "@modelcontextprotocol/sdk/types.js";
7
- import { authenticateHttpRequest, startClientCacheCleanup, stopClientCacheCleanup, cleanupAllClients, } from "../auth/http.js";
8
- import { SessionManager } from "../session/session-manager.js";
4
+ import cors from "cors";
5
+ import express from "express";
6
+ import { randomUUID } from "node:crypto";
7
+ import { authenticateHttpRequest, cleanupAllClients, startClientCacheCleanup, stopClientCacheCleanup, } from "../auth/http.js";
9
8
  import { getSessionConfig } from "../config/session-config.js";
9
+ import { PACKAGE_NAME, VERSION } from "../constants.js";
10
+ import { SessionManager } from "../session/session-manager.js";
10
11
  // Unified session management
11
12
  export const sessionManager = new SessionManager();
12
13
  // Configuration - loaded from environment
@@ -52,8 +53,8 @@ export async function setupHttpTransport(server, config) {
52
53
  // Health check endpoint
53
54
  app.get("/", (req, res) => {
54
55
  res.json({
55
- name: "mcp-sunsama",
56
- version: "0.15.0",
56
+ name: PACKAGE_NAME,
57
+ version: VERSION,
57
58
  transport: "http",
58
59
  activeSessions: sessionManager.getSessionCount(),
59
60
  });
package/glama.json ADDED
@@ -0,0 +1,6 @@
1
+ {
2
+ "$schema": "https://glama.ai/mcp/schemas/server.json",
3
+ "maintainers": [
4
+ "robertn702"
5
+ ]
6
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mcp-sunsama",
3
- "version": "0.15.4",
3
+ "version": "0.16.0",
4
4
  "description": "MCP server for Sunsama API integration",
5
5
  "type": "module",
6
6
  "private": false,
@@ -16,15 +16,17 @@
16
16
  "test:integration": "bun test --test-name-pattern 'Integration Tests'",
17
17
  "test:all": "bun test",
18
18
  "test:watch": "bun test --watch --test-name-pattern '^(?!.*Integration Tests).*$'",
19
- "typecheck": "bunx tsc --noEmit",
20
- "typecheck:watch": "bunx tsc --noEmit --watch",
21
- "build": "bunx tsc",
19
+ "typecheck": "tsc --noEmit",
20
+ "typecheck:watch": "tsc --noEmit --watch",
21
+ "clean": "rm -rf dist",
22
+ "build": "tsc",
23
+ "build:clean": "npm run clean && npm run build",
22
24
  "postbuild": "chmod +x dist/main.js",
23
25
  "inspect": "bunx @modelcontextprotocol/inspector --config ./mcp-inspector.json --server sunsama",
24
26
  "changeset": "changeset",
25
27
  "version": "changeset version",
26
- "release": "bun run build && changeset publish",
27
- "prepublishOnly": "bun run build"
28
+ "release": "npm run build && changeset publish",
29
+ "prepublishOnly": "npm run build:clean"
28
30
  },
29
31
  "dependencies": {
30
32
  "@modelcontextprotocol/sdk": "1.18.2",
@@ -32,7 +34,7 @@
32
34
  "cors": "^2.8.5",
33
35
  "express": "^5.1.0",
34
36
  "papaparse": "^5.5.3",
35
- "sunsama-api": "0.11.2",
37
+ "sunsama-api": "0.12.0",
36
38
  "zod": "3.24.4"
37
39
  },
38
40
  "devDependencies": {
package/smithery.yaml ADDED
@@ -0,0 +1,9 @@
1
+ runtime: "container"
2
+ startCommand:
3
+ type: "http"
4
+ build:
5
+ dockerfile: "Dockerfile"
6
+ dockerBuildPath: "."
7
+ env:
8
+ TRANSPORT_MODE: "http"
9
+ PORT: "3000"
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Application constants
3
+ *
4
+ * IMPORTANT: Keep VERSION in sync with package.json version
5
+ */
6
+
7
+ export const VERSION = "0.16.0";
8
+ export const SERVER_NAME = "Sunsama API Server";
9
+ export const PACKAGE_NAME = "mcp-sunsama";
package/src/main.ts CHANGED
@@ -5,12 +5,13 @@ import { setupStdioTransport } from "./transports/stdio.js";
5
5
  import { setupHttpTransport } from "./transports/http.js";
6
6
  import { allTools } from "./tools/index.js";
7
7
  import { apiDocumentationResource } from "./resources/index.js";
8
+ import { VERSION, SERVER_NAME } from "./constants.js";
8
9
 
9
10
  // Async IIFE for top-level await and error handling
10
11
  (async () => {
11
12
  const server = new McpServer({
12
- name: "Sunsama API Server",
13
- version: "0.15.4",
13
+ name: SERVER_NAME,
14
+ version: VERSION,
14
15
  instructions: `
15
16
  This MCP server provides access to the Sunsama API for task and project management.
16
17
 
package/src/schemas.ts CHANGED
@@ -59,6 +59,50 @@ export const getUserSchema = z.object({});
59
59
  // Get streams parameters (no parameters needed, uses cached group ID)
60
60
  export const getStreamsSchema = z.object({});
61
61
 
62
+ /**
63
+ * Task Integration Schemas
64
+ */
65
+
66
+ // GitHub integration identifier schema
67
+ const githubIntegrationIdentifierSchema = z.object({
68
+ id: z.string().describe("GitHub issue or PR ID"),
69
+ repositoryOwnerLogin: z.string().describe("GitHub repository owner login"),
70
+ repositoryName: z.string().describe("GitHub repository name"),
71
+ number: z.number().int().describe("GitHub issue or PR number"),
72
+ type: z.enum(["Issue", "PullRequest"]).describe("Type of GitHub item"),
73
+ url: z.string().url().describe("URL to the GitHub issue or PR"),
74
+ __typename: z.literal("TaskGithubIntegrationIdentifier"),
75
+ });
76
+
77
+ // GitHub integration schema
78
+ const githubIntegrationSchema = z.object({
79
+ service: z.literal("github"),
80
+ identifier: githubIntegrationIdentifierSchema,
81
+ __typename: z.literal("TaskGithubIntegration"),
82
+ });
83
+
84
+ // Gmail integration identifier schema
85
+ const gmailIntegrationIdentifierSchema = z.object({
86
+ id: z.string().describe("Gmail message ID"),
87
+ messageId: z.string().describe("Gmail message ID (duplicate of id)"),
88
+ accountId: z.string().describe("Gmail account ID"),
89
+ url: z.string().url().describe("URL to the Gmail message"),
90
+ __typename: z.literal("TaskGmailIntegrationIdentifier"),
91
+ });
92
+
93
+ // Gmail integration schema
94
+ const gmailIntegrationSchema = z.object({
95
+ service: z.literal("gmail"),
96
+ identifier: gmailIntegrationIdentifierSchema,
97
+ __typename: z.literal("TaskGmailIntegration"),
98
+ });
99
+
100
+ // Union schema for all task integrations
101
+ const taskIntegrationSchema = z.discriminatedUnion("service", [
102
+ githubIntegrationSchema,
103
+ gmailIntegrationSchema,
104
+ ]);
105
+
62
106
  /**
63
107
  * Task Mutation Operation Schemas
64
108
  */
@@ -83,6 +127,9 @@ export const createTaskSchema = z.object({
83
127
  taskId: z.string().optional().describe(
84
128
  "Custom task ID (auto-generated if not provided)",
85
129
  ),
130
+ integration: taskIntegrationSchema.optional().describe(
131
+ "Integration information for linking task to external services (GitHub, Gmail, etc.)",
132
+ ),
86
133
  });
87
134
 
88
135
  // Update task complete parameters
@@ -130,6 +130,7 @@ export const createTaskTool = withTransportClient({
130
130
  snoozeUntil,
131
131
  private: isPrivate,
132
132
  taskId,
133
+ integration,
133
134
  }: CreateTaskInput,
134
135
  context: ToolContext,
135
136
  ) => {
@@ -141,6 +142,7 @@ export const createTaskTool = withTransportClient({
141
142
  if (snoozeUntil) options.snoozeUntil = snoozeUntil;
142
143
  if (isPrivate !== undefined) options.private = isPrivate;
143
144
  if (taskId) options.taskId = taskId;
145
+ if (integration) options.integration = integration;
144
146
 
145
147
  const result = await context.client.createTask(text, options);
146
148
 
@@ -1,19 +1,20 @@
1
- import express from "express";
2
- import cors from "cors";
3
- import { randomUUID } from "node:crypto";
4
1
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
5
2
  import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
6
3
  import { isInitializeRequest } from "@modelcontextprotocol/sdk/types.js";
4
+ import cors from "cors";
5
+ import express from "express";
6
+ import { randomUUID } from "node:crypto";
7
7
  import {
8
8
  authenticateHttpRequest,
9
+ cleanupAllClients,
9
10
  startClientCacheCleanup,
10
11
  stopClientCacheCleanup,
11
- cleanupAllClients,
12
12
  } from "../auth/http.js";
13
- import type { TransportConfig } from "../config/transport.js";
14
13
  import type { SessionData } from "../auth/types.js";
15
- import { SessionManager } from "../session/session-manager.js";
16
14
  import { getSessionConfig } from "../config/session-config.js";
15
+ import type { TransportConfig } from "../config/transport.js";
16
+ import { PACKAGE_NAME, VERSION } from "../constants.js";
17
+ import { SessionManager } from "../session/session-manager.js";
17
18
 
18
19
  // Unified session management
19
20
  export const sessionManager = new SessionManager();
@@ -69,13 +70,13 @@ export async function setupHttpTransport(
69
70
  })
70
71
  );
71
72
 
72
- app.use(express.json({ limit: "4mb" }));
73
+ app.use(express.json({limit: "4mb"}));
73
74
 
74
75
  // Health check endpoint
75
76
  app.get("/", (req, res) => {
76
77
  res.json({
77
- name: "mcp-sunsama",
78
- version: "0.15.0",
78
+ name: PACKAGE_NAME,
79
+ version: VERSION,
79
80
  transport: "http",
80
81
  activeSessions: sessionManager.getSessionCount(),
81
82
  });
@@ -248,7 +249,7 @@ export async function setupHttpTransport(
248
249
  }
249
250
  });
250
251
 
251
- const { port } = config.httpStream;
252
+ const {port} = config.httpStream;
252
253
 
253
254
  // Start cleanup timers
254
255
  startClientCacheCleanup();