@brxce/mcp-server 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 +220 -0
- package/dist/config/environment.d.ts +8 -0
- package/dist/config/environment.d.ts.map +1 -0
- package/dist/config/environment.js +16 -0
- package/dist/config/environment.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +167 -0
- package/dist/index.js.map +1 -0
- package/dist/prompts/worknode-prompts.d.ts +7 -0
- package/dist/prompts/worknode-prompts.d.ts.map +1 -0
- package/dist/prompts/worknode-prompts.js +369 -0
- package/dist/prompts/worknode-prompts.js.map +1 -0
- package/dist/prompts/workspace-context-prompt.d.ts +4 -0
- package/dist/prompts/workspace-context-prompt.d.ts.map +1 -0
- package/dist/prompts/workspace-context-prompt.js +101 -0
- package/dist/prompts/workspace-context-prompt.js.map +1 -0
- package/dist/resources/user-resource.d.ts +4 -0
- package/dist/resources/user-resource.d.ts.map +1 -0
- package/dist/resources/user-resource.js +40 -0
- package/dist/resources/user-resource.js.map +1 -0
- package/dist/resources/workspace-members-resource.d.ts +4 -0
- package/dist/resources/workspace-members-resource.d.ts.map +1 -0
- package/dist/resources/workspace-members-resource.js +39 -0
- package/dist/resources/workspace-members-resource.js.map +1 -0
- package/dist/resources/workspace-resource.d.ts +4 -0
- package/dist/resources/workspace-resource.d.ts.map +1 -0
- package/dist/resources/workspace-resource.js +27 -0
- package/dist/resources/workspace-resource.js.map +1 -0
- package/dist/services/api-client.d.ts +17 -0
- package/dist/services/api-client.d.ts.map +1 -0
- package/dist/services/api-client.js +118 -0
- package/dist/services/api-client.js.map +1 -0
- package/dist/tools/meeting-agenda-tool.d.ts +7 -0
- package/dist/tools/meeting-agenda-tool.d.ts.map +1 -0
- package/dist/tools/meeting-agenda-tool.js +452 -0
- package/dist/tools/meeting-agenda-tool.js.map +1 -0
- package/dist/tools/meeting-create-tool.d.ts +8 -0
- package/dist/tools/meeting-create-tool.d.ts.map +1 -0
- package/dist/tools/meeting-create-tool.js +309 -0
- package/dist/tools/meeting-create-tool.js.map +1 -0
- package/dist/tools/meeting-decisions-tool.d.ts +7 -0
- package/dist/tools/meeting-decisions-tool.d.ts.map +1 -0
- package/dist/tools/meeting-decisions-tool.js +431 -0
- package/dist/tools/meeting-decisions-tool.js.map +1 -0
- package/dist/tools/meeting-list-tool.d.ts +7 -0
- package/dist/tools/meeting-list-tool.d.ts.map +1 -0
- package/dist/tools/meeting-list-tool.js +305 -0
- package/dist/tools/meeting-list-tool.js.map +1 -0
- package/dist/tools/meeting-notes-tool.d.ts +7 -0
- package/dist/tools/meeting-notes-tool.d.ts.map +1 -0
- package/dist/tools/meeting-notes-tool.js +318 -0
- package/dist/tools/meeting-notes-tool.js.map +1 -0
- package/dist/tools/meeting-update-tool.d.ts +7 -0
- package/dist/tools/meeting-update-tool.d.ts.map +1 -0
- package/dist/tools/meeting-update-tool.js +310 -0
- package/dist/tools/meeting-update-tool.js.map +1 -0
- package/dist/tools/tag-category-tool.d.ts +4 -0
- package/dist/tools/tag-category-tool.d.ts.map +1 -0
- package/dist/tools/tag-category-tool.js +293 -0
- package/dist/tools/tag-category-tool.js.map +1 -0
- package/dist/tools/tag-search-tool.d.ts +4 -0
- package/dist/tools/tag-search-tool.d.ts.map +1 -0
- package/dist/tools/tag-search-tool.js +358 -0
- package/dist/tools/tag-search-tool.js.map +1 -0
- package/dist/tools/tag-tool.d.ts +4 -0
- package/dist/tools/tag-tool.d.ts.map +1 -0
- package/dist/tools/tag-tool.js +450 -0
- package/dist/tools/tag-tool.js.map +1 -0
- package/dist/tools/worknode-archive-tool.d.ts +7 -0
- package/dist/tools/worknode-archive-tool.d.ts.map +1 -0
- package/dist/tools/worknode-archive-tool.js +163 -0
- package/dist/tools/worknode-archive-tool.js.map +1 -0
- package/dist/tools/worknode-create-tool.d.ts +4 -0
- package/dist/tools/worknode-create-tool.d.ts.map +1 -0
- package/dist/tools/worknode-create-tool.js +382 -0
- package/dist/tools/worknode-create-tool.js.map +1 -0
- package/dist/tools/worknode-my-work-tool.d.ts +8 -0
- package/dist/tools/worknode-my-work-tool.d.ts.map +1 -0
- package/dist/tools/worknode-my-work-tool.js +302 -0
- package/dist/tools/worknode-my-work-tool.js.map +1 -0
- package/dist/tools/worknode-search-tool.d.ts +4 -0
- package/dist/tools/worknode-search-tool.d.ts.map +1 -0
- package/dist/tools/worknode-search-tool.js +289 -0
- package/dist/tools/worknode-search-tool.js.map +1 -0
- package/dist/tools/worknode-subtree-tool.d.ts +4 -0
- package/dist/tools/worknode-subtree-tool.d.ts.map +1 -0
- package/dist/tools/worknode-subtree-tool.js +175 -0
- package/dist/tools/worknode-subtree-tool.js.map +1 -0
- package/dist/tools/worknode-tag-tool.d.ts +4 -0
- package/dist/tools/worknode-tag-tool.d.ts.map +1 -0
- package/dist/tools/worknode-tag-tool.js +353 -0
- package/dist/tools/worknode-tag-tool.js.map +1 -0
- package/dist/tools/worknode-update-tool.d.ts +4 -0
- package/dist/tools/worknode-update-tool.d.ts.map +1 -0
- package/dist/tools/worknode-update-tool.js +409 -0
- package/dist/tools/worknode-update-tool.js.map +1 -0
- package/dist/tools/workspace-inbox-tool.d.ts +8 -0
- package/dist/tools/workspace-inbox-tool.d.ts.map +1 -0
- package/dist/tools/workspace-inbox-tool.js +210 -0
- package/dist/tools/workspace-inbox-tool.js.map +1 -0
- package/dist/tools/workspace-tree-tool.d.ts +4 -0
- package/dist/tools/workspace-tree-tool.d.ts.map +1 -0
- package/dist/tools/workspace-tree-tool.js +419 -0
- package/dist/tools/workspace-tree-tool.js.map +1 -0
- package/package.json +61 -0
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* Register WorkNode my-work tool for LLM-invoked queries
|
|
4
|
+
* This tool allows the LLM to automatically fetch user's work based on context
|
|
5
|
+
*/
|
|
6
|
+
export function registerWorknodeMyWorkTool(server, apiClient) {
|
|
7
|
+
server.registerTool('brxce_my_work', {
|
|
8
|
+
description: `Query user's WorkNodes with flexible filtering for common workflows.
|
|
9
|
+
|
|
10
|
+
ā ļø **CRITICAL: Workspace Verification (Optional but Recommended)**
|
|
11
|
+
If filtering by workspace:
|
|
12
|
+
1. Read the \`user://me\` resource to get available workspaces
|
|
13
|
+
2. Identify the correct workspaceId from the resource data
|
|
14
|
+
3. If user mentions a specific workspace, verify it exists in user://me
|
|
15
|
+
4. NEVER assume or guess workspaceId values
|
|
16
|
+
5. If workspaceId is omitted, returns work across ALL user's workspaces
|
|
17
|
+
|
|
18
|
+
**Example Workflow:**
|
|
19
|
+
\`\`\`
|
|
20
|
+
User: "What am I working on in BRXCE Development?"
|
|
21
|
+
LLM:
|
|
22
|
+
1. Reads user://me resource
|
|
23
|
+
2. Finds workspace: {id: 138, name: "BRXCE Development"}
|
|
24
|
+
3. Calls brxce_my_work with mode=active, workspaceId=138
|
|
25
|
+
\`\`\`
|
|
26
|
+
|
|
27
|
+
**When to use this tool:**
|
|
28
|
+
The LLM should automatically call this tool when the user asks about:
|
|
29
|
+
- "What am I working on?" ā Use mode=active
|
|
30
|
+
- "What did I complete today/this week?" ā Use mode=completed with completedSince
|
|
31
|
+
- "What's urgent?" or "What's due soon?" ā Use mode=urgent with dueWithin
|
|
32
|
+
- "What's in my inbox?" or "What needs organizing?" ā Use mode=inbox
|
|
33
|
+
- "Show me all my work" ā Use mode=all
|
|
34
|
+
|
|
35
|
+
**Query Modes:**
|
|
36
|
+
- active: Currently in_progress WorkNodes
|
|
37
|
+
- completed: Completed WorkNodes (use completedSince for time range)
|
|
38
|
+
- urgent: Critical/urgent priority OR due soon (use dueWithin for deadline)
|
|
39
|
+
- inbox: Backlog status items needing organization
|
|
40
|
+
- all: Everything assigned to or created by user
|
|
41
|
+
|
|
42
|
+
**Scope Options:**
|
|
43
|
+
- assigned: Only WorkNodes assigned to me
|
|
44
|
+
- created: Only WorkNodes I created
|
|
45
|
+
- both: WorkNodes I'm assigned to OR created (default)
|
|
46
|
+
|
|
47
|
+
**Time Filters:**
|
|
48
|
+
For completed mode (completedSince):
|
|
49
|
+
- today, yesterday, this-week, last-week, this-month, last-month
|
|
50
|
+
- Or ISO date string
|
|
51
|
+
|
|
52
|
+
For urgent mode (dueWithin):
|
|
53
|
+
- today, tomorrow, this-week, next-week
|
|
54
|
+
- Or ISO date string
|
|
55
|
+
|
|
56
|
+
**Best Practices:**
|
|
57
|
+
1. Use mode=active when user asks about current work
|
|
58
|
+
2. Use mode=completed with time filter for retrospectives
|
|
59
|
+
3. Use mode=urgent for priority/deadline-based queries
|
|
60
|
+
4. Use mode=inbox when user mentions organizing or backlog
|
|
61
|
+
5. Always use scope=both unless user specifically mentions "assigned to me" or "I created"
|
|
62
|
+
6. Filter by workspaceId if user mentions a specific workspace
|
|
63
|
+
|
|
64
|
+
**Output Format:**
|
|
65
|
+
Returns JSON with:
|
|
66
|
+
- data: Array of WorkNode objects with full details
|
|
67
|
+
- meta: Query metadata (total count, mode, scope, workspace, userId)
|
|
68
|
+
|
|
69
|
+
ā° **TIMEZONE HANDLING:**
|
|
70
|
+
ALL date/time fields in the response are in UTC (ISO 8601 format):
|
|
71
|
+
- completedAt, createdAt, updatedAt, dueDate, startDate
|
|
72
|
+
|
|
73
|
+
When presenting results to the user, you MUST convert UTC timestamps to the user's local timezone:
|
|
74
|
+
1. Check the current date/time from the <env> tag in the system prompt
|
|
75
|
+
2. Identify the user's timezone (e.g., Asia/Seoul = UTC+9)
|
|
76
|
+
3. Convert ALL displayed timestamps from UTC to local time
|
|
77
|
+
4. Format dates in a user-friendly way (e.g., "ģ¤ķ 5:16" not "08:16 UTC")
|
|
78
|
+
|
|
79
|
+
Example conversion (Korea Time, UTC+9):
|
|
80
|
+
- API returns: "completedAt": "2025-10-20T08:16:25.556Z" (UTC)
|
|
81
|
+
- Display to user: "ģė£: 2025-10-20 ģ¤ķ 5:16" (KST)
|
|
82
|
+
|
|
83
|
+
The LLM should format this data into a readable summary for the user.`,
|
|
84
|
+
inputSchema: {
|
|
85
|
+
mode: z
|
|
86
|
+
.enum(['active', 'completed', 'urgent', 'inbox', 'all'])
|
|
87
|
+
.describe('Query mode: active (in_progress), completed, urgent (high priority/due soon), inbox (backlog), all'),
|
|
88
|
+
workspaceId: z
|
|
89
|
+
.number()
|
|
90
|
+
.optional()
|
|
91
|
+
.describe('Optional workspace ID to filter results'),
|
|
92
|
+
scope: z
|
|
93
|
+
.enum(['assigned', 'created', 'both'])
|
|
94
|
+
.optional()
|
|
95
|
+
.describe('Filter scope: assigned (assigned to me), created (I created), both (default)'),
|
|
96
|
+
completedSince: z
|
|
97
|
+
.string()
|
|
98
|
+
.optional()
|
|
99
|
+
.describe('For completed mode: today, yesterday, this-week, last-week, this-month, last-month, or ISO date'),
|
|
100
|
+
dueWithin: z
|
|
101
|
+
.string()
|
|
102
|
+
.optional()
|
|
103
|
+
.describe('For urgent mode: today, tomorrow, this-week, next-week, or ISO date'),
|
|
104
|
+
includeArchived: z
|
|
105
|
+
.boolean()
|
|
106
|
+
.optional()
|
|
107
|
+
.describe('Include archived items (default: false)'),
|
|
108
|
+
limit: z
|
|
109
|
+
.number()
|
|
110
|
+
.optional()
|
|
111
|
+
.describe('Max results to return (default: 100, max: 500)'),
|
|
112
|
+
compact: z
|
|
113
|
+
.boolean()
|
|
114
|
+
.optional()
|
|
115
|
+
.describe('Return compact format (minimal fields for token efficiency, ~80% size reduction, default: false)'),
|
|
116
|
+
tagIds: z
|
|
117
|
+
.string()
|
|
118
|
+
.optional()
|
|
119
|
+
.describe('Filter by tag IDs (comma-separated, e.g., "13,29")'),
|
|
120
|
+
tagSlugs: z
|
|
121
|
+
.string()
|
|
122
|
+
.optional()
|
|
123
|
+
.describe('Filter by tag slugs (comma-separated, e.g., "mcp-server,backend")'),
|
|
124
|
+
matchAllTags: z
|
|
125
|
+
.boolean()
|
|
126
|
+
.optional()
|
|
127
|
+
.describe('If true, WorkNode must have ALL specified tags. If false (default), ANY tag matches'),
|
|
128
|
+
createdAfter: z
|
|
129
|
+
.string()
|
|
130
|
+
.optional()
|
|
131
|
+
.describe('Filter nodes created after this date (ISO 8601)'),
|
|
132
|
+
createdBefore: z
|
|
133
|
+
.string()
|
|
134
|
+
.optional()
|
|
135
|
+
.describe('Filter nodes created before this date (ISO 8601)'),
|
|
136
|
+
updatedAfter: z
|
|
137
|
+
.string()
|
|
138
|
+
.optional()
|
|
139
|
+
.describe('Filter nodes updated after this date (ISO 8601)'),
|
|
140
|
+
updatedBefore: z
|
|
141
|
+
.string()
|
|
142
|
+
.optional()
|
|
143
|
+
.describe('Filter nodes updated before this date (ISO 8601)'),
|
|
144
|
+
dueAfter: z
|
|
145
|
+
.string()
|
|
146
|
+
.optional()
|
|
147
|
+
.describe('Filter nodes with due date after this date (ISO 8601)'),
|
|
148
|
+
dueBefore: z
|
|
149
|
+
.string()
|
|
150
|
+
.optional()
|
|
151
|
+
.describe('Filter nodes with due date before this date (ISO 8601)'),
|
|
152
|
+
completedAfter: z
|
|
153
|
+
.string()
|
|
154
|
+
.optional()
|
|
155
|
+
.describe('Filter nodes completed after this date (ISO 8601)'),
|
|
156
|
+
completedBefore: z
|
|
157
|
+
.string()
|
|
158
|
+
.optional()
|
|
159
|
+
.describe('Filter nodes completed before this date (ISO 8601)'),
|
|
160
|
+
startAfter: z
|
|
161
|
+
.string()
|
|
162
|
+
.optional()
|
|
163
|
+
.describe('Filter nodes with start date after this date (ISO 8601)'),
|
|
164
|
+
startBefore: z
|
|
165
|
+
.string()
|
|
166
|
+
.optional()
|
|
167
|
+
.describe('Filter nodes with start date before this date (ISO 8601)'),
|
|
168
|
+
sortBy: z
|
|
169
|
+
.enum(['title', 'priority', 'status', 'dueDate', 'createdAt', 'updatedAt', 'completedAt', 'nodeType', 'progress'])
|
|
170
|
+
.optional()
|
|
171
|
+
.describe('Sort field'),
|
|
172
|
+
sortOrder: z
|
|
173
|
+
.enum(['asc', 'desc'])
|
|
174
|
+
.optional()
|
|
175
|
+
.describe('Sort direction (default: asc)'),
|
|
176
|
+
},
|
|
177
|
+
}, async (args) => {
|
|
178
|
+
const { mode = 'all', workspaceId, scope = 'both', completedSince, dueWithin, includeArchived = false, limit = 100, compact = false, tagIds, tagSlugs, matchAllTags = false, createdAfter, createdBefore, updatedAfter, updatedBefore, dueAfter, dueBefore, completedAfter, completedBefore, startAfter, startBefore, sortBy, sortOrder, } = args;
|
|
179
|
+
try {
|
|
180
|
+
// Build query string
|
|
181
|
+
const params = new URLSearchParams({
|
|
182
|
+
mode,
|
|
183
|
+
scope,
|
|
184
|
+
});
|
|
185
|
+
if (workspaceId) {
|
|
186
|
+
params.append('workspaceId', workspaceId.toString());
|
|
187
|
+
}
|
|
188
|
+
if (completedSince) {
|
|
189
|
+
params.append('completedSince', completedSince);
|
|
190
|
+
}
|
|
191
|
+
if (dueWithin) {
|
|
192
|
+
params.append('dueWithin', dueWithin);
|
|
193
|
+
}
|
|
194
|
+
if (includeArchived) {
|
|
195
|
+
params.append('includeArchived', 'true');
|
|
196
|
+
}
|
|
197
|
+
if (limit) {
|
|
198
|
+
params.append('limit', limit.toString());
|
|
199
|
+
}
|
|
200
|
+
if (compact) {
|
|
201
|
+
params.append('compact', 'true');
|
|
202
|
+
}
|
|
203
|
+
if (tagIds) {
|
|
204
|
+
params.append('tagIds', tagIds);
|
|
205
|
+
}
|
|
206
|
+
if (tagSlugs) {
|
|
207
|
+
params.append('tagSlugs', tagSlugs);
|
|
208
|
+
}
|
|
209
|
+
if (matchAllTags) {
|
|
210
|
+
params.append('matchAllTags', 'true');
|
|
211
|
+
}
|
|
212
|
+
if (createdAfter) {
|
|
213
|
+
params.append('createdAfter', createdAfter);
|
|
214
|
+
}
|
|
215
|
+
if (createdBefore) {
|
|
216
|
+
params.append('createdBefore', createdBefore);
|
|
217
|
+
}
|
|
218
|
+
if (updatedAfter) {
|
|
219
|
+
params.append('updatedAfter', updatedAfter);
|
|
220
|
+
}
|
|
221
|
+
if (updatedBefore) {
|
|
222
|
+
params.append('updatedBefore', updatedBefore);
|
|
223
|
+
}
|
|
224
|
+
if (dueAfter) {
|
|
225
|
+
params.append('dueAfter', dueAfter);
|
|
226
|
+
}
|
|
227
|
+
if (dueBefore) {
|
|
228
|
+
params.append('dueBefore', dueBefore);
|
|
229
|
+
}
|
|
230
|
+
if (completedAfter) {
|
|
231
|
+
params.append('completedAfter', completedAfter);
|
|
232
|
+
}
|
|
233
|
+
if (completedBefore) {
|
|
234
|
+
params.append('completedBefore', completedBefore);
|
|
235
|
+
}
|
|
236
|
+
if (startAfter) {
|
|
237
|
+
params.append('startAfter', startAfter);
|
|
238
|
+
}
|
|
239
|
+
if (startBefore) {
|
|
240
|
+
params.append('startBefore', startBefore);
|
|
241
|
+
}
|
|
242
|
+
if (sortBy) {
|
|
243
|
+
params.append('sortBy', sortBy);
|
|
244
|
+
}
|
|
245
|
+
if (sortOrder) {
|
|
246
|
+
params.append('sortOrder', sortOrder);
|
|
247
|
+
}
|
|
248
|
+
const response = await apiClient.get(`/mcp/worknodes/my-work?${params.toString()}`);
|
|
249
|
+
if (!response.success || !response.data) {
|
|
250
|
+
return {
|
|
251
|
+
content: [
|
|
252
|
+
{
|
|
253
|
+
type: 'text',
|
|
254
|
+
text: JSON.stringify({
|
|
255
|
+
error: 'Failed to fetch my work',
|
|
256
|
+
mode,
|
|
257
|
+
scope,
|
|
258
|
+
}),
|
|
259
|
+
},
|
|
260
|
+
],
|
|
261
|
+
isError: true,
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
const { data, meta } = response;
|
|
265
|
+
// Return structured JSON for LLM to format
|
|
266
|
+
return {
|
|
267
|
+
content: [
|
|
268
|
+
{
|
|
269
|
+
type: 'text',
|
|
270
|
+
text: JSON.stringify({
|
|
271
|
+
summary: {
|
|
272
|
+
mode: meta.mode,
|
|
273
|
+
scope: meta.scope,
|
|
274
|
+
total: meta.total,
|
|
275
|
+
workspaceId: meta.workspace,
|
|
276
|
+
userId: meta.userId,
|
|
277
|
+
},
|
|
278
|
+
worknodes: data,
|
|
279
|
+
}, null, 2),
|
|
280
|
+
},
|
|
281
|
+
],
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
catch (error) {
|
|
285
|
+
return {
|
|
286
|
+
content: [
|
|
287
|
+
{
|
|
288
|
+
type: 'text',
|
|
289
|
+
text: JSON.stringify({
|
|
290
|
+
error: 'Failed to fetch my work',
|
|
291
|
+
message: error.message,
|
|
292
|
+
mode,
|
|
293
|
+
scope,
|
|
294
|
+
}),
|
|
295
|
+
},
|
|
296
|
+
],
|
|
297
|
+
isError: true,
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
//# sourceMappingURL=worknode-my-work-tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worknode-my-work-tool.js","sourceRoot":"","sources":["../../src/tools/worknode-my-work-tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import { ApiClient } from '../services/api-client.js';
|
|
3
|
+
export declare function registerWorknodeSearchTool(server: McpServer, apiClient: ApiClient): void;
|
|
4
|
+
//# sourceMappingURL=worknode-search-tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worknode-search-tool.d.ts","sourceRoot":"","sources":["../../src/tools/worknode-search-tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAEtD,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,QAoUjF"}
|
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export function registerWorknodeSearchTool(server, apiClient) {
|
|
3
|
+
/**
|
|
4
|
+
* Search WorkNodes by keyword with compact mode
|
|
5
|
+
*/
|
|
6
|
+
server.registerTool('brxce_search_worknodes', {
|
|
7
|
+
description: `Search WorkNodes by keyword with token-efficient compact mode.
|
|
8
|
+
|
|
9
|
+
ā ļø **CRITICAL: Workspace Verification (Optional but Recommended)**
|
|
10
|
+
If filtering by workspace:
|
|
11
|
+
1. Read the \`user://me\` resource to get available workspaces
|
|
12
|
+
2. Identify the correct workspaceId from the resource data
|
|
13
|
+
3. If user mentions a specific workspace, verify it exists in user://me
|
|
14
|
+
4. NEVER assume or guess workspaceId values
|
|
15
|
+
5. If workspaceId is omitted, searches across ALL user's accessible workspaces
|
|
16
|
+
|
|
17
|
+
**Example Workflow:**
|
|
18
|
+
\`\`\`
|
|
19
|
+
User: "Find all MCP related tasks in BRXCE Development"
|
|
20
|
+
LLM:
|
|
21
|
+
1. Reads user://me resource
|
|
22
|
+
2. Finds workspace: {id: 138, name: "BRXCE Development"}
|
|
23
|
+
3. Calls brxce_search_worknodes with query="MCP", workspaceId=138, nodeTypes=["task"]
|
|
24
|
+
\`\`\`
|
|
25
|
+
|
|
26
|
+
**When to use this tool:**
|
|
27
|
+
The LLM should automatically call this tool when the user asks about:
|
|
28
|
+
- "Find tasks about X" ā Use query="X", nodeTypes=["task"]
|
|
29
|
+
- "Search for AI projects" ā Use query="AI", nodeTypes=["project"]
|
|
30
|
+
- "Find all MCP-related work" ā Use query="MCP"
|
|
31
|
+
- "Show me critical priority items" ā Use priorities=["critical"]
|
|
32
|
+
- "Find completed tasks about backend" ā Use query="backend", statuses=["completed"]
|
|
33
|
+
|
|
34
|
+
**Compact Mode:**
|
|
35
|
+
- When \`compact=true\`, returns only essential fields: id, title, nodeType, status, priority, parentNodeId, nodeLevel, workspaceId
|
|
36
|
+
- When \`compact=false\` or omitted, returns all WorkNode fields including description, dates, assignee, etc.
|
|
37
|
+
- Use compact mode to reduce token usage when only basic info is needed
|
|
38
|
+
|
|
39
|
+
**Search Features:**
|
|
40
|
+
- Keyword search: Searches in both title and description fields (case-insensitive)
|
|
41
|
+
- Filter by workspace: Limit search to specific workspace
|
|
42
|
+
- Filter by nodeType: goal, project, subproject, task, subtask
|
|
43
|
+
- Filter by status: backlog, not_started, in_progress, in_review, completed, cancelled
|
|
44
|
+
- Filter by priority: critical, urgent, high, medium, low
|
|
45
|
+
- Pagination: Use limit and offset for large result sets
|
|
46
|
+
|
|
47
|
+
**Access Control:**
|
|
48
|
+
- Only searches WorkNodes in workspaces the user has access to
|
|
49
|
+
- If workspaceId specified, validates user membership before searching
|
|
50
|
+
|
|
51
|
+
**Best Practices:**
|
|
52
|
+
1. Use compact mode when you only need basic info to reduce tokens
|
|
53
|
+
2. Combine multiple filters for precise searches (e.g., query + nodeTypes + statuses)
|
|
54
|
+
3. Use pagination (limit 50-100) for initial searches
|
|
55
|
+
4. Filter by workspace when user mentions a specific workspace
|
|
56
|
+
5. Use appropriate nodeTypes filter when user asks about specific levels (goals, projects, tasks)
|
|
57
|
+
|
|
58
|
+
**Example Searches:**
|
|
59
|
+
|
|
60
|
+
1. Find all MCP-related work across all workspaces:
|
|
61
|
+
\`\`\`typescript
|
|
62
|
+
brxce_search_worknodes({
|
|
63
|
+
query: "MCP",
|
|
64
|
+
compact: true,
|
|
65
|
+
limit: 50
|
|
66
|
+
})
|
|
67
|
+
\`\`\`
|
|
68
|
+
|
|
69
|
+
2. Find high-priority tasks in specific workspace:
|
|
70
|
+
\`\`\`typescript
|
|
71
|
+
brxce_search_worknodes({
|
|
72
|
+
workspaceId: 138,
|
|
73
|
+
nodeTypes: ["task", "subtask"],
|
|
74
|
+
priorities: ["high", "critical"],
|
|
75
|
+
statuses: ["not_started", "in_progress"],
|
|
76
|
+
compact: false
|
|
77
|
+
})
|
|
78
|
+
\`\`\`
|
|
79
|
+
|
|
80
|
+
3. Search for AI-related projects with full details:
|
|
81
|
+
\`\`\`typescript
|
|
82
|
+
brxce_search_worknodes({
|
|
83
|
+
query: "AI",
|
|
84
|
+
nodeTypes: ["project", "subproject"],
|
|
85
|
+
compact: false,
|
|
86
|
+
limit: 20
|
|
87
|
+
})
|
|
88
|
+
\`\`\`
|
|
89
|
+
|
|
90
|
+
4. Find all backlog items (inbox) about API:
|
|
91
|
+
\`\`\`typescript
|
|
92
|
+
brxce_search_worknodes({
|
|
93
|
+
query: "API",
|
|
94
|
+
statuses: ["backlog"],
|
|
95
|
+
compact: true
|
|
96
|
+
})
|
|
97
|
+
\`\`\`
|
|
98
|
+
|
|
99
|
+
**Output Format:**
|
|
100
|
+
Returns JSON with:
|
|
101
|
+
- nodes: Array of WorkNode objects (compact or full based on mode)
|
|
102
|
+
- total: Total count of matching WorkNodes
|
|
103
|
+
- limit, offset: Pagination info
|
|
104
|
+
- compact: Boolean indicating which mode was used
|
|
105
|
+
|
|
106
|
+
ā° **TIMEZONE HANDLING:**
|
|
107
|
+
ALL date/time fields in the response are in UTC (ISO 8601 format):
|
|
108
|
+
- completedAt, createdAt, updatedAt, dueDate, startDate
|
|
109
|
+
|
|
110
|
+
When presenting results to the user, you MUST convert UTC timestamps to the user's local timezone:
|
|
111
|
+
1. Check the current date/time from the <env> tag in the system prompt
|
|
112
|
+
2. Identify the user's timezone (e.g., Asia/Seoul = UTC+9)
|
|
113
|
+
3. Convert ALL displayed timestamps from UTC to local time
|
|
114
|
+
4. Format dates in a user-friendly way (e.g., "ģ¤ķ 5:16" not "08:16 UTC")
|
|
115
|
+
|
|
116
|
+
Example conversion (Korea Time, UTC+9):
|
|
117
|
+
- API returns: "completedAt": "2025-10-20T08:16:25.556Z" (UTC)
|
|
118
|
+
- Display to user: "ģė£: 2025-10-20 ģ¤ķ 5:16" (KST)
|
|
119
|
+
|
|
120
|
+
The LLM should format this data into a readable summary for the user.`,
|
|
121
|
+
inputSchema: {
|
|
122
|
+
query: z.string().optional().describe('Search keyword for title/description (case-insensitive)'),
|
|
123
|
+
workspaceId: z.number().optional().describe('Filter by workspace ID (validates user access)'),
|
|
124
|
+
nodeTypes: z.array(z.enum(['goal', 'project', 'subproject', 'task', 'subtask'])).optional()
|
|
125
|
+
.describe('Filter by node types'),
|
|
126
|
+
statuses: z.array(z.enum(['backlog', 'not_started', 'in_progress', 'in_review', 'completed', 'cancelled'])).optional()
|
|
127
|
+
.describe('Filter by statuses'),
|
|
128
|
+
priorities: z.array(z.enum(['critical', 'urgent', 'high', 'medium', 'low'])).optional()
|
|
129
|
+
.describe('Filter by priorities'),
|
|
130
|
+
compact: z.boolean().optional().describe('Return compact format (minimal fields for token efficiency, default: false)'),
|
|
131
|
+
limit: z.number().optional().describe('Maximum results (default: 50, max: 200)'),
|
|
132
|
+
offset: z.number().optional().describe('Offset for pagination (default: 0)')
|
|
133
|
+
}
|
|
134
|
+
}, async (args) => {
|
|
135
|
+
try {
|
|
136
|
+
const { query, workspaceId, nodeTypes, statuses, priorities, compact = false, limit = 50, offset = 0 } = args;
|
|
137
|
+
const requestBody = {
|
|
138
|
+
compact,
|
|
139
|
+
limit,
|
|
140
|
+
offset
|
|
141
|
+
};
|
|
142
|
+
if (query)
|
|
143
|
+
requestBody.query = query;
|
|
144
|
+
if (workspaceId !== undefined)
|
|
145
|
+
requestBody.workspaceId = workspaceId;
|
|
146
|
+
if (nodeTypes && nodeTypes.length > 0)
|
|
147
|
+
requestBody.nodeTypes = nodeTypes;
|
|
148
|
+
if (statuses && statuses.length > 0)
|
|
149
|
+
requestBody.statuses = statuses;
|
|
150
|
+
if (priorities && priorities.length > 0)
|
|
151
|
+
requestBody.priorities = priorities;
|
|
152
|
+
const response = await apiClient.post('/mcp/worknodes/search', requestBody);
|
|
153
|
+
if (!response.success) {
|
|
154
|
+
return {
|
|
155
|
+
content: [
|
|
156
|
+
{
|
|
157
|
+
type: 'text',
|
|
158
|
+
text: `Failed to search WorkNodes: ${response.message || 'Unknown error'}`,
|
|
159
|
+
},
|
|
160
|
+
],
|
|
161
|
+
isError: true,
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
const { nodes, total, compact: isCompact } = response.data;
|
|
165
|
+
let resultText = `## WorkNode Search Results\n\n`;
|
|
166
|
+
// Search criteria
|
|
167
|
+
if (query)
|
|
168
|
+
resultText += `š Query: "${query}"\n`;
|
|
169
|
+
if (workspaceId)
|
|
170
|
+
resultText += `š Workspace: #${workspaceId}\n`;
|
|
171
|
+
if (nodeTypes && nodeTypes.length > 0)
|
|
172
|
+
resultText += `š Types: ${nodeTypes.join(', ')}\n`;
|
|
173
|
+
if (statuses && statuses.length > 0)
|
|
174
|
+
resultText += `š·ļø Statuses: ${statuses.join(', ')}\n`;
|
|
175
|
+
if (priorities && priorities.length > 0)
|
|
176
|
+
resultText += `ā” Priorities: ${priorities.join(', ')}\n`;
|
|
177
|
+
resultText += `š Mode: ${isCompact ? 'Compact (token-efficient)' : 'Full details'}\n`;
|
|
178
|
+
resultText += `\n**Found: ${total} WorkNode(s)** (showing ${nodes.length})\n\n`;
|
|
179
|
+
if (nodes.length === 0) {
|
|
180
|
+
resultText += `No WorkNodes found matching the criteria.\n\n`;
|
|
181
|
+
resultText += `š” **Tip**: Try:\n`;
|
|
182
|
+
resultText += `- Broader search terms\n`;
|
|
183
|
+
resultText += `- Removing filters\n`;
|
|
184
|
+
resultText += `- Checking different workspaces\n`;
|
|
185
|
+
}
|
|
186
|
+
else {
|
|
187
|
+
// Group by nodeType for better organization
|
|
188
|
+
const byType = nodes.reduce((acc, node) => {
|
|
189
|
+
if (!acc[node.nodeType])
|
|
190
|
+
acc[node.nodeType] = [];
|
|
191
|
+
acc[node.nodeType].push(node);
|
|
192
|
+
return acc;
|
|
193
|
+
}, {});
|
|
194
|
+
const typeOrder = ['goal', 'project', 'subproject', 'task', 'subtask'];
|
|
195
|
+
typeOrder.forEach((type) => {
|
|
196
|
+
const typeNodes = byType[type];
|
|
197
|
+
if (!typeNodes || typeNodes.length === 0)
|
|
198
|
+
return;
|
|
199
|
+
const typeEmoji = {
|
|
200
|
+
goal: 'šÆ',
|
|
201
|
+
project: 'š',
|
|
202
|
+
subproject: 'š',
|
|
203
|
+
task: 'ā
',
|
|
204
|
+
subtask: 'āļø'
|
|
205
|
+
}[type] || 'š';
|
|
206
|
+
resultText += `### ${typeEmoji} ${type.charAt(0).toUpperCase() + type.slice(1)}s (${typeNodes.length})\n\n`;
|
|
207
|
+
typeNodes.forEach((node) => {
|
|
208
|
+
const statusEmojiMap = {
|
|
209
|
+
backlog: 'š„',
|
|
210
|
+
not_started: 'ā',
|
|
211
|
+
in_progress: 'š',
|
|
212
|
+
in_review: 'š',
|
|
213
|
+
completed: 'ā
',
|
|
214
|
+
cancelled: 'ā'
|
|
215
|
+
};
|
|
216
|
+
const statusEmoji = statusEmojiMap[node.status] || 'ā';
|
|
217
|
+
const priorityEmojiMap = {
|
|
218
|
+
critical: 'š„',
|
|
219
|
+
urgent: 'ā”',
|
|
220
|
+
high: 'š“',
|
|
221
|
+
medium: 'š”',
|
|
222
|
+
low: 'š¢'
|
|
223
|
+
};
|
|
224
|
+
const priorityEmoji = priorityEmojiMap[node.priority] || '';
|
|
225
|
+
resultText += `**${node.title}** (ID: ${node.id})\n`;
|
|
226
|
+
resultText += ` ${statusEmoji} ${node.status}`;
|
|
227
|
+
if (priorityEmoji)
|
|
228
|
+
resultText += ` | ${priorityEmoji} ${node.priority}`;
|
|
229
|
+
if (node.workspaceId)
|
|
230
|
+
resultText += ` | Workspace: ${node.workspaceId}`;
|
|
231
|
+
if (node.parentNodeId)
|
|
232
|
+
resultText += ` | Parent: #${node.parentNodeId}`;
|
|
233
|
+
resultText += `\n`;
|
|
234
|
+
// Full mode shows additional details
|
|
235
|
+
if (!isCompact && node.description) {
|
|
236
|
+
const desc = node.description.length > 100
|
|
237
|
+
? node.description.substring(0, 100) + '...'
|
|
238
|
+
: node.description;
|
|
239
|
+
resultText += ` š ${desc}\n`;
|
|
240
|
+
}
|
|
241
|
+
if (!isCompact && node.assignee && Array.isArray(node.assignee) && node.assignee.length > 0) {
|
|
242
|
+
resultText += ` š¤ Assigned: ${node.assignee.join(', ')}\n`;
|
|
243
|
+
}
|
|
244
|
+
if (!isCompact && node.dueDate) {
|
|
245
|
+
resultText += ` š
Due: ${node.dueDate}\n`;
|
|
246
|
+
}
|
|
247
|
+
if (!isCompact && node.progress !== undefined && node.progress > 0) {
|
|
248
|
+
resultText += ` š Progress: ${node.progress}%\n`;
|
|
249
|
+
}
|
|
250
|
+
resultText += `\n`;
|
|
251
|
+
});
|
|
252
|
+
});
|
|
253
|
+
// Pagination info
|
|
254
|
+
if (total > nodes.length) {
|
|
255
|
+
const remaining = total - (offset + nodes.length);
|
|
256
|
+
resultText += `\n---\n\n`;
|
|
257
|
+
resultText += `š **Pagination**: Showing ${offset + 1}-${offset + nodes.length} of ${total}\n`;
|
|
258
|
+
if (remaining > 0) {
|
|
259
|
+
resultText += `š” **Tip**: Use \`offset: ${offset + limit}\` to see next ${Math.min(remaining, limit)} results\n`;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
// Token efficiency note
|
|
263
|
+
if (!isCompact && total > 20) {
|
|
264
|
+
resultText += `\nš” **Token Tip**: For large result sets, use \`compact: true\` to reduce token usage\n`;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
return {
|
|
268
|
+
content: [
|
|
269
|
+
{
|
|
270
|
+
type: 'text',
|
|
271
|
+
text: resultText,
|
|
272
|
+
},
|
|
273
|
+
],
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
catch (error) {
|
|
277
|
+
return {
|
|
278
|
+
content: [
|
|
279
|
+
{
|
|
280
|
+
type: 'text',
|
|
281
|
+
text: `Error searching WorkNodes: ${error.message || 'Unknown error'}`,
|
|
282
|
+
},
|
|
283
|
+
],
|
|
284
|
+
isError: true,
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
//# sourceMappingURL=worknode-search-tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worknode-search-tool.js","sourceRoot":"","sources":["../../src/tools/worknode-search-tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import type { ApiClient } from '../services/api-client.js';
|
|
3
|
+
export declare function registerWorknodeSubtreeTool(server: McpServer, apiClient: ApiClient): void;
|
|
4
|
+
//# sourceMappingURL=worknode-subtree-tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worknode-subtree-tool.d.ts","sourceRoot":"","sources":["../../src/tools/worknode-subtree-tool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AA8D3D,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,QAuKlF"}
|