@brxce/mcp-server 1.0.0 → 1.0.2

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.
Files changed (85) hide show
  1. package/README.md +3 -3
  2. package/dist/index.d.ts +3 -1
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +24 -10
  5. package/dist/index.js.map +1 -1
  6. package/dist/prompts/worknode-prompts.d.ts.map +1 -1
  7. package/dist/prompts/worknode-prompts.js +43 -15
  8. package/dist/prompts/worknode-prompts.js.map +1 -1
  9. package/dist/prompts/workspace-context-prompt.js +6 -6
  10. package/dist/prompts/workspace-context-prompt.js.map +1 -1
  11. package/dist/resources/user-resource.d.ts.map +1 -1
  12. package/dist/resources/user-resource.js +12 -1
  13. package/dist/resources/user-resource.js.map +1 -1
  14. package/dist/resources/workspace-members-resource.d.ts.map +1 -1
  15. package/dist/resources/workspace-members-resource.js +12 -3
  16. package/dist/resources/workspace-members-resource.js.map +1 -1
  17. package/dist/resources/workspace-resource.d.ts.map +1 -1
  18. package/dist/resources/workspace-resource.js +9 -1
  19. package/dist/resources/workspace-resource.js.map +1 -1
  20. package/dist/services/api-client.d.ts.map +1 -1
  21. package/dist/services/api-client.js +2 -6
  22. package/dist/services/api-client.js.map +1 -1
  23. package/dist/tools/meeting-agenda-tool.js +1 -1
  24. package/dist/tools/meeting-agenda-tool.js.map +1 -1
  25. package/dist/tools/meeting-create-tool.d.ts.map +1 -1
  26. package/dist/tools/meeting-create-tool.js +2 -2
  27. package/dist/tools/meeting-create-tool.js.map +1 -1
  28. package/dist/tools/meeting-decisions-tool.js +1 -1
  29. package/dist/tools/meeting-decisions-tool.js.map +1 -1
  30. package/dist/tools/meeting-list-tool.d.ts.map +1 -1
  31. package/dist/tools/meeting-list-tool.js +1 -1
  32. package/dist/tools/meeting-list-tool.js.map +1 -1
  33. package/dist/tools/tag-category-tool.js +6 -6
  34. package/dist/tools/tag-category-tool.js.map +1 -1
  35. package/dist/tools/tag-search-tool.js +4 -4
  36. package/dist/tools/tag-search-tool.js.map +1 -1
  37. package/dist/tools/tag-tool.js +13 -13
  38. package/dist/tools/tag-tool.js.map +1 -1
  39. package/dist/tools/worknode-archive-tool.d.ts.map +1 -1
  40. package/dist/tools/worknode-archive-tool.js +2 -2
  41. package/dist/tools/worknode-archive-tool.js.map +1 -1
  42. package/dist/tools/worknode-create-tool.d.ts.map +1 -1
  43. package/dist/tools/worknode-create-tool.js +113 -225
  44. package/dist/tools/worknode-create-tool.js.map +1 -1
  45. package/dist/tools/worknode-my-work-tool.d.ts.map +1 -1
  46. package/dist/tools/worknode-my-work-tool.js +1 -8
  47. package/dist/tools/worknode-my-work-tool.js.map +1 -1
  48. package/dist/tools/worknode-plan-organize-tool.d.ts +4 -0
  49. package/dist/tools/worknode-plan-organize-tool.d.ts.map +1 -0
  50. package/dist/tools/worknode-plan-organize-tool.js +356 -0
  51. package/dist/tools/worknode-plan-organize-tool.js.map +1 -0
  52. package/dist/tools/worknode-read-tool.d.ts +4 -0
  53. package/dist/tools/worknode-read-tool.d.ts.map +1 -0
  54. package/dist/tools/worknode-read-tool.js +312 -0
  55. package/dist/tools/worknode-read-tool.js.map +1 -0
  56. package/dist/tools/worknode-search-tool.d.ts.map +1 -1
  57. package/dist/tools/worknode-search-tool.js +25 -44
  58. package/dist/tools/worknode-search-tool.js.map +1 -1
  59. package/dist/tools/worknode-subtree-tool.d.ts.map +1 -1
  60. package/dist/tools/worknode-subtree-tool.js +8 -12
  61. package/dist/tools/worknode-subtree-tool.js.map +1 -1
  62. package/dist/tools/worknode-tag-tool.js +12 -12
  63. package/dist/tools/worknode-tag-tool.js.map +1 -1
  64. package/dist/tools/worknode-update-tool.d.ts.map +1 -1
  65. package/dist/tools/worknode-update-tool.js +104 -173
  66. package/dist/tools/worknode-update-tool.js.map +1 -1
  67. package/dist/tools/workspace-inbox-tool.d.ts.map +1 -1
  68. package/dist/tools/workspace-inbox-tool.js +3 -2
  69. package/dist/tools/workspace-inbox-tool.js.map +1 -1
  70. package/dist/tools/workspace-list-tool.d.ts +8 -0
  71. package/dist/tools/workspace-list-tool.d.ts.map +1 -0
  72. package/dist/tools/workspace-list-tool.js +113 -0
  73. package/dist/tools/workspace-list-tool.js.map +1 -0
  74. package/dist/tools/workspace-members-list-tool.d.ts +8 -0
  75. package/dist/tools/workspace-members-list-tool.d.ts.map +1 -0
  76. package/dist/tools/workspace-members-list-tool.js +207 -0
  77. package/dist/tools/workspace-members-list-tool.js.map +1 -0
  78. package/dist/tools/workspace-statistics-tool.d.ts +8 -0
  79. package/dist/tools/workspace-statistics-tool.d.ts.map +1 -0
  80. package/dist/tools/workspace-statistics-tool.js +300 -0
  81. package/dist/tools/workspace-statistics-tool.js.map +1 -0
  82. package/dist/tools/workspace-tree-tool.d.ts.map +1 -1
  83. package/dist/tools/workspace-tree-tool.js +6 -12
  84. package/dist/tools/workspace-tree-tool.js.map +1 -1
  85. package/package.json +11 -10
@@ -0,0 +1,113 @@
1
+ /**
2
+ * Register Workspace List tool for LLM-invoked queries
3
+ * This tool allows the LLM to list all workspaces the user has access to
4
+ */
5
+ export function registerWorkspaceListTool(server, apiClient) {
6
+ server.registerTool('brxce_list_workspaces', {
7
+ description: `List all workspaces the authenticated user has access to.
8
+
9
+ ⚠️ **IMPORTANT: When to use this tool vs user://me resource**
10
+
11
+ **Use this tool when:**
12
+ - User explicitly asks to "list workspaces" or "show all workspaces"
13
+ - You need workspace details beyond basic info (description, type, role)
14
+ - You want to filter workspaces by specific criteria
15
+
16
+ **Use user://me resource when:**
17
+ - You just need workspace IDs and names for context
18
+ - You're about to call another MCP tool that needs workspaceId
19
+ - You want both user info AND workspaces in one call
20
+
21
+ **Common Use Cases:**
22
+ - "Show me all my workspaces" → Use this tool
23
+ - "What workspaces do I have access to?" → Use this tool
24
+ - "I need the workspace ID for BRXCE Development" → Use user://me resource instead
25
+ - Before calling brxce_workspace_overview → Use user://me resource instead
26
+
27
+ **Output Format:**
28
+ Returns JSON with:
29
+ - workspaces: Array of workspace objects with full details
30
+ - id: Workspace ID
31
+ - name: Workspace name
32
+ - slug: URL-friendly identifier
33
+ - description: Workspace description
34
+ - workspaceType: Type of workspace (e.g., "team", "personal")
35
+ - planType: Subscription plan (e.g., "free", "pro")
36
+ - spaceId: Parent space ID (if applicable)
37
+ - userRole: User's role in this workspace (e.g., "owner", "member")
38
+ - total: Total number of workspaces
39
+
40
+ **Best Practices:**
41
+ 1. Prefer user://me resource for simple workspace lookups
42
+ 2. Use this tool when user explicitly asks for workspace list
43
+ 3. Cache workspace data to avoid repeated calls
44
+ 4. Use workspace slug for user-friendly URLs
45
+
46
+ **Example Workflow:**
47
+ \`\`\`
48
+ User: "Show me all my workspaces"
49
+ LLM:
50
+ 1. Calls brxce_list_workspaces
51
+ 2. Formats response in readable list
52
+ 3. Shows workspace names, types, and roles
53
+ \`\`\`
54
+
55
+ ⏰ **TIMEZONE HANDLING:**
56
+ All timestamps in the response are in UTC (ISO 8601 format).
57
+ Convert to user's local timezone when presenting results.`,
58
+ inputSchema: {},
59
+ }, async (args) => {
60
+ try {
61
+ const response = await apiClient.get('/mcp/workspaces');
62
+ if (!response.success || !response.data) {
63
+ return {
64
+ content: [
65
+ {
66
+ type: 'text',
67
+ text: JSON.stringify({
68
+ error: 'Failed to fetch workspaces',
69
+ message: 'API returned unsuccessful response',
70
+ }),
71
+ },
72
+ ],
73
+ isError: true,
74
+ };
75
+ }
76
+ const workspaces = response.data;
77
+ // Return structured JSON for LLM to format
78
+ return {
79
+ content: [
80
+ {
81
+ type: 'text',
82
+ text: JSON.stringify({
83
+ total: workspaces.length,
84
+ workspaces: workspaces.map((ws) => ({
85
+ id: ws.id,
86
+ name: ws.name,
87
+ slug: ws.slug,
88
+ type: ws.workspaceType,
89
+ plan: ws.planType,
90
+ userRole: ws.userRole,
91
+ })),
92
+ }, null, 2),
93
+ },
94
+ ],
95
+ };
96
+ }
97
+ catch (error) {
98
+ return {
99
+ content: [
100
+ {
101
+ type: 'text',
102
+ text: JSON.stringify({
103
+ error: 'Failed to fetch workspaces',
104
+ message: error.message,
105
+ }),
106
+ },
107
+ ],
108
+ isError: true,
109
+ };
110
+ }
111
+ });
112
+ }
113
+ //# sourceMappingURL=workspace-list-tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace-list-tool.js","sourceRoot":"","sources":["../../src/tools/workspace-list-tool.ts"],"names":[],"mappings":"AAkBA;;;GAGG;AACH,MAAM,UAAU,yBAAyB,CAAC,MAAiB,EAAE,SAAoB;IAC/E,MAAM,CAAC,YAAY,CACjB,uBAAuB,EACvB;QACE,WAAW,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0DAkDuC;QACpD,WAAW,EAAE,EAAE;KAChB,EACD,KAAK,EAAE,IAAyB,EAAE,EAAE;QAClC,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,GAAG,CAAwB,iBAAiB,CAAC,CAAC;YAE/E,IAAI,CAAC,QAAQ,CAAC,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;gBACxC,OAAO;oBACL,OAAO,EAAE;wBACP;4BACE,IAAI,EAAE,MAAM;4BACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gCACnB,KAAK,EAAE,4BAA4B;gCACnC,OAAO,EAAE,oCAAoC;6BAC9C,CAAC;yBACH;qBACF;oBACD,OAAO,EAAE,IAAI;iBACd,CAAC;YACJ,CAAC;YAED,MAAM,UAAU,GAAG,QAAQ,CAAC,IAAI,CAAC;YAEjC,2CAA2C;YAC3C,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAClB;4BACE,KAAK,EAAE,UAAU,CAAC,MAAM;4BACxB,UAAU,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;gCAClC,EAAE,EAAE,EAAE,CAAC,EAAE;gCACT,IAAI,EAAE,EAAE,CAAC,IAAI;gCACb,IAAI,EAAE,EAAE,CAAC,IAAI;gCACb,IAAI,EAAE,EAAE,CAAC,aAAa;gCACtB,IAAI,EAAE,EAAE,CAAC,QAAQ;gCACjB,QAAQ,EAAE,EAAE,CAAC,QAAQ;6BACtB,CAAC,CAAC;yBACJ,EACD,IAAI,EACJ,CAAC,CACF;qBACF;iBACF;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;4BACnB,KAAK,EAAE,4BAA4B;4BACnC,OAAO,EAAE,KAAK,CAAC,OAAO;yBACvB,CAAC;qBACH;iBACF;gBACD,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { ApiClient } from '../services/api-client.js';
3
+ /**
4
+ * Register Workspace Members List tool for LLM-invoked queries
5
+ * This tool allows the LLM to list all members of a specific workspace
6
+ */
7
+ export declare function registerWorkspaceMembersListTool(server: McpServer, apiClient: ApiClient): void;
8
+ //# sourceMappingURL=workspace-members-list-tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace-members-list-tool.d.ts","sourceRoot":"","sources":["../../src/tools/workspace-members-list-tool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAqB3D;;;GAGG;AACH,wBAAgB,gCAAgC,CAAC,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,QAwNvF"}
@@ -0,0 +1,207 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * Register Workspace Members List tool for LLM-invoked queries
4
+ * This tool allows the LLM to list all members of a specific workspace
5
+ */
6
+ export function registerWorkspaceMembersListTool(server, apiClient) {
7
+ server.registerTool('brxce_list_workspace_members', {
8
+ description: `List all members of a specific workspace.
9
+
10
+ ⚠️ **CRITICAL: Workspace Verification Required**
11
+ Before calling this tool, you MUST:
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 doesn't specify workspace, use their default workspace
15
+ 4. NEVER assume or guess workspaceId values
16
+
17
+ **Example Workflow:**
18
+ \`\`\`
19
+ User: "Who are the members of BRXCE Development workspace?"
20
+ LLM:
21
+ 1. Reads user://me resource
22
+ 2. Finds workspace: {id: 138, name: "BRXCE Development"}
23
+ 3. Calls brxce_list_workspace_members with workspaceId: 138
24
+ \`\`\`
25
+
26
+ **When to use this tool:**
27
+ The LLM should call this tool when the user asks about:
28
+ - "Who are the members of workspace X?"
29
+ - "Show me team members"
30
+ - "Who can I assign this task to?"
31
+ - "List all people in this workspace"
32
+ - When creating meetings and need to select participants
33
+
34
+ **Output Format:**
35
+ Returns JSON with:
36
+ - workspaceId: The workspace ID
37
+ - workspaceName: The workspace name
38
+ - totalMembers: Total number of members
39
+ - members: Array of member objects
40
+ - userId: User ID (use this for assignee/participant fields)
41
+ - email: Email address
42
+ - name: Display name
43
+ - role: Role in workspace (e.g., "owner", "admin", "member")
44
+ - joinedAt: When they joined (ISO 8601, UTC)
45
+
46
+ **Best Practices:**
47
+ 1. Always verify workspaceId exists via user://me resource first
48
+ 2. Use userId when assigning WorkNodes or adding meeting participants
49
+ 3. Show user-friendly names (name or username) in UI, but use userId internally
50
+ 4. Cache member list to avoid repeated calls during task assignment
51
+
52
+ **Common Use Cases:**
53
+ 1. **Meeting Creation**: Get member list to select participants
54
+ \`\`\`
55
+ User: "Create a meeting with the team"
56
+ LLM:
57
+ 1. Get workspace ID from context
58
+ 2. Call brxce_list_workspace_members
59
+ 3. Show member list for user to select
60
+ 4. Use selected userId values in brxce_create_meeting
61
+ \`\`\`
62
+
63
+ 2. **Task Assignment**: Get member list to assign WorkNode
64
+ \`\`\`
65
+ User: "Assign this task to someone"
66
+ LLM:
67
+ 1. Get workspace ID from WorkNode context
68
+ 2. Call brxce_list_workspace_members
69
+ 3. Show member list
70
+ 4. Use selected userId in brxce_update_worknodes
71
+ \`\`\`
72
+
73
+ 3. **Team Overview**: Show who's in the workspace
74
+ \`\`\`
75
+ User: "Who's on the team?"
76
+ LLM:
77
+ 1. Get default workspace ID
78
+ 2. Call brxce_list_workspace_members
79
+ 3. Format as readable list with roles
80
+ \`\`\`
81
+
82
+ ⏰ **TIMEZONE HANDLING:**
83
+ The \`joinedAt\` field is in UTC (ISO 8601 format).
84
+ When presenting to the user, convert to their local timezone:
85
+ 1. Check the current date/time from the <env> tag
86
+ 2. Identify the user's timezone (e.g., Asia/Seoul = UTC+9)
87
+ 3. Convert UTC timestamps to local time
88
+ 4. Format in user-friendly way (e.g., "가입: 2025-10-20")
89
+
90
+ Example conversion (Korea Time, UTC+9):
91
+ - API returns: "joinedAt": "2025-10-20T08:16:25.556Z" (UTC)
92
+ - Display to user: "가입: 2025-10-20 오후 5:16" (KST)`,
93
+ inputSchema: {
94
+ workspaceId: z
95
+ .string()
96
+ .uuid()
97
+ .describe('Workspace ID (get from user://me resource)'),
98
+ },
99
+ }, async (args) => {
100
+ const { workspaceId } = args;
101
+ // Validate workspaceId
102
+ if (!workspaceId || typeof workspaceId !== 'string') {
103
+ return {
104
+ content: [
105
+ {
106
+ type: 'text',
107
+ text: JSON.stringify({
108
+ error: 'Invalid workspace ID',
109
+ message: 'workspaceId is required and must be a UUID string',
110
+ hint: 'Use user://me resource to get valid workspace IDs',
111
+ }),
112
+ },
113
+ ],
114
+ isError: true,
115
+ };
116
+ }
117
+ try {
118
+ const response = await apiClient.get(`/mcp/workspaces/${workspaceId}/members`);
119
+ if (!response.success || !response.data) {
120
+ return {
121
+ content: [
122
+ {
123
+ type: 'text',
124
+ text: JSON.stringify({
125
+ error: 'Failed to fetch workspace members',
126
+ message: response.message || 'API returned unsuccessful response',
127
+ workspaceId,
128
+ }),
129
+ },
130
+ ],
131
+ isError: true,
132
+ };
133
+ }
134
+ const { workspaceId: wsId, workspaceName, members } = response.data;
135
+ // Return structured JSON for LLM to format
136
+ return {
137
+ content: [
138
+ {
139
+ type: 'text',
140
+ text: JSON.stringify({
141
+ workspaceId: wsId,
142
+ workspaceName,
143
+ totalMembers: members.length,
144
+ members: members.map((member) => ({
145
+ userId: member.userId,
146
+ name: member.name,
147
+ email: member.email,
148
+ role: member.role,
149
+ joinedAt: member.joinedAt,
150
+ })),
151
+ }, null, 2),
152
+ },
153
+ ],
154
+ };
155
+ }
156
+ catch (error) {
157
+ // Handle 404 - workspace not found or no access
158
+ if (error.response?.status === 404) {
159
+ return {
160
+ content: [
161
+ {
162
+ type: 'text',
163
+ text: JSON.stringify({
164
+ error: 'Workspace not found',
165
+ message: `Workspace with ID ${workspaceId} does not exist or you don't have access to it`,
166
+ workspaceId,
167
+ hint: 'Use user://me resource to get valid workspace IDs',
168
+ }),
169
+ },
170
+ ],
171
+ isError: true,
172
+ };
173
+ }
174
+ // Handle 403 - access denied
175
+ if (error.response?.status === 403) {
176
+ return {
177
+ content: [
178
+ {
179
+ type: 'text',
180
+ text: JSON.stringify({
181
+ error: 'Access denied',
182
+ message: `You don't have permission to view members of workspace ${workspaceId}`,
183
+ workspaceId,
184
+ }),
185
+ },
186
+ ],
187
+ isError: true,
188
+ };
189
+ }
190
+ // General error
191
+ return {
192
+ content: [
193
+ {
194
+ type: 'text',
195
+ text: JSON.stringify({
196
+ error: 'Failed to fetch workspace members',
197
+ message: error.message,
198
+ workspaceId,
199
+ }),
200
+ },
201
+ ],
202
+ isError: true,
203
+ };
204
+ }
205
+ });
206
+ }
207
+ //# sourceMappingURL=workspace-members-list-tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace-members-list-tool.js","sourceRoot":"","sources":["../../src/tools/workspace-members-list-tool.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { ApiClient } from '../services/api-client.js';
3
+ /**
4
+ * Register Workspace Statistics tool for analytics and insights
5
+ * Provides comprehensive statistics about workspace progress and team performance
6
+ */
7
+ export declare function registerWorkspaceStatisticsTool(server: McpServer, apiClient: ApiClient): void;
8
+ //# sourceMappingURL=workspace-statistics-tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace-statistics-tool.d.ts","sourceRoot":"","sources":["../../src/tools/workspace-statistics-tool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AA0D3D;;;GAGG;AACH,wBAAgB,+BAA+B,CAAC,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,QAuTtF"}
@@ -0,0 +1,300 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * Register Workspace Statistics tool for analytics and insights
4
+ * Provides comprehensive statistics about workspace progress and team performance
5
+ */
6
+ export function registerWorkspaceStatisticsTool(server, apiClient) {
7
+ server.registerTool('brxce_workspace_statistics', {
8
+ description: `Get comprehensive statistics and analytics for a workspace.
9
+
10
+ ⚠️ **CRITICAL: Workspace Verification Required**
11
+ Before calling this tool, you MUST:
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 doesn't specify workspace, use their default workspace
15
+ 4. NEVER assume or guess workspaceId values
16
+
17
+ **Example Workflow:**
18
+ \`\`\`
19
+ User: "이번 주 우리 팀 진행 상황 정리해줘"
20
+ LLM:
21
+ 1. Reads user://me resource
22
+ 2. Finds workspace: {id: 138, name: "BRXCE Development"}
23
+ 3. Calls brxce_workspace_statistics with workspaceId: 138, period: "this-week"
24
+ 4. Formats statistics in readable Korean format
25
+ \`\`\`
26
+
27
+ **When to use this tool:**
28
+ The LLM should call this tool when the user asks about:
29
+ - "우리 팀 진행 상황 어때?" → Use with period: "all"
30
+ - "이번 주 완료한 작업 몇 개야?" → Use with period: "this-week"
31
+ - "누가 제일 많이 작업하고 있어?" → Check memberStats
32
+ - "마감 임박한 작업 있어?" → Check dueDates.dueToday, dueDates.dueThisWeek
33
+ - "전체적인 통계 보여줘" → Use with period: "all"
34
+
35
+ **Time Periods:**
36
+ - \`today\`: 오늘 생성/완료된 작업 중심 통계
37
+ - \`this-week\`: 이번 주 작업 중심 통계
38
+ - \`this-month\`: 이번 달 작업 중심 통계
39
+ - \`all\`: 전체 작업 통계 (default)
40
+
41
+ **Output Format:**
42
+ Returns comprehensive statistics including:
43
+
44
+ 1. **Overview** - 전체 개요
45
+ - totalNodes: 전체 작업 수
46
+ - activeNodes: 진행 중인 작업 수 (완료/취소 제외)
47
+ - completedNodes: 완료된 작업 수
48
+ - completionRate: 완료율 (%)
49
+
50
+ 2. **By Status** - 상태별 분포
51
+ - backlog: 백로그 (인박스)
52
+ - not_started: 시작 전
53
+ - in_progress: 진행 중
54
+ - in_review: 리뷰 중
55
+ - completed: 완료
56
+ - cancelled: 취소
57
+
58
+ 3. **By Priority** - 우선순위별 분포
59
+ - critical: 긴급
60
+ - urgent: 시급
61
+ - high: 높음
62
+ - medium: 보통
63
+ - low: 낮음
64
+
65
+ 4. **By Node Type** - 타입별 분포
66
+ - goal: 목표
67
+ - project: 프로젝트
68
+ - subproject: 하위 프로젝트
69
+ - task: 작업
70
+ - subtask: 하위 작업
71
+
72
+ 5. **Member Stats** - 팀원별 통계
73
+ - userId: 사용자 ID
74
+ - name: 이름
75
+ - email: 이메일
76
+ - totalAssigned: 할당된 총 작업 수
77
+ - inProgress: 진행 중인 작업 수
78
+ - completed: 완료한 작업 수
79
+ - completionRate: 완료율 (%)
80
+
81
+ 6. **Due Dates** - 마감일 현황
82
+ - overdue: 마감 지난 작업 수
83
+ - dueToday: 오늘 마감 작업 수
84
+ - dueThisWeek: 이번 주 마감 작업 수
85
+ - dueThisMonth: 이번 달 마감 작업 수
86
+
87
+ **Best Practices:**
88
+ 1. Always verify workspaceId via user://me resource first
89
+ 2. Use appropriate period based on user's question
90
+ 3. Format statistics in user-friendly Korean when presenting
91
+ 4. Highlight important metrics (overdue, high completion rates, etc.)
92
+ 5. Suggest actionable insights based on statistics
93
+
94
+ **Common Use Cases:**
95
+
96
+ 1. **Team Progress Review**:
97
+ \`\`\`
98
+ User: "우리 팀 이번 주 진행 상황 보고서 만들어줘"
99
+ LLM:
100
+ 1. Get workspace ID from context
101
+ 2. Call brxce_workspace_statistics(workspaceId: 138, period: "this-week")
102
+ 3. Format as progress report:
103
+ - "이번 주 총 15개 작업 중 8개 완료 (53% 완료율)"
104
+ - "3개 진행 중, 4개 대기 중"
105
+ - "마감 지난 작업: 2개 (주의 필요)"
106
+ \`\`\`
107
+
108
+ 2. **Team Member Workload**:
109
+ \`\`\`
110
+ User: "누가 제일 바빠?"
111
+ LLM:
112
+ 1. Call brxce_workspace_statistics
113
+ 2. Sort memberStats by totalAssigned
114
+ 3. Present: "김개발님이 현재 12개 작업 진행 중 (가장 많음)"
115
+ \`\`\`
116
+
117
+ 3. **Priority Analysis**:
118
+ \`\`\`
119
+ User: "긴급한 작업 얼마나 남았어?"
120
+ LLM:
121
+ 1. Call brxce_workspace_statistics
122
+ 2. Check byPriority.critical and byPriority.urgent
123
+ 3. Present: "긴급 작업 5개, 시급 작업 3개 남아있습니다"
124
+ \`\`\`
125
+
126
+ 4. **Deadline Tracking**:
127
+ \`\`\`
128
+ User: "이번 주 마감 작업 있어?"
129
+ LLM:
130
+ 1. Call brxce_workspace_statistics
131
+ 2. Check dueDates
132
+ 3. Present: "오늘 마감 2개, 이번 주 마감 5개 있습니다"
133
+ \`\`\`
134
+
135
+ ⏰ **TIMEZONE HANDLING:**
136
+ All date calculations are performed in UTC on the backend.
137
+ When presenting results to the user, dates are already processed relative to the server's timezone.
138
+
139
+ **Example Output:**
140
+ \`\`\`json
141
+ {
142
+ "workspaceId": 138,
143
+ "workspaceName": "BRXCE Development",
144
+ "period": "this-week",
145
+ "overview": {
146
+ "totalNodes": 45,
147
+ "activeNodes": 23,
148
+ "completedNodes": 18,
149
+ "completionRate": 40
150
+ },
151
+ "byStatus": {
152
+ "backlog": 5,
153
+ "not_started": 8,
154
+ "in_progress": 10,
155
+ "in_review": 4,
156
+ "completed": 18,
157
+ "cancelled": 0
158
+ },
159
+ "memberStats": [
160
+ {
161
+ "userId": "user-123",
162
+ "name": "김개발",
163
+ "email": "dev@example.com",
164
+ "totalAssigned": 12,
165
+ "inProgress": 5,
166
+ "completed": 7,
167
+ "completionRate": 58
168
+ }
169
+ ],
170
+ "dueDates": {
171
+ "overdue": 2,
172
+ "dueToday": 3,
173
+ "dueThisWeek": 5,
174
+ "dueThisMonth": 8
175
+ }
176
+ }
177
+ \`\`\``,
178
+ inputSchema: {
179
+ workspaceId: z
180
+ .string()
181
+ .uuid()
182
+ .describe('Workspace ID (get from user://me resource)'),
183
+ period: z
184
+ .enum(['today', 'this-week', 'this-month', 'all'])
185
+ .optional()
186
+ .describe('Time period for statistics (default: all)'),
187
+ },
188
+ }, async (args) => {
189
+ const { workspaceId, period = 'all' } = args;
190
+ // Validate workspaceId
191
+ if (!workspaceId || typeof workspaceId !== 'string') {
192
+ return {
193
+ content: [
194
+ {
195
+ type: 'text',
196
+ text: JSON.stringify({
197
+ error: 'Invalid workspace ID',
198
+ message: 'workspaceId is required and must be a UUID string',
199
+ hint: 'Use user://me resource to get valid workspace IDs',
200
+ }),
201
+ },
202
+ ],
203
+ isError: true,
204
+ };
205
+ }
206
+ try {
207
+ const queryParams = new URLSearchParams();
208
+ if (period) {
209
+ queryParams.append('period', period);
210
+ }
211
+ const url = `/mcp/workspaces/${workspaceId}/statistics?${queryParams.toString()}`;
212
+ const response = await apiClient.get(url);
213
+ if (!response.success || !response.data) {
214
+ return {
215
+ content: [
216
+ {
217
+ type: 'text',
218
+ text: JSON.stringify({
219
+ error: 'Failed to fetch workspace statistics',
220
+ message: response.message || 'API returned unsuccessful response',
221
+ workspaceId,
222
+ }),
223
+ },
224
+ ],
225
+ isError: true,
226
+ };
227
+ }
228
+ const stats = response.data;
229
+ // Return structured JSON for LLM to format
230
+ return {
231
+ content: [
232
+ {
233
+ type: 'text',
234
+ text: JSON.stringify({
235
+ workspaceId: stats.workspaceId,
236
+ workspaceName: stats.workspaceName,
237
+ period: stats.period,
238
+ overview: stats.overview,
239
+ byStatus: stats.byStatus,
240
+ byPriority: stats.byPriority,
241
+ byNodeType: stats.byNodeType,
242
+ memberStats: stats.memberStats,
243
+ dueDates: stats.dueDates,
244
+ }, null, 2),
245
+ },
246
+ ],
247
+ };
248
+ }
249
+ catch (error) {
250
+ // Handle 404 - workspace not found or no access
251
+ if (error.response?.status === 404) {
252
+ return {
253
+ content: [
254
+ {
255
+ type: 'text',
256
+ text: JSON.stringify({
257
+ error: 'Workspace not found',
258
+ message: `Workspace with ID ${workspaceId} does not exist or you don't have access to it`,
259
+ workspaceId,
260
+ hint: 'Use user://me resource to get valid workspace IDs',
261
+ }),
262
+ },
263
+ ],
264
+ isError: true,
265
+ };
266
+ }
267
+ // Handle 403 - access denied
268
+ if (error.response?.status === 403) {
269
+ return {
270
+ content: [
271
+ {
272
+ type: 'text',
273
+ text: JSON.stringify({
274
+ error: 'Access denied',
275
+ message: `You don't have permission to view statistics for workspace ${workspaceId}`,
276
+ workspaceId,
277
+ }),
278
+ },
279
+ ],
280
+ isError: true,
281
+ };
282
+ }
283
+ // General error
284
+ return {
285
+ content: [
286
+ {
287
+ type: 'text',
288
+ text: JSON.stringify({
289
+ error: 'Failed to fetch workspace statistics',
290
+ message: error.message,
291
+ workspaceId,
292
+ }),
293
+ },
294
+ ],
295
+ isError: true,
296
+ };
297
+ }
298
+ });
299
+ }
300
+ //# sourceMappingURL=workspace-statistics-tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace-statistics-tool.js","sourceRoot":"","sources":["../../src/tools/workspace-statistics-tool.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"workspace-tree-tool.d.ts","sourceRoot":"","sources":["../../src/tools/workspace-tree-tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAiCtD,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,QAwbhF"}
1
+ {"version":3,"file":"workspace-tree-tool.d.ts","sourceRoot":"","sources":["../../src/tools/workspace-tree-tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAgCtD,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,QAmbhF"}