mcp-sunsama 0.3.0 → 0.5.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.
@@ -0,0 +1,156 @@
1
+ # Product Requirements Document: get-archived-tasks Tool
2
+
3
+ ## Overview
4
+ This document outlines the requirements for implementing the `get-archived-tasks` MCP tool for the Sunsama MCP Server, providing access to archived task history with pagination and filtering capabilities.
5
+
6
+ ## Background
7
+ With the update to sunsama-api v0.6.1, the `getArchivedTasks()` method is now available, enabling access to tasks that have been archived in Sunsama. This is a high-priority feature that provides essential access to historical task data for productivity analysis and task retrieval.
8
+
9
+ ## Objectives
10
+ - Provide MCP tool access to archived tasks in Sunsama
11
+ - Enable pagination for efficient handling of large archived task datasets
12
+ - Maintain response optimization patterns established in the codebase
13
+
14
+ ## Functional Requirements
15
+
16
+ ### FR1: Core Functionality
17
+ - **Tool Name**: `get-archived-tasks`
18
+ - **API Method**: `sunsamaClient.getArchivedTasks(offset?, limit?)`
19
+ - **Purpose**: Retrieve archived tasks with optional pagination and completion filtering
20
+
21
+ ### FR2: Parameters
22
+ | Parameter | Type | Required | Default | Description |
23
+ |-----------|------|----------|---------|-------------|
24
+ | `offset` | number | No | 0 | Pagination offset for archived tasks |
25
+ | `limit` | number | No | 100 | Maximum number of archived tasks to return (max: 1000) |
26
+
27
+ ### FR3: Response Format
28
+ - **Format**: TSV (Tab-Separated Values) with pagination metadata header
29
+ - **Content**: Trimmed Task objects using existing `trimTasksForResponse()` utility
30
+ - **Pagination Metadata**: Include offset, limit, count, hasMore flag, and nextOffset
31
+ - **Optimization**: Apply task trimming for response efficiency
32
+
33
+ ### FR4: Enhanced Pagination
34
+ - **Pattern**: Fetch limit+1 to determine if more results are available
35
+ - **Context**: Provide LLM with clear indication of whether to fetch more data
36
+ - **Metadata**: Include pagination information in response header
37
+
38
+ ### FR5: Error Handling
39
+ - Authentication errors from client resolver
40
+ - Invalid pagination parameters (negative offset, excessive limit)
41
+ - Network/API errors with descriptive messages
42
+ - Consistent error logging pattern matching existing tools
43
+
44
+ ## Technical Requirements
45
+
46
+ ### TR1: Schema Definition
47
+ ```typescript
48
+ export const getArchivedTasksSchema = z.object({
49
+ offset: z.number().int().min(0).optional().describe("Pagination offset (defaults to 0)"),
50
+ limit: z.number().int().min(1).max(1000).optional().describe("Maximum number of tasks to return (defaults to 300)"),
51
+ });
52
+ ```
53
+
54
+ ### TR2: Tool Implementation Pattern
55
+ - Follow existing tool structure from `get-tasks-by-day` and `get-tasks-backlog`
56
+ - Use `getSunsamaClient()` for transport-agnostic client resolution
57
+ - Apply `trimTasksForResponse()` for response optimization
58
+ - Use `toTsv()` for consistent array output formatting
59
+
60
+ ### TR3: Logging Requirements
61
+ - Info logs for operation start with parameters
62
+ - Success logs with task counts and pagination info
63
+ - Error logs with parameter context and error details
64
+ - Consistent log structure matching existing tools
65
+
66
+ ### TR4: Authentication
67
+ - Leverage existing dual transport authentication system
68
+ - Support both stdio and HTTP Stream transport modes
69
+ - Use session-based client resolution pattern
70
+
71
+ ## Non-Functional Requirements
72
+
73
+ ### NFR1: Performance
74
+ - **Response Optimization**: Apply task trimming to reduce payload by 60-80%
75
+ - **Efficient Filtering**: Filter by completion status before trimming
76
+ - **Pagination Support**: Handle large archived task datasets efficiently
77
+
78
+ ### NFR2: Consistency
79
+ - **Code Patterns**: Follow established patterns in `src/main.ts`
80
+ - **Error Handling**: Match existing error handling approach
81
+ - **Response Format**: Consistent with other task list endpoints (TSV)
82
+ - **Logging**: Maintain logging pattern consistency
83
+
84
+ ### NFR3: Maintainability
85
+ - **Schema Validation**: Use Zod for type-safe parameter validation
86
+ - **Type Safety**: Leverage TypeScript inference from schemas
87
+ - **Documentation**: Clear parameter descriptions and usage notes
88
+
89
+ ## Integration Requirements
90
+
91
+ ### IR1: Schema Integration
92
+ - Add `getArchivedTasksSchema` to `src/schemas.ts`
93
+ - Include in schema exports
94
+ - Import in `src/main.ts`
95
+
96
+ ### IR2: Utility Integration
97
+ - Use existing `filterTasksByCompletion()` from `utils/task-filters.ts`
98
+ - Use existing `trimTasksForResponse()` from `utils/task-trimmer.ts`
99
+ - Use existing `toTsv()` from `utils/to-tsv.ts`
100
+ - Use existing `getSunsamaClient()` from `utils/client-resolver.ts`
101
+
102
+ ### IR3: Documentation Updates
103
+ - Update server instructions to include `get-archived-tasks` tool
104
+ - Add tool description to embedded documentation resource
105
+ - Update parameter descriptions and usage examples
106
+
107
+ ## Testing Requirements
108
+
109
+ ### T1: Functional Testing
110
+ - Test with valid pagination parameters (offset/limit)
111
+ - Test with different completion filters ("all", "incomplete", "completed")
112
+ - Test with edge cases (offset=0, large limits)
113
+ - Verify TSV output format correctness
114
+
115
+ ### T2: Error Testing
116
+ - Test with invalid parameters (negative offset, excessive limit)
117
+ - Test authentication failure scenarios
118
+ - Test network error handling
119
+ - Verify error message clarity and consistency
120
+
121
+ ### T3: Integration Testing
122
+ - Test with MCP Inspector (`bun run inspect`)
123
+ - Verify compatibility with both stdio and HTTP Stream transports
124
+ - Test response optimization (filtering + trimming)
125
+ - Validate against existing sample data
126
+
127
+ ## Success Criteria
128
+ - [ ] Tool successfully retrieves archived tasks via `getArchivedTasks()` API
129
+ - [ ] Pagination works correctly with offset/limit parameters
130
+ - [ ] Completion filtering functions consistently with other task tools
131
+ - [ ] Response optimization reduces payload size by 60-80%
132
+ - [ ] Error handling provides clear, actionable error messages
133
+ - [ ] Integration testing passes with MCP Inspector
134
+ - [ ] Code follows established patterns and maintains consistency
135
+
136
+ ## Implementation Priority
137
+ **High Priority** - This tool provides essential access to archived task history and is identified as a critical gap in the current MCP server functionality.
138
+
139
+ ## Dependencies
140
+ - sunsama-api v0.6.1+ (already updated)
141
+ - Existing utility functions in `utils/` directory
142
+ - Existing schema patterns in `src/schemas.ts`
143
+ - Existing authentication and transport infrastructure
144
+
145
+ ## Risk Assessment
146
+ - **Low Risk**: Implementation follows well-established patterns
147
+ - **API Stability**: Method is available and documented in sunsama-api
148
+ - **Testing Coverage**: Sample data available for validation
149
+ - **Integration**: Minimal impact on existing functionality
150
+
151
+ ---
152
+
153
+ **Document Version**: 1.0
154
+ **Created**: 2025-06-20
155
+ **Author**: Implementation Team
156
+ **Status**: Ready for Implementation
@@ -3,13 +3,15 @@
3
3
  * Supports both stdio and httpStream transports based on environment variables
4
4
  */
5
5
  export type TransportType = "stdio" | "httpStream";
6
- export interface TransportConfig {
7
- transportType: TransportType;
8
- httpStream?: {
6
+ export type TransportConfig = {
7
+ transportType: "stdio";
8
+ } | {
9
+ transportType: "httpStream";
10
+ httpStream: {
9
11
  port: number;
10
- endpoint: string;
12
+ endpoint: `/${string}`;
11
13
  };
12
- }
14
+ };
13
15
  /**
14
16
  * Gets the transport configuration based on environment variables
15
17
  *
@@ -1 +1 @@
1
- {"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../src/config/transport.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,YAAY,CAAC;AAEnD,MAAM,WAAW,eAAe;IAC9B,aAAa,EAAE,aAAa,CAAC;IAC7B,UAAU,CAAC,EAAE;QACX,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;CACH;AAcD;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,IAAI,eAAe,CA0BpD;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,OAAO,CAE/C;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,OAAO,CAE1C"}
1
+ {"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../src/config/transport.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,YAAY,CAAC;AAEnD,MAAM,MAAM,eAAe,GACvB;IACF,aAAa,EAAE,OAAO,CAAC;CACxB,GACG;IACF,aAAa,EAAE,YAAY,CAAC;IAC5B,UAAU,EAAE;QACV,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,IAAI,MAAM,EAAE,CAAC;KACxB,CAAC;CACH,CAAC;AAgBF;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,IAAI,eAAe,CA0BpD;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,OAAO,CAE/C;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,OAAO,CAE1C"}
@@ -12,7 +12,9 @@ const TransportEnvSchema = z.object({
12
12
  .transform(val => parseInt(val, 10))
13
13
  .pipe(z.number().min(1).max(65535))
14
14
  .optional(),
15
- HTTP_ENDPOINT: z.string().default("/mcp")
15
+ HTTP_ENDPOINT: z.string().refine(val => val.startsWith("/"), {
16
+ message: "HTTP_ENDPOINT must start with '/'"
17
+ }).transform(val => val).default("/mcp")
16
18
  });
17
19
  /**
18
20
  * Gets the transport configuration based on environment variables
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.2.2",
19
+ version: "0.4.0",
20
20
  instructions: `
21
21
  This MCP server provides access to the Sunsama API for task and project management.
22
22
 
@@ -509,19 +509,12 @@ Required environment variables:
509
509
  if (transportConfig.transportType === "httpStream") {
510
510
  // Log startup information
511
511
  console.log(`HTTP Stream configuration: port=${transportConfig.httpStream?.port}, endpoint=${transportConfig.httpStream?.endpoint}`);
512
- server.start({
513
- transportType: "httpStream",
514
- httpStream: {
515
- port: transportConfig.httpStream.port
516
- }
517
- }).then(() => {
512
+ server.start(transportConfig).then(() => {
518
513
  console.log(`Sunsama MCP Server running on port ${transportConfig.httpStream.port}`);
519
514
  console.log(`HTTP endpoint: ${transportConfig.httpStream.endpoint}`);
520
515
  console.log("Authentication: HTTP Basic Auth with Sunsama credentials");
521
516
  });
522
517
  }
523
518
  else {
524
- server.start({
525
- transportType: "stdio"
526
- });
519
+ server.start(transportConfig);
527
520
  }
@@ -1,4 +1,4 @@
1
- import type { Task } from "sunsama-api";
1
+ import type { Task, TaskIntegration } from "sunsama-api";
2
2
  /**
3
3
  * Trimmed task type containing only essential properties for API responses.
4
4
  * Reduces response size by 60-80% while preserving core task information.
@@ -9,7 +9,10 @@ import type { Task } from "sunsama-api";
9
9
  */
10
10
  export type TrimmedTask = Pick<Task, '_id' | 'text' | 'completed' | 'assigneeId' | 'createdAt' | 'lastModified' | 'objectiveId' | 'completeDate' | 'timeEstimate' | 'dueDate' | 'notes' | 'streamIds'> & {
11
11
  /** Integration service name (e.g., 'website', 'googleCalendar') or null */
12
- integration: string | null;
12
+ integration: {
13
+ service: TaskIntegration['service'];
14
+ url?: string;
15
+ } | null;
13
16
  /** Array of subtask titles only (simplified from full subtask objects) */
14
17
  subtasks: string[];
15
18
  };
@@ -1 +1 @@
1
- {"version":3,"file":"task-trimmer.d.ts","sourceRoot":"","sources":["../../src/utils/task-trimmer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAExC;;;;;;;GAOG;AACH,MAAM,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,EAC/B,KAAK,GACL,MAAM,GACN,WAAW,GACX,YAAY,GACZ,WAAW,GACX,cAAc,GACd,aAAa,GACb,cAAc,GACd,cAAc,GACd,SAAS,GACT,OAAO,GACP,WAAW,CACd,GAAG;IACF,2EAA2E;IAC3E,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,0EAA0E;IAC1E,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,IAAI,GAAG,WAAW,CAiB3D;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,WAAW,EAAE,CAEjE"}
1
+ {"version":3,"file":"task-trimmer.d.ts","sourceRoot":"","sources":["../../src/utils/task-trimmer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEzD;;;;;;;GAOG;AACH,MAAM,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,EAC/B,KAAK,GACL,MAAM,GACN,WAAW,GACX,YAAY,GACZ,WAAW,GACX,cAAc,GACd,aAAa,GACb,cAAc,GACd,cAAc,GACd,SAAS,GACT,OAAO,GACP,WAAW,CACd,GAAG;IACF,2EAA2E;IAC3E,WAAW,EAAE;QACX,OAAO,EAAE,eAAe,CAAC,SAAS,CAAC,CAAC;QACpC,GAAG,CAAC,EAAE,MAAM,CAAC;KACd,GAAG,IAAI,CAAC;IACT,0EAA0E;IAC1E,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,IAAI,GAAG,WAAW,CA4B3D;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,WAAW,EAAE,CAEjE"}
@@ -22,6 +22,15 @@
22
22
  * @returns Trimmed task object with only essential properties
23
23
  */
24
24
  export function trimTaskForResponse(task) {
25
+ let integration = null;
26
+ // Extract minimal integration data: service type and URL if available
27
+ // Integration identifiers vary by service - some have URLs (websites), others have different properties
28
+ if (task.integration) {
29
+ integration = { service: task.integration.service };
30
+ if ("url" in task.integration.identifier) {
31
+ integration.url = task.integration.identifier.url;
32
+ }
33
+ }
25
34
  return {
26
35
  _id: task._id,
27
36
  assigneeId: task.assigneeId,
@@ -29,7 +38,7 @@ export function trimTaskForResponse(task) {
29
38
  completed: task.completed,
30
39
  createdAt: task.createdAt,
31
40
  dueDate: task.dueDate,
32
- integration: task.integration?.service || null,
41
+ integration: integration,
33
42
  lastModified: task.lastModified,
34
43
  notes: task.notes,
35
44
  objectiveId: task.objectiveId,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mcp-sunsama",
3
- "version": "0.3.0",
3
+ "version": "0.5.0",
4
4
  "description": "MCP server for Sunsama API integration",
5
5
  "type": "module",
6
6
  "private": false,
@@ -23,9 +23,9 @@
23
23
  },
24
24
  "dependencies": {
25
25
  "@types/papaparse": "^5.3.16",
26
- "fastmcp": "2.1.3",
26
+ "fastmcp": "3.3.1",
27
27
  "papaparse": "^5.5.3",
28
- "sunsama-api": "0.3.0",
28
+ "sunsama-api": "0.6.1",
29
29
  "zod": "3.24.4"
30
30
  },
31
31
  "devDependencies": {
@@ -7,13 +7,17 @@ import { z } from "zod";
7
7
 
8
8
  export type TransportType = "stdio" | "httpStream";
9
9
 
10
- export interface TransportConfig {
11
- transportType: TransportType;
12
- httpStream?: {
10
+ export type TransportConfig =
11
+ | {
12
+ transportType: "stdio";
13
+ }
14
+ | {
15
+ transportType: "httpStream";
16
+ httpStream: {
13
17
  port: number;
14
- endpoint: string;
18
+ endpoint: `/${string}`;
15
19
  };
16
- }
20
+ };
17
21
 
18
22
  /**
19
23
  * Zod schema for validating transport-related environment variables
@@ -24,7 +28,9 @@ const TransportEnvSchema = z.object({
24
28
  .transform(val => parseInt(val, 10))
25
29
  .pipe(z.number().min(1).max(65535))
26
30
  .optional(),
27
- HTTP_ENDPOINT: z.string().default("/mcp")
31
+ HTTP_ENDPOINT: z.string().refine(val => val.startsWith("/"), {
32
+ message: "HTTP_ENDPOINT must start with '/'"
33
+ }).transform(val => val as `/${string}`).default("/mcp")
28
34
  });
29
35
 
30
36
  /**
package/src/main.ts CHANGED
@@ -8,6 +8,7 @@ import { getTransportConfig } from "./config/transport.js";
8
8
  import {
9
9
  createTaskSchema,
10
10
  deleteTaskSchema,
11
+ getArchivedTasksSchema,
11
12
  getStreamsSchema,
12
13
  getTasksBacklogSchema,
13
14
  getTasksByDaySchema,
@@ -28,17 +29,16 @@ if (transportConfig.transportType === "stdio") {
28
29
  await initializeStdioAuth();
29
30
  }
30
31
 
31
-
32
32
  const server = new FastMCP({
33
33
  name: "Sunsama API Server",
34
- version: "0.3.0",
34
+ version: "0.5.0",
35
35
  instructions: `
36
36
  This MCP server provides access to the Sunsama API for task and project management.
37
37
 
38
38
  Available tools:
39
39
  - Authentication: login, logout, check authentication status
40
40
  - User operations: get current user information
41
- - Task operations: get tasks by day, get backlog tasks
41
+ - Task operations: get tasks by day, get backlog tasks, get archived tasks
42
42
  - Stream operations: get streams/channels for the user's group
43
43
 
44
44
  Authentication is required for all operations. You can either:
@@ -188,6 +188,79 @@ server.addTool({
188
188
  }
189
189
  });
190
190
 
191
+ server.addTool({
192
+ name: "get-archived-tasks",
193
+ description: "Get archived tasks with optional pagination",
194
+ parameters: getArchivedTasksSchema,
195
+ execute: async (args, {session, log}) => {
196
+ try {
197
+ // Extract and set defaults for parameters
198
+ const offset = args.offset || 0;
199
+ const requestedLimit = args.limit || 100;
200
+
201
+ // Fetch limit + 1 to determine if there are more results
202
+ const fetchLimit = requestedLimit + 1;
203
+
204
+ log.info("Getting archived tasks", {
205
+ offset,
206
+ requestedLimit,
207
+ fetchLimit
208
+ });
209
+
210
+ // Get the appropriate client based on transport type
211
+ const sunsamaClient = getSunsamaClient(session as SessionData | null);
212
+
213
+ // Get archived tasks (fetch limit + 1 to check for more)
214
+ const allTasks = await sunsamaClient.getArchivedTasks(offset, fetchLimit);
215
+
216
+ // Determine if there are more results and slice to requested limit
217
+ const hasMore = allTasks.length > requestedLimit;
218
+ const tasks = hasMore ? allTasks.slice(0, requestedLimit) : allTasks;
219
+
220
+ // Trim tasks to reduce response size while preserving essential data
221
+ const trimmedTasks = trimTasksForResponse(tasks);
222
+
223
+ // Create pagination metadata
224
+ const paginationInfo = {
225
+ offset,
226
+ limit: requestedLimit,
227
+ count: tasks.length,
228
+ hasMore,
229
+ nextOffset: hasMore ? offset + requestedLimit : null
230
+ };
231
+
232
+ log.info("Successfully retrieved archived tasks", {
233
+ totalReturned: tasks.length,
234
+ hasMore,
235
+ offset,
236
+ requestedLimit
237
+ });
238
+
239
+ // Create response with pagination metadata header and TSV data
240
+ const responseText = `# Pagination: offset=${paginationInfo.offset}, limit=${paginationInfo.limit}, count=${paginationInfo.count}, hasMore=${paginationInfo.hasMore}, nextOffset=${paginationInfo.nextOffset || 'null'}
241
+ ${toTsv(trimmedTasks)}`;
242
+
243
+ return {
244
+ content: [
245
+ {
246
+ type: "text",
247
+ text: responseText
248
+ }
249
+ ]
250
+ };
251
+
252
+ } catch (error) {
253
+ log.error("Failed to get archived tasks", {
254
+ offset: args.offset,
255
+ limit: args.limit,
256
+ error: error instanceof Error ? error.message : 'Unknown error'
257
+ });
258
+
259
+ throw new Error(`Failed to get archived tasks: ${error instanceof Error ? error.message : 'Unknown error'}`);
260
+ }
261
+ }
262
+ });
263
+
191
264
  // Task Mutation Operations
192
265
  server.addTool({
193
266
  name: "create-task",
@@ -478,15 +551,32 @@ server.addResource({
478
551
  text: `# Sunsama MCP Server Documentation
479
552
 
480
553
  ## Overview
481
- This MCP server provides access to the Sunsama API for task and project management.
482
- Authentication is handled server-side using environment variables.
554
+ This MCP server provides comprehensive access to the Sunsama API for task and project management.
555
+ Supports dual transport modes with different authentication strategies.
556
+
557
+ ## Transport Modes
558
+
559
+ ### Stdio Transport (Default)
560
+ - Single global authentication using environment variables
561
+ - Session maintained for entire server lifetime
562
+ - Best for single-user local development
563
+
564
+ ### HTTP Stream Transport
565
+ - Per-request authentication via HTTP Basic Auth
566
+ - Session-isolated client instances
567
+ - Supports multiple concurrent users
483
568
 
484
569
  ## Authentication
485
- The server authenticates to Sunsama using environment variables:
570
+
571
+ ### Stdio Transport
572
+ Uses environment variables (authenticated once at startup):
486
573
  - \`SUNSAMA_EMAIL\`: Your Sunsama account email
487
574
  - \`SUNSAMA_PASSWORD\`: Your Sunsama account password
488
575
 
489
- Authentication happens automatically on server startup. No client-side authentication is required.
576
+ ### HTTP Stream Transport
577
+ Uses HTTP Basic Auth headers (per-request authentication):
578
+ - \`Authorization: Basic <base64(email:password)>\`
579
+ - Credentials provided in each HTTP request
490
580
 
491
581
  ## Available Tools
492
582
 
@@ -495,93 +585,85 @@ Authentication happens automatically on server startup. No client-side authentic
495
585
  - Parameters: none
496
586
  - Returns: User object with profile, timezone, and primary group details
497
587
 
498
- ### Task Operations
588
+ ### Task Management
499
589
  - **get-tasks-by-day**: Get tasks for a specific day with optional filtering
500
590
  - Parameters:
501
591
  - \`day\` (required): Date in YYYY-MM-DD format
502
592
  - \`timezone\` (optional): Timezone string (e.g., "America/New_York")
503
- - \`completionFilter\` (optional): Filter by completion status
504
- - \`"all"\` (default): Return all tasks
505
- - \`"incomplete"\`: Return only incomplete tasks
506
- - \`"completed"\`: Return only completed tasks
507
- - Returns: Array of filtered Task objects for the specified day
593
+ - \`completionFilter\` (optional): Filter by completion status ("all", "incomplete", "completed")
594
+ - Returns: TSV of filtered Task objects for the specified day
508
595
 
509
596
  - **get-tasks-backlog**: Get tasks from the backlog
510
597
  - Parameters: none
511
- - Returns: Array of Task objects from the backlog
598
+ - Returns: TSV of Task objects from the backlog
599
+
600
+ - **get-archived-tasks**: Get archived tasks with optional pagination
601
+ - Parameters:
602
+ - \`offset\` (optional): Pagination offset (defaults to 0)
603
+ - \`limit\` (optional): Maximum number of tasks to return (defaults to 100, max: 1000)
604
+ - Returns: TSV of trimmed archived Task objects with pagination metadata header
605
+ - Pagination: Uses limit+1 pattern to determine if more results are available
606
+
607
+ - **create-task**: Create a new task with optional properties
608
+ - Parameters:
609
+ - \`text\` (required): Task title/description
610
+ - \`notes\` (optional): Additional task notes
611
+ - \`streamIds\` (optional): Array of stream IDs to associate with task
612
+ - \`timeEstimate\` (optional): Time estimate in minutes
613
+ - \`dueDate\` (optional): Due date string (ISO format)
614
+ - \`snoozeUntil\` (optional): Snooze until date string (ISO format)
615
+ - \`private\` (optional): Whether the task is private
616
+ - \`taskId\` (optional): Custom task ID
617
+ - Returns: JSON with task creation result
618
+
619
+ - **update-task-complete**: Mark a task as complete
620
+ - Parameters:
621
+ - \`taskId\` (required): The ID of the task to mark as complete
622
+ - \`completeOn\` (optional): Completion timestamp (ISO format)
623
+ - \`limitResponsePayload\` (optional): Whether to limit response size
624
+ - Returns: JSON with completion result
625
+
626
+ - **delete-task**: Delete a task permanently
627
+ - Parameters:
628
+ - \`taskId\` (required): The ID of the task to delete
629
+ - \`limitResponsePayload\` (optional): Whether to limit response size
630
+ - \`wasTaskMerged\` (optional): Whether the task was merged before deletion
631
+ - Returns: JSON with deletion result
632
+
633
+ - **update-task-snooze-date**: Reschedule tasks or move to backlog
634
+ - Parameters:
635
+ - \`taskId\` (required): The ID of the task to reschedule
636
+ - \`newDay\` (required): Target date in YYYY-MM-DD format, or null for backlog
637
+ - \`timezone\` (optional): Timezone string
638
+ - \`limitResponsePayload\` (optional): Whether to limit response size
639
+ - Returns: JSON with update result
512
640
 
513
641
  ### Stream Operations
514
642
  - **get-streams**: Get streams for the user's group
515
643
  - Parameters: none
516
- - Returns: Array of Stream objects
517
- - Note: Streams are called "channels" in the Sunsama UI. If a user requests channels, use this tool.
518
-
519
- ## Data Types
520
-
521
- ### User Object
522
- \`\`\`typescript
523
- {
524
- _id: string;
525
- email: string;
526
- profile: {
527
- _id: string;
528
- email: string;
529
- firstName: string;
530
- lastName: string;
531
- timezone: string;
532
- avatarUrl?: string;
533
- };
534
- primaryGroup?: {
535
- groupId: string;
536
- name: string;
537
- role?: string;
538
- };
539
- }
540
- \`\`\`
541
-
542
- ### Task Object
543
- \`\`\`typescript
544
- {
545
- _id: string;
546
- title: string;
547
- description?: string;
548
- status: string;
549
- createdAt: string;
550
- updatedAt: string;
551
- scheduledDate?: string;
552
- completedAt?: string;
553
- streamId?: string;
554
- userId: string;
555
- groupId: string;
556
- }
557
- \`\`\`
558
-
559
- ### Stream Object
560
- Note: Streams are called "channels" in the Sunsama UI.
561
- \`\`\`typescript
562
- {
563
- _id: string;
564
- name: string;
565
- color?: string;
566
- groupId: string;
567
- isActive: boolean;
568
- createdAt: string;
569
- updatedAt: string;
570
- }
571
- \`\`\`
644
+ - Returns: TSV of Stream objects
645
+ - Note: Streams are called "channels" in the Sunsama UI
572
646
 
573
- ## Error Handling
574
- - All operations require valid Sunsama authentication
575
- - Invalid dates will return validation errors
576
- - Network errors are handled gracefully with descriptive messages
577
- - Server maintains session state across tool calls
647
+ ## Response Optimization
648
+ - **Task Filtering**: Applied before processing for efficiency
649
+ - **Task Trimming**: Removes non-essential fields, reducing payload by 60-80%
650
+ - **TSV Format**: Used for arrays to optimize data processing
578
651
 
579
652
  ## Environment Setup
580
- Required environment variables:
581
- - \`API_KEY\`: MCP server authentication key
653
+
654
+ ### Required (Stdio Transport)
582
655
  - \`SUNSAMA_EMAIL\`: Sunsama account email
583
656
  - \`SUNSAMA_PASSWORD\`: Sunsama account password
584
- - \`PORT\`: Server port (default: 3000)
657
+
658
+ ### Optional Configuration
659
+ - \`TRANSPORT_TYPE\`: "stdio" (default) | "httpStream"
660
+ - \`PORT\`: Server port for HTTP transport (default: 3002)
661
+
662
+ ## Error Handling
663
+ - Comprehensive parameter validation using Zod schemas
664
+ - Graceful handling of network errors with descriptive messages
665
+ - Session-specific error isolation in HTTP transport mode
666
+ - Proper authentication error responses
585
667
  `.trim()
586
668
  };
587
669
  }
@@ -593,18 +675,11 @@ if (transportConfig.transportType === "httpStream") {
593
675
  // Log startup information
594
676
  console.log(`HTTP Stream configuration: port=${transportConfig.httpStream?.port}, endpoint=${transportConfig.httpStream?.endpoint}`);
595
677
 
596
- server.start({
597
- transportType: "httpStream",
598
- httpStream: {
599
- port: transportConfig.httpStream!.port
600
- }
601
- }).then(() => {
678
+ server.start(transportConfig).then(() => {
602
679
  console.log(`Sunsama MCP Server running on port ${transportConfig.httpStream!.port}`);
603
680
  console.log(`HTTP endpoint: ${transportConfig.httpStream!.endpoint}`);
604
681
  console.log("Authentication: HTTP Basic Auth with Sunsama credentials");
605
682
  });
606
683
  } else {
607
- server.start({
608
- transportType: "stdio"
609
- });
684
+ server.start(transportConfig);
610
685
  }
package/src/schemas.ts CHANGED
@@ -17,6 +17,12 @@ export const getTasksByDaySchema = z.object({
17
17
  // Get tasks backlog parameters (no parameters needed)
18
18
  export const getTasksBacklogSchema = z.object({});
19
19
 
20
+ // Get archived tasks parameters
21
+ export const getArchivedTasksSchema = z.object({
22
+ offset: z.number().int().min(0).optional().describe("Pagination offset (defaults to 0)"),
23
+ limit: z.number().int().min(1).max(1000).optional().describe("Maximum number of tasks to return (defaults to 100)"),
24
+ });
25
+
20
26
  /**
21
27
  * User Operation Schemas
22
28
  */
@@ -161,6 +167,7 @@ export type CompletionFilter = z.infer<typeof completionFilterSchema>;
161
167
 
162
168
  export type GetTasksByDayInput = z.infer<typeof getTasksByDaySchema>;
163
169
  export type GetTasksBacklogInput = z.infer<typeof getTasksBacklogSchema>;
170
+ export type GetArchivedTasksInput = z.infer<typeof getArchivedTasksSchema>;
164
171
  export type GetUserInput = z.infer<typeof getUserSchema>;
165
172
  export type GetStreamsInput = z.infer<typeof getStreamsSchema>;
166
173