@open-sunsama/mcp 1.0.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/README.md +374 -0
- package/build/index.d.ts +13 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +71 -0
- package/build/index.js.map +1 -0
- package/build/lib/api-client.d.ts +177 -0
- package/build/lib/api-client.d.ts.map +1 -0
- package/build/lib/api-client.js +126 -0
- package/build/lib/api-client.js.map +1 -0
- package/build/tools/subtasks.d.ts +11 -0
- package/build/tools/subtasks.d.ts.map +1 -0
- package/build/tools/subtasks.js +194 -0
- package/build/tools/subtasks.js.map +1 -0
- package/build/tools/tasks.d.ts +11 -0
- package/build/tools/tasks.d.ts.map +1 -0
- package/build/tools/tasks.js +426 -0
- package/build/tools/tasks.js.map +1 -0
- package/build/tools/time-blocks.d.ts +13 -0
- package/build/tools/time-blocks.d.ts.map +1 -0
- package/build/tools/time-blocks.js +456 -0
- package/build/tools/time-blocks.js.map +1 -0
- package/build/tools/user.d.ts +11 -0
- package/build/tools/user.d.ts.map +1 -0
- package/build/tools/user.js +147 -0
- package/build/tools/user.js.map +1 -0
- package/package.json +39 -0
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* API client for Open Sunsama REST API
|
|
3
|
+
* Handles authentication and HTTP requests
|
|
4
|
+
*/
|
|
5
|
+
export class ApiClient {
|
|
6
|
+
baseUrl;
|
|
7
|
+
apiKey;
|
|
8
|
+
constructor(config) {
|
|
9
|
+
this.baseUrl = config.baseUrl.replace(/\/$/, ""); // Remove trailing slash
|
|
10
|
+
this.apiKey = config.apiKey;
|
|
11
|
+
}
|
|
12
|
+
async request(method, path, body, query) {
|
|
13
|
+
let url = `${this.baseUrl}${path}`;
|
|
14
|
+
// Add query parameters
|
|
15
|
+
if (query) {
|
|
16
|
+
const params = new URLSearchParams();
|
|
17
|
+
for (const [key, value] of Object.entries(query)) {
|
|
18
|
+
if (value !== undefined) {
|
|
19
|
+
params.append(key, String(value));
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
const queryString = params.toString();
|
|
23
|
+
if (queryString) {
|
|
24
|
+
url += `?${queryString}`;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
const headers = {
|
|
28
|
+
"X-API-Key": this.apiKey,
|
|
29
|
+
"Content-Type": "application/json",
|
|
30
|
+
};
|
|
31
|
+
const options = {
|
|
32
|
+
method,
|
|
33
|
+
headers,
|
|
34
|
+
};
|
|
35
|
+
if (body && (method === "POST" || method === "PATCH" || method === "PUT")) {
|
|
36
|
+
options.body = JSON.stringify(body);
|
|
37
|
+
}
|
|
38
|
+
try {
|
|
39
|
+
const response = await fetch(url, options);
|
|
40
|
+
const data = await response.json();
|
|
41
|
+
return data;
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
return {
|
|
45
|
+
success: false,
|
|
46
|
+
error: {
|
|
47
|
+
code: "NETWORK_ERROR",
|
|
48
|
+
message: error instanceof Error ? error.message : "Network request failed",
|
|
49
|
+
statusCode: 0,
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
// Tasks
|
|
55
|
+
async listTasks(params) {
|
|
56
|
+
return this.request("GET", "/tasks", undefined, {
|
|
57
|
+
date: params?.date,
|
|
58
|
+
from: params?.from,
|
|
59
|
+
to: params?.to,
|
|
60
|
+
completed: params?.completed,
|
|
61
|
+
backlog: params?.backlog,
|
|
62
|
+
sortBy: params?.sortBy,
|
|
63
|
+
page: params?.page,
|
|
64
|
+
limit: params?.limit,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
async getTask(id) {
|
|
68
|
+
return this.request("GET", `/tasks/${id}`);
|
|
69
|
+
}
|
|
70
|
+
async createTask(data) {
|
|
71
|
+
return this.request("POST", "/tasks", data);
|
|
72
|
+
}
|
|
73
|
+
async updateTask(id, data) {
|
|
74
|
+
return this.request("PATCH", `/tasks/${id}`, data);
|
|
75
|
+
}
|
|
76
|
+
async deleteTask(id) {
|
|
77
|
+
return this.request("DELETE", `/tasks/${id}`);
|
|
78
|
+
}
|
|
79
|
+
async reorderTasks(date, taskIds) {
|
|
80
|
+
return this.request("POST", "/tasks/reorder", { date, taskIds });
|
|
81
|
+
}
|
|
82
|
+
// Subtasks
|
|
83
|
+
async listSubtasks(taskId) {
|
|
84
|
+
return this.request("GET", `/tasks/${taskId}/subtasks`);
|
|
85
|
+
}
|
|
86
|
+
async createSubtask(taskId, data) {
|
|
87
|
+
return this.request("POST", `/tasks/${taskId}/subtasks`, data);
|
|
88
|
+
}
|
|
89
|
+
async updateSubtask(taskId, subtaskId, data) {
|
|
90
|
+
return this.request("PATCH", `/tasks/${taskId}/subtasks/${subtaskId}`, data);
|
|
91
|
+
}
|
|
92
|
+
async deleteSubtask(taskId, subtaskId) {
|
|
93
|
+
return this.request("DELETE", `/tasks/${taskId}/subtasks/${subtaskId}`);
|
|
94
|
+
}
|
|
95
|
+
// Time Blocks
|
|
96
|
+
async listTimeBlocks(params) {
|
|
97
|
+
return this.request("GET", "/time-blocks", undefined, {
|
|
98
|
+
date: params?.date,
|
|
99
|
+
from: params?.from,
|
|
100
|
+
to: params?.to,
|
|
101
|
+
taskId: params?.taskId,
|
|
102
|
+
page: params?.page,
|
|
103
|
+
limit: params?.limit,
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
async getTimeBlock(id) {
|
|
107
|
+
return this.request("GET", `/time-blocks/${id}`);
|
|
108
|
+
}
|
|
109
|
+
async createTimeBlock(data) {
|
|
110
|
+
return this.request("POST", "/time-blocks", data);
|
|
111
|
+
}
|
|
112
|
+
async updateTimeBlock(id, data) {
|
|
113
|
+
return this.request("PATCH", `/time-blocks/${id}`, data);
|
|
114
|
+
}
|
|
115
|
+
async deleteTimeBlock(id) {
|
|
116
|
+
return this.request("DELETE", `/time-blocks/${id}`);
|
|
117
|
+
}
|
|
118
|
+
// User
|
|
119
|
+
async getMe() {
|
|
120
|
+
return this.request("GET", "/auth/me");
|
|
121
|
+
}
|
|
122
|
+
async updateMe(data) {
|
|
123
|
+
return this.request("PATCH", "/auth/me", data);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=api-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-client.js","sourceRoot":"","sources":["../../src/lib/api-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP tools for subtask management
|
|
3
|
+
* Provides tools for listing, creating, updating, toggling, and deleting subtasks
|
|
4
|
+
*/
|
|
5
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
6
|
+
import type { ApiClient } from "../lib/api-client.js";
|
|
7
|
+
/**
|
|
8
|
+
* Register all subtask-related tools with the MCP server
|
|
9
|
+
*/
|
|
10
|
+
export declare function registerSubtaskTools(server: McpServer, apiClient: ApiClient): void;
|
|
11
|
+
//# sourceMappingURL=subtasks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subtasks.d.ts","sourceRoot":"","sources":["../../src/tools/subtasks.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,KAAK,EAAE,SAAS,EAAW,MAAM,sBAAsB,CAAC;AAuC/D;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,SAAS,EACjB,SAAS,EAAE,SAAS,GACnB,IAAI,CA0QN"}
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP tools for subtask management
|
|
3
|
+
* Provides tools for listing, creating, updating, toggling, and deleting subtasks
|
|
4
|
+
*/
|
|
5
|
+
import { z } from "zod";
|
|
6
|
+
/**
|
|
7
|
+
* Format a subtask for display
|
|
8
|
+
*/
|
|
9
|
+
function formatSubtask(subtask) {
|
|
10
|
+
const checkbox = subtask.completed ? "[x]" : "[ ]";
|
|
11
|
+
return `${checkbox} ${subtask.title} (id: ${subtask.id}, position: ${subtask.position})`;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Format an array of subtasks for display
|
|
15
|
+
*/
|
|
16
|
+
function formatSubtaskList(subtasks) {
|
|
17
|
+
if (subtasks.length === 0) {
|
|
18
|
+
return "No subtasks found.";
|
|
19
|
+
}
|
|
20
|
+
return subtasks.map(formatSubtask).join("\n");
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Creates a success response for MCP tools
|
|
24
|
+
*/
|
|
25
|
+
function successResponse(text) {
|
|
26
|
+
return {
|
|
27
|
+
content: [{ type: "text", text }],
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Creates an error response for MCP tools
|
|
32
|
+
*/
|
|
33
|
+
function errorResponse(message) {
|
|
34
|
+
return {
|
|
35
|
+
content: [{ type: "text", text: `Error: ${message}` }],
|
|
36
|
+
isError: true,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Register all subtask-related tools with the MCP server
|
|
41
|
+
*/
|
|
42
|
+
export function registerSubtaskTools(server, apiClient) {
|
|
43
|
+
// List subtasks for a task
|
|
44
|
+
server.tool("list_subtasks", "List all subtasks for a specific task. Subtasks are checklist items within a task that help break down work into smaller actionable steps. Returns all subtasks with their completion status, title, and position.", {
|
|
45
|
+
taskId: z
|
|
46
|
+
.string()
|
|
47
|
+
.describe("The unique identifier (UUID) of the parent task to list subtasks for"),
|
|
48
|
+
}, async (input) => {
|
|
49
|
+
try {
|
|
50
|
+
const response = await apiClient.listSubtasks(input.taskId);
|
|
51
|
+
if (!response.success) {
|
|
52
|
+
return errorResponse(response.error?.message || "Failed to list subtasks");
|
|
53
|
+
}
|
|
54
|
+
const subtasks = response.data || [];
|
|
55
|
+
const formattedList = formatSubtaskList(subtasks);
|
|
56
|
+
return successResponse(`Subtasks for task ${input.taskId}:\n\n${formattedList}\n\nTotal: ${subtasks.length} subtask(s)`);
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
return errorResponse(error instanceof Error ? error.message : "Unknown error");
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
// Create a subtask
|
|
63
|
+
server.tool("create_subtask", "Create a new subtask within a task. Subtasks are smaller actionable items that help break down a task into manageable steps. Each subtask has a title and can optionally be positioned at a specific order within the task's subtask list.", {
|
|
64
|
+
taskId: z
|
|
65
|
+
.string()
|
|
66
|
+
.describe("The unique identifier (UUID) of the parent task to add the subtask to"),
|
|
67
|
+
title: z
|
|
68
|
+
.string()
|
|
69
|
+
.describe("The title/description of the subtask. Should be a clear, actionable item (e.g., 'Review PR comments', 'Update documentation')"),
|
|
70
|
+
position: z
|
|
71
|
+
.number()
|
|
72
|
+
.optional()
|
|
73
|
+
.describe("Optional position in the subtask list (0-indexed). If not provided, the subtask will be added at the end"),
|
|
74
|
+
}, async (input) => {
|
|
75
|
+
try {
|
|
76
|
+
const response = await apiClient.createSubtask(input.taskId, {
|
|
77
|
+
title: input.title,
|
|
78
|
+
position: input.position,
|
|
79
|
+
});
|
|
80
|
+
if (!response.success) {
|
|
81
|
+
return errorResponse(response.error?.message || "Failed to create subtask");
|
|
82
|
+
}
|
|
83
|
+
const subtask = response.data;
|
|
84
|
+
return successResponse(`Successfully created subtask:\n\n${formatSubtask(subtask)}\n\nSubtask ID: ${subtask.id}`);
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
return errorResponse(error instanceof Error ? error.message : "Unknown error");
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
// Toggle subtask completion
|
|
91
|
+
server.tool("toggle_subtask", "Toggle a subtask's completed status. If the subtask is incomplete, it will be marked as complete. If it's already complete, it will be marked as incomplete. This is useful for quickly checking off items in a checklist.", {
|
|
92
|
+
taskId: z
|
|
93
|
+
.string()
|
|
94
|
+
.describe("The unique identifier (UUID) of the parent task containing the subtask"),
|
|
95
|
+
subtaskId: z
|
|
96
|
+
.string()
|
|
97
|
+
.describe("The unique identifier (UUID) of the subtask to toggle"),
|
|
98
|
+
}, async (input) => {
|
|
99
|
+
try {
|
|
100
|
+
// First, get the current subtask state
|
|
101
|
+
const listResponse = await apiClient.listSubtasks(input.taskId);
|
|
102
|
+
if (!listResponse.success) {
|
|
103
|
+
return errorResponse(listResponse.error?.message || "Failed to fetch subtask");
|
|
104
|
+
}
|
|
105
|
+
const subtasks = listResponse.data || [];
|
|
106
|
+
const currentSubtask = subtasks.find((s) => s.id === input.subtaskId);
|
|
107
|
+
if (!currentSubtask) {
|
|
108
|
+
return errorResponse(`Subtask with ID ${input.subtaskId} not found in task ${input.taskId}`);
|
|
109
|
+
}
|
|
110
|
+
// Toggle the completed status
|
|
111
|
+
const newCompletedStatus = !currentSubtask.completed;
|
|
112
|
+
const response = await apiClient.updateSubtask(input.taskId, input.subtaskId, { completed: newCompletedStatus });
|
|
113
|
+
if (!response.success) {
|
|
114
|
+
return errorResponse(response.error?.message || "Failed to toggle subtask");
|
|
115
|
+
}
|
|
116
|
+
const subtask = response.data;
|
|
117
|
+
const statusText = subtask.completed ? "completed" : "incomplete";
|
|
118
|
+
return successResponse(`Successfully toggled subtask to ${statusText}:\n\n${formatSubtask(subtask)}`);
|
|
119
|
+
}
|
|
120
|
+
catch (error) {
|
|
121
|
+
return errorResponse(error instanceof Error ? error.message : "Unknown error");
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
// Update a subtask
|
|
125
|
+
server.tool("update_subtask", "Update a subtask's title, completion status, or position. Use this to rename a subtask, manually set its completion status, or reorder it within the task's subtask list. At least one field (title, completed, or position) must be provided.", {
|
|
126
|
+
taskId: z
|
|
127
|
+
.string()
|
|
128
|
+
.describe("The unique identifier (UUID) of the parent task containing the subtask"),
|
|
129
|
+
subtaskId: z
|
|
130
|
+
.string()
|
|
131
|
+
.describe("The unique identifier (UUID) of the subtask to update"),
|
|
132
|
+
title: z
|
|
133
|
+
.string()
|
|
134
|
+
.optional()
|
|
135
|
+
.describe("New title for the subtask. If not provided, title remains unchanged"),
|
|
136
|
+
completed: z
|
|
137
|
+
.boolean()
|
|
138
|
+
.optional()
|
|
139
|
+
.describe("Set the completion status directly. true = completed, false = incomplete. Use toggle_subtask for simple toggling"),
|
|
140
|
+
position: z
|
|
141
|
+
.number()
|
|
142
|
+
.optional()
|
|
143
|
+
.describe("New position in the subtask list (0-indexed). Lower numbers appear first"),
|
|
144
|
+
}, async (input) => {
|
|
145
|
+
try {
|
|
146
|
+
// Build update data, only including provided fields
|
|
147
|
+
const updateData = {};
|
|
148
|
+
if (input.title !== undefined) {
|
|
149
|
+
updateData.title = input.title;
|
|
150
|
+
}
|
|
151
|
+
if (input.completed !== undefined) {
|
|
152
|
+
updateData.completed = input.completed;
|
|
153
|
+
}
|
|
154
|
+
if (input.position !== undefined) {
|
|
155
|
+
updateData.position = input.position;
|
|
156
|
+
}
|
|
157
|
+
// Check if at least one field is provided
|
|
158
|
+
if (Object.keys(updateData).length === 0) {
|
|
159
|
+
return errorResponse("At least one field (title, completed, or position) must be provided to update");
|
|
160
|
+
}
|
|
161
|
+
const response = await apiClient.updateSubtask(input.taskId, input.subtaskId, updateData);
|
|
162
|
+
if (!response.success) {
|
|
163
|
+
return errorResponse(response.error?.message || "Failed to update subtask");
|
|
164
|
+
}
|
|
165
|
+
const subtask = response.data;
|
|
166
|
+
const updatedFields = Object.keys(updateData).join(", ");
|
|
167
|
+
return successResponse(`Successfully updated subtask (fields: ${updatedFields}):\n\n${formatSubtask(subtask)}`);
|
|
168
|
+
}
|
|
169
|
+
catch (error) {
|
|
170
|
+
return errorResponse(error instanceof Error ? error.message : "Unknown error");
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
// Delete a subtask
|
|
174
|
+
server.tool("delete_subtask", "Permanently delete a subtask from a task. This action cannot be undone. Use this when a subtask is no longer needed or was created by mistake.", {
|
|
175
|
+
taskId: z
|
|
176
|
+
.string()
|
|
177
|
+
.describe("The unique identifier (UUID) of the parent task containing the subtask"),
|
|
178
|
+
subtaskId: z
|
|
179
|
+
.string()
|
|
180
|
+
.describe("The unique identifier (UUID) of the subtask to delete"),
|
|
181
|
+
}, async (input) => {
|
|
182
|
+
try {
|
|
183
|
+
const response = await apiClient.deleteSubtask(input.taskId, input.subtaskId);
|
|
184
|
+
if (!response.success) {
|
|
185
|
+
return errorResponse(response.error?.message || "Failed to delete subtask");
|
|
186
|
+
}
|
|
187
|
+
return successResponse(`Successfully deleted subtask ${input.subtaskId} from task ${input.taskId}`);
|
|
188
|
+
}
|
|
189
|
+
catch (error) {
|
|
190
|
+
return errorResponse(error instanceof Error ? error.message : "Unknown error");
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
//# sourceMappingURL=subtasks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subtasks.js","sourceRoot":"","sources":["../../src/tools/subtasks.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB;;GAEG;AACH,SAAS,aAAa,CAAC,OAAgB;IACrC,MAAM,QAAQ,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC;IACnD,OAAO,GAAG,QAAQ,IAAI,OAAO,CAAC,KAAK,SAAS,OAAO,CAAC,EAAE,eAAe,OAAO,CAAC,QAAQ,GAAG,CAAC;AAC3F,CAAC;AAED;;GAEG;AACH,SAAS,iBAAiB,CAAC,QAAmB;IAC5C,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,oBAAoB,CAAC;IAC9B,CAAC;IACD,OAAO,QAAQ,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAChD,CAAC;AAED;;GAEG;AACH,SAAS,eAAe,CAAC,IAAY;IACnC,OAAO;QACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,CAAC;KAC3C,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,aAAa,CAAC,OAAe;IACpC,OAAO;QACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,UAAU,OAAO,EAAE,EAAE,CAAC;QAC/D,OAAO,EAAE,IAAI;KACd,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAClC,MAAiB,EACjB,SAAoB;IAEpB,2BAA2B;IAC3B,MAAM,CAAC,IAAI,CACT,eAAe,EACf,oNAAoN,EACpN;QACE,MAAM,EAAE,CAAC;aACN,MAAM,EAAE;aACR,QAAQ,CACP,sEAAsE,CACvE;KACJ,EACD,KAAK,EAAE,KAAK,EAAE,EAAE;QACd,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YAE5D,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;gBACtB,OAAO,aAAa,CAClB,QAAQ,CAAC,KAAK,EAAE,OAAO,IAAI,yBAAyB,CACrD,CAAC;YACJ,CAAC;YAED,MAAM,QAAQ,GAAG,QAAQ,CAAC,IAAI,IAAI,EAAE,CAAC;YACrC,MAAM,aAAa,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAC;YAElD,OAAO,eAAe,CACpB,qBAAqB,KAAK,CAAC,MAAM,QAAQ,aAAa,cAAc,QAAQ,CAAC,MAAM,aAAa,CACjG,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,aAAa,CAClB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CACzD,CAAC;QACJ,CAAC;IACH,CAAC,CACF,CAAC;IAEF,mBAAmB;IACnB,MAAM,CAAC,IAAI,CACT,gBAAgB,EAChB,4OAA4O,EAC5O;QACE,MAAM,EAAE,CAAC;aACN,MAAM,EAAE;aACR,QAAQ,CACP,uEAAuE,CACxE;QACH,KAAK,EAAE,CAAC;aACL,MAAM,EAAE;aACR,QAAQ,CACP,+HAA+H,CAChI;QACH,QAAQ,EAAE,CAAC;aACR,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CACP,0GAA0G,CAC3G;KACJ,EACD,KAAK,EAAE,KAAK,EAAE,EAAE;QACd,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,aAAa,CAAC,KAAK,CAAC,MAAM,EAAE;gBAC3D,KAAK,EAAE,KAAK,CAAC,KAAK;gBAClB,QAAQ,EAAE,KAAK,CAAC,QAAQ;aACzB,CAAC,CAAC;YAEH,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;gBACtB,OAAO,aAAa,CAClB,QAAQ,CAAC,KAAK,EAAE,OAAO,IAAI,0BAA0B,CACtD,CAAC;YACJ,CAAC;YAED,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAK,CAAC;YAC/B,OAAO,eAAe,CACpB,oCAAoC,aAAa,CAAC,OAAO,CAAC,mBAAmB,OAAO,CAAC,EAAE,EAAE,CAC1F,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,aAAa,CAClB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CACzD,CAAC;QACJ,CAAC;IACH,CAAC,CACF,CAAC;IAEF,4BAA4B;IAC5B,MAAM,CAAC,IAAI,CACT,gBAAgB,EAChB,4NAA4N,EAC5N;QACE,MAAM,EAAE,CAAC;aACN,MAAM,EAAE;aACR,QAAQ,CACP,wEAAwE,CACzE;QACH,SAAS,EAAE,CAAC;aACT,MAAM,EAAE;aACR,QAAQ,CAAC,uDAAuD,CAAC;KACrE,EACD,KAAK,EAAE,KAAK,EAAE,EAAE;QACd,IAAI,CAAC;YACH,uCAAuC;YACvC,MAAM,YAAY,GAAG,MAAM,SAAS,CAAC,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YAEhE,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC;gBAC1B,OAAO,aAAa,CAClB,YAAY,CAAC,KAAK,EAAE,OAAO,IAAI,yBAAyB,CACzD,CAAC;YACJ,CAAC;YAED,MAAM,QAAQ,GAAG,YAAY,CAAC,IAAI,IAAI,EAAE,CAAC;YACzC,MAAM,cAAc,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,KAAK,CAAC,SAAS,CAAC,CAAC;YAEtE,IAAI,CAAC,cAAc,EAAE,CAAC;gBACpB,OAAO,aAAa,CAClB,mBAAmB,KAAK,CAAC,SAAS,sBAAsB,KAAK,CAAC,MAAM,EAAE,CACvE,CAAC;YACJ,CAAC;YAED,8BAA8B;YAC9B,MAAM,kBAAkB,GAAG,CAAC,cAAc,CAAC,SAAS,CAAC;YACrD,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,aAAa,CAC5C,KAAK,CAAC,MAAM,EACZ,KAAK,CAAC,SAAS,EACf,EAAE,SAAS,EAAE,kBAAkB,EAAE,CAClC,CAAC;YAEF,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;gBACtB,OAAO,aAAa,CAClB,QAAQ,CAAC,KAAK,EAAE,OAAO,IAAI,0BAA0B,CACtD,CAAC;YACJ,CAAC;YAED,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAK,CAAC;YAC/B,MAAM,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,YAAY,CAAC;YAElE,OAAO,eAAe,CACpB,mCAAmC,UAAU,QAAQ,aAAa,CAAC,OAAO,CAAC,EAAE,CAC9E,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,aAAa,CAClB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CACzD,CAAC;QACJ,CAAC;IACH,CAAC,CACF,CAAC;IAEF,mBAAmB;IACnB,MAAM,CAAC,IAAI,CACT,gBAAgB,EAChB,gPAAgP,EAChP;QACE,MAAM,EAAE,CAAC;aACN,MAAM,EAAE;aACR,QAAQ,CACP,wEAAwE,CACzE;QACH,SAAS,EAAE,CAAC;aACT,MAAM,EAAE;aACR,QAAQ,CAAC,uDAAuD,CAAC;QACpE,KAAK,EAAE,CAAC;aACL,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CACP,qEAAqE,CACtE;QACH,SAAS,EAAE,CAAC;aACT,OAAO,EAAE;aACT,QAAQ,EAAE;aACV,QAAQ,CACP,kHAAkH,CACnH;QACH,QAAQ,EAAE,CAAC;aACR,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CACP,0EAA0E,CAC3E;KACJ,EACD,KAAK,EAAE,KAAK,EAAE,EAAE;QACd,IAAI,CAAC;YACH,oDAAoD;YACpD,MAAM,UAAU,GAIZ,EAAE,CAAC;YAEP,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;gBAC9B,UAAU,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;YACjC,CAAC;YACD,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;gBAClC,UAAU,CAAC,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC;YACzC,CAAC;YACD,IAAI,KAAK,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;gBACjC,UAAU,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;YACvC,CAAC;YAED,0CAA0C;YAC1C,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACzC,OAAO,aAAa,CAClB,+EAA+E,CAChF,CAAC;YACJ,CAAC;YAED,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,aAAa,CAC5C,KAAK,CAAC,MAAM,EACZ,KAAK,CAAC,SAAS,EACf,UAAU,CACX,CAAC;YAEF,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;gBACtB,OAAO,aAAa,CAClB,QAAQ,CAAC,KAAK,EAAE,OAAO,IAAI,0BAA0B,CACtD,CAAC;YACJ,CAAC;YAED,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAK,CAAC;YAC/B,MAAM,aAAa,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAEzD,OAAO,eAAe,CACpB,yCAAyC,aAAa,SAAS,aAAa,CAAC,OAAO,CAAC,EAAE,CACxF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,aAAa,CAClB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CACzD,CAAC;QACJ,CAAC;IACH,CAAC,CACF,CAAC;IAEF,mBAAmB;IACnB,MAAM,CAAC,IAAI,CACT,gBAAgB,EAChB,gJAAgJ,EAChJ;QACE,MAAM,EAAE,CAAC;aACN,MAAM,EAAE;aACR,QAAQ,CACP,wEAAwE,CACzE;QACH,SAAS,EAAE,CAAC;aACT,MAAM,EAAE;aACR,QAAQ,CAAC,uDAAuD,CAAC;KACrE,EACD,KAAK,EAAE,KAAK,EAAE,EAAE;QACd,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,aAAa,CAC5C,KAAK,CAAC,MAAM,EACZ,KAAK,CAAC,SAAS,CAChB,CAAC;YAEF,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;gBACtB,OAAO,aAAa,CAClB,QAAQ,CAAC,KAAK,EAAE,OAAO,IAAI,0BAA0B,CACtD,CAAC;YACJ,CAAC;YAED,OAAO,eAAe,CACpB,gCAAgC,KAAK,CAAC,SAAS,cAAc,KAAK,CAAC,MAAM,EAAE,CAC5E,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,aAAa,CAClB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CACzD,CAAC;QACJ,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Tools for Task Management
|
|
3
|
+
* Provides AI agents with tools to create, read, update, and delete tasks
|
|
4
|
+
*/
|
|
5
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
6
|
+
import type { ApiClient } from "../lib/api-client.js";
|
|
7
|
+
/**
|
|
8
|
+
* Registers all task management tools with the MCP server
|
|
9
|
+
*/
|
|
10
|
+
export declare function registerTaskTools(server: McpServer, apiClient: ApiClient): void;
|
|
11
|
+
//# sourceMappingURL=tasks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tasks.d.ts","sourceRoot":"","sources":["../../src/tools/tasks.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,KAAK,EAAE,SAAS,EAAQ,MAAM,sBAAsB,CAAC;AAoE5D;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,SAAS,EACjB,SAAS,EAAE,SAAS,GACnB,IAAI,CAieN"}
|