mcp-sunsama 0.15.4 → 0.16.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 +26 -0
- package/CLAUDE.md +43 -11
- package/CONTRIBUTING.md +20 -7
- package/README.md +75 -3
- package/bun.lock +3 -2
- package/dist/constants.d.ts +10 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +9 -0
- package/dist/main.js +3 -2
- package/dist/schemas.d.ts +142 -11
- package/dist/schemas.d.ts.map +1 -1
- package/dist/schemas.js +42 -9
- package/dist/tools/task-tools.d.ts.map +1 -1
- package/dist/tools/task-tools.js +9 -1
- package/dist/transports/http.d.ts.map +1 -1
- package/dist/transports/http.js +8 -7
- package/glama.json +6 -0
- package/package.json +10 -8
- package/scripts/sync-version.ts +35 -0
- package/smithery.yaml +9 -0
- package/src/constants.ts +10 -0
- package/src/main.ts +3 -2
- package/src/schemas.ts +51 -13
- package/src/tools/task-tools.ts +9 -0
- package/src/transports/http.ts +11 -10
- package/tsconfig.json +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,31 @@
|
|
|
1
1
|
# mcp-sunsama
|
|
2
2
|
|
|
3
|
+
## 0.16.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 5df00f4: Bump sunsama-api dependency from 0.12.0 to 0.12.1
|
|
8
|
+
- 14c0713: Fix update-task-notes tool failing with MCP error -32603. Removed Zod `.refine()` from schema which was causing MCP SDK to fail parsing the tool parameters. XOR validation between html/markdown is now handled at runtime.
|
|
9
|
+
|
|
10
|
+
## 0.16.0
|
|
11
|
+
|
|
12
|
+
### Minor Changes
|
|
13
|
+
|
|
14
|
+
- 56872df: Add GitHub and Gmail integration support to create-task tool
|
|
15
|
+
|
|
16
|
+
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.
|
|
17
|
+
|
|
18
|
+
**New Features:**
|
|
19
|
+
|
|
20
|
+
- Added `TaskGithubIntegration` schema with all required fields (id, repositoryOwnerLogin, repositoryName, number, type, url)
|
|
21
|
+
- Added `TaskGmailIntegration` schema with all required fields (id, messageId, accountId, url)
|
|
22
|
+
- Updated `create-task` tool to accept optional `integration` parameter
|
|
23
|
+
- Implemented discriminated union pattern for type-safe integration handling
|
|
24
|
+
- Full TypeScript support with Zod schema validation
|
|
25
|
+
|
|
26
|
+
**Migration:**
|
|
27
|
+
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.
|
|
28
|
+
|
|
3
29
|
## 0.15.4
|
|
4
30
|
|
|
5
31
|
### Patch Changes
|
package/CLAUDE.md
CHANGED
|
@@ -28,6 +28,31 @@ bun run version # Apply changesets and update version
|
|
|
28
28
|
bun run release # Build and publish to npm
|
|
29
29
|
```
|
|
30
30
|
|
|
31
|
+
## Contribution Workflow
|
|
32
|
+
|
|
33
|
+
**IMPORTANT**: When making changes that affect package users, always create a changeset.
|
|
34
|
+
|
|
35
|
+
### When to Create a Changeset
|
|
36
|
+
- ✅ New user-facing features or tools
|
|
37
|
+
- ✅ Bug fixes that affect npm package users
|
|
38
|
+
- ✅ API changes or breaking changes
|
|
39
|
+
- ✅ Dependency updates that change behavior
|
|
40
|
+
|
|
41
|
+
### When NOT to Create a Changeset
|
|
42
|
+
- ❌ Infrastructure/deployment changes (CI/CD, Docker, Smithery config)
|
|
43
|
+
- ❌ Internal refactoring with no behavior changes
|
|
44
|
+
- ❌ Documentation updates
|
|
45
|
+
- ❌ Development tooling changes
|
|
46
|
+
|
|
47
|
+
### Standard Workflow
|
|
48
|
+
1. Create a branch: `git checkout -b {type}/{short-name}`
|
|
49
|
+
2. Make changes and test: `bun test && bun run typecheck`
|
|
50
|
+
3. **Create a changeset**: `bun run changeset` (if changes affect users)
|
|
51
|
+
4. Commit with conventional format: `git commit -m "fix: description"`
|
|
52
|
+
5. Push and create PR
|
|
53
|
+
|
|
54
|
+
See `CONTRIBUTING.md` for full details.
|
|
55
|
+
|
|
31
56
|
## Architecture Overview
|
|
32
57
|
|
|
33
58
|
### Dual Transport MCP Server
|
|
@@ -87,8 +112,16 @@ All tools use Zod schemas from `schemas.ts`:
|
|
|
87
112
|
- Automatic TypeScript inference
|
|
88
113
|
- Comprehensive parameter documentation
|
|
89
114
|
- Union types for completion filters
|
|
90
|
-
-
|
|
91
|
-
- Example: `update-task-notes` requires either `html` OR `markdown`,
|
|
115
|
+
- **Important**: Avoid using `.refine()` on schemas - it transforms `ZodObject` into `ZodEffects` which the MCP SDK cannot parse (results in empty `properties`). Handle complex validation (e.g., XOR between fields) in the tool's `execute` function instead.
|
|
116
|
+
- Example: `update-task-notes` requires either `html` OR `markdown`, validated at runtime
|
|
117
|
+
- Discriminated unions for task integrations (GitHub, Gmail)
|
|
118
|
+
|
|
119
|
+
### Integration Support
|
|
120
|
+
The `create-task` tool supports external integrations:
|
|
121
|
+
- **GitHub Integration**: Link tasks to GitHub issues or pull requests
|
|
122
|
+
- **Gmail Integration**: Link tasks to Gmail emails
|
|
123
|
+
- Uses discriminated union pattern for type-safe integration handling
|
|
124
|
+
- Integration parameter is optional to maintain backward compatibility
|
|
92
125
|
|
|
93
126
|
## Key Patterns
|
|
94
127
|
|
|
@@ -149,7 +182,7 @@ src/
|
|
|
149
182
|
├── tools/
|
|
150
183
|
│ ├── shared.ts # Common utilities and tool wrapper patterns
|
|
151
184
|
│ ├── user-tools.ts # User operations (get-user)
|
|
152
|
-
│ ├── task-tools.ts # Task operations (
|
|
185
|
+
│ ├── task-tools.ts # Task operations (15 tools)
|
|
153
186
|
│ ├── stream-tools.ts # Stream operations (get-streams)
|
|
154
187
|
│ └── index.ts # Export all tools
|
|
155
188
|
├── resources/
|
|
@@ -193,7 +226,7 @@ __tests__/
|
|
|
193
226
|
|
|
194
227
|
**Resource-Based Organization**:
|
|
195
228
|
- **User Tools**: Single tool for user operations
|
|
196
|
-
- **Task Tools**:
|
|
229
|
+
- **Task Tools**: 15 tools organized by function (query, lifecycle, update)
|
|
197
230
|
- **Stream Tools**: Single tool for stream operations
|
|
198
231
|
|
|
199
232
|
**Type Safety Improvements**:
|
|
@@ -227,7 +260,7 @@ Tests are organized in the `__tests__/` directory following standard conventions
|
|
|
227
260
|
## Important Notes
|
|
228
261
|
|
|
229
262
|
### Version Synchronization
|
|
230
|
-
|
|
263
|
+
The MCP server version in `src/constants.ts` is automatically synced from `package.json` when running `bun run version`.
|
|
231
264
|
|
|
232
265
|
### Environment Variables
|
|
233
266
|
Required for stdio transport:
|
|
@@ -244,7 +277,7 @@ Optional:
|
|
|
244
277
|
### Task Operations
|
|
245
278
|
Full CRUD support:
|
|
246
279
|
- **Read**: `get-tasks-by-day`, `get-tasks-backlog`, `get-archived-tasks`, `get-task-by-id`, `get-streams`
|
|
247
|
-
- **Write**: `create-task
|
|
280
|
+
- **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
281
|
|
|
249
282
|
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
283
|
|
|
@@ -254,12 +287,11 @@ Configure different server variants in `mcp-inspector.json` for testing various
|
|
|
254
287
|
|
|
255
288
|
## Version Management
|
|
256
289
|
|
|
257
|
-
|
|
290
|
+
Version is managed automatically via changesets. When you run `bun run version`:
|
|
291
|
+
1. Changesets updates `package.json` version
|
|
292
|
+
2. `scripts/sync-version.ts` automatically syncs the version to `src/constants.ts`
|
|
258
293
|
|
|
259
|
-
|
|
260
|
-
1. Update `package.json` version (done automatically by changesets)
|
|
261
|
-
2. Manually update the FastMCP server version in `src/main.ts` (line 19)
|
|
262
|
-
3. Both versions must be identical for consistency
|
|
294
|
+
No manual version updates needed.
|
|
263
295
|
|
|
264
296
|
## Git Rules
|
|
265
297
|
|
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
|
|
170
|
+
**IMPORTANT**: After this command, manually update the version in `src/constants.ts` to match `package.json`:
|
|
159
171
|
```typescript
|
|
160
|
-
const
|
|
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
|
-
|
|
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
|
|
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 (
|
|
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
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"lockfileVersion": 1,
|
|
3
|
+
"configVersion": 0,
|
|
3
4
|
"workspaces": {
|
|
4
5
|
"": {
|
|
5
6
|
"name": "mcp-sunsama",
|
|
@@ -9,7 +10,7 @@
|
|
|
9
10
|
"cors": "^2.8.5",
|
|
10
11
|
"express": "^5.1.0",
|
|
11
12
|
"papaparse": "^5.5.3",
|
|
12
|
-
"sunsama-api": "0.
|
|
13
|
+
"sunsama-api": "0.12.1",
|
|
13
14
|
"zod": "3.24.4",
|
|
14
15
|
},
|
|
15
16
|
"devDependencies": {
|
|
@@ -396,7 +397,7 @@
|
|
|
396
397
|
|
|
397
398
|
"strip-bom": ["strip-bom@3.0.0", "", {}, "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA=="],
|
|
398
399
|
|
|
399
|
-
"sunsama-api": ["sunsama-api@0.
|
|
400
|
+
"sunsama-api": ["sunsama-api@0.12.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-F2GLJjanAeboP4vYg3VIKP8xxQ/8LLqHhNFx3lm9oONOSvLzVAXEJlwonESuUI/iIf93b2i/jYCJ/2guoUhRYQ=="],
|
|
400
401
|
|
|
401
402
|
"term-size": ["term-size@2.2.1", "", {}, "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg=="],
|
|
402
403
|
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Application constants
|
|
3
|
+
*
|
|
4
|
+
* VERSION is automatically synced from package.json by scripts/sync-version.ts
|
|
5
|
+
* when running `bun run version`
|
|
6
|
+
*/
|
|
7
|
+
export declare const VERSION = "0.16.1";
|
|
8
|
+
export declare const SERVER_NAME = "Sunsama API Server";
|
|
9
|
+
export declare const PACKAGE_NAME = "mcp-sunsama";
|
|
10
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,OAAO,WAAW,CAAC;AAChC,eAAO,MAAM,WAAW,uBAAuB,CAAC;AAChD,eAAO,MAAM,YAAY,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Application constants
|
|
3
|
+
*
|
|
4
|
+
* VERSION is automatically synced from package.json by scripts/sync-version.ts
|
|
5
|
+
* when running `bun run version`
|
|
6
|
+
*/
|
|
7
|
+
export const VERSION = "0.16.1";
|
|
8
|
+
export const SERVER_NAME = "Sunsama API Server";
|
|
9
|
+
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:
|
|
12
|
-
version:
|
|
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;
|
|
@@ -141,7 +282,7 @@ export declare const updateTaskPlannedTimeSchema: z.ZodObject<{
|
|
|
141
282
|
timeEstimateMinutes: number;
|
|
142
283
|
limitResponsePayload?: boolean | undefined;
|
|
143
284
|
}>;
|
|
144
|
-
export declare const updateTaskNotesSchema: z.
|
|
285
|
+
export declare const updateTaskNotesSchema: z.ZodObject<{
|
|
145
286
|
taskId: z.ZodString;
|
|
146
287
|
html: z.ZodOptional<z.ZodString>;
|
|
147
288
|
markdown: z.ZodOptional<z.ZodString>;
|
|
@@ -156,16 +297,6 @@ export declare const updateTaskNotesSchema: z.ZodEffects<z.ZodObject<{
|
|
|
156
297
|
limitResponsePayload?: boolean | undefined;
|
|
157
298
|
html?: string | undefined;
|
|
158
299
|
markdown?: string | undefined;
|
|
159
|
-
}>, {
|
|
160
|
-
taskId: string;
|
|
161
|
-
limitResponsePayload?: boolean | undefined;
|
|
162
|
-
html?: string | undefined;
|
|
163
|
-
markdown?: string | undefined;
|
|
164
|
-
}, {
|
|
165
|
-
taskId: string;
|
|
166
|
-
limitResponsePayload?: boolean | undefined;
|
|
167
|
-
html?: string | undefined;
|
|
168
|
-
markdown?: string | undefined;
|
|
169
300
|
}>;
|
|
170
301
|
export declare const updateTaskDueDateSchema: z.ZodObject<{
|
|
171
302
|
taskId: z.ZodString;
|
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;AAGH,eAAO,MAAM,sBAAsB,+CAIjC,CAAC;AAGH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;EAW9B,CAAC;AAGH,eAAO,MAAM,qBAAqB,gDAAe,CAAC;AAGlD,eAAO,MAAM,sBAAsB;;;;;;;;;EAOjC,CAAC;AAGH,eAAO,MAAM,iBAAiB;;;;;;EAI5B,CAAC;AAEH;;GAEG;AAGH,eAAO,MAAM,aAAa,gDAAe,CAAC;AAE1C;;GAEG;AAGH,eAAO,MAAM,gBAAgB,gDAAe,CAAC;
|
|
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({
|
|
@@ -80,20 +119,14 @@ export const updateTaskPlannedTimeSchema = z.object({
|
|
|
80
119
|
timeEstimateMinutes: z.number().int().min(0).describe("Time estimate in minutes (use 0 to clear the time estimate)"),
|
|
81
120
|
limitResponsePayload: z.boolean().optional().describe("Whether to limit the response payload size"),
|
|
82
121
|
});
|
|
83
|
-
// Update task notes parameters
|
|
122
|
+
// Update task notes parameters
|
|
123
|
+
// Note: XOR validation between html/markdown is done in the tool execute function
|
|
124
|
+
// to keep the schema as a plain ZodObject (required for MCP SDK compatibility)
|
|
84
125
|
export const updateTaskNotesSchema = z.object({
|
|
85
126
|
taskId: z.string().min(1, "Task ID is required").describe("The ID of the task to update notes for"),
|
|
86
127
|
html: z.string().optional().describe("HTML content for the task notes (mutually exclusive with markdown)"),
|
|
87
128
|
markdown: z.string().optional().describe("Markdown content for the task notes (mutually exclusive with html)"),
|
|
88
129
|
limitResponsePayload: z.boolean().optional().describe("Whether to limit the response payload size (defaults to true)"),
|
|
89
|
-
}).refine((data) => {
|
|
90
|
-
// Exactly one of html or markdown must be provided
|
|
91
|
-
const hasHtml = data.html !== undefined;
|
|
92
|
-
const hasMarkdown = data.markdown !== undefined;
|
|
93
|
-
return hasHtml !== hasMarkdown; // XOR: exactly one must be true
|
|
94
|
-
}, {
|
|
95
|
-
message: "Exactly one of 'html' or 'markdown' must be provided",
|
|
96
|
-
path: [], // This will show the error at the root level
|
|
97
130
|
});
|
|
98
131
|
// Update task due date parameters
|
|
99
132
|
export const updateTaskDueDateSchema = 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;;;;;
|
|
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;;;;;CAwC9B,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"}
|
package/dist/tools/task-tools.js
CHANGED
|
@@ -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,
|
|
@@ -178,6 +180,12 @@ export const updateTaskNotesTool = withTransportClient({
|
|
|
178
180
|
description: "Update the notes content for a task",
|
|
179
181
|
parameters: updateTaskNotesSchema,
|
|
180
182
|
execute: async ({ taskId, html, markdown, limitResponsePayload }, context) => {
|
|
183
|
+
// XOR validation: exactly one of html or markdown must be provided
|
|
184
|
+
const hasHtml = html !== undefined;
|
|
185
|
+
const hasMarkdown = markdown !== undefined;
|
|
186
|
+
if (hasHtml === hasMarkdown) {
|
|
187
|
+
throw new Error("Exactly one of 'html' or 'markdown' must be provided");
|
|
188
|
+
}
|
|
181
189
|
const content = html
|
|
182
190
|
? { type: "html", value: html }
|
|
183
191
|
: { type: "markdown", value: markdown };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/transports/http.ts"],"names":[],"mappings":"
|
|
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"}
|
package/dist/transports/http.js
CHANGED
|
@@ -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
|
|
8
|
-
import
|
|
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:
|
|
56
|
-
version:
|
|
56
|
+
name: PACKAGE_NAME,
|
|
57
|
+
version: VERSION,
|
|
57
58
|
transport: "http",
|
|
58
59
|
activeSessions: sessionManager.getSessionCount(),
|
|
59
60
|
});
|
package/glama.json
ADDED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mcp-sunsama",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.1",
|
|
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": "
|
|
20
|
-
"typecheck:watch": "
|
|
21
|
-
"
|
|
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
|
-
"version": "changeset version",
|
|
26
|
-
"release": "
|
|
27
|
-
"prepublishOnly": "
|
|
27
|
+
"version": "changeset version && bun scripts/sync-version.ts",
|
|
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.
|
|
37
|
+
"sunsama-api": "0.12.1",
|
|
36
38
|
"zod": "3.24.4"
|
|
37
39
|
},
|
|
38
40
|
"devDependencies": {
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
/**
|
|
3
|
+
* Syncs the version from package.json to src/constants.ts
|
|
4
|
+
* Run automatically as part of `bun run version`
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { readFileSync, writeFileSync } from "fs";
|
|
8
|
+
import { join } from "path";
|
|
9
|
+
|
|
10
|
+
const ROOT_DIR = join(import.meta.dirname, "..");
|
|
11
|
+
const PACKAGE_JSON_PATH = join(ROOT_DIR, "package.json");
|
|
12
|
+
const CONSTANTS_PATH = join(ROOT_DIR, "src", "constants.ts");
|
|
13
|
+
|
|
14
|
+
// Read version from package.json
|
|
15
|
+
const packageJson = JSON.parse(readFileSync(PACKAGE_JSON_PATH, "utf-8"));
|
|
16
|
+
const version = packageJson.version;
|
|
17
|
+
|
|
18
|
+
// Read constants.ts
|
|
19
|
+
let constantsContent = readFileSync(CONSTANTS_PATH, "utf-8");
|
|
20
|
+
|
|
21
|
+
// Replace VERSION value
|
|
22
|
+
const versionRegex = /export const VERSION = "[^"]+";/;
|
|
23
|
+
const newVersionLine = `export const VERSION = "${version}";`;
|
|
24
|
+
|
|
25
|
+
if (!versionRegex.test(constantsContent)) {
|
|
26
|
+
console.error("Could not find VERSION export in constants.ts");
|
|
27
|
+
process.exit(1);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
constantsContent = constantsContent.replace(versionRegex, newVersionLine);
|
|
31
|
+
|
|
32
|
+
// Write back
|
|
33
|
+
writeFileSync(CONSTANTS_PATH, constantsContent);
|
|
34
|
+
|
|
35
|
+
console.log(`Synced VERSION to ${version} in src/constants.ts`);
|
package/smithery.yaml
ADDED
package/src/constants.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Application constants
|
|
3
|
+
*
|
|
4
|
+
* VERSION is automatically synced from package.json by scripts/sync-version.ts
|
|
5
|
+
* when running `bun run version`
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export const VERSION = "0.16.1";
|
|
9
|
+
export const SERVER_NAME = "Sunsama API Server";
|
|
10
|
+
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:
|
|
13
|
-
version:
|
|
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
|
|
@@ -153,7 +200,9 @@ export const updateTaskPlannedTimeSchema = z.object({
|
|
|
153
200
|
),
|
|
154
201
|
});
|
|
155
202
|
|
|
156
|
-
// Update task notes parameters
|
|
203
|
+
// Update task notes parameters
|
|
204
|
+
// Note: XOR validation between html/markdown is done in the tool execute function
|
|
205
|
+
// to keep the schema as a plain ZodObject (required for MCP SDK compatibility)
|
|
157
206
|
export const updateTaskNotesSchema = z.object({
|
|
158
207
|
taskId: z.string().min(1, "Task ID is required").describe(
|
|
159
208
|
"The ID of the task to update notes for",
|
|
@@ -167,18 +216,7 @@ export const updateTaskNotesSchema = z.object({
|
|
|
167
216
|
limitResponsePayload: z.boolean().optional().describe(
|
|
168
217
|
"Whether to limit the response payload size (defaults to true)",
|
|
169
218
|
),
|
|
170
|
-
})
|
|
171
|
-
(data) => {
|
|
172
|
-
// Exactly one of html or markdown must be provided
|
|
173
|
-
const hasHtml = data.html !== undefined;
|
|
174
|
-
const hasMarkdown = data.markdown !== undefined;
|
|
175
|
-
return hasHtml !== hasMarkdown; // XOR: exactly one must be true
|
|
176
|
-
},
|
|
177
|
-
{
|
|
178
|
-
message: "Exactly one of 'html' or 'markdown' must be provided",
|
|
179
|
-
path: [], // This will show the error at the root level
|
|
180
|
-
},
|
|
181
|
-
);
|
|
219
|
+
});
|
|
182
220
|
|
|
183
221
|
// Update task due date parameters
|
|
184
222
|
export const updateTaskDueDateSchema = z.object({
|
package/src/tools/task-tools.ts
CHANGED
|
@@ -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
|
|
|
@@ -293,6 +295,13 @@ export const updateTaskNotesTool = withTransportClient({
|
|
|
293
295
|
{ taskId, html, markdown, limitResponsePayload }: UpdateTaskNotesInput,
|
|
294
296
|
context: ToolContext,
|
|
295
297
|
) => {
|
|
298
|
+
// XOR validation: exactly one of html or markdown must be provided
|
|
299
|
+
const hasHtml = html !== undefined;
|
|
300
|
+
const hasMarkdown = markdown !== undefined;
|
|
301
|
+
if (hasHtml === hasMarkdown) {
|
|
302
|
+
throw new Error("Exactly one of 'html' or 'markdown' must be provided");
|
|
303
|
+
}
|
|
304
|
+
|
|
296
305
|
const content = html
|
|
297
306
|
? { type: "html" as const, value: html }
|
|
298
307
|
: { type: "markdown" as const, value: markdown! };
|
package/src/transports/http.ts
CHANGED
|
@@ -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({
|
|
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:
|
|
78
|
-
version:
|
|
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 {
|
|
252
|
+
const {port} = config.httpStream;
|
|
252
253
|
|
|
253
254
|
// Start cleanup timers
|
|
254
255
|
startClientCacheCleanup();
|