@mtaap/mcp 0.2.13 → 0.5.1
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 +4 -4
- package/dist/apps/activity.html +159 -0
- package/dist/apps/agent-sessions.html +159 -0
- package/dist/apps/kanban.html +159 -0
- package/dist/apps/project-overview.html +159 -0
- package/dist/apps/task-details.html +159 -0
- package/dist/cli.js +1067 -285
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +43 -29
- package/dist/index.js +1065 -283
- package/dist/index.js.map +1 -1
- package/dist/server.js +1234 -295
- package/dist/server.js.map +1 -1
- package/package.json +22 -8
package/dist/cli.js
CHANGED
|
@@ -30,15 +30,18 @@ var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
|
30
30
|
// package.json
|
|
31
31
|
var package_default = {
|
|
32
32
|
name: "@mtaap/mcp",
|
|
33
|
-
version: "0.
|
|
33
|
+
version: "0.5.1",
|
|
34
34
|
description: "Model Context Protocol (MCP) server for AI agents to interact with Collab - the multi-tenant collaborative agent development platform",
|
|
35
35
|
mcpName: "collab",
|
|
36
36
|
scripts: {
|
|
37
|
-
build: "tsup"
|
|
37
|
+
build: "pnpm build:ui && tsup",
|
|
38
|
+
"build:ui": "node scripts/build-ui.mjs",
|
|
39
|
+
"dev:ui": "vite build --watch"
|
|
38
40
|
},
|
|
39
41
|
main: "./dist/index.js",
|
|
40
42
|
types: "./dist/index.d.ts",
|
|
41
43
|
bin: {
|
|
44
|
+
mcp: "./dist/cli.js",
|
|
42
45
|
"collab-mcp": "./dist/cli.js",
|
|
43
46
|
"collab-mcp-server": "./dist/server.js"
|
|
44
47
|
},
|
|
@@ -71,6 +74,7 @@ var package_default = {
|
|
|
71
74
|
},
|
|
72
75
|
dependencies: {
|
|
73
76
|
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
77
|
+
"@modelcontextprotocol/ext-apps": "^1.0.1",
|
|
74
78
|
express: "^5.0.1",
|
|
75
79
|
zod: "^4.3.5"
|
|
76
80
|
},
|
|
@@ -79,8 +83,18 @@ var package_default = {
|
|
|
79
83
|
"@mtaap/core": "workspace:*",
|
|
80
84
|
"@types/express": "^5.0.0",
|
|
81
85
|
"@types/node": "^22.0.0",
|
|
86
|
+
"@types/react": "^19.0.0",
|
|
87
|
+
"@types/react-dom": "^19.0.0",
|
|
88
|
+
"@vitejs/plugin-react": "^4.4.0",
|
|
89
|
+
autoprefixer: "^10.4.21",
|
|
90
|
+
postcss: "^8.5.3",
|
|
91
|
+
react: "^19.0.0",
|
|
92
|
+
"react-dom": "^19.0.0",
|
|
93
|
+
tailwindcss: "^3.4.17",
|
|
82
94
|
tsup: "^8.5.1",
|
|
83
|
-
typescript: "^5.4.0"
|
|
95
|
+
typescript: "^5.4.0",
|
|
96
|
+
vite: "^6.3.2",
|
|
97
|
+
"vite-plugin-singlefile": "^2.0.3"
|
|
84
98
|
}
|
|
85
99
|
};
|
|
86
100
|
|
|
@@ -88,7 +102,7 @@ var package_default = {
|
|
|
88
102
|
var VERSION = package_default.version;
|
|
89
103
|
|
|
90
104
|
// src/index.ts
|
|
91
|
-
var
|
|
105
|
+
var import_zod9 = require("zod");
|
|
92
106
|
|
|
93
107
|
// ../../packages/core/dist/constants/enums.js
|
|
94
108
|
var TaskState;
|
|
@@ -174,13 +188,11 @@ var WebSocketEventType;
|
|
|
174
188
|
WebSocketEventType2["TASK_UPDATED"] = "task.updated";
|
|
175
189
|
WebSocketEventType2["TASK_DELETED"] = "task.deleted";
|
|
176
190
|
WebSocketEventType2["MEMBER_JOINED"] = "member.joined";
|
|
191
|
+
WebSocketEventType2["AGENT_STARTED"] = "agent.started";
|
|
192
|
+
WebSocketEventType2["AGENT_OUTPUT"] = "agent.output";
|
|
193
|
+
WebSocketEventType2["AGENT_STOPPED"] = "agent.stopped";
|
|
194
|
+
WebSocketEventType2["AGENT_ERROR"] = "agent.error";
|
|
177
195
|
})(WebSocketEventType || (WebSocketEventType = {}));
|
|
178
|
-
var AuthProvider;
|
|
179
|
-
(function(AuthProvider2) {
|
|
180
|
-
AuthProvider2["CREDENTIALS"] = "credentials";
|
|
181
|
-
AuthProvider2["LDAP"] = "ldap";
|
|
182
|
-
AuthProvider2["SSO"] = "sso";
|
|
183
|
-
})(AuthProvider || (AuthProvider = {}));
|
|
184
196
|
var SubscriptionStatus;
|
|
185
197
|
(function(SubscriptionStatus2) {
|
|
186
198
|
SubscriptionStatus2["ACTIVE"] = "ACTIVE";
|
|
@@ -196,6 +208,37 @@ var EventType;
|
|
|
196
208
|
EventType2["ACCESS"] = "ACCESS";
|
|
197
209
|
EventType2["MODIFICATION"] = "MODIFICATION";
|
|
198
210
|
})(EventType || (EventType = {}));
|
|
211
|
+
var CreatedVia;
|
|
212
|
+
(function(CreatedVia2) {
|
|
213
|
+
CreatedVia2["UI"] = "UI";
|
|
214
|
+
CreatedVia2["API_KEY"] = "API_KEY";
|
|
215
|
+
CreatedVia2["OAUTH"] = "OAUTH";
|
|
216
|
+
})(CreatedVia || (CreatedVia = {}));
|
|
217
|
+
var AgentModel;
|
|
218
|
+
(function(AgentModel2) {
|
|
219
|
+
AgentModel2["OPUS"] = "OPUS";
|
|
220
|
+
AgentModel2["SONNET"] = "SONNET";
|
|
221
|
+
AgentModel2["HAIKU"] = "HAIKU";
|
|
222
|
+
})(AgentModel || (AgentModel = {}));
|
|
223
|
+
var AgentModelMode;
|
|
224
|
+
(function(AgentModelMode2) {
|
|
225
|
+
AgentModelMode2["DEFAULT"] = "DEFAULT";
|
|
226
|
+
AgentModelMode2["PRESET"] = "PRESET";
|
|
227
|
+
AgentModelMode2["CUSTOM"] = "CUSTOM";
|
|
228
|
+
})(AgentModelMode || (AgentModelMode = {}));
|
|
229
|
+
var AgentCLIType;
|
|
230
|
+
(function(AgentCLIType2) {
|
|
231
|
+
AgentCLIType2["CLAUDE_CODE"] = "CLAUDE_CODE";
|
|
232
|
+
AgentCLIType2["OPENCODE"] = "OPENCODE";
|
|
233
|
+
})(AgentCLIType || (AgentCLIType = {}));
|
|
234
|
+
var AgentSessionStatus;
|
|
235
|
+
(function(AgentSessionStatus2) {
|
|
236
|
+
AgentSessionStatus2["STARTING"] = "STARTING";
|
|
237
|
+
AgentSessionStatus2["RUNNING"] = "RUNNING";
|
|
238
|
+
AgentSessionStatus2["STOPPING"] = "STOPPING";
|
|
239
|
+
AgentSessionStatus2["STOPPED"] = "STOPPED";
|
|
240
|
+
AgentSessionStatus2["ERROR"] = "ERROR";
|
|
241
|
+
})(AgentSessionStatus || (AgentSessionStatus = {}));
|
|
199
242
|
|
|
200
243
|
// ../../packages/core/dist/constants/state-machine.js
|
|
201
244
|
var VALID_TRANSITIONS = {
|
|
@@ -219,6 +262,62 @@ var VALID_TRANSITIONS = {
|
|
|
219
262
|
[TaskState.DONE]: []
|
|
220
263
|
};
|
|
221
264
|
|
|
265
|
+
// ../../packages/core/dist/constants/oauth.js
|
|
266
|
+
var OAuthScopes = {
|
|
267
|
+
/** Read-only access to MCP resources */
|
|
268
|
+
READ: "mcp:read",
|
|
269
|
+
/** Read and write access to MCP resources */
|
|
270
|
+
WRITE: "mcp:write",
|
|
271
|
+
/** Full administrative access */
|
|
272
|
+
ADMIN: "mcp:admin"
|
|
273
|
+
};
|
|
274
|
+
var VALID_OAUTH_SCOPES = [
|
|
275
|
+
OAuthScopes.READ,
|
|
276
|
+
OAuthScopes.WRITE,
|
|
277
|
+
OAuthScopes.ADMIN
|
|
278
|
+
];
|
|
279
|
+
var DEFAULT_OAUTH_SCOPES = `${OAuthScopes.READ} ${OAuthScopes.WRITE}`;
|
|
280
|
+
var OAUTH_SCOPE_TO_PERMISSION = {
|
|
281
|
+
[OAuthScopes.READ]: ApiKeyPermission.READ,
|
|
282
|
+
[OAuthScopes.WRITE]: ApiKeyPermission.WRITE,
|
|
283
|
+
[OAuthScopes.ADMIN]: ApiKeyPermission.ADMIN
|
|
284
|
+
};
|
|
285
|
+
var PERMISSION_TO_OAUTH_SCOPE = {
|
|
286
|
+
[ApiKeyPermission.READ]: OAuthScopes.READ,
|
|
287
|
+
[ApiKeyPermission.WRITE]: OAuthScopes.WRITE,
|
|
288
|
+
[ApiKeyPermission.ADMIN]: OAuthScopes.ADMIN
|
|
289
|
+
};
|
|
290
|
+
var OAuthTokenLifetimes = {
|
|
291
|
+
/** Access token lifetime: 1 hour */
|
|
292
|
+
ACCESS_TOKEN_MS: 60 * 60 * 1e3,
|
|
293
|
+
/** Refresh token lifetime: 30 days */
|
|
294
|
+
REFRESH_TOKEN_MS: 30 * 24 * 60 * 60 * 1e3,
|
|
295
|
+
/** Authorization code lifetime: 10 minutes */
|
|
296
|
+
AUTHORIZATION_CODE_MS: 10 * 60 * 1e3
|
|
297
|
+
};
|
|
298
|
+
var OAuthGrantTypes = {
|
|
299
|
+
AUTHORIZATION_CODE: "authorization_code",
|
|
300
|
+
REFRESH_TOKEN: "refresh_token"
|
|
301
|
+
};
|
|
302
|
+
var SUPPORTED_GRANT_TYPES = [
|
|
303
|
+
OAuthGrantTypes.AUTHORIZATION_CODE,
|
|
304
|
+
OAuthGrantTypes.REFRESH_TOKEN
|
|
305
|
+
];
|
|
306
|
+
var OAuthResponseTypes = {
|
|
307
|
+
CODE: "code"
|
|
308
|
+
};
|
|
309
|
+
var OAuthCodeChallengeMethods = {
|
|
310
|
+
S256: "S256"
|
|
311
|
+
};
|
|
312
|
+
var OAuthRateLimits = {
|
|
313
|
+
/** /oauth/token: 30 requests per minute per client */
|
|
314
|
+
TOKEN_ENDPOINT: { limit: 30, windowMs: 60 * 1e3 },
|
|
315
|
+
/** /oauth/authorize: 10 requests per minute per user */
|
|
316
|
+
AUTHORIZE_ENDPOINT: { limit: 10, windowMs: 60 * 1e3 },
|
|
317
|
+
/** /oauth/register: 5 requests per minute per IP */
|
|
318
|
+
REGISTER_ENDPOINT: { limit: 5, windowMs: 60 * 1e3 }
|
|
319
|
+
};
|
|
320
|
+
|
|
222
321
|
// ../../packages/core/dist/config/deployment.js
|
|
223
322
|
var config = {
|
|
224
323
|
deploymentMode: process.env.DEPLOYMENT_MODE || "saas"
|
|
@@ -226,20 +325,24 @@ var config = {
|
|
|
226
325
|
var isSaas = config.deploymentMode === "saas";
|
|
227
326
|
var isOnPrem = config.deploymentMode === "onprem";
|
|
228
327
|
|
|
229
|
-
// ../../packages/core/dist/
|
|
230
|
-
var
|
|
328
|
+
// ../../packages/core/dist/versions.js
|
|
329
|
+
var VERSIONS = {
|
|
330
|
+
core: "0.4.0",
|
|
331
|
+
web: "0.4.0",
|
|
332
|
+
mcp: "0.5.0"
|
|
333
|
+
};
|
|
334
|
+
var VERSION2 = VERSIONS.core;
|
|
231
335
|
|
|
232
336
|
// ../../packages/core/dist/config/index.js
|
|
233
337
|
var DEPLOYMENT_MODE = process.env.DEPLOYMENT_MODE || "saas";
|
|
234
338
|
var config2 = {
|
|
235
339
|
version: VERSION2,
|
|
340
|
+
packages: VERSIONS,
|
|
236
341
|
deploymentMode: DEPLOYMENT_MODE,
|
|
237
342
|
billing: {
|
|
238
343
|
enabled: DEPLOYMENT_MODE === "saas",
|
|
239
344
|
revenuecat: {
|
|
240
|
-
publicKey: process.env.
|
|
241
|
-
stripeKey: process.env.STRIPE_SECRET_KEY
|
|
242
|
-
// Required by RevenueCat Web Billing
|
|
345
|
+
publicKey: process.env.NEXT_PUBLIC_REVENUECAT_PUBLIC_KEY
|
|
243
346
|
}
|
|
244
347
|
},
|
|
245
348
|
licensing: {
|
|
@@ -307,6 +410,18 @@ var config2 = {
|
|
|
307
410
|
requestsPerHour: 1e3
|
|
308
411
|
}
|
|
309
412
|
},
|
|
413
|
+
agent: {
|
|
414
|
+
defaultModel: "SONNET",
|
|
415
|
+
sessionTimeoutMs: 30 * 60 * 1e3,
|
|
416
|
+
// 30 minutes
|
|
417
|
+
maxSessionDurationMs: 4 * 60 * 60 * 1e3,
|
|
418
|
+
// 4 hours
|
|
419
|
+
maxConcurrentSessions: {
|
|
420
|
+
FREE: 1,
|
|
421
|
+
PRO: 5,
|
|
422
|
+
ENTERPRISE: -1
|
|
423
|
+
}
|
|
424
|
+
},
|
|
310
425
|
limits: {
|
|
311
426
|
projectNameMaxLength: 100,
|
|
312
427
|
taskDescriptionMaxLength: 5e3,
|
|
@@ -345,7 +460,6 @@ var OrganizationIdSchema = import_zod.z.string().regex(/^org_[a-zA-Z0-9]+$/);
|
|
|
345
460
|
var OrganizationSchema = import_zod.z.object({
|
|
346
461
|
id: OrganizationIdSchema,
|
|
347
462
|
name: import_zod.z.string().min(1).max(255),
|
|
348
|
-
slug: import_zod.z.string().min(1).max(100).regex(/^[a-z0-9-]+$/),
|
|
349
463
|
logoUrl: import_zod.z.string().url().nullable(),
|
|
350
464
|
accentColor: import_zod.z.string().regex(/^#[0-9A-Fa-f]{6}$/).nullable(),
|
|
351
465
|
tenantName: import_zod.z.string().nullable(),
|
|
@@ -473,239 +587,376 @@ var ProjectCollaboratorSchema = import_zod.z.object({
|
|
|
473
587
|
});
|
|
474
588
|
|
|
475
589
|
// ../../packages/core/dist/validation/index.js
|
|
590
|
+
var import_zod3 = require("zod");
|
|
591
|
+
|
|
592
|
+
// ../../packages/core/dist/validation/oauth.js
|
|
476
593
|
var import_zod2 = require("zod");
|
|
477
|
-
var
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
var
|
|
594
|
+
var scopeString = import_zod2.z.string().optional().transform((val) => {
|
|
595
|
+
if (!val)
|
|
596
|
+
return void 0;
|
|
597
|
+
const scopes = val.split(" ").filter(Boolean);
|
|
598
|
+
const validScopes = scopes.filter((s) => VALID_OAUTH_SCOPES.includes(s));
|
|
599
|
+
return validScopes.length > 0 ? validScopes.join(" ") : void 0;
|
|
600
|
+
});
|
|
601
|
+
var redirectUri = import_zod2.z.string().url().refine((uri) => {
|
|
602
|
+
const url = new URL(uri);
|
|
603
|
+
return url.protocol === "https:" || url.hostname === "localhost" || url.hostname === "127.0.0.1";
|
|
604
|
+
}, { message: "redirect_uri must use HTTPS or be localhost" });
|
|
605
|
+
var codeVerifier = import_zod2.z.string().min(43).max(128).regex(/^[A-Za-z0-9._~-]+$/, "code_verifier must only contain unreserved characters");
|
|
606
|
+
var codeChallenge = import_zod2.z.string().min(43).max(128).regex(/^[A-Za-z0-9_-]+$/, "code_challenge must be base64url encoded (no padding)");
|
|
607
|
+
var DynamicClientRegistrationSchema = import_zod2.z.object({
|
|
608
|
+
redirect_uris: import_zod2.z.array(redirectUri).min(1),
|
|
609
|
+
client_name: import_zod2.z.string().min(1).max(255),
|
|
610
|
+
client_uri: import_zod2.z.string().url().optional(),
|
|
611
|
+
logo_uri: import_zod2.z.string().url().optional(),
|
|
612
|
+
// Accept lowercase OAuth spec values
|
|
613
|
+
grant_types: import_zod2.z.array(import_zod2.z.enum(["authorization_code", "refresh_token"])).default(["authorization_code", "refresh_token"]),
|
|
614
|
+
response_types: import_zod2.z.array(import_zod2.z.enum([OAuthResponseTypes.CODE])).default([OAuthResponseTypes.CODE]),
|
|
615
|
+
scope: scopeString,
|
|
616
|
+
// Accept lowercase OAuth spec values
|
|
617
|
+
token_endpoint_auth_method: import_zod2.z.enum(["none", "client_secret_post", "client_secret_basic"]).default("none")
|
|
618
|
+
});
|
|
619
|
+
var DynamicClientRegistrationResponseSchema = import_zod2.z.object({
|
|
620
|
+
client_id: import_zod2.z.string(),
|
|
621
|
+
client_secret: import_zod2.z.string().optional(),
|
|
622
|
+
client_id_issued_at: import_zod2.z.number(),
|
|
623
|
+
client_secret_expires_at: import_zod2.z.number().optional(),
|
|
624
|
+
redirect_uris: import_zod2.z.array(import_zod2.z.string()),
|
|
625
|
+
client_name: import_zod2.z.string(),
|
|
626
|
+
client_uri: import_zod2.z.string().optional(),
|
|
627
|
+
logo_uri: import_zod2.z.string().optional(),
|
|
628
|
+
grant_types: import_zod2.z.array(import_zod2.z.string()),
|
|
629
|
+
response_types: import_zod2.z.array(import_zod2.z.string()),
|
|
630
|
+
scope: import_zod2.z.string(),
|
|
631
|
+
token_endpoint_auth_method: import_zod2.z.string(),
|
|
632
|
+
registration_access_token: import_zod2.z.string().optional(),
|
|
633
|
+
registration_client_uri: import_zod2.z.string().optional()
|
|
634
|
+
});
|
|
635
|
+
var AuthorizationRequestSchema = import_zod2.z.object({
|
|
636
|
+
response_type: import_zod2.z.literal(OAuthResponseTypes.CODE),
|
|
637
|
+
client_id: import_zod2.z.string().min(1),
|
|
638
|
+
redirect_uri: redirectUri,
|
|
639
|
+
scope: scopeString,
|
|
640
|
+
state: import_zod2.z.string().max(255).optional(),
|
|
641
|
+
// PKCE is mandatory in OAuth 2.1
|
|
642
|
+
code_challenge: codeChallenge,
|
|
643
|
+
code_challenge_method: import_zod2.z.literal(OAuthCodeChallengeMethods.S256)
|
|
644
|
+
});
|
|
645
|
+
var TokenRequestAuthorizationCodeSchema = import_zod2.z.object({
|
|
646
|
+
grant_type: import_zod2.z.literal(OAuthGrantTypes.AUTHORIZATION_CODE),
|
|
647
|
+
code: import_zod2.z.string().min(1),
|
|
648
|
+
redirect_uri: redirectUri,
|
|
649
|
+
client_id: import_zod2.z.string().min(1),
|
|
650
|
+
// PKCE code verifier is mandatory
|
|
651
|
+
code_verifier: codeVerifier,
|
|
652
|
+
// Client secret is optional (for confidential clients)
|
|
653
|
+
client_secret: import_zod2.z.string().optional()
|
|
654
|
+
});
|
|
655
|
+
var TokenRequestRefreshTokenSchema = import_zod2.z.object({
|
|
656
|
+
grant_type: import_zod2.z.literal(OAuthGrantTypes.REFRESH_TOKEN),
|
|
657
|
+
refresh_token: import_zod2.z.string().min(1),
|
|
658
|
+
client_id: import_zod2.z.string().min(1),
|
|
659
|
+
// Optional: request reduced scope
|
|
660
|
+
scope: scopeString,
|
|
661
|
+
// Client secret is optional (for confidential clients)
|
|
662
|
+
client_secret: import_zod2.z.string().optional()
|
|
663
|
+
});
|
|
664
|
+
var TokenRequestSchema = import_zod2.z.discriminatedUnion("grant_type", [
|
|
665
|
+
TokenRequestAuthorizationCodeSchema,
|
|
666
|
+
TokenRequestRefreshTokenSchema
|
|
667
|
+
]);
|
|
668
|
+
var TokenResponseSchema = import_zod2.z.object({
|
|
669
|
+
access_token: import_zod2.z.string(),
|
|
670
|
+
token_type: import_zod2.z.literal("Bearer"),
|
|
671
|
+
expires_in: import_zod2.z.number(),
|
|
672
|
+
refresh_token: import_zod2.z.string().optional(),
|
|
673
|
+
scope: import_zod2.z.string()
|
|
674
|
+
});
|
|
675
|
+
var TokenRevocationRequestSchema = import_zod2.z.object({
|
|
676
|
+
token: import_zod2.z.string().min(1),
|
|
677
|
+
token_type_hint: import_zod2.z.enum(["access_token", "refresh_token"]).optional(),
|
|
678
|
+
client_id: import_zod2.z.string().min(1),
|
|
679
|
+
client_secret: import_zod2.z.string().optional()
|
|
680
|
+
});
|
|
681
|
+
var OAuthErrorResponseSchema = import_zod2.z.object({
|
|
682
|
+
error: import_zod2.z.string(),
|
|
683
|
+
error_description: import_zod2.z.string().optional(),
|
|
684
|
+
error_uri: import_zod2.z.string().url().optional(),
|
|
685
|
+
state: import_zod2.z.string().optional()
|
|
686
|
+
});
|
|
687
|
+
var AuthorizationServerMetadataSchema = import_zod2.z.object({
|
|
688
|
+
issuer: import_zod2.z.string().url(),
|
|
689
|
+
authorization_endpoint: import_zod2.z.string().url(),
|
|
690
|
+
token_endpoint: import_zod2.z.string().url(),
|
|
691
|
+
registration_endpoint: import_zod2.z.string().url().optional(),
|
|
692
|
+
revocation_endpoint: import_zod2.z.string().url().optional(),
|
|
693
|
+
scopes_supported: import_zod2.z.array(import_zod2.z.string()),
|
|
694
|
+
response_types_supported: import_zod2.z.array(import_zod2.z.string()),
|
|
695
|
+
grant_types_supported: import_zod2.z.array(import_zod2.z.string()),
|
|
696
|
+
token_endpoint_auth_methods_supported: import_zod2.z.array(import_zod2.z.string()),
|
|
697
|
+
code_challenge_methods_supported: import_zod2.z.array(import_zod2.z.string()),
|
|
698
|
+
service_documentation: import_zod2.z.string().url().optional()
|
|
699
|
+
});
|
|
700
|
+
var ProtectedResourceMetadataSchema = import_zod2.z.object({
|
|
701
|
+
resource: import_zod2.z.string().url(),
|
|
702
|
+
authorization_servers: import_zod2.z.array(import_zod2.z.string().url()),
|
|
703
|
+
scopes_supported: import_zod2.z.array(import_zod2.z.string()).optional(),
|
|
704
|
+
bearer_methods_supported: import_zod2.z.array(import_zod2.z.string()).optional(),
|
|
705
|
+
resource_signing_alg_values_supported: import_zod2.z.array(import_zod2.z.string()).optional(),
|
|
706
|
+
resource_documentation: import_zod2.z.string().url().optional()
|
|
707
|
+
});
|
|
708
|
+
var InternalTokenValidationRequestSchema = import_zod2.z.object({
|
|
709
|
+
access_token: import_zod2.z.string().min(1)
|
|
710
|
+
});
|
|
711
|
+
var InternalTokenValidationResponseSchema = import_zod2.z.object({
|
|
712
|
+
valid: import_zod2.z.boolean(),
|
|
713
|
+
userId: import_zod2.z.string().optional(),
|
|
714
|
+
userEmail: import_zod2.z.string().optional(),
|
|
715
|
+
userName: import_zod2.z.string().optional(),
|
|
716
|
+
scope: import_zod2.z.string().optional(),
|
|
717
|
+
permissions: import_zod2.z.string().optional(),
|
|
718
|
+
clientId: import_zod2.z.string().optional(),
|
|
719
|
+
expiresAt: import_zod2.z.string().optional()
|
|
720
|
+
});
|
|
721
|
+
|
|
722
|
+
// ../../packages/core/dist/validation/index.js
|
|
723
|
+
var ListProjectsInputSchema = import_zod3.z.object({
|
|
724
|
+
workspaceType: import_zod3.z.preprocess((val) => typeof val === "string" ? val.toUpperCase() : val, import_zod3.z.enum(["TEAM", "PERSONAL", "ALL"]).optional())
|
|
725
|
+
});
|
|
726
|
+
var ListTasksInputSchema = import_zod3.z.object({
|
|
727
|
+
projectId: import_zod3.z.string().optional(),
|
|
728
|
+
state: import_zod3.z.nativeEnum(TaskState).optional(),
|
|
729
|
+
assigneeId: import_zod3.z.string().optional(),
|
|
730
|
+
includeArchived: import_zod3.z.boolean().optional()
|
|
731
|
+
});
|
|
732
|
+
var cuidOrPrefixedId = import_zod3.z.string().regex(/^([a-z0-9]+|[a-z]+_[a-zA-Z0-9]+)$/);
|
|
733
|
+
var gitBranchName = import_zod3.z.string().min(1).max(100).regex(/^[a-zA-Z0-9][-a-zA-Z0-9._/]*[a-zA-Z0-9]$|^[a-zA-Z0-9]$/, "Branch name must start and end with alphanumeric character").refine((val) => !val.includes("..") && !val.includes("@{") && !val.includes("//") && !val.endsWith(".lock") && !val.includes("~") && !val.includes("^") && !val.includes(":") && !val.includes("?") && !val.includes("*") && !val.includes("[") && !val.includes("\\") && !val.includes(" ") && !val.includes(";") && !val.includes("&") && !val.includes("|") && !val.includes("$") && !val.includes("`") && !val.includes("'") && !val.includes('"') && !val.includes("<") && !val.includes(">") && !val.includes("(") && !val.includes(")"), "Invalid branch name: contains forbidden characters or sequences");
|
|
734
|
+
var GetTaskInputSchema = import_zod3.z.object({
|
|
489
735
|
taskId: cuidOrPrefixedId
|
|
490
736
|
});
|
|
491
|
-
var AssignTaskInputSchema =
|
|
737
|
+
var AssignTaskInputSchema = import_zod3.z.object({
|
|
492
738
|
projectId: cuidOrPrefixedId,
|
|
493
739
|
taskId: cuidOrPrefixedId,
|
|
494
|
-
expectedState:
|
|
740
|
+
expectedState: import_zod3.z.nativeEnum(TaskState).default(TaskState.TODO)
|
|
495
741
|
});
|
|
496
|
-
var UpdateProgressInputSchema =
|
|
742
|
+
var UpdateProgressInputSchema = import_zod3.z.object({
|
|
497
743
|
taskId: cuidOrPrefixedId,
|
|
498
|
-
statusMessage:
|
|
499
|
-
completedCheckpointIds:
|
|
500
|
-
currentCheckpointIndex:
|
|
744
|
+
statusMessage: import_zod3.z.string().max(1e3).optional(),
|
|
745
|
+
completedCheckpointIds: import_zod3.z.array(import_zod3.z.string()).optional(),
|
|
746
|
+
currentCheckpointIndex: import_zod3.z.number().int().optional()
|
|
501
747
|
});
|
|
502
|
-
var CompleteTaskInputSchema =
|
|
748
|
+
var CompleteTaskInputSchema = import_zod3.z.object({
|
|
503
749
|
projectId: cuidOrPrefixedId,
|
|
504
750
|
taskId: cuidOrPrefixedId,
|
|
505
|
-
pullRequestTitle:
|
|
506
|
-
pullRequestBody:
|
|
751
|
+
pullRequestTitle: import_zod3.z.string().min(1).max(300).optional(),
|
|
752
|
+
pullRequestBody: import_zod3.z.string().max(1e4).optional()
|
|
507
753
|
});
|
|
508
|
-
var ReportErrorInputSchema =
|
|
754
|
+
var ReportErrorInputSchema = import_zod3.z.object({
|
|
509
755
|
taskId: cuidOrPrefixedId,
|
|
510
|
-
errorType:
|
|
511
|
-
errorMessage:
|
|
512
|
-
context:
|
|
756
|
+
errorType: import_zod3.z.nativeEnum(ErrorType),
|
|
757
|
+
errorMessage: import_zod3.z.string().min(1).max(1e3),
|
|
758
|
+
context: import_zod3.z.string().max(2e3).optional()
|
|
513
759
|
});
|
|
514
|
-
var GetProjectContextInputSchema =
|
|
760
|
+
var GetProjectContextInputSchema = import_zod3.z.object({
|
|
515
761
|
projectId: cuidOrPrefixedId
|
|
516
762
|
});
|
|
517
|
-
var AddNoteInputSchema =
|
|
763
|
+
var AddNoteInputSchema = import_zod3.z.object({
|
|
518
764
|
taskId: cuidOrPrefixedId,
|
|
519
|
-
content:
|
|
765
|
+
content: import_zod3.z.string().min(1).max(500)
|
|
520
766
|
});
|
|
521
|
-
var AbandonTaskInputSchema =
|
|
767
|
+
var AbandonTaskInputSchema = import_zod3.z.object({
|
|
522
768
|
projectId: cuidOrPrefixedId,
|
|
523
769
|
taskId: cuidOrPrefixedId,
|
|
524
|
-
deleteBranch:
|
|
770
|
+
deleteBranch: import_zod3.z.boolean().optional()
|
|
525
771
|
});
|
|
526
|
-
var RequestChangesInputSchema =
|
|
772
|
+
var RequestChangesInputSchema = import_zod3.z.object({
|
|
527
773
|
projectId: cuidOrPrefixedId,
|
|
528
774
|
taskId: cuidOrPrefixedId,
|
|
529
|
-
reviewComments:
|
|
530
|
-
requestedChanges:
|
|
775
|
+
reviewComments: import_zod3.z.string().min(1).max(5e3),
|
|
776
|
+
requestedChanges: import_zod3.z.array(import_zod3.z.string().min(1).max(500)).optional()
|
|
531
777
|
});
|
|
532
|
-
var ApproveTaskInputSchema =
|
|
778
|
+
var ApproveTaskInputSchema = import_zod3.z.object({
|
|
533
779
|
projectId: cuidOrPrefixedId,
|
|
534
780
|
taskId: cuidOrPrefixedId,
|
|
535
|
-
reviewComments:
|
|
781
|
+
reviewComments: import_zod3.z.string().max(2e3).optional()
|
|
536
782
|
});
|
|
537
|
-
var ArchiveTaskInputSchema =
|
|
783
|
+
var ArchiveTaskInputSchema = import_zod3.z.object({
|
|
538
784
|
projectId: cuidOrPrefixedId,
|
|
539
785
|
taskId: cuidOrPrefixedId
|
|
540
786
|
});
|
|
541
|
-
var UnarchiveTaskInputSchema =
|
|
787
|
+
var UnarchiveTaskInputSchema = import_zod3.z.object({
|
|
542
788
|
projectId: cuidOrPrefixedId,
|
|
543
789
|
taskId: cuidOrPrefixedId
|
|
544
790
|
});
|
|
545
|
-
var CreatePersonalProjectInputSchema =
|
|
546
|
-
name:
|
|
547
|
-
description:
|
|
548
|
-
repositoryUrl:
|
|
791
|
+
var CreatePersonalProjectInputSchema = import_zod3.z.object({
|
|
792
|
+
name: import_zod3.z.string().min(1).max(100),
|
|
793
|
+
description: import_zod3.z.string().max(500).optional(),
|
|
794
|
+
repositoryUrl: import_zod3.z.string().url()
|
|
549
795
|
});
|
|
550
|
-
var CheckActiveTaskInputSchema =
|
|
551
|
-
var CreateTaskMCPInputSchema =
|
|
796
|
+
var CheckActiveTaskInputSchema = import_zod3.z.object({});
|
|
797
|
+
var CreateTaskMCPInputSchema = import_zod3.z.object({
|
|
552
798
|
projectId: cuidOrPrefixedId,
|
|
553
799
|
epicId: cuidOrPrefixedId.nullable().optional(),
|
|
554
|
-
title:
|
|
555
|
-
description:
|
|
556
|
-
priority:
|
|
557
|
-
acceptanceCriteria:
|
|
558
|
-
description:
|
|
800
|
+
title: import_zod3.z.string().min(1).max(200),
|
|
801
|
+
description: import_zod3.z.string().max(5e3),
|
|
802
|
+
priority: import_zod3.z.nativeEnum(TaskPriority).default(TaskPriority.MEDIUM),
|
|
803
|
+
acceptanceCriteria: import_zod3.z.array(import_zod3.z.object({
|
|
804
|
+
description: import_zod3.z.string().min(1).max(500)
|
|
559
805
|
})).min(1)
|
|
560
806
|
});
|
|
561
|
-
var CreateOrganizationInputSchema =
|
|
562
|
-
name:
|
|
563
|
-
slug: import_zod2.z.string().min(1).max(100).regex(/^[a-z0-9-]+$/).optional()
|
|
807
|
+
var CreateOrganizationInputSchema = import_zod3.z.object({
|
|
808
|
+
name: import_zod3.z.string().min(1).max(255)
|
|
564
809
|
});
|
|
565
|
-
var UpdateOrganizationInputSchema =
|
|
810
|
+
var UpdateOrganizationInputSchema = import_zod3.z.object({
|
|
566
811
|
organizationId: cuidOrPrefixedId,
|
|
567
|
-
name:
|
|
568
|
-
logoUrl:
|
|
569
|
-
accentColor:
|
|
570
|
-
tenantName:
|
|
571
|
-
});
|
|
572
|
-
var CreateProjectInputSchema =
|
|
573
|
-
name:
|
|
574
|
-
description:
|
|
575
|
-
type:
|
|
576
|
-
repositoryUrl:
|
|
577
|
-
baseBranch:
|
|
578
|
-
tags:
|
|
579
|
-
});
|
|
580
|
-
var UpdateProjectInputSchema =
|
|
581
|
-
projectId:
|
|
582
|
-
name:
|
|
583
|
-
description:
|
|
584
|
-
repositoryUrl:
|
|
585
|
-
baseBranch:
|
|
586
|
-
tags:
|
|
587
|
-
allowMemberArchive:
|
|
588
|
-
|
|
589
|
-
|
|
812
|
+
name: import_zod3.z.string().min(1).max(255).optional(),
|
|
813
|
+
logoUrl: import_zod3.z.string().url().nullable().optional(),
|
|
814
|
+
accentColor: import_zod3.z.string().regex(/^#[0-9A-Fa-f]{6}$/, "Invalid hex color format. Expected #RRGGBB").nullable().optional(),
|
|
815
|
+
tenantName: import_zod3.z.string().max(255).nullable().optional()
|
|
816
|
+
});
|
|
817
|
+
var CreateProjectInputSchema = import_zod3.z.object({
|
|
818
|
+
name: import_zod3.z.string().min(1).max(100),
|
|
819
|
+
description: import_zod3.z.string().max(500).optional(),
|
|
820
|
+
type: import_zod3.z.nativeEnum(ProjectType),
|
|
821
|
+
repositoryUrl: import_zod3.z.string().url(),
|
|
822
|
+
baseBranch: import_zod3.z.string().default("develop").optional(),
|
|
823
|
+
tags: import_zod3.z.array(import_zod3.z.string()).default([])
|
|
824
|
+
});
|
|
825
|
+
var UpdateProjectInputSchema = import_zod3.z.object({
|
|
826
|
+
projectId: import_zod3.z.string().min(1).optional(),
|
|
827
|
+
name: import_zod3.z.string().min(1).max(100).optional(),
|
|
828
|
+
description: import_zod3.z.string().max(500).optional(),
|
|
829
|
+
repositoryUrl: import_zod3.z.string().url().optional(),
|
|
830
|
+
baseBranch: import_zod3.z.string().optional(),
|
|
831
|
+
tags: import_zod3.z.array(import_zod3.z.string()).optional(),
|
|
832
|
+
allowMemberArchive: import_zod3.z.boolean().optional(),
|
|
833
|
+
localRepoPath: import_zod3.z.string().max(500).optional()
|
|
834
|
+
});
|
|
835
|
+
var CreateEpicInputSchema = import_zod3.z.object({
|
|
590
836
|
projectId: cuidOrPrefixedId,
|
|
591
|
-
name:
|
|
592
|
-
description:
|
|
593
|
-
});
|
|
594
|
-
var CreateTaskInputSchema =
|
|
595
|
-
projectId:
|
|
596
|
-
epicId:
|
|
597
|
-
title:
|
|
598
|
-
description:
|
|
599
|
-
priority:
|
|
600
|
-
acceptanceCriteria:
|
|
601
|
-
description:
|
|
837
|
+
name: import_zod3.z.string().min(1).max(200),
|
|
838
|
+
description: import_zod3.z.string().max(2e3).optional()
|
|
839
|
+
});
|
|
840
|
+
var CreateTaskInputSchema = import_zod3.z.object({
|
|
841
|
+
projectId: import_zod3.z.string().min(1),
|
|
842
|
+
epicId: import_zod3.z.string().min(1).nullable().optional(),
|
|
843
|
+
title: import_zod3.z.string().min(1).max(200),
|
|
844
|
+
description: import_zod3.z.string().max(5e3),
|
|
845
|
+
priority: import_zod3.z.nativeEnum(TaskPriority).default(TaskPriority.MEDIUM),
|
|
846
|
+
acceptanceCriteria: import_zod3.z.array(import_zod3.z.object({
|
|
847
|
+
description: import_zod3.z.string().min(1).max(500)
|
|
602
848
|
})).min(1)
|
|
603
849
|
});
|
|
604
|
-
var UpdateTaskInputSchema =
|
|
605
|
-
taskId:
|
|
606
|
-
title:
|
|
607
|
-
description:
|
|
608
|
-
priority:
|
|
609
|
-
state:
|
|
610
|
-
assigneeId:
|
|
611
|
-
acceptanceCriteria:
|
|
612
|
-
id:
|
|
613
|
-
description:
|
|
614
|
-
completed:
|
|
850
|
+
var UpdateTaskInputSchema = import_zod3.z.object({
|
|
851
|
+
taskId: import_zod3.z.string().min(1),
|
|
852
|
+
title: import_zod3.z.string().min(1).max(200).optional(),
|
|
853
|
+
description: import_zod3.z.string().max(5e3).optional(),
|
|
854
|
+
priority: import_zod3.z.nativeEnum(TaskPriority).optional(),
|
|
855
|
+
state: import_zod3.z.nativeEnum(TaskState).optional(),
|
|
856
|
+
assigneeId: import_zod3.z.string().nullable().optional(),
|
|
857
|
+
acceptanceCriteria: import_zod3.z.array(import_zod3.z.object({
|
|
858
|
+
id: import_zod3.z.string().optional(),
|
|
859
|
+
description: import_zod3.z.string().min(1).max(500),
|
|
860
|
+
completed: import_zod3.z.boolean().optional()
|
|
615
861
|
})).optional()
|
|
616
862
|
});
|
|
617
|
-
var AssignTaskWebappInputSchema =
|
|
618
|
-
taskId:
|
|
619
|
-
userId:
|
|
863
|
+
var AssignTaskWebappInputSchema = import_zod3.z.object({
|
|
864
|
+
taskId: import_zod3.z.string().min(1),
|
|
865
|
+
userId: import_zod3.z.string().min(1)
|
|
620
866
|
});
|
|
621
|
-
var CreateTagInputSchema =
|
|
867
|
+
var CreateTagInputSchema = import_zod3.z.object({
|
|
622
868
|
organizationId: cuidOrPrefixedId,
|
|
623
|
-
name:
|
|
869
|
+
name: import_zod3.z.string().min(1).max(50).regex(/^[a-zA-Z0-9\s-]+$/)
|
|
624
870
|
});
|
|
625
|
-
var UpdateTagInputSchema =
|
|
626
|
-
name:
|
|
871
|
+
var UpdateTagInputSchema = import_zod3.z.object({
|
|
872
|
+
name: import_zod3.z.string().min(1).max(50).regex(/^[a-zA-Z0-9\s-]+$/)
|
|
627
873
|
});
|
|
628
|
-
var UpdateOrganizationSettingsInputSchema =
|
|
874
|
+
var UpdateOrganizationSettingsInputSchema = import_zod3.z.object({
|
|
629
875
|
organizationId: cuidOrPrefixedId,
|
|
630
|
-
ldapEnabled:
|
|
631
|
-
ldapUrl:
|
|
632
|
-
ldapBindDN:
|
|
633
|
-
ldapSearchBase:
|
|
634
|
-
deleteMergedBranches:
|
|
635
|
-
enforceConventionalCommits:
|
|
636
|
-
maxPersonalProjectsPerUser:
|
|
637
|
-
logoUrl:
|
|
638
|
-
accentColor:
|
|
639
|
-
tenantName:
|
|
640
|
-
});
|
|
641
|
-
var InviteUserInputSchema =
|
|
876
|
+
ldapEnabled: import_zod3.z.boolean().optional(),
|
|
877
|
+
ldapUrl: import_zod3.z.string().url().nullable().optional(),
|
|
878
|
+
ldapBindDN: import_zod3.z.string().nullable().optional(),
|
|
879
|
+
ldapSearchBase: import_zod3.z.string().nullable().optional(),
|
|
880
|
+
deleteMergedBranches: import_zod3.z.boolean().optional(),
|
|
881
|
+
enforceConventionalCommits: import_zod3.z.boolean().optional(),
|
|
882
|
+
maxPersonalProjectsPerUser: import_zod3.z.number().int().min(0).optional(),
|
|
883
|
+
logoUrl: import_zod3.z.string().url().nullable().optional(),
|
|
884
|
+
accentColor: import_zod3.z.string().regex(/^#[0-9A-Fa-f]{6}$/, "Invalid hex color format. Expected #RRGGBB").nullable().optional(),
|
|
885
|
+
tenantName: import_zod3.z.string().max(255).nullable().optional()
|
|
886
|
+
});
|
|
887
|
+
var InviteUserInputSchema = import_zod3.z.object({
|
|
642
888
|
organizationId: cuidOrPrefixedId,
|
|
643
|
-
email:
|
|
644
|
-
role:
|
|
645
|
-
tags:
|
|
889
|
+
email: import_zod3.z.string().email(),
|
|
890
|
+
role: import_zod3.z.nativeEnum(UserRole).default(UserRole.MEMBER),
|
|
891
|
+
tags: import_zod3.z.array(import_zod3.z.string()).default([])
|
|
646
892
|
});
|
|
647
|
-
var AssignUserTagsInputSchema =
|
|
893
|
+
var AssignUserTagsInputSchema = import_zod3.z.object({
|
|
648
894
|
userId: cuidOrPrefixedId,
|
|
649
|
-
tags:
|
|
895
|
+
tags: import_zod3.z.array(import_zod3.z.string()).min(0)
|
|
650
896
|
});
|
|
651
|
-
var InviteCollaboratorInputSchema =
|
|
897
|
+
var InviteCollaboratorInputSchema = import_zod3.z.object({
|
|
652
898
|
projectId: cuidOrPrefixedId,
|
|
653
|
-
email:
|
|
899
|
+
email: import_zod3.z.string().email()
|
|
654
900
|
});
|
|
655
|
-
var PublishProjectInputSchema =
|
|
901
|
+
var PublishProjectInputSchema = import_zod3.z.object({
|
|
656
902
|
projectId: cuidOrPrefixedId,
|
|
657
|
-
transferOwnership:
|
|
658
|
-
tags:
|
|
903
|
+
transferOwnership: import_zod3.z.boolean().default(false),
|
|
904
|
+
tags: import_zod3.z.array(import_zod3.z.string()).min(1)
|
|
659
905
|
});
|
|
660
|
-
var GenerateApiKeyInputSchema =
|
|
661
|
-
name:
|
|
662
|
-
|
|
663
|
-
|
|
906
|
+
var GenerateApiKeyInputSchema = import_zod3.z.object({
|
|
907
|
+
name: import_zod3.z.string().min(1).max(100),
|
|
908
|
+
publicNickname: import_zod3.z.string().max(50).optional(),
|
|
909
|
+
expiresInDays: import_zod3.z.number().int().min(1).max(365).default(90),
|
|
910
|
+
permissions: import_zod3.z.nativeEnum(ApiKeyPermission).default(ApiKeyPermission.WRITE)
|
|
664
911
|
});
|
|
665
|
-
var
|
|
912
|
+
var UpdateApiKeyInputSchema = import_zod3.z.object({
|
|
913
|
+
publicNickname: import_zod3.z.string().max(50).nullable().optional(),
|
|
914
|
+
scopedOrganizationId: import_zod3.z.string().optional().nullable(),
|
|
915
|
+
scopedProjectIds: import_zod3.z.array(import_zod3.z.string()).optional()
|
|
916
|
+
});
|
|
917
|
+
var RevokeApiKeyInputSchema = import_zod3.z.object({
|
|
666
918
|
keyId: cuidOrPrefixedId
|
|
667
919
|
});
|
|
668
|
-
var LoginInputSchema =
|
|
669
|
-
email:
|
|
670
|
-
password:
|
|
920
|
+
var LoginInputSchema = import_zod3.z.object({
|
|
921
|
+
email: import_zod3.z.string().email(),
|
|
922
|
+
password: import_zod3.z.string().min(8).max(255)
|
|
671
923
|
});
|
|
672
|
-
var RegisterInputSchema =
|
|
673
|
-
email:
|
|
674
|
-
password:
|
|
675
|
-
name:
|
|
676
|
-
organizationSlug: import_zod2.z.string().min(1).max(100).regex(/^[a-z0-9-]+$/).optional()
|
|
924
|
+
var RegisterInputSchema = import_zod3.z.object({
|
|
925
|
+
email: import_zod3.z.string().email(),
|
|
926
|
+
password: import_zod3.z.string().min(8).max(255),
|
|
927
|
+
name: import_zod3.z.string().min(1).max(255)
|
|
677
928
|
});
|
|
678
|
-
var VerifyTaskInputSchema =
|
|
929
|
+
var VerifyTaskInputSchema = import_zod3.z.object({
|
|
679
930
|
projectId: cuidOrPrefixedId,
|
|
680
931
|
taskId: cuidOrPrefixedId,
|
|
681
|
-
approved:
|
|
682
|
-
feedback:
|
|
932
|
+
approved: import_zod3.z.boolean(),
|
|
933
|
+
feedback: import_zod3.z.string().max(5e3).optional()
|
|
683
934
|
});
|
|
684
|
-
var GetTaskPromptInputSchema =
|
|
935
|
+
var GetTaskPromptInputSchema = import_zod3.z.object({
|
|
685
936
|
projectId: cuidOrPrefixedId,
|
|
686
937
|
taskId: cuidOrPrefixedId
|
|
687
938
|
});
|
|
688
|
-
var UpdateTaskMCPInputSchema =
|
|
939
|
+
var UpdateTaskMCPInputSchema = import_zod3.z.object({
|
|
689
940
|
projectId: cuidOrPrefixedId,
|
|
690
941
|
taskId: cuidOrPrefixedId,
|
|
691
|
-
title:
|
|
692
|
-
description:
|
|
693
|
-
priority:
|
|
694
|
-
acceptanceCriteria:
|
|
695
|
-
id:
|
|
696
|
-
description:
|
|
942
|
+
title: import_zod3.z.string().min(1).max(200).optional(),
|
|
943
|
+
description: import_zod3.z.string().max(5e3).optional(),
|
|
944
|
+
priority: import_zod3.z.nativeEnum(TaskPriority).optional(),
|
|
945
|
+
acceptanceCriteria: import_zod3.z.array(import_zod3.z.object({
|
|
946
|
+
id: import_zod3.z.string().optional(),
|
|
947
|
+
description: import_zod3.z.string().min(1).max(500)
|
|
697
948
|
})).optional()
|
|
698
949
|
});
|
|
699
|
-
var ReportBranchInputSchema =
|
|
950
|
+
var ReportBranchInputSchema = import_zod3.z.object({
|
|
700
951
|
projectId: cuidOrPrefixedId,
|
|
701
952
|
taskId: cuidOrPrefixedId,
|
|
702
953
|
branchName: gitBranchName
|
|
703
954
|
});
|
|
704
|
-
var ReportPRInputSchema =
|
|
955
|
+
var ReportPRInputSchema = import_zod3.z.object({
|
|
705
956
|
projectId: cuidOrPrefixedId,
|
|
706
957
|
taskId: cuidOrPrefixedId,
|
|
707
|
-
pullRequestUrl:
|
|
708
|
-
pullRequestNumber:
|
|
958
|
+
pullRequestUrl: import_zod3.z.string().url(),
|
|
959
|
+
pullRequestNumber: import_zod3.z.number().int().positive()
|
|
709
960
|
});
|
|
710
961
|
|
|
711
962
|
// ../../packages/core/dist/logging/metrics.js
|
|
@@ -786,23 +1037,20 @@ function createHistogram(name, help, buckets = [5e-3, 0.01, 0.025, 0.05, 0.1, 0.
|
|
|
786
1037
|
var httpRequestsTotal = createCounter("mtaap_http_requests_total", "Total number of HTTP requests");
|
|
787
1038
|
var httpRequestDuration = createHistogram("mtaap_http_request_duration_seconds", "HTTP request duration in seconds");
|
|
788
1039
|
var activeUsers = createGauge("mtaap_active_users", "Number of active users");
|
|
789
|
-
var tasksTotal = createCounter("mtaap_tasks_total", "Total number of tasks by state");
|
|
790
|
-
var taskStateChanges = createCounter("mtaap_task_state_changes_total", "Total number of task state changes");
|
|
791
1040
|
var httpErrorsTotal = createCounter("mtaap_http_errors_total", "Total number of HTTP errors");
|
|
792
1041
|
var httpActiveConnections = createGauge("mtaap_http_active_connections", "Number of active HTTP connections");
|
|
793
1042
|
var newSignupsTotal = createCounter("mtaap_new_signups_total", "Total number of new user signups");
|
|
794
1043
|
var loginSuccessTotal = createCounter("mtaap_login_success_total", "Total number of successful logins");
|
|
795
1044
|
var loginFailureTotal = createCounter("mtaap_login_failure_total", "Total number of failed logins");
|
|
796
|
-
var dbConnectionPoolActive = createGauge("mtaap_db_connection_pool_active", "Number of active database connections");
|
|
797
|
-
var dbConnectionPoolIdle = createGauge("mtaap_db_connection_pool_idle", "Number of idle database connections");
|
|
798
|
-
var dbConnectionPoolMax = createGauge("mtaap_db_connection_pool_max", "Maximum number of database connections");
|
|
799
1045
|
var dbQueryDuration = createHistogram("mtaap_db_query_duration_seconds", "Database query duration in seconds");
|
|
800
1046
|
var dbSlowQueriesTotal = createCounter("mtaap_db_slow_queries_total", "Total number of slow database queries (>1s)");
|
|
801
|
-
var dbErrorsTotal = createCounter("mtaap_db_errors_total", "Total number of database errors");
|
|
802
1047
|
var tasksCreatedTotal = createCounter("mtaap_tasks_created_total", "Total number of tasks created");
|
|
803
1048
|
var tasksAssignedTotal = createCounter("mtaap_tasks_assigned_total", "Total number of tasks assigned");
|
|
804
1049
|
var tasksCompletedTotal = createCounter("mtaap_tasks_completed_total", "Total number of tasks completed");
|
|
805
|
-
var
|
|
1050
|
+
var agentSessionsTotal = createCounter("mtaap_agent_sessions_total", "Total number of agent sessions started");
|
|
1051
|
+
var agentErrorsTotal = createCounter("mtaap_agent_errors_total", "Total number of agent errors");
|
|
1052
|
+
var agentSessionDuration = createHistogram("mtaap_agent_session_duration_seconds", "Agent session duration in seconds", [1, 5, 15, 30, 60, 120, 300, 600, 1800, 3600]);
|
|
1053
|
+
var agentSessionsActive = createGauge("mtaap_agent_sessions_active", "Number of currently active agent sessions");
|
|
806
1054
|
|
|
807
1055
|
// ../../packages/core/dist/logging/performance-monitor.js
|
|
808
1056
|
var MAX_SAMPLES = 1e3;
|
|
@@ -1006,6 +1254,9 @@ var errorTrackerInstance = new NoOpErrorTracker();
|
|
|
1006
1254
|
|
|
1007
1255
|
// src/api-client.ts
|
|
1008
1256
|
var DEFAULT_TIMEOUT = 3e4;
|
|
1257
|
+
var DEFAULT_CACHE_TTL = 3e4;
|
|
1258
|
+
var MAX_RETRIES = 2;
|
|
1259
|
+
var INITIAL_RETRY_DELAY = 500;
|
|
1009
1260
|
function sanitizeForLogging(str) {
|
|
1010
1261
|
let sanitized = str.replace(/\bcollab_[a-zA-Z0-9_-]+\b/gi, "[REDACTED_API_KEY]");
|
|
1011
1262
|
sanitized = sanitized.replace(/\bBearer\s+[a-zA-Z0-9._-]+\b/gi, "Bearer [REDACTED]");
|
|
@@ -1020,42 +1271,113 @@ var ApiError = class extends Error {
|
|
|
1020
1271
|
this.details = details;
|
|
1021
1272
|
this.name = "ApiError";
|
|
1022
1273
|
}
|
|
1274
|
+
/**
|
|
1275
|
+
* Whether this error is transient and the request can be retried.
|
|
1276
|
+
* Retries on network errors (status 0), timeouts (408), and server errors (5xx).
|
|
1277
|
+
*/
|
|
1278
|
+
get isRetryable() {
|
|
1279
|
+
return this.status === 0 || this.status === 408 || this.status >= 500;
|
|
1280
|
+
}
|
|
1023
1281
|
};
|
|
1282
|
+
function sleep(ms) {
|
|
1283
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
1284
|
+
}
|
|
1024
1285
|
var MCPApiClient = class {
|
|
1025
1286
|
baseUrl;
|
|
1026
1287
|
apiKey;
|
|
1288
|
+
oauthToken;
|
|
1027
1289
|
timeout;
|
|
1028
1290
|
debug;
|
|
1029
1291
|
authContext = null;
|
|
1292
|
+
cache = /* @__PURE__ */ new Map();
|
|
1030
1293
|
constructor(config3) {
|
|
1294
|
+
if (!config3.apiKey && !config3.oauthToken) {
|
|
1295
|
+
throw new Error("Either apiKey or oauthToken must be provided");
|
|
1296
|
+
}
|
|
1031
1297
|
this.baseUrl = config3.baseUrl.replace(/\/$/, "");
|
|
1032
1298
|
this.apiKey = config3.apiKey;
|
|
1299
|
+
this.oauthToken = config3.oauthToken;
|
|
1033
1300
|
this.timeout = config3.timeout ?? DEFAULT_TIMEOUT;
|
|
1034
1301
|
this.debug = config3.debug ?? false;
|
|
1035
1302
|
}
|
|
1036
1303
|
/**
|
|
1037
|
-
*
|
|
1304
|
+
* Get a cached value if it exists and hasn't expired.
|
|
1305
|
+
*/
|
|
1306
|
+
getCached(key) {
|
|
1307
|
+
const entry = this.cache.get(key);
|
|
1308
|
+
if (!entry) return void 0;
|
|
1309
|
+
if (Date.now() > entry.expiresAt) {
|
|
1310
|
+
this.cache.delete(key);
|
|
1311
|
+
return void 0;
|
|
1312
|
+
}
|
|
1313
|
+
return entry.data;
|
|
1314
|
+
}
|
|
1315
|
+
/**
|
|
1316
|
+
* Store a value in cache with a TTL.
|
|
1038
1317
|
*/
|
|
1039
|
-
|
|
1040
|
-
|
|
1318
|
+
setCache(key, data, ttl = DEFAULT_CACHE_TTL) {
|
|
1319
|
+
this.cache.set(key, { data, expiresAt: Date.now() + ttl });
|
|
1320
|
+
}
|
|
1321
|
+
/**
|
|
1322
|
+
* Make an HTTP request to the API with automatic retry on transient failures.
|
|
1323
|
+
*/
|
|
1324
|
+
async request(method, path2, body) {
|
|
1325
|
+
let lastError;
|
|
1326
|
+
for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
|
|
1327
|
+
try {
|
|
1328
|
+
return await this.requestOnce(method, path2, body);
|
|
1329
|
+
} catch (error) {
|
|
1330
|
+
if (!(error instanceof ApiError) || !error.isRetryable || attempt === MAX_RETRIES) {
|
|
1331
|
+
throw error;
|
|
1332
|
+
}
|
|
1333
|
+
lastError = error;
|
|
1334
|
+
const delay = INITIAL_RETRY_DELAY * Math.pow(2, attempt);
|
|
1335
|
+
if (this.debug) {
|
|
1336
|
+
console.error(`[mcp-api] Retry ${attempt + 1}/${MAX_RETRIES} after ${delay}ms (${lastError.code})`);
|
|
1337
|
+
}
|
|
1338
|
+
await sleep(delay);
|
|
1339
|
+
}
|
|
1340
|
+
}
|
|
1341
|
+
throw lastError;
|
|
1342
|
+
}
|
|
1343
|
+
/**
|
|
1344
|
+
* Execute a single HTTP request to the API.
|
|
1345
|
+
*/
|
|
1346
|
+
async requestOnce(method, path2, body) {
|
|
1347
|
+
const url = `${this.baseUrl}${path2}`;
|
|
1041
1348
|
const controller = new AbortController();
|
|
1042
1349
|
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
1043
1350
|
if (this.debug) {
|
|
1044
|
-
console.error(`[mcp-api] ${method} ${sanitizeForLogging(
|
|
1351
|
+
console.error(`[mcp-api] ${method} ${sanitizeForLogging(path2)}`);
|
|
1045
1352
|
}
|
|
1046
1353
|
try {
|
|
1354
|
+
const headers = {
|
|
1355
|
+
"Content-Type": "application/json"
|
|
1356
|
+
};
|
|
1357
|
+
if (this.oauthToken) {
|
|
1358
|
+
headers["Authorization"] = `Bearer ${this.oauthToken}`;
|
|
1359
|
+
} else if (this.apiKey) {
|
|
1360
|
+
headers["X-API-Key"] = this.apiKey;
|
|
1361
|
+
}
|
|
1047
1362
|
const response = await fetch(url, {
|
|
1048
1363
|
method,
|
|
1049
|
-
headers
|
|
1050
|
-
"Content-Type": "application/json",
|
|
1051
|
-
"X-API-Key": this.apiKey
|
|
1052
|
-
},
|
|
1364
|
+
headers,
|
|
1053
1365
|
body: body ? JSON.stringify(body) : void 0,
|
|
1054
1366
|
signal: controller.signal
|
|
1055
1367
|
});
|
|
1056
1368
|
clearTimeout(timeoutId);
|
|
1057
1369
|
const data = await response.json();
|
|
1058
1370
|
if (!response.ok) {
|
|
1371
|
+
if (response.status === 403 && data.code === "EMAIL_NOT_VERIFIED" && data.verificationUrl) {
|
|
1372
|
+
throw new ApiError(
|
|
1373
|
+
`${data.error}
|
|
1374
|
+
|
|
1375
|
+
To verify your email, visit: ${data.verificationUrl}
|
|
1376
|
+
${data.hint ? `Hint: ${data.hint}` : ""}`,
|
|
1377
|
+
"EMAIL_NOT_VERIFIED",
|
|
1378
|
+
403
|
|
1379
|
+
);
|
|
1380
|
+
}
|
|
1059
1381
|
throw new ApiError(
|
|
1060
1382
|
data.error || "API request failed",
|
|
1061
1383
|
data.code || "UNKNOWN_ERROR",
|
|
@@ -1102,14 +1424,19 @@ var MCPApiClient = class {
|
|
|
1102
1424
|
return this.authenticate();
|
|
1103
1425
|
}
|
|
1104
1426
|
/**
|
|
1105
|
-
* List accessible projects
|
|
1427
|
+
* List accessible projects (cached for 30s)
|
|
1106
1428
|
*/
|
|
1107
1429
|
async listProjects(workspaceType) {
|
|
1108
1430
|
const type = workspaceType || "ALL";
|
|
1109
|
-
|
|
1431
|
+
const cacheKey = `listProjects:${type}`;
|
|
1432
|
+
const cached = this.getCached(cacheKey);
|
|
1433
|
+
if (cached) return cached;
|
|
1434
|
+
const result = await this.request(
|
|
1110
1435
|
"GET",
|
|
1111
1436
|
`/api/mcp/projects?workspaceType=${encodeURIComponent(type)}`
|
|
1112
1437
|
);
|
|
1438
|
+
this.setCache(cacheKey, result);
|
|
1439
|
+
return result;
|
|
1113
1440
|
}
|
|
1114
1441
|
/**
|
|
1115
1442
|
* Get single project details
|
|
@@ -1118,13 +1445,18 @@ var MCPApiClient = class {
|
|
|
1118
1445
|
return this.request("GET", `/api/mcp/projects/${projectId}`);
|
|
1119
1446
|
}
|
|
1120
1447
|
/**
|
|
1121
|
-
* Get project context (README, stack, conventions)
|
|
1448
|
+
* Get project context (README, stack, conventions) (cached for 60s)
|
|
1122
1449
|
*/
|
|
1123
1450
|
async getProjectContext(projectId) {
|
|
1124
|
-
|
|
1451
|
+
const cacheKey = `projectContext:${projectId}`;
|
|
1452
|
+
const cached = this.getCached(cacheKey);
|
|
1453
|
+
if (cached) return cached;
|
|
1454
|
+
const result = await this.request(
|
|
1125
1455
|
"GET",
|
|
1126
1456
|
`/api/mcp/projects/${projectId}/context`
|
|
1127
1457
|
);
|
|
1458
|
+
this.setCache(cacheKey, result, 6e4);
|
|
1459
|
+
return result;
|
|
1128
1460
|
}
|
|
1129
1461
|
/**
|
|
1130
1462
|
* Create a personal project
|
|
@@ -1152,8 +1484,8 @@ var MCPApiClient = class {
|
|
|
1152
1484
|
if (filters.assigneeId) params.set("assigneeId", filters.assigneeId);
|
|
1153
1485
|
if (filters.includeArchived) params.set("includeArchived", "true");
|
|
1154
1486
|
const queryString = params.toString();
|
|
1155
|
-
const
|
|
1156
|
-
return this.request("GET",
|
|
1487
|
+
const path2 = queryString ? `/api/mcp/tasks?${queryString}` : "/api/mcp/tasks";
|
|
1488
|
+
return this.request("GET", path2);
|
|
1157
1489
|
}
|
|
1158
1490
|
/**
|
|
1159
1491
|
* Get full task details
|
|
@@ -1286,7 +1618,8 @@ var MCPApiClient = class {
|
|
|
1286
1618
|
);
|
|
1287
1619
|
}
|
|
1288
1620
|
/**
|
|
1289
|
-
* Update task details (DRAFT/TODO states only)
|
|
1621
|
+
* Update task details (DRAFT/TODO states only).
|
|
1622
|
+
* Task stays in its current state.
|
|
1290
1623
|
*/
|
|
1291
1624
|
async updateTask(taskId, projectId, data) {
|
|
1292
1625
|
return this.request("PATCH", `/api/mcp/tasks/${taskId}`, {
|
|
@@ -1318,7 +1651,7 @@ var PERMISSION_RANK = {
|
|
|
1318
1651
|
ADMIN: 3
|
|
1319
1652
|
};
|
|
1320
1653
|
function assertApiKeyPermission(apiKey, required, toolName) {
|
|
1321
|
-
const actualRank = PERMISSION_RANK[apiKey.permissions] ?? 0;
|
|
1654
|
+
const actualRank = apiKey.permissions ? PERMISSION_RANK[apiKey.permissions] ?? 0 : 0;
|
|
1322
1655
|
const requiredRank = PERMISSION_RANK[required] ?? 0;
|
|
1323
1656
|
if (actualRank >= requiredRank) {
|
|
1324
1657
|
return;
|
|
@@ -1336,6 +1669,454 @@ function assertApiKeyPermission(apiKey, required, toolName) {
|
|
|
1336
1669
|
throw error;
|
|
1337
1670
|
}
|
|
1338
1671
|
|
|
1672
|
+
// src/apps/task-details.ts
|
|
1673
|
+
var import_server2 = require("@modelcontextprotocol/ext-apps/server");
|
|
1674
|
+
var import_zod4 = require("zod");
|
|
1675
|
+
|
|
1676
|
+
// src/apps/helpers.ts
|
|
1677
|
+
var import_server = require("@modelcontextprotocol/ext-apps/server");
|
|
1678
|
+
var import_promises = __toESM(require("fs/promises"));
|
|
1679
|
+
var import_node_path = __toESM(require("path"));
|
|
1680
|
+
var import_node_url = require("url");
|
|
1681
|
+
var import_meta = {};
|
|
1682
|
+
var getDirname = () => {
|
|
1683
|
+
try {
|
|
1684
|
+
return import_node_path.default.dirname((0, import_node_url.fileURLToPath)(import_meta.url));
|
|
1685
|
+
} catch {
|
|
1686
|
+
return __dirname;
|
|
1687
|
+
}
|
|
1688
|
+
};
|
|
1689
|
+
function getAppHtmlPath(htmlFileName) {
|
|
1690
|
+
return import_node_path.default.join(getDirname(), "apps", htmlFileName);
|
|
1691
|
+
}
|
|
1692
|
+
function registerAppHtmlResource(server, config3) {
|
|
1693
|
+
(0, import_server.registerAppResource)(
|
|
1694
|
+
server,
|
|
1695
|
+
config3.name,
|
|
1696
|
+
config3.uri,
|
|
1697
|
+
{
|
|
1698
|
+
mimeType: import_server.RESOURCE_MIME_TYPE,
|
|
1699
|
+
description: config3.description
|
|
1700
|
+
},
|
|
1701
|
+
async () => {
|
|
1702
|
+
const htmlPath = getAppHtmlPath(config3.htmlFileName);
|
|
1703
|
+
try {
|
|
1704
|
+
const html = await import_promises.default.readFile(htmlPath, "utf-8");
|
|
1705
|
+
return {
|
|
1706
|
+
contents: [
|
|
1707
|
+
{
|
|
1708
|
+
uri: config3.uri,
|
|
1709
|
+
mimeType: import_server.RESOURCE_MIME_TYPE,
|
|
1710
|
+
text: html
|
|
1711
|
+
}
|
|
1712
|
+
]
|
|
1713
|
+
};
|
|
1714
|
+
} catch {
|
|
1715
|
+
return {
|
|
1716
|
+
contents: [
|
|
1717
|
+
{
|
|
1718
|
+
uri: config3.uri,
|
|
1719
|
+
mimeType: import_server.RESOURCE_MIME_TYPE,
|
|
1720
|
+
text: `<!DOCTYPE html><html><body><p>${config3.fallbackLabel} UI not available. Build the UI apps first.</p></body></html>`
|
|
1721
|
+
}
|
|
1722
|
+
]
|
|
1723
|
+
};
|
|
1724
|
+
}
|
|
1725
|
+
}
|
|
1726
|
+
);
|
|
1727
|
+
}
|
|
1728
|
+
|
|
1729
|
+
// src/apps/task-details.ts
|
|
1730
|
+
var RESOURCE_URI = "ui://collab/task-details.html";
|
|
1731
|
+
function registerTaskDetailsApp(server, apiClient, _authContext) {
|
|
1732
|
+
(0, import_server2.registerAppTool)(
|
|
1733
|
+
server,
|
|
1734
|
+
"view_task_details",
|
|
1735
|
+
{
|
|
1736
|
+
title: "Task Details",
|
|
1737
|
+
description: "View interactive task details with acceptance criteria, notes, and progress. Opens a rich UI panel.",
|
|
1738
|
+
inputSchema: {
|
|
1739
|
+
taskId: import_zod4.z.string().describe("The task ID to view"),
|
|
1740
|
+
projectId: import_zod4.z.string().describe("The project ID")
|
|
1741
|
+
},
|
|
1742
|
+
_meta: { ui: { resourceUri: RESOURCE_URI } }
|
|
1743
|
+
},
|
|
1744
|
+
async ({ taskId, projectId }) => {
|
|
1745
|
+
try {
|
|
1746
|
+
const task = await apiClient.getTask(taskId);
|
|
1747
|
+
let project = null;
|
|
1748
|
+
try {
|
|
1749
|
+
project = await apiClient.getProject(projectId);
|
|
1750
|
+
} catch {
|
|
1751
|
+
}
|
|
1752
|
+
return {
|
|
1753
|
+
content: [
|
|
1754
|
+
{
|
|
1755
|
+
type: "text",
|
|
1756
|
+
text: `Viewing task: ${task.title}`
|
|
1757
|
+
}
|
|
1758
|
+
],
|
|
1759
|
+
structuredContent: {
|
|
1760
|
+
task,
|
|
1761
|
+
project
|
|
1762
|
+
}
|
|
1763
|
+
};
|
|
1764
|
+
} catch (error) {
|
|
1765
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1766
|
+
return {
|
|
1767
|
+
content: [{ type: "text", text: `Error loading task: ${message}` }],
|
|
1768
|
+
isError: true
|
|
1769
|
+
};
|
|
1770
|
+
}
|
|
1771
|
+
}
|
|
1772
|
+
);
|
|
1773
|
+
registerAppHtmlResource(server, {
|
|
1774
|
+
name: "Task Details UI",
|
|
1775
|
+
uri: RESOURCE_URI,
|
|
1776
|
+
description: "Interactive task details view with acceptance criteria and notes",
|
|
1777
|
+
htmlFileName: "task-details.html",
|
|
1778
|
+
fallbackLabel: "Task Details"
|
|
1779
|
+
});
|
|
1780
|
+
}
|
|
1781
|
+
|
|
1782
|
+
// src/apps/kanban.ts
|
|
1783
|
+
var import_server3 = require("@modelcontextprotocol/ext-apps/server");
|
|
1784
|
+
var import_zod5 = require("zod");
|
|
1785
|
+
var RESOURCE_URI2 = "ui://collab/kanban.html";
|
|
1786
|
+
function registerKanbanApp(server, apiClient, _authContext) {
|
|
1787
|
+
(0, import_server3.registerAppTool)(
|
|
1788
|
+
server,
|
|
1789
|
+
"view_kanban_board",
|
|
1790
|
+
{
|
|
1791
|
+
title: "Kanban Board",
|
|
1792
|
+
description: "View interactive drag-and-drop Kanban board for a project. Drag tasks between columns to change their state.",
|
|
1793
|
+
inputSchema: {
|
|
1794
|
+
projectId: import_zod5.z.string().describe("The project ID to display")
|
|
1795
|
+
},
|
|
1796
|
+
_meta: { ui: { resourceUri: RESOURCE_URI2 } }
|
|
1797
|
+
},
|
|
1798
|
+
async ({ projectId }) => {
|
|
1799
|
+
try {
|
|
1800
|
+
const [project, tasks] = await Promise.all([
|
|
1801
|
+
apiClient.getProject(projectId),
|
|
1802
|
+
apiClient.listTasks({ projectId })
|
|
1803
|
+
]);
|
|
1804
|
+
return {
|
|
1805
|
+
content: [
|
|
1806
|
+
{
|
|
1807
|
+
type: "text",
|
|
1808
|
+
text: `Kanban board for ${project.name} (${tasks.length} tasks)`
|
|
1809
|
+
}
|
|
1810
|
+
],
|
|
1811
|
+
structuredContent: {
|
|
1812
|
+
project,
|
|
1813
|
+
tasks
|
|
1814
|
+
}
|
|
1815
|
+
};
|
|
1816
|
+
} catch (error) {
|
|
1817
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1818
|
+
return {
|
|
1819
|
+
content: [{ type: "text", text: `Error loading kanban: ${message}` }],
|
|
1820
|
+
isError: true
|
|
1821
|
+
};
|
|
1822
|
+
}
|
|
1823
|
+
}
|
|
1824
|
+
);
|
|
1825
|
+
registerAppHtmlResource(server, {
|
|
1826
|
+
name: "Kanban Board UI",
|
|
1827
|
+
uri: RESOURCE_URI2,
|
|
1828
|
+
description: "Interactive drag-and-drop Kanban board for task management",
|
|
1829
|
+
htmlFileName: "kanban.html",
|
|
1830
|
+
fallbackLabel: "Kanban"
|
|
1831
|
+
});
|
|
1832
|
+
}
|
|
1833
|
+
|
|
1834
|
+
// src/apps/activity.ts
|
|
1835
|
+
var import_server4 = require("@modelcontextprotocol/ext-apps/server");
|
|
1836
|
+
var import_zod6 = require("zod");
|
|
1837
|
+
var RESOURCE_URI3 = "ui://collab/activity.html";
|
|
1838
|
+
function registerActivityApp(server, apiClient, _authContext) {
|
|
1839
|
+
(0, import_server4.registerAppTool)(
|
|
1840
|
+
server,
|
|
1841
|
+
"view_activity",
|
|
1842
|
+
{
|
|
1843
|
+
title: "User Activity",
|
|
1844
|
+
description: "View who is working on what across the team. Shows IN_PROGRESS and REVIEW tasks per user.",
|
|
1845
|
+
inputSchema: {
|
|
1846
|
+
projectId: import_zod6.z.string().optional().describe("Optional project ID to filter by")
|
|
1847
|
+
},
|
|
1848
|
+
_meta: { ui: { resourceUri: RESOURCE_URI3 } }
|
|
1849
|
+
},
|
|
1850
|
+
async ({ projectId }) => {
|
|
1851
|
+
try {
|
|
1852
|
+
const [inProgressTasks, reviewTasks] = await Promise.all([
|
|
1853
|
+
apiClient.listTasks({
|
|
1854
|
+
projectId,
|
|
1855
|
+
state: TaskState.IN_PROGRESS
|
|
1856
|
+
}),
|
|
1857
|
+
apiClient.listTasks({
|
|
1858
|
+
projectId,
|
|
1859
|
+
state: TaskState.REVIEW
|
|
1860
|
+
})
|
|
1861
|
+
]);
|
|
1862
|
+
const userMap = /* @__PURE__ */ new Map();
|
|
1863
|
+
for (const task of inProgressTasks) {
|
|
1864
|
+
if (task.assigneeId) {
|
|
1865
|
+
if (!userMap.has(task.assigneeId)) {
|
|
1866
|
+
userMap.set(task.assigneeId, {
|
|
1867
|
+
id: task.assigneeId,
|
|
1868
|
+
name: task.assigneeName || "Unknown",
|
|
1869
|
+
email: task.assigneeEmail || "",
|
|
1870
|
+
activeTasks: [],
|
|
1871
|
+
reviewTasks: []
|
|
1872
|
+
});
|
|
1873
|
+
}
|
|
1874
|
+
userMap.get(task.assigneeId).activeTasks.push(task);
|
|
1875
|
+
}
|
|
1876
|
+
}
|
|
1877
|
+
for (const task of reviewTasks) {
|
|
1878
|
+
if (task.assigneeId) {
|
|
1879
|
+
if (!userMap.has(task.assigneeId)) {
|
|
1880
|
+
userMap.set(task.assigneeId, {
|
|
1881
|
+
id: task.assigneeId,
|
|
1882
|
+
name: task.assigneeName || "Unknown",
|
|
1883
|
+
email: task.assigneeEmail || "",
|
|
1884
|
+
activeTasks: [],
|
|
1885
|
+
reviewTasks: []
|
|
1886
|
+
});
|
|
1887
|
+
}
|
|
1888
|
+
userMap.get(task.assigneeId).reviewTasks.push(task);
|
|
1889
|
+
}
|
|
1890
|
+
}
|
|
1891
|
+
const users = Array.from(userMap.values());
|
|
1892
|
+
return {
|
|
1893
|
+
content: [
|
|
1894
|
+
{
|
|
1895
|
+
type: "text",
|
|
1896
|
+
text: `Activity: ${users.length} users with active work`
|
|
1897
|
+
}
|
|
1898
|
+
],
|
|
1899
|
+
structuredContent: {
|
|
1900
|
+
users,
|
|
1901
|
+
projectId
|
|
1902
|
+
}
|
|
1903
|
+
};
|
|
1904
|
+
} catch (error) {
|
|
1905
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1906
|
+
return {
|
|
1907
|
+
content: [
|
|
1908
|
+
{ type: "text", text: `Error loading activity: ${message}` }
|
|
1909
|
+
],
|
|
1910
|
+
isError: true
|
|
1911
|
+
};
|
|
1912
|
+
}
|
|
1913
|
+
}
|
|
1914
|
+
);
|
|
1915
|
+
registerAppHtmlResource(server, {
|
|
1916
|
+
name: "User Activity UI",
|
|
1917
|
+
uri: RESOURCE_URI3,
|
|
1918
|
+
description: "Dashboard showing team member activity and workload",
|
|
1919
|
+
htmlFileName: "activity.html",
|
|
1920
|
+
fallbackLabel: "Activity"
|
|
1921
|
+
});
|
|
1922
|
+
}
|
|
1923
|
+
|
|
1924
|
+
// src/apps/project-overview.ts
|
|
1925
|
+
var import_server5 = require("@modelcontextprotocol/ext-apps/server");
|
|
1926
|
+
var import_zod7 = require("zod");
|
|
1927
|
+
var RESOURCE_URI4 = "ui://collab/project-overview.html";
|
|
1928
|
+
function registerProjectOverviewApp(server, apiClient, _authContext) {
|
|
1929
|
+
(0, import_server5.registerAppTool)(
|
|
1930
|
+
server,
|
|
1931
|
+
"view_project_overview",
|
|
1932
|
+
{
|
|
1933
|
+
title: "Project Overview",
|
|
1934
|
+
description: "View project health dashboard with task metrics, state distribution, and conventions.",
|
|
1935
|
+
inputSchema: {
|
|
1936
|
+
projectId: import_zod7.z.string().describe("The project ID to display")
|
|
1937
|
+
},
|
|
1938
|
+
_meta: { ui: { resourceUri: RESOURCE_URI4 } }
|
|
1939
|
+
},
|
|
1940
|
+
async ({ projectId }) => {
|
|
1941
|
+
try {
|
|
1942
|
+
const [project, context, tasks] = await Promise.all([
|
|
1943
|
+
apiClient.getProject(projectId),
|
|
1944
|
+
apiClient.getProjectContext(projectId).catch(() => null),
|
|
1945
|
+
apiClient.listTasks({ projectId })
|
|
1946
|
+
]);
|
|
1947
|
+
const activeTasks = tasks.filter((t) => !t.isArchived);
|
|
1948
|
+
const inProgress = activeTasks.filter(
|
|
1949
|
+
(t) => t.state === TaskState.IN_PROGRESS
|
|
1950
|
+
).length;
|
|
1951
|
+
const done = activeTasks.filter(
|
|
1952
|
+
(t) => t.state === TaskState.DONE
|
|
1953
|
+
).length;
|
|
1954
|
+
const blocked = activeTasks.filter((t) => t.errorType).length;
|
|
1955
|
+
const tasksByState = {
|
|
1956
|
+
DRAFT: 0,
|
|
1957
|
+
TODO: 0,
|
|
1958
|
+
IN_PROGRESS: 0,
|
|
1959
|
+
REVIEW: 0,
|
|
1960
|
+
DONE: 0
|
|
1961
|
+
};
|
|
1962
|
+
for (const task of activeTasks) {
|
|
1963
|
+
tasksByState[task.state]++;
|
|
1964
|
+
}
|
|
1965
|
+
const tasksByPriority = {
|
|
1966
|
+
LOW: 0,
|
|
1967
|
+
MEDIUM: 0,
|
|
1968
|
+
HIGH: 0,
|
|
1969
|
+
CRITICAL: 0
|
|
1970
|
+
};
|
|
1971
|
+
for (const task of activeTasks) {
|
|
1972
|
+
tasksByPriority[task.priority]++;
|
|
1973
|
+
}
|
|
1974
|
+
const recentCompleted = activeTasks.filter((t) => t.state === TaskState.DONE).sort(
|
|
1975
|
+
(a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime()
|
|
1976
|
+
).slice(0, 5);
|
|
1977
|
+
return {
|
|
1978
|
+
content: [
|
|
1979
|
+
{
|
|
1980
|
+
type: "text",
|
|
1981
|
+
text: `Project overview for ${project.name}: ${activeTasks.length} tasks`
|
|
1982
|
+
}
|
|
1983
|
+
],
|
|
1984
|
+
structuredContent: {
|
|
1985
|
+
project,
|
|
1986
|
+
context,
|
|
1987
|
+
metrics: {
|
|
1988
|
+
totalTasks: activeTasks.length,
|
|
1989
|
+
inProgress,
|
|
1990
|
+
blocked,
|
|
1991
|
+
done
|
|
1992
|
+
},
|
|
1993
|
+
tasksByState,
|
|
1994
|
+
tasksByPriority,
|
|
1995
|
+
recentCompleted
|
|
1996
|
+
}
|
|
1997
|
+
};
|
|
1998
|
+
} catch (error) {
|
|
1999
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2000
|
+
return {
|
|
2001
|
+
content: [
|
|
2002
|
+
{ type: "text", text: `Error loading project overview: ${message}` }
|
|
2003
|
+
],
|
|
2004
|
+
isError: true
|
|
2005
|
+
};
|
|
2006
|
+
}
|
|
2007
|
+
}
|
|
2008
|
+
);
|
|
2009
|
+
registerAppHtmlResource(server, {
|
|
2010
|
+
name: "Project Overview UI",
|
|
2011
|
+
uri: RESOURCE_URI4,
|
|
2012
|
+
description: "Project health dashboard with metrics and visualizations",
|
|
2013
|
+
htmlFileName: "project-overview.html",
|
|
2014
|
+
fallbackLabel: "Project Overview"
|
|
2015
|
+
});
|
|
2016
|
+
}
|
|
2017
|
+
|
|
2018
|
+
// src/apps/agent-sessions.ts
|
|
2019
|
+
var import_server6 = require("@modelcontextprotocol/ext-apps/server");
|
|
2020
|
+
var import_zod8 = require("zod");
|
|
2021
|
+
var RESOURCE_URI5 = "ui://collab/agent-sessions.html";
|
|
2022
|
+
function registerAgentSessionsApp(server, apiClient, authContext) {
|
|
2023
|
+
(0, import_server6.registerAppTool)(
|
|
2024
|
+
server,
|
|
2025
|
+
"view_agent_sessions",
|
|
2026
|
+
{
|
|
2027
|
+
title: "Agent Sessions",
|
|
2028
|
+
description: "View active AI agent sessions working on tasks. Monitor real-time progress and session status.",
|
|
2029
|
+
inputSchema: {
|
|
2030
|
+
projectId: import_zod8.z.string().optional().describe("Optional project ID to filter by")
|
|
2031
|
+
},
|
|
2032
|
+
_meta: { ui: { resourceUri: RESOURCE_URI5 } }
|
|
2033
|
+
},
|
|
2034
|
+
async ({ projectId }) => {
|
|
2035
|
+
try {
|
|
2036
|
+
const [inProgressTasks, reviewTasks] = await Promise.all([
|
|
2037
|
+
apiClient.listTasks({
|
|
2038
|
+
projectId,
|
|
2039
|
+
state: TaskState.IN_PROGRESS
|
|
2040
|
+
}),
|
|
2041
|
+
apiClient.listTasks({
|
|
2042
|
+
projectId,
|
|
2043
|
+
state: TaskState.REVIEW
|
|
2044
|
+
})
|
|
2045
|
+
]);
|
|
2046
|
+
const sessions = [];
|
|
2047
|
+
for (const task of inProgressTasks) {
|
|
2048
|
+
if (task.assigneeId) {
|
|
2049
|
+
const totalCriteria = task.acceptanceCriteria?.length || 0;
|
|
2050
|
+
const completedCriteria = task.acceptanceCriteria?.filter((c) => c.completed).length || 0;
|
|
2051
|
+
const progress = totalCriteria > 0 ? Math.round(completedCriteria / totalCriteria * 100) : 0;
|
|
2052
|
+
const latestUpdate = task.progressUpdates?.[task.progressUpdates.length - 1];
|
|
2053
|
+
sessions.push({
|
|
2054
|
+
id: `session-${task.id}`,
|
|
2055
|
+
taskId: task.id,
|
|
2056
|
+
taskTitle: task.title,
|
|
2057
|
+
agentName: task.assigneeName || "Agent",
|
|
2058
|
+
status: "RUNNING",
|
|
2059
|
+
startedAt: task.updatedAt,
|
|
2060
|
+
lastCheckpoint: latestUpdate?.timestamp,
|
|
2061
|
+
currentStep: latestUpdate?.statusMessage,
|
|
2062
|
+
progress
|
|
2063
|
+
});
|
|
2064
|
+
}
|
|
2065
|
+
}
|
|
2066
|
+
for (const task of reviewTasks) {
|
|
2067
|
+
if (task.assigneeId) {
|
|
2068
|
+
sessions.push({
|
|
2069
|
+
id: `session-${task.id}`,
|
|
2070
|
+
taskId: task.id,
|
|
2071
|
+
taskTitle: task.title,
|
|
2072
|
+
agentName: task.assigneeName || "Agent",
|
|
2073
|
+
status: "STOPPED",
|
|
2074
|
+
startedAt: task.updatedAt,
|
|
2075
|
+
progress: 100
|
|
2076
|
+
});
|
|
2077
|
+
}
|
|
2078
|
+
}
|
|
2079
|
+
return {
|
|
2080
|
+
content: [
|
|
2081
|
+
{
|
|
2082
|
+
type: "text",
|
|
2083
|
+
text: `Agent sessions: ${sessions.length} active`
|
|
2084
|
+
}
|
|
2085
|
+
],
|
|
2086
|
+
structuredContent: {
|
|
2087
|
+
sessions,
|
|
2088
|
+
projectId
|
|
2089
|
+
}
|
|
2090
|
+
};
|
|
2091
|
+
} catch (error) {
|
|
2092
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2093
|
+
return {
|
|
2094
|
+
content: [
|
|
2095
|
+
{ type: "text", text: `Error loading agent sessions: ${message}` }
|
|
2096
|
+
],
|
|
2097
|
+
isError: true
|
|
2098
|
+
};
|
|
2099
|
+
}
|
|
2100
|
+
}
|
|
2101
|
+
);
|
|
2102
|
+
registerAppHtmlResource(server, {
|
|
2103
|
+
name: "Agent Sessions UI",
|
|
2104
|
+
uri: RESOURCE_URI5,
|
|
2105
|
+
description: "Real-time view of AI agent sessions and their progress",
|
|
2106
|
+
htmlFileName: "agent-sessions.html",
|
|
2107
|
+
fallbackLabel: "Agent Sessions"
|
|
2108
|
+
});
|
|
2109
|
+
}
|
|
2110
|
+
|
|
2111
|
+
// src/apps/index.ts
|
|
2112
|
+
function registerMCPApps(server, apiClient, authContext) {
|
|
2113
|
+
registerTaskDetailsApp(server, apiClient, authContext);
|
|
2114
|
+
registerKanbanApp(server, apiClient, authContext);
|
|
2115
|
+
registerActivityApp(server, apiClient, authContext);
|
|
2116
|
+
registerProjectOverviewApp(server, apiClient, authContext);
|
|
2117
|
+
registerAgentSessionsApp(server, apiClient, authContext);
|
|
2118
|
+
}
|
|
2119
|
+
|
|
1339
2120
|
// src/index.ts
|
|
1340
2121
|
var COLLAB_SERVER_INSTRUCTIONS = `Collab - AI-assisted software development task management platform.
|
|
1341
2122
|
|
|
@@ -1387,7 +2168,7 @@ Review Workflow:
|
|
|
1387
2168
|
list_tasks(state=REVIEW) -> get_task -> approve_task OR request_changes
|
|
1388
2169
|
|
|
1389
2170
|
Task Editing:
|
|
1390
|
-
update_task (DRAFT/TODO only) ->
|
|
2171
|
+
update_task (DRAFT/TODO only) -> task stays in current state
|
|
1391
2172
|
|
|
1392
2173
|
Error Recovery:
|
|
1393
2174
|
report_error -> abandon_task -> list_tasks -> assign_task (retry or pick different task)
|
|
@@ -1406,7 +2187,7 @@ GIT OPERATIONS NOTE:
|
|
|
1406
2187
|
TASK STATE FLOW:
|
|
1407
2188
|
DRAFT -> TODO -> IN_PROGRESS -> REVIEW -> DONE
|
|
1408
2189
|
(verify_task: DRAFT -> TODO)
|
|
1409
|
-
(update_task
|
|
2190
|
+
(update_task: DRAFT/TODO only, state unchanged)
|
|
1410
2191
|
(request_changes: REVIEW -> IN_PROGRESS)
|
|
1411
2192
|
(abandon_task: IN_PROGRESS -> TODO)
|
|
1412
2193
|
|
|
@@ -1439,7 +2220,7 @@ function initializeMCPServer(apiClient, authContext) {
|
|
|
1439
2220
|
{
|
|
1440
2221
|
description: "Discover all accessible projects. Use first to find project IDs. Filter by TEAM, PERSONAL, or ALL workspaces.",
|
|
1441
2222
|
inputSchema: {
|
|
1442
|
-
workspaceType:
|
|
2223
|
+
workspaceType: import_zod9.z.enum(["TEAM", "PERSONAL", "ALL"]).optional().describe("Filter by workspace type")
|
|
1443
2224
|
}
|
|
1444
2225
|
},
|
|
1445
2226
|
async (args) => {
|
|
@@ -1469,10 +2250,10 @@ function initializeMCPServer(apiClient, authContext) {
|
|
|
1469
2250
|
{
|
|
1470
2251
|
description: "Query tasks with filters. Use state=TODO for assignable tasks, state=REVIEW for pending reviews.",
|
|
1471
2252
|
inputSchema: {
|
|
1472
|
-
projectId:
|
|
1473
|
-
state:
|
|
1474
|
-
assigneeId:
|
|
1475
|
-
includeArchived:
|
|
2253
|
+
projectId: import_zod9.z.string().optional().describe("Filter by project ID"),
|
|
2254
|
+
state: import_zod9.z.nativeEnum(TaskState).optional().describe("Filter by task state"),
|
|
2255
|
+
assigneeId: import_zod9.z.string().optional().describe("Filter by assignee ID"),
|
|
2256
|
+
includeArchived: import_zod9.z.boolean().optional().describe("Include archived tasks (default: false)")
|
|
1476
2257
|
}
|
|
1477
2258
|
},
|
|
1478
2259
|
async (args) => {
|
|
@@ -1503,7 +2284,7 @@ function initializeMCPServer(apiClient, authContext) {
|
|
|
1503
2284
|
{
|
|
1504
2285
|
description: "Get complete task details with acceptance criteria and notes. Call before assign_task to understand requirements.",
|
|
1505
2286
|
inputSchema: {
|
|
1506
|
-
taskId:
|
|
2287
|
+
taskId: import_zod9.z.string().describe("The task ID to retrieve")
|
|
1507
2288
|
}
|
|
1508
2289
|
},
|
|
1509
2290
|
async (args) => {
|
|
@@ -1529,9 +2310,9 @@ function initializeMCPServer(apiClient, authContext) {
|
|
|
1529
2310
|
{
|
|
1530
2311
|
description: "Atomically claim a task. Race-safe - fails if already assigned. Task must be TODO. Returns suggested branch name and worktree path for isolated parallel development.",
|
|
1531
2312
|
inputSchema: {
|
|
1532
|
-
projectId:
|
|
1533
|
-
taskId:
|
|
1534
|
-
expectedState:
|
|
2313
|
+
projectId: import_zod9.z.string().describe("The project ID"),
|
|
2314
|
+
taskId: import_zod9.z.string().describe("The task ID to assign"),
|
|
2315
|
+
expectedState: import_zod9.z.nativeEnum(TaskState).optional().describe("Expected task state (default: TODO)")
|
|
1535
2316
|
}
|
|
1536
2317
|
},
|
|
1537
2318
|
async (args) => {
|
|
@@ -1565,10 +2346,10 @@ function initializeMCPServer(apiClient, authContext) {
|
|
|
1565
2346
|
{
|
|
1566
2347
|
description: "Report progress and checkpoint work. Call frequently during execution. Marks acceptance criteria complete.",
|
|
1567
2348
|
inputSchema: {
|
|
1568
|
-
taskId:
|
|
1569
|
-
statusMessage:
|
|
1570
|
-
completedCheckpointIds:
|
|
1571
|
-
currentCheckpointIndex:
|
|
2349
|
+
taskId: import_zod9.z.string().describe("The task ID to update"),
|
|
2350
|
+
statusMessage: import_zod9.z.string().optional().describe("Status message (max 1000 chars)"),
|
|
2351
|
+
completedCheckpointIds: import_zod9.z.array(import_zod9.z.string()).optional().describe("Array of completed checkpoint IDs"),
|
|
2352
|
+
currentCheckpointIndex: import_zod9.z.number().optional().describe("Current checkpoint index")
|
|
1572
2353
|
}
|
|
1573
2354
|
},
|
|
1574
2355
|
async (args) => {
|
|
@@ -1602,10 +2383,10 @@ function initializeMCPServer(apiClient, authContext) {
|
|
|
1602
2383
|
{
|
|
1603
2384
|
description: "Prepare task for PR creation. Returns PR suggestions. After creating PR locally, call report_pr to transition to REVIEW. Requires IN_PROGRESS state.",
|
|
1604
2385
|
inputSchema: {
|
|
1605
|
-
projectId:
|
|
1606
|
-
taskId:
|
|
1607
|
-
pullRequestTitle:
|
|
1608
|
-
pullRequestBody:
|
|
2386
|
+
projectId: import_zod9.z.string().describe("The project ID"),
|
|
2387
|
+
taskId: import_zod9.z.string().describe("The task ID to complete"),
|
|
2388
|
+
pullRequestTitle: import_zod9.z.string().optional().describe("PR title (max 300 chars)"),
|
|
2389
|
+
pullRequestBody: import_zod9.z.string().optional().describe("PR body/description (max 10000 chars)")
|
|
1609
2390
|
}
|
|
1610
2391
|
},
|
|
1611
2392
|
async (args) => {
|
|
@@ -1662,10 +2443,10 @@ function initializeMCPServer(apiClient, authContext) {
|
|
|
1662
2443
|
{
|
|
1663
2444
|
description: "Report unrecoverable errors (BUILD_FAILURE, TEST_FAILURE, CONFLICT, AUTH_ERROR). Consider abandon_task after.",
|
|
1664
2445
|
inputSchema: {
|
|
1665
|
-
taskId:
|
|
1666
|
-
errorType:
|
|
1667
|
-
errorMessage:
|
|
1668
|
-
context:
|
|
2446
|
+
taskId: import_zod9.z.string().describe("The task ID"),
|
|
2447
|
+
errorType: import_zod9.z.nativeEnum(ErrorType).describe("Error type: BUILD_FAILURE, TEST_FAILURE, CONFLICT, AUTH_ERROR, OTHER"),
|
|
2448
|
+
errorMessage: import_zod9.z.string().describe("Error message (max 1000 chars)"),
|
|
2449
|
+
context: import_zod9.z.string().optional().describe("Additional context (max 2000 chars)")
|
|
1669
2450
|
}
|
|
1670
2451
|
},
|
|
1671
2452
|
async (args) => {
|
|
@@ -1700,7 +2481,7 @@ function initializeMCPServer(apiClient, authContext) {
|
|
|
1700
2481
|
{
|
|
1701
2482
|
description: "Load project README, tech stack, and coding conventions. Call after selecting project.",
|
|
1702
2483
|
inputSchema: {
|
|
1703
|
-
projectId:
|
|
2484
|
+
projectId: import_zod9.z.string().describe("The project ID")
|
|
1704
2485
|
}
|
|
1705
2486
|
},
|
|
1706
2487
|
async (args) => {
|
|
@@ -1730,8 +2511,8 @@ function initializeMCPServer(apiClient, authContext) {
|
|
|
1730
2511
|
{
|
|
1731
2512
|
description: "Document implementation decisions. Notes persist for future reference and handoff.",
|
|
1732
2513
|
inputSchema: {
|
|
1733
|
-
taskId:
|
|
1734
|
-
content:
|
|
2514
|
+
taskId: import_zod9.z.string().describe("The task ID"),
|
|
2515
|
+
content: import_zod9.z.string().describe("Note content (max 500 chars)")
|
|
1735
2516
|
}
|
|
1736
2517
|
},
|
|
1737
2518
|
async (args) => {
|
|
@@ -1760,9 +2541,9 @@ function initializeMCPServer(apiClient, authContext) {
|
|
|
1760
2541
|
{
|
|
1761
2542
|
description: "Release task assignment and optionally clean up branch. Task returns to TODO. Use after errors.",
|
|
1762
2543
|
inputSchema: {
|
|
1763
|
-
projectId:
|
|
1764
|
-
taskId:
|
|
1765
|
-
deleteBranch:
|
|
2544
|
+
projectId: import_zod9.z.string().describe("The project ID"),
|
|
2545
|
+
taskId: import_zod9.z.string().describe("The task ID to abandon"),
|
|
2546
|
+
deleteBranch: import_zod9.z.boolean().optional().describe("Whether to delete the associated branch")
|
|
1766
2547
|
}
|
|
1767
2548
|
},
|
|
1768
2549
|
async (args) => {
|
|
@@ -1796,9 +2577,9 @@ function initializeMCPServer(apiClient, authContext) {
|
|
|
1796
2577
|
{
|
|
1797
2578
|
description: "Report a branch created by the agent. Call after using git to create and push a branch. Task must be IN_PROGRESS.",
|
|
1798
2579
|
inputSchema: {
|
|
1799
|
-
projectId:
|
|
1800
|
-
taskId:
|
|
1801
|
-
branchName:
|
|
2580
|
+
projectId: import_zod9.z.string().describe("The project ID"),
|
|
2581
|
+
taskId: import_zod9.z.string().describe("The task ID"),
|
|
2582
|
+
branchName: import_zod9.z.string().describe("Name of the branch created (e.g., feature/TASK-123-fix-login)")
|
|
1802
2583
|
}
|
|
1803
2584
|
},
|
|
1804
2585
|
async (args) => {
|
|
@@ -1832,10 +2613,10 @@ function initializeMCPServer(apiClient, authContext) {
|
|
|
1832
2613
|
{
|
|
1833
2614
|
description: "Report a PR created by the agent. Call after using gh pr create. Transitions task to REVIEW state.",
|
|
1834
2615
|
inputSchema: {
|
|
1835
|
-
projectId:
|
|
1836
|
-
taskId:
|
|
1837
|
-
pullRequestUrl:
|
|
1838
|
-
pullRequestNumber:
|
|
2616
|
+
projectId: import_zod9.z.string().describe("The project ID"),
|
|
2617
|
+
taskId: import_zod9.z.string().describe("The task ID"),
|
|
2618
|
+
pullRequestUrl: import_zod9.z.string().describe("Full URL of the created PR (e.g., https://github.com/owner/repo/pull/123)"),
|
|
2619
|
+
pullRequestNumber: import_zod9.z.number().describe("PR number (e.g., 123)")
|
|
1839
2620
|
}
|
|
1840
2621
|
},
|
|
1841
2622
|
async (args) => {
|
|
@@ -1870,8 +2651,8 @@ function initializeMCPServer(apiClient, authContext) {
|
|
|
1870
2651
|
{
|
|
1871
2652
|
description: "Soft-delete a task. Hidden but restorable via unarchive_task.",
|
|
1872
2653
|
inputSchema: {
|
|
1873
|
-
projectId:
|
|
1874
|
-
taskId:
|
|
2654
|
+
projectId: import_zod9.z.string().describe("The project ID"),
|
|
2655
|
+
taskId: import_zod9.z.string().describe("The task ID to archive")
|
|
1875
2656
|
}
|
|
1876
2657
|
},
|
|
1877
2658
|
async (args) => {
|
|
@@ -1904,8 +2685,8 @@ function initializeMCPServer(apiClient, authContext) {
|
|
|
1904
2685
|
{
|
|
1905
2686
|
description: "Restore previously archived task to original state.",
|
|
1906
2687
|
inputSchema: {
|
|
1907
|
-
projectId:
|
|
1908
|
-
taskId:
|
|
2688
|
+
projectId: import_zod9.z.string().describe("The project ID"),
|
|
2689
|
+
taskId: import_zod9.z.string().describe("The task ID to restore")
|
|
1909
2690
|
}
|
|
1910
2691
|
},
|
|
1911
2692
|
async (args) => {
|
|
@@ -1938,9 +2719,9 @@ function initializeMCPServer(apiClient, authContext) {
|
|
|
1938
2719
|
{
|
|
1939
2720
|
description: "Create new project in personal workspace linked to GitHub repository.",
|
|
1940
2721
|
inputSchema: {
|
|
1941
|
-
name:
|
|
1942
|
-
description:
|
|
1943
|
-
repositoryUrl:
|
|
2722
|
+
name: import_zod9.z.string().describe("Project name (max 100 chars)"),
|
|
2723
|
+
description: import_zod9.z.string().optional().describe("Project description (max 500 chars)"),
|
|
2724
|
+
repositoryUrl: import_zod9.z.string().describe("GitHub repository URL")
|
|
1944
2725
|
}
|
|
1945
2726
|
},
|
|
1946
2727
|
async (args) => {
|
|
@@ -1974,14 +2755,14 @@ function initializeMCPServer(apiClient, authContext) {
|
|
|
1974
2755
|
{
|
|
1975
2756
|
description: "Create task with title, description, acceptance criteria. Starts in DRAFT. Priority: LOW/MEDIUM/HIGH/CRITICAL.",
|
|
1976
2757
|
inputSchema: {
|
|
1977
|
-
projectId:
|
|
1978
|
-
epicId:
|
|
1979
|
-
title:
|
|
1980
|
-
description:
|
|
1981
|
-
priority:
|
|
1982
|
-
acceptanceCriteria:
|
|
1983
|
-
|
|
1984
|
-
description:
|
|
2758
|
+
projectId: import_zod9.z.string().describe("The project ID to create the task in"),
|
|
2759
|
+
epicId: import_zod9.z.string().nullable().optional().describe("Optional epic ID to associate the task with"),
|
|
2760
|
+
title: import_zod9.z.string().describe("Task title (max 200 chars)"),
|
|
2761
|
+
description: import_zod9.z.string().describe("Task description (max 5000 chars)"),
|
|
2762
|
+
priority: import_zod9.z.nativeEnum(TaskPriority).optional().describe("Task priority: LOW, MEDIUM, HIGH, CRITICAL (default: MEDIUM)"),
|
|
2763
|
+
acceptanceCriteria: import_zod9.z.array(
|
|
2764
|
+
import_zod9.z.object({
|
|
2765
|
+
description: import_zod9.z.string().describe("Acceptance criterion description (max 500 chars)")
|
|
1985
2766
|
})
|
|
1986
2767
|
).describe("Array of acceptance criteria (at least 1 required)")
|
|
1987
2768
|
}
|
|
@@ -2020,10 +2801,10 @@ function initializeMCPServer(apiClient, authContext) {
|
|
|
2020
2801
|
{
|
|
2021
2802
|
description: "Return task from REVIEW to IN_PROGRESS with feedback. Original assignee addresses changes.",
|
|
2022
2803
|
inputSchema: {
|
|
2023
|
-
projectId:
|
|
2024
|
-
taskId:
|
|
2025
|
-
reviewComments:
|
|
2026
|
-
requestedChanges:
|
|
2804
|
+
projectId: import_zod9.z.string().describe("The project ID"),
|
|
2805
|
+
taskId: import_zod9.z.string().describe("The task ID to review"),
|
|
2806
|
+
reviewComments: import_zod9.z.string().describe("Review comments explaining requested changes (max 5000 chars)"),
|
|
2807
|
+
requestedChanges: import_zod9.z.array(import_zod9.z.string()).optional().describe("List of specific changes requested")
|
|
2027
2808
|
}
|
|
2028
2809
|
},
|
|
2029
2810
|
async (args) => {
|
|
@@ -2058,9 +2839,9 @@ function initializeMCPServer(apiClient, authContext) {
|
|
|
2058
2839
|
{
|
|
2059
2840
|
description: "Approve completed work and mark DONE. Only for REVIEW state tasks.",
|
|
2060
2841
|
inputSchema: {
|
|
2061
|
-
projectId:
|
|
2062
|
-
taskId:
|
|
2063
|
-
reviewComments:
|
|
2842
|
+
projectId: import_zod9.z.string().describe("The project ID"),
|
|
2843
|
+
taskId: import_zod9.z.string().describe("The task ID to approve"),
|
|
2844
|
+
reviewComments: import_zod9.z.string().optional().describe("Optional approval comments (max 2000 chars)")
|
|
2064
2845
|
}
|
|
2065
2846
|
},
|
|
2066
2847
|
async (args) => {
|
|
@@ -2094,10 +2875,10 @@ function initializeMCPServer(apiClient, authContext) {
|
|
|
2094
2875
|
{
|
|
2095
2876
|
description: "Verify a DRAFT task and move it to TODO state. Requires task to pass programmatic validation (title 10+ chars, description 50+ chars, each criterion 20+ chars). If approved=false, stores feedback with NEEDS_REVISION status.",
|
|
2096
2877
|
inputSchema: {
|
|
2097
|
-
projectId:
|
|
2098
|
-
taskId:
|
|
2099
|
-
approved:
|
|
2100
|
-
feedback:
|
|
2878
|
+
projectId: import_zod9.z.string().describe("The project ID"),
|
|
2879
|
+
taskId: import_zod9.z.string().describe("The task ID to verify"),
|
|
2880
|
+
approved: import_zod9.z.boolean().describe("Whether to approve the task"),
|
|
2881
|
+
feedback: import_zod9.z.string().optional().describe("Feedback for the task (required if not approved)")
|
|
2101
2882
|
}
|
|
2102
2883
|
},
|
|
2103
2884
|
async (args) => {
|
|
@@ -2128,8 +2909,8 @@ function initializeMCPServer(apiClient, authContext) {
|
|
|
2128
2909
|
{
|
|
2129
2910
|
description: "Get state-appropriate prompt for a task. Returns verify prompt for DRAFT, assignment prompt for TODO, or continue prompt for IN_PROGRESS tasks.",
|
|
2130
2911
|
inputSchema: {
|
|
2131
|
-
projectId:
|
|
2132
|
-
taskId:
|
|
2912
|
+
projectId: import_zod9.z.string().describe("The project ID"),
|
|
2913
|
+
taskId: import_zod9.z.string().describe("The task ID")
|
|
2133
2914
|
}
|
|
2134
2915
|
},
|
|
2135
2916
|
async (args) => {
|
|
@@ -2160,17 +2941,17 @@ function initializeMCPServer(apiClient, authContext) {
|
|
|
2160
2941
|
server.registerTool(
|
|
2161
2942
|
"update_task",
|
|
2162
2943
|
{
|
|
2163
|
-
description: "Update task details (title, description, priority, acceptanceCriteria). Only works for DRAFT and TODO states.
|
|
2944
|
+
description: "Update task details (title, description, priority, acceptanceCriteria). Only works for DRAFT and TODO states. Task stays in its current state.",
|
|
2164
2945
|
inputSchema: {
|
|
2165
|
-
projectId:
|
|
2166
|
-
taskId:
|
|
2167
|
-
title:
|
|
2168
|
-
description:
|
|
2169
|
-
priority:
|
|
2170
|
-
acceptanceCriteria:
|
|
2171
|
-
|
|
2172
|
-
id:
|
|
2173
|
-
description:
|
|
2946
|
+
projectId: import_zod9.z.string().describe("The project ID"),
|
|
2947
|
+
taskId: import_zod9.z.string().describe("The task ID to update"),
|
|
2948
|
+
title: import_zod9.z.string().optional().describe("New task title"),
|
|
2949
|
+
description: import_zod9.z.string().optional().describe("New task description"),
|
|
2950
|
+
priority: import_zod9.z.nativeEnum(TaskPriority).optional().describe("New task priority"),
|
|
2951
|
+
acceptanceCriteria: import_zod9.z.array(
|
|
2952
|
+
import_zod9.z.object({
|
|
2953
|
+
id: import_zod9.z.string().optional().describe("Existing criterion ID (for updates)"),
|
|
2954
|
+
description: import_zod9.z.string().describe("Criterion description")
|
|
2174
2955
|
})
|
|
2175
2956
|
).optional().describe("New acceptance criteria (replaces existing)")
|
|
2176
2957
|
}
|
|
@@ -2226,6 +3007,7 @@ function initializeMCPServer(apiClient, authContext) {
|
|
|
2226
3007
|
};
|
|
2227
3008
|
}
|
|
2228
3009
|
);
|
|
3010
|
+
registerMCPApps(server, apiClient, authContext);
|
|
2229
3011
|
return server;
|
|
2230
3012
|
}
|
|
2231
3013
|
async function connectMCPServer(server, transport) {
|
|
@@ -2278,30 +3060,30 @@ function handleApiError(error) {
|
|
|
2278
3060
|
isError: true
|
|
2279
3061
|
};
|
|
2280
3062
|
}
|
|
2281
|
-
var ActiveTaskSchema =
|
|
2282
|
-
taskId:
|
|
2283
|
-
projectId:
|
|
2284
|
-
branchName:
|
|
2285
|
-
worktreePath:
|
|
2286
|
-
startedAt:
|
|
3063
|
+
var ActiveTaskSchema = import_zod9.z.object({
|
|
3064
|
+
taskId: import_zod9.z.string().min(1),
|
|
3065
|
+
projectId: import_zod9.z.string().min(1),
|
|
3066
|
+
branchName: import_zod9.z.string().optional(),
|
|
3067
|
+
worktreePath: import_zod9.z.string().optional(),
|
|
3068
|
+
startedAt: import_zod9.z.string().optional()
|
|
2287
3069
|
});
|
|
2288
3070
|
async function checkActiveTask() {
|
|
2289
|
-
const
|
|
2290
|
-
const
|
|
3071
|
+
const fs2 = await import("fs");
|
|
3072
|
+
const path2 = await import("path");
|
|
2291
3073
|
const cwd = process.cwd();
|
|
2292
|
-
const collabDir =
|
|
2293
|
-
const activeTaskPath =
|
|
3074
|
+
const collabDir = path2.join(cwd, ".collab");
|
|
3075
|
+
const activeTaskPath = path2.join(collabDir, "active-task.json");
|
|
2294
3076
|
try {
|
|
2295
|
-
const resolvedPath =
|
|
2296
|
-
const resolvedCollabDir =
|
|
2297
|
-
if (!resolvedPath.startsWith(resolvedCollabDir +
|
|
3077
|
+
const resolvedPath = path2.resolve(activeTaskPath);
|
|
3078
|
+
const resolvedCollabDir = path2.resolve(collabDir);
|
|
3079
|
+
if (!resolvedPath.startsWith(resolvedCollabDir + path2.sep) && resolvedPath !== resolvedCollabDir) {
|
|
2298
3080
|
return {
|
|
2299
3081
|
hasActiveTask: false,
|
|
2300
3082
|
task: null,
|
|
2301
3083
|
error: "Invalid active task path"
|
|
2302
3084
|
};
|
|
2303
3085
|
}
|
|
2304
|
-
const stats = await
|
|
3086
|
+
const stats = await fs2.promises.lstat(activeTaskPath);
|
|
2305
3087
|
if (stats.isSymbolicLink()) {
|
|
2306
3088
|
return {
|
|
2307
3089
|
hasActiveTask: false,
|
|
@@ -2315,7 +3097,7 @@ async function checkActiveTask() {
|
|
|
2315
3097
|
task: null
|
|
2316
3098
|
};
|
|
2317
3099
|
}
|
|
2318
|
-
const content = await
|
|
3100
|
+
const content = await fs2.promises.readFile(activeTaskPath, "utf-8");
|
|
2319
3101
|
let parsed;
|
|
2320
3102
|
try {
|
|
2321
3103
|
parsed = JSON.parse(content);
|
|
@@ -2381,7 +3163,7 @@ Example mcp.json configuration:
|
|
|
2381
3163
|
"mcpServers": {
|
|
2382
3164
|
"collab": {
|
|
2383
3165
|
"command": "npx",
|
|
2384
|
-
"args": ["@mtaap/mcp"],
|
|
3166
|
+
"args": ["-p", "@mtaap/mcp", "collab-mcp"],
|
|
2385
3167
|
"env": {
|
|
2386
3168
|
"COLLAB_API_KEY": "collab_your_api_key_here",
|
|
2387
3169
|
"COLLAB_BASE_URL": "https://collab.mtaap.de"
|
|
@@ -2416,7 +3198,7 @@ function validateEnvironment() {
|
|
|
2416
3198
|
"mcpServers": {
|
|
2417
3199
|
"collab": {
|
|
2418
3200
|
"command": "npx",
|
|
2419
|
-
"args": ["@mtaap/mcp"],
|
|
3201
|
+
"args": ["-p", "@mtaap/mcp", "collab-mcp"],
|
|
2420
3202
|
"env": {
|
|
2421
3203
|
"COLLAB_API_KEY": "collab_your_api_key_here",
|
|
2422
3204
|
"COLLAB_BASE_URL": "https://collab.mtaap.de"
|