@lindblad/complai-mcp 0.1.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 +303 -0
- package/dist/api/complai-client.d.ts +46 -0
- package/dist/api/complai-client.d.ts.map +1 -0
- package/dist/api/complai-client.js +113 -0
- package/dist/api/complai-client.js.map +1 -0
- package/dist/auth/device-auth.d.ts +98 -0
- package/dist/auth/device-auth.d.ts.map +1 -0
- package/dist/auth/device-auth.js +274 -0
- package/dist/auth/device-auth.js.map +1 -0
- package/dist/auth/pkce-auth.d.ts +67 -0
- package/dist/auth/pkce-auth.d.ts.map +1 -0
- package/dist/auth/pkce-auth.js +311 -0
- package/dist/auth/pkce-auth.js.map +1 -0
- package/dist/auth/token-manager.d.ts +58 -0
- package/dist/auth/token-manager.d.ts.map +1 -0
- package/dist/auth/token-manager.js +131 -0
- package/dist/auth/token-manager.js.map +1 -0
- package/dist/config/config-loader.d.ts +21 -0
- package/dist/config/config-loader.d.ts.map +1 -0
- package/dist/config/config-loader.js +152 -0
- package/dist/config/config-loader.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +483 -0
- package/dist/index.js.map +1 -0
- package/dist/tools/compliance-brief.d.ts +8 -0
- package/dist/tools/compliance-brief.d.ts.map +1 -0
- package/dist/tools/compliance-brief.js +122 -0
- package/dist/tools/compliance-brief.js.map +1 -0
- package/dist/types.d.ts +169 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +45 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,483 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
3
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
import { loadConfig, validateConfig, getAuthModeDescription } from './config/config-loader.js';
|
|
6
|
+
import { ComplaiClient } from './api/complai-client.js';
|
|
7
|
+
import { TokenManager } from './auth/token-manager.js';
|
|
8
|
+
import { getComplianceBrief } from './tools/compliance-brief.js';
|
|
9
|
+
/**
|
|
10
|
+
* COMPLAI MCP Server
|
|
11
|
+
*
|
|
12
|
+
* Provides compliance overview tools for AI assistants.
|
|
13
|
+
* Supports two authentication modes:
|
|
14
|
+
* 1. M2M: Uses client credentials (requires COMPLAI_AUTH0_CLIENT_SECRET)
|
|
15
|
+
* 2. User: PKCE flow - opens browser for login (no client secret needed)
|
|
16
|
+
*/
|
|
17
|
+
// Check for mock mode
|
|
18
|
+
const MOCK_MODE = process.env.COMPLAI_MOCK_MODE === 'true';
|
|
19
|
+
let config = null;
|
|
20
|
+
let client = null;
|
|
21
|
+
let tokenManager = null;
|
|
22
|
+
// Load configuration
|
|
23
|
+
console.error('[DEBUG] MOCK_MODE:', MOCK_MODE);
|
|
24
|
+
try {
|
|
25
|
+
if (!MOCK_MODE) {
|
|
26
|
+
console.error('[DEBUG] Loading config...');
|
|
27
|
+
config = loadConfig();
|
|
28
|
+
console.error('[DEBUG] Config loaded:', config ? 'yes' : 'no');
|
|
29
|
+
validateConfig(config);
|
|
30
|
+
console.error('[DEBUG] Config validated');
|
|
31
|
+
tokenManager = new TokenManager(config);
|
|
32
|
+
client = new ComplaiClient(config, tokenManager);
|
|
33
|
+
console.error('[DEBUG] Client created');
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
console.error('[DEBUG] Error loading config:', error);
|
|
38
|
+
const hasPartialConfig = process.env.COMPLAI_AUTH0_DOMAIN ||
|
|
39
|
+
process.env.COMPLAI_API_URL ||
|
|
40
|
+
process.env.COMPLAI_CONFIG_PATH;
|
|
41
|
+
if (hasPartialConfig) {
|
|
42
|
+
console.error(`Configuration error: ${error instanceof Error ? error.message : String(error)}`);
|
|
43
|
+
process.exit(1);
|
|
44
|
+
}
|
|
45
|
+
console.error('No configuration found. Running in mock mode with sample data.');
|
|
46
|
+
}
|
|
47
|
+
// Create MCP server
|
|
48
|
+
const server = new McpServer({
|
|
49
|
+
name: 'complai-brief',
|
|
50
|
+
version: '0.1.0',
|
|
51
|
+
});
|
|
52
|
+
// Register the list_organizations tool
|
|
53
|
+
server.registerTool('complai_list_organizations', {
|
|
54
|
+
description: `List all COMPLAI organizations the user has access to. Use this first when the user asks about compliance status and no specific organization is configured. Returns organization IDs and names that can be used with complai_compliance_brief.`,
|
|
55
|
+
}, async () => {
|
|
56
|
+
// Check if authenticated for user mode
|
|
57
|
+
if (tokenManager && tokenManager.getAuthMode() === 'user' && !tokenManager.isAuthenticated()) {
|
|
58
|
+
return {
|
|
59
|
+
content: [
|
|
60
|
+
{
|
|
61
|
+
type: 'text',
|
|
62
|
+
text: JSON.stringify({
|
|
63
|
+
error: 'Not authenticated',
|
|
64
|
+
message: 'Please call complai_login first to authenticate.',
|
|
65
|
+
}, null, 2),
|
|
66
|
+
},
|
|
67
|
+
],
|
|
68
|
+
isError: true,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
if (!client) {
|
|
72
|
+
return {
|
|
73
|
+
content: [
|
|
74
|
+
{
|
|
75
|
+
type: 'text',
|
|
76
|
+
text: JSON.stringify({
|
|
77
|
+
organizations: [
|
|
78
|
+
{ id: 'org_demo1', name: 'Demo Organization 1' },
|
|
79
|
+
{ id: 'org_demo2', name: 'Demo Organization 2' },
|
|
80
|
+
],
|
|
81
|
+
message: 'Mock mode - showing sample organizations',
|
|
82
|
+
}, null, 2),
|
|
83
|
+
},
|
|
84
|
+
],
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
try {
|
|
88
|
+
const profile = await client.getMe();
|
|
89
|
+
return {
|
|
90
|
+
content: [
|
|
91
|
+
{
|
|
92
|
+
type: 'text',
|
|
93
|
+
text: JSON.stringify({
|
|
94
|
+
organizations: profile.organizations.map(org => ({
|
|
95
|
+
id: org.id,
|
|
96
|
+
name: org.displayName || org.name,
|
|
97
|
+
})),
|
|
98
|
+
defaultOrganizationId: client.getDefaultOrganizationId(),
|
|
99
|
+
message: profile.organizations.length === 1
|
|
100
|
+
? 'User has access to 1 organization.'
|
|
101
|
+
: `User has access to ${profile.organizations.length} organizations. Ask which one to check.`,
|
|
102
|
+
}, null, 2),
|
|
103
|
+
},
|
|
104
|
+
],
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
const message = error instanceof Error ? error.message : 'Unknown error occurred';
|
|
109
|
+
return {
|
|
110
|
+
content: [
|
|
111
|
+
{
|
|
112
|
+
type: 'text',
|
|
113
|
+
text: JSON.stringify({ error: message }),
|
|
114
|
+
},
|
|
115
|
+
],
|
|
116
|
+
isError: true,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
// Register the compliance_brief tool
|
|
121
|
+
server.registerTool('complai_compliance_brief', {
|
|
122
|
+
description: `Get compliance status overview for a specific COMPLAI organization. Use when the user asks about compliance status, risk levels, overdue tasks, or overall data room health. Returns counts of data rooms, tasks, assets, risk distribution with percentages, and actionable alerts for overdue items. If the user has multiple organizations, call complai_list_organizations first to get the organization IDs, then ask which one to check. NOTE: If you get an authentication error, call complai_login first.`,
|
|
123
|
+
inputSchema: {
|
|
124
|
+
organizationId: z.string().describe('The organization ID to get compliance brief for. Get this from complai_list_organizations.'),
|
|
125
|
+
workspaceId: z.string().optional().describe('Optional workspace ID to filter results. Omit for organization-wide overview.'),
|
|
126
|
+
},
|
|
127
|
+
}, async ({ organizationId, workspaceId }) => {
|
|
128
|
+
// Check if authenticated for user mode
|
|
129
|
+
if (tokenManager && tokenManager.getAuthMode() === 'user' && !tokenManager.isAuthenticated()) {
|
|
130
|
+
return {
|
|
131
|
+
content: [
|
|
132
|
+
{
|
|
133
|
+
type: 'text',
|
|
134
|
+
text: JSON.stringify({
|
|
135
|
+
error: 'Not authenticated',
|
|
136
|
+
message: 'Please call complai_login first to authenticate.',
|
|
137
|
+
}, null, 2),
|
|
138
|
+
},
|
|
139
|
+
],
|
|
140
|
+
isError: true,
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
// Use provided orgId, fall back to default if configured
|
|
144
|
+
const effectiveOrgId = organizationId || client?.getDefaultOrganizationId();
|
|
145
|
+
if (!effectiveOrgId) {
|
|
146
|
+
return {
|
|
147
|
+
content: [
|
|
148
|
+
{
|
|
149
|
+
type: 'text',
|
|
150
|
+
text: JSON.stringify({
|
|
151
|
+
error: 'Organization ID required',
|
|
152
|
+
message: 'Please provide an organizationId. Use complai_list_organizations to see available organizations.',
|
|
153
|
+
}, null, 2),
|
|
154
|
+
},
|
|
155
|
+
],
|
|
156
|
+
isError: true,
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
const startTime = Date.now();
|
|
160
|
+
try {
|
|
161
|
+
const result = await getComplianceBrief(client, effectiveOrgId, workspaceId);
|
|
162
|
+
const elapsed = Date.now() - startTime;
|
|
163
|
+
if (elapsed > 3000) {
|
|
164
|
+
console.error(`Warning: Response time ${elapsed}ms exceeds 3s target`);
|
|
165
|
+
}
|
|
166
|
+
return {
|
|
167
|
+
content: [
|
|
168
|
+
{
|
|
169
|
+
type: 'text',
|
|
170
|
+
text: JSON.stringify(result, null, 2),
|
|
171
|
+
},
|
|
172
|
+
],
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
catch (error) {
|
|
176
|
+
const message = error instanceof Error ? error.message : 'Unknown error occurred';
|
|
177
|
+
if (message.includes('fetch') || message.includes('ENOTFOUND') || message.includes('ECONNREFUSED')) {
|
|
178
|
+
return {
|
|
179
|
+
content: [
|
|
180
|
+
{
|
|
181
|
+
type: 'text',
|
|
182
|
+
text: JSON.stringify({
|
|
183
|
+
error: 'Cannot reach COMPLAI API. Check your network connection.',
|
|
184
|
+
}),
|
|
185
|
+
},
|
|
186
|
+
],
|
|
187
|
+
isError: true,
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
return {
|
|
191
|
+
content: [
|
|
192
|
+
{
|
|
193
|
+
type: 'text',
|
|
194
|
+
text: JSON.stringify({ error: message }),
|
|
195
|
+
},
|
|
196
|
+
],
|
|
197
|
+
isError: true,
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
// Register the audit_rooms tool (detailed data)
|
|
202
|
+
server.registerTool('complai_audit_rooms', {
|
|
203
|
+
description: `Get audit room list from COMPLAI with status details. Returns:
|
|
204
|
+
- Room names, tags, person responsible, due dates
|
|
205
|
+
- Risk rating and engagement status (with colors)
|
|
206
|
+
- Task completion status per form template
|
|
207
|
+
- Manufacturer details
|
|
208
|
+
- Asset counts
|
|
209
|
+
|
|
210
|
+
Use this when the user needs:
|
|
211
|
+
- List of all audit rooms with their status
|
|
212
|
+
- Risk ratings across rooms
|
|
213
|
+
- Task completion overview
|
|
214
|
+
- Manufacturer/supplier information
|
|
215
|
+
|
|
216
|
+
For aggregate counts only, use complai_compliance_brief instead.
|
|
217
|
+
NOTE: Returns paginated results (1-based pages).`,
|
|
218
|
+
inputSchema: {
|
|
219
|
+
organizationId: z.string().describe('The organization ID to get audit rooms for. Get this from complai_list_organizations.'),
|
|
220
|
+
page: z.number().optional().describe('Page number (1-based). Default: 1'),
|
|
221
|
+
pageSize: z.number().optional().describe('Number of rooms per page (1-100). Default: 20'),
|
|
222
|
+
},
|
|
223
|
+
}, async ({ organizationId, page, pageSize }) => {
|
|
224
|
+
// Check if authenticated for user mode
|
|
225
|
+
if (tokenManager && tokenManager.getAuthMode() === 'user' && !tokenManager.isAuthenticated()) {
|
|
226
|
+
return {
|
|
227
|
+
content: [
|
|
228
|
+
{
|
|
229
|
+
type: 'text',
|
|
230
|
+
text: JSON.stringify({
|
|
231
|
+
error: 'Not authenticated',
|
|
232
|
+
message: 'Please call complai_login first to authenticate.',
|
|
233
|
+
}, null, 2),
|
|
234
|
+
},
|
|
235
|
+
],
|
|
236
|
+
isError: true,
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
if (!client) {
|
|
240
|
+
return {
|
|
241
|
+
content: [
|
|
242
|
+
{
|
|
243
|
+
type: 'text',
|
|
244
|
+
text: JSON.stringify({
|
|
245
|
+
error: 'No client configured',
|
|
246
|
+
message: 'Server running in mock mode. Configure COMPLAI credentials to use this tool.',
|
|
247
|
+
}, null, 2),
|
|
248
|
+
},
|
|
249
|
+
],
|
|
250
|
+
isError: true,
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
const effectivePage = Math.max(page ?? 1, 1);
|
|
254
|
+
const effectivePageSize = Math.min(Math.max(pageSize ?? 20, 1), 100);
|
|
255
|
+
try {
|
|
256
|
+
const result = await client.getAuditRooms(organizationId, effectivePage, effectivePageSize);
|
|
257
|
+
const { auditRooms, count } = result;
|
|
258
|
+
// Transform to a more AI-friendly format
|
|
259
|
+
const summary = {
|
|
260
|
+
pagination: {
|
|
261
|
+
page: effectivePage,
|
|
262
|
+
pageSize: effectivePageSize,
|
|
263
|
+
totalCount: count,
|
|
264
|
+
totalPages: Math.ceil(count / effectivePageSize),
|
|
265
|
+
},
|
|
266
|
+
rooms: auditRooms.map(room => ({
|
|
267
|
+
id: room.id,
|
|
268
|
+
name: room.name,
|
|
269
|
+
tags: room.tags,
|
|
270
|
+
personResponsible: room.personResponsible,
|
|
271
|
+
dueDate: room.dueDate,
|
|
272
|
+
assetsCount: room.assetsCount,
|
|
273
|
+
riskRating: room.riskRating?.displayName,
|
|
274
|
+
engagement: room.engagement?.displayName,
|
|
275
|
+
manufacturer: room.manufacturer?.name,
|
|
276
|
+
taskCompletion: room.taskCompletion?.map(tc => ({
|
|
277
|
+
template: tc.templateName,
|
|
278
|
+
status: tc.statusName,
|
|
279
|
+
})),
|
|
280
|
+
})),
|
|
281
|
+
};
|
|
282
|
+
return {
|
|
283
|
+
content: [
|
|
284
|
+
{
|
|
285
|
+
type: 'text',
|
|
286
|
+
text: JSON.stringify(summary, null, 2),
|
|
287
|
+
},
|
|
288
|
+
],
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
catch (error) {
|
|
292
|
+
const message = error instanceof Error ? error.message : 'Unknown error occurred';
|
|
293
|
+
return {
|
|
294
|
+
content: [
|
|
295
|
+
{
|
|
296
|
+
type: 'text',
|
|
297
|
+
text: JSON.stringify({ error: message }),
|
|
298
|
+
},
|
|
299
|
+
],
|
|
300
|
+
isError: true,
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
});
|
|
304
|
+
// Register login tool (for user auth mode - PKCE flow)
|
|
305
|
+
server.registerTool('complai_login', {
|
|
306
|
+
description: `Authenticate with COMPLAI. This opens your browser for secure login. After you log in, authentication is saved locally. Call this if complai_compliance_brief returns an authentication error.
|
|
307
|
+
|
|
308
|
+
IMPORTANT: For organization-specific access, provide an organizationId. Without it, you can list organizations but cannot access their data. Workflow:
|
|
309
|
+
1. First call complai_login (no org) to authenticate
|
|
310
|
+
2. Call complai_list_organizations to see available orgs
|
|
311
|
+
3. Call complai_login with the chosen organizationId to get org-scoped access
|
|
312
|
+
4. Now complai_compliance_brief will work for that org`,
|
|
313
|
+
inputSchema: {
|
|
314
|
+
organizationId: z.string().optional().describe('Organization ID to authenticate with. Get this from complai_list_organizations. Required for accessing compliance data.'),
|
|
315
|
+
},
|
|
316
|
+
}, async ({ organizationId }) => {
|
|
317
|
+
if (!tokenManager) {
|
|
318
|
+
return {
|
|
319
|
+
content: [
|
|
320
|
+
{
|
|
321
|
+
type: 'text',
|
|
322
|
+
text: JSON.stringify({
|
|
323
|
+
status: 'mock_mode',
|
|
324
|
+
message: 'Server running in mock mode. No authentication needed.',
|
|
325
|
+
}, null, 2),
|
|
326
|
+
},
|
|
327
|
+
],
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
if (tokenManager.getAuthMode() === 'm2m') {
|
|
331
|
+
return {
|
|
332
|
+
content: [
|
|
333
|
+
{
|
|
334
|
+
type: 'text',
|
|
335
|
+
text: JSON.stringify({
|
|
336
|
+
status: 'ok',
|
|
337
|
+
authMode: 'm2m',
|
|
338
|
+
message: 'Using M2M authentication (client credentials). Already authenticated.',
|
|
339
|
+
}, null, 2),
|
|
340
|
+
},
|
|
341
|
+
],
|
|
342
|
+
};
|
|
343
|
+
}
|
|
344
|
+
// If organizationId provided, we need to re-authenticate with that org
|
|
345
|
+
// (even if already authenticated, since we need org-scoped token)
|
|
346
|
+
if (organizationId) {
|
|
347
|
+
try {
|
|
348
|
+
console.error(`Starting PKCE authentication flow for org ${organizationId}...`);
|
|
349
|
+
tokenManager.logout(); // Clear existing tokens
|
|
350
|
+
await tokenManager.loginWithOrganization(organizationId);
|
|
351
|
+
return {
|
|
352
|
+
content: [
|
|
353
|
+
{
|
|
354
|
+
type: 'text',
|
|
355
|
+
text: JSON.stringify({
|
|
356
|
+
status: 'ok',
|
|
357
|
+
organizationId,
|
|
358
|
+
message: `Authentication successful for organization! You can now use complai_compliance_brief.`,
|
|
359
|
+
}, null, 2),
|
|
360
|
+
},
|
|
361
|
+
],
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
catch (error) {
|
|
365
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
366
|
+
return {
|
|
367
|
+
content: [
|
|
368
|
+
{
|
|
369
|
+
type: 'text',
|
|
370
|
+
text: JSON.stringify({
|
|
371
|
+
status: 'error',
|
|
372
|
+
error: `Login failed: ${message}`,
|
|
373
|
+
}, null, 2),
|
|
374
|
+
},
|
|
375
|
+
],
|
|
376
|
+
isError: true,
|
|
377
|
+
};
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
// Check if already authenticated (no org specified)
|
|
381
|
+
if (tokenManager.isAuthenticated()) {
|
|
382
|
+
return {
|
|
383
|
+
content: [
|
|
384
|
+
{
|
|
385
|
+
type: 'text',
|
|
386
|
+
text: JSON.stringify({
|
|
387
|
+
status: 'ok',
|
|
388
|
+
message: 'Already authenticated. To access compliance data, call complai_login with an organizationId.',
|
|
389
|
+
}, null, 2),
|
|
390
|
+
},
|
|
391
|
+
],
|
|
392
|
+
};
|
|
393
|
+
}
|
|
394
|
+
// Perform PKCE login without org (for listing orgs)
|
|
395
|
+
try {
|
|
396
|
+
console.error('Starting PKCE authentication flow (no org)...');
|
|
397
|
+
await tokenManager.login();
|
|
398
|
+
return {
|
|
399
|
+
content: [
|
|
400
|
+
{
|
|
401
|
+
type: 'text',
|
|
402
|
+
text: JSON.stringify({
|
|
403
|
+
status: 'ok',
|
|
404
|
+
message: 'Authentication successful! You can now use complai_compliance_brief.',
|
|
405
|
+
}, null, 2),
|
|
406
|
+
},
|
|
407
|
+
],
|
|
408
|
+
};
|
|
409
|
+
}
|
|
410
|
+
catch (error) {
|
|
411
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
412
|
+
return {
|
|
413
|
+
content: [
|
|
414
|
+
{
|
|
415
|
+
type: 'text',
|
|
416
|
+
text: JSON.stringify({
|
|
417
|
+
status: 'error',
|
|
418
|
+
error: `Login failed: ${message}`,
|
|
419
|
+
}, null, 2),
|
|
420
|
+
},
|
|
421
|
+
],
|
|
422
|
+
isError: true,
|
|
423
|
+
};
|
|
424
|
+
}
|
|
425
|
+
});
|
|
426
|
+
// Register auth status tool
|
|
427
|
+
server.registerTool('complai_auth_status', {
|
|
428
|
+
description: `Check COMPLAI authentication status. Shows whether you're logged in and what authentication mode is being used.`,
|
|
429
|
+
}, async () => {
|
|
430
|
+
if (!tokenManager) {
|
|
431
|
+
return {
|
|
432
|
+
content: [
|
|
433
|
+
{
|
|
434
|
+
type: 'text',
|
|
435
|
+
text: JSON.stringify({
|
|
436
|
+
mode: 'mock',
|
|
437
|
+
authenticated: true,
|
|
438
|
+
message: 'Server running in mock mode. No authentication required.',
|
|
439
|
+
}, null, 2),
|
|
440
|
+
},
|
|
441
|
+
],
|
|
442
|
+
};
|
|
443
|
+
}
|
|
444
|
+
const authMode = tokenManager.getAuthMode();
|
|
445
|
+
const isAuthenticated = tokenManager.isAuthenticated();
|
|
446
|
+
return {
|
|
447
|
+
content: [
|
|
448
|
+
{
|
|
449
|
+
type: 'text',
|
|
450
|
+
text: JSON.stringify({
|
|
451
|
+
authMode,
|
|
452
|
+
authenticated: isAuthenticated,
|
|
453
|
+
message: authMode === 'm2m'
|
|
454
|
+
? 'Using M2M authentication with client credentials.'
|
|
455
|
+
: isAuthenticated
|
|
456
|
+
? 'Logged in with user credentials.'
|
|
457
|
+
: 'Not logged in. Call complai_login to authenticate.',
|
|
458
|
+
}, null, 2),
|
|
459
|
+
},
|
|
460
|
+
],
|
|
461
|
+
};
|
|
462
|
+
});
|
|
463
|
+
// Start the server
|
|
464
|
+
async function main() {
|
|
465
|
+
const transport = new StdioServerTransport();
|
|
466
|
+
await server.connect(transport);
|
|
467
|
+
// Log to stderr
|
|
468
|
+
if (config) {
|
|
469
|
+
const authMode = getAuthModeDescription(config);
|
|
470
|
+
const status = tokenManager?.getAuthMode() === 'user'
|
|
471
|
+
? (tokenManager.isAuthenticated() ? 'authenticated' : 'not authenticated')
|
|
472
|
+
: 'ready';
|
|
473
|
+
console.error(`COMPLAI MCP server started (${authMode}, ${status})`);
|
|
474
|
+
}
|
|
475
|
+
else {
|
|
476
|
+
console.error('COMPLAI MCP server started (mock mode)');
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
main().catch((error) => {
|
|
480
|
+
console.error('Error:', error);
|
|
481
|
+
process.exit(1);
|
|
482
|
+
});
|
|
483
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ComplianceBriefResponse } from '../types.js';
|
|
2
|
+
import { ComplaiClient } from '../api/complai-client.js';
|
|
3
|
+
/**
|
|
4
|
+
* Get a compliance brief from the COMPLAI API.
|
|
5
|
+
* This is the main tool implementation.
|
|
6
|
+
*/
|
|
7
|
+
export declare function getComplianceBrief(client: ComplaiClient | null, organizationId: string, workspaceId?: string): Promise<ComplianceBriefResponse>;
|
|
8
|
+
//# sourceMappingURL=compliance-brief.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compliance-brief.d.ts","sourceRoot":"","sources":["../../src/tools/compliance-brief.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAA6B,MAAM,aAAa,CAAC;AACjF,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAOzD;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,aAAa,GAAG,IAAI,EAC5B,cAAc,EAAE,MAAM,EACtB,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,uBAAuB,CAAC,CASlC"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Maximum number of alerts to include in the response
|
|
3
|
+
*/
|
|
4
|
+
const MAX_ALERTS = 10;
|
|
5
|
+
/**
|
|
6
|
+
* Get a compliance brief from the COMPLAI API.
|
|
7
|
+
* This is the main tool implementation.
|
|
8
|
+
*/
|
|
9
|
+
export async function getComplianceBrief(client, organizationId, workspaceId) {
|
|
10
|
+
// If no client (mock mode), return mock data
|
|
11
|
+
if (!client) {
|
|
12
|
+
return getMockComplianceBrief();
|
|
13
|
+
}
|
|
14
|
+
// Fetch real data from api-auth0
|
|
15
|
+
const overview = await client.getDashboardOverview(organizationId, workspaceId);
|
|
16
|
+
return transformToComplianceBrief(overview);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Transform the dashboard response to AI-friendly format
|
|
20
|
+
*/
|
|
21
|
+
function transformToComplianceBrief(overview) {
|
|
22
|
+
const today = new Date().toISOString().split('T')[0];
|
|
23
|
+
// Transform risk rating from Record<string, CustomStatusData> to array with percentages
|
|
24
|
+
const riskEntries = Object.entries(overview.riskRating);
|
|
25
|
+
const totalRiskItems = riskEntries.reduce((sum, [, data]) => sum + data.elementsAmount, 0);
|
|
26
|
+
const riskDistribution = riskEntries.map(([key, data]) => ({
|
|
27
|
+
level: data.displayName || key,
|
|
28
|
+
count: data.elementsAmount,
|
|
29
|
+
percentage: totalRiskItems > 0
|
|
30
|
+
? Math.round((data.elementsAmount / totalRiskItems) * 1000) / 10
|
|
31
|
+
: 0,
|
|
32
|
+
}));
|
|
33
|
+
// Sort by count descending for clarity
|
|
34
|
+
riskDistribution.sort((a, b) => b.count - a.count);
|
|
35
|
+
// Calculate task status from deadline arrays
|
|
36
|
+
const taskStatus = {
|
|
37
|
+
overdue: overview.taskDeadline.before.length,
|
|
38
|
+
dueThisWeek: 0, // API doesn't distinguish "this week" vs "future" - all future are in "after"
|
|
39
|
+
onTrack: overview.taskDeadline.after.length,
|
|
40
|
+
noDeadline: overview.taskDeadline.noDeadline.length,
|
|
41
|
+
};
|
|
42
|
+
// Build alerts array
|
|
43
|
+
const alerts = buildAlerts(overview, taskStatus);
|
|
44
|
+
return {
|
|
45
|
+
summary: {
|
|
46
|
+
description: `Compliance overview as of ${today}`,
|
|
47
|
+
dataRooms: overview.dataRoomsAmount,
|
|
48
|
+
assets: overview.assetsAmount,
|
|
49
|
+
manufacturers: overview.manufacturersAmount,
|
|
50
|
+
totalTasks: overview.tasksAmount,
|
|
51
|
+
overdueActions: overview.openActions,
|
|
52
|
+
},
|
|
53
|
+
riskDistribution,
|
|
54
|
+
taskStatus,
|
|
55
|
+
alerts,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Build human-readable alerts from the overview data
|
|
60
|
+
*/
|
|
61
|
+
function buildAlerts(overview, taskStatus) {
|
|
62
|
+
const alerts = [];
|
|
63
|
+
// Overdue corrective actions (open actions)
|
|
64
|
+
if (overview.openActions > 0) {
|
|
65
|
+
alerts.push(`${overview.openActions} corrective action${overview.openActions === 1 ? ' is' : 's are'} past ${overview.openActions === 1 ? 'its' : 'their'} deadline`);
|
|
66
|
+
}
|
|
67
|
+
// Overdue tasks
|
|
68
|
+
if (taskStatus.overdue > 0) {
|
|
69
|
+
alerts.push(`${taskStatus.overdue} task${taskStatus.overdue === 1 ? ' is' : 's are'} overdue`);
|
|
70
|
+
}
|
|
71
|
+
// High risk data rooms
|
|
72
|
+
const highRiskEntry = Object.entries(overview.riskRating).find(([key, data]) => key.toLowerCase().includes('high') || data.displayName?.toLowerCase().includes('high'));
|
|
73
|
+
if (highRiskEntry && highRiskEntry[1].elementsAmount > 0) {
|
|
74
|
+
const count = highRiskEntry[1].elementsAmount;
|
|
75
|
+
alerts.push(`${count} data room${count === 1 ? '' : 's'} rated as high risk`);
|
|
76
|
+
}
|
|
77
|
+
// Tasks without deadlines (potential tracking gap)
|
|
78
|
+
if (taskStatus.noDeadline > 10) {
|
|
79
|
+
alerts.push(`${taskStatus.noDeadline} tasks have no deadline set`);
|
|
80
|
+
}
|
|
81
|
+
// Cap alerts and add "...and X more" if needed
|
|
82
|
+
if (alerts.length > MAX_ALERTS) {
|
|
83
|
+
const remaining = alerts.length - MAX_ALERTS + 1;
|
|
84
|
+
const truncated = alerts.slice(0, MAX_ALERTS - 1);
|
|
85
|
+
truncated.push(`...and ${remaining} more alert${remaining === 1 ? '' : 's'}`);
|
|
86
|
+
return truncated;
|
|
87
|
+
}
|
|
88
|
+
return alerts;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Generate mock data for testing without API connection
|
|
92
|
+
*/
|
|
93
|
+
function getMockComplianceBrief() {
|
|
94
|
+
const today = new Date().toISOString().split('T')[0];
|
|
95
|
+
return {
|
|
96
|
+
summary: {
|
|
97
|
+
description: `Compliance overview for Demo Organization as of ${today}`,
|
|
98
|
+
dataRooms: 24,
|
|
99
|
+
assets: 156,
|
|
100
|
+
manufacturers: 42,
|
|
101
|
+
totalTasks: 89,
|
|
102
|
+
overdueActions: 7,
|
|
103
|
+
},
|
|
104
|
+
riskDistribution: [
|
|
105
|
+
{ level: 'High', count: 3, percentage: 12.5 },
|
|
106
|
+
{ level: 'Medium', count: 8, percentage: 33.3 },
|
|
107
|
+
{ level: 'Low', count: 13, percentage: 54.2 },
|
|
108
|
+
],
|
|
109
|
+
taskStatus: {
|
|
110
|
+
overdue: 12,
|
|
111
|
+
dueThisWeek: 8,
|
|
112
|
+
onTrack: 45,
|
|
113
|
+
noDeadline: 24,
|
|
114
|
+
},
|
|
115
|
+
alerts: [
|
|
116
|
+
'7 corrective actions are past their deadline',
|
|
117
|
+
'12 tasks are overdue',
|
|
118
|
+
'3 data rooms rated as high risk',
|
|
119
|
+
],
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=compliance-brief.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compliance-brief.js","sourceRoot":"","sources":["../../src/tools/compliance-brief.ts"],"names":[],"mappings":"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"}
|