@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/index.js
CHANGED
|
@@ -44,15 +44,18 @@ var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
|
44
44
|
// package.json
|
|
45
45
|
var package_default = {
|
|
46
46
|
name: "@mtaap/mcp",
|
|
47
|
-
version: "0.
|
|
47
|
+
version: "0.5.1",
|
|
48
48
|
description: "Model Context Protocol (MCP) server for AI agents to interact with Collab - the multi-tenant collaborative agent development platform",
|
|
49
49
|
mcpName: "collab",
|
|
50
50
|
scripts: {
|
|
51
|
-
build: "tsup"
|
|
51
|
+
build: "pnpm build:ui && tsup",
|
|
52
|
+
"build:ui": "node scripts/build-ui.mjs",
|
|
53
|
+
"dev:ui": "vite build --watch"
|
|
52
54
|
},
|
|
53
55
|
main: "./dist/index.js",
|
|
54
56
|
types: "./dist/index.d.ts",
|
|
55
57
|
bin: {
|
|
58
|
+
mcp: "./dist/cli.js",
|
|
56
59
|
"collab-mcp": "./dist/cli.js",
|
|
57
60
|
"collab-mcp-server": "./dist/server.js"
|
|
58
61
|
},
|
|
@@ -85,6 +88,7 @@ var package_default = {
|
|
|
85
88
|
},
|
|
86
89
|
dependencies: {
|
|
87
90
|
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
91
|
+
"@modelcontextprotocol/ext-apps": "^1.0.1",
|
|
88
92
|
express: "^5.0.1",
|
|
89
93
|
zod: "^4.3.5"
|
|
90
94
|
},
|
|
@@ -93,8 +97,18 @@ var package_default = {
|
|
|
93
97
|
"@mtaap/core": "workspace:*",
|
|
94
98
|
"@types/express": "^5.0.0",
|
|
95
99
|
"@types/node": "^22.0.0",
|
|
100
|
+
"@types/react": "^19.0.0",
|
|
101
|
+
"@types/react-dom": "^19.0.0",
|
|
102
|
+
"@vitejs/plugin-react": "^4.4.0",
|
|
103
|
+
autoprefixer: "^10.4.21",
|
|
104
|
+
postcss: "^8.5.3",
|
|
105
|
+
react: "^19.0.0",
|
|
106
|
+
"react-dom": "^19.0.0",
|
|
107
|
+
tailwindcss: "^3.4.17",
|
|
96
108
|
tsup: "^8.5.1",
|
|
97
|
-
typescript: "^5.4.0"
|
|
109
|
+
typescript: "^5.4.0",
|
|
110
|
+
vite: "^6.3.2",
|
|
111
|
+
"vite-plugin-singlefile": "^2.0.3"
|
|
98
112
|
}
|
|
99
113
|
};
|
|
100
114
|
|
|
@@ -102,7 +116,7 @@ var package_default = {
|
|
|
102
116
|
var VERSION = package_default.version;
|
|
103
117
|
|
|
104
118
|
// src/index.ts
|
|
105
|
-
var
|
|
119
|
+
var import_zod9 = require("zod");
|
|
106
120
|
|
|
107
121
|
// ../../packages/core/dist/constants/enums.js
|
|
108
122
|
var TaskState;
|
|
@@ -188,13 +202,11 @@ var WebSocketEventType;
|
|
|
188
202
|
WebSocketEventType2["TASK_UPDATED"] = "task.updated";
|
|
189
203
|
WebSocketEventType2["TASK_DELETED"] = "task.deleted";
|
|
190
204
|
WebSocketEventType2["MEMBER_JOINED"] = "member.joined";
|
|
205
|
+
WebSocketEventType2["AGENT_STARTED"] = "agent.started";
|
|
206
|
+
WebSocketEventType2["AGENT_OUTPUT"] = "agent.output";
|
|
207
|
+
WebSocketEventType2["AGENT_STOPPED"] = "agent.stopped";
|
|
208
|
+
WebSocketEventType2["AGENT_ERROR"] = "agent.error";
|
|
191
209
|
})(WebSocketEventType || (WebSocketEventType = {}));
|
|
192
|
-
var AuthProvider;
|
|
193
|
-
(function(AuthProvider2) {
|
|
194
|
-
AuthProvider2["CREDENTIALS"] = "credentials";
|
|
195
|
-
AuthProvider2["LDAP"] = "ldap";
|
|
196
|
-
AuthProvider2["SSO"] = "sso";
|
|
197
|
-
})(AuthProvider || (AuthProvider = {}));
|
|
198
210
|
var SubscriptionStatus;
|
|
199
211
|
(function(SubscriptionStatus2) {
|
|
200
212
|
SubscriptionStatus2["ACTIVE"] = "ACTIVE";
|
|
@@ -210,6 +222,37 @@ var EventType;
|
|
|
210
222
|
EventType2["ACCESS"] = "ACCESS";
|
|
211
223
|
EventType2["MODIFICATION"] = "MODIFICATION";
|
|
212
224
|
})(EventType || (EventType = {}));
|
|
225
|
+
var CreatedVia;
|
|
226
|
+
(function(CreatedVia2) {
|
|
227
|
+
CreatedVia2["UI"] = "UI";
|
|
228
|
+
CreatedVia2["API_KEY"] = "API_KEY";
|
|
229
|
+
CreatedVia2["OAUTH"] = "OAUTH";
|
|
230
|
+
})(CreatedVia || (CreatedVia = {}));
|
|
231
|
+
var AgentModel;
|
|
232
|
+
(function(AgentModel2) {
|
|
233
|
+
AgentModel2["OPUS"] = "OPUS";
|
|
234
|
+
AgentModel2["SONNET"] = "SONNET";
|
|
235
|
+
AgentModel2["HAIKU"] = "HAIKU";
|
|
236
|
+
})(AgentModel || (AgentModel = {}));
|
|
237
|
+
var AgentModelMode;
|
|
238
|
+
(function(AgentModelMode2) {
|
|
239
|
+
AgentModelMode2["DEFAULT"] = "DEFAULT";
|
|
240
|
+
AgentModelMode2["PRESET"] = "PRESET";
|
|
241
|
+
AgentModelMode2["CUSTOM"] = "CUSTOM";
|
|
242
|
+
})(AgentModelMode || (AgentModelMode = {}));
|
|
243
|
+
var AgentCLIType;
|
|
244
|
+
(function(AgentCLIType2) {
|
|
245
|
+
AgentCLIType2["CLAUDE_CODE"] = "CLAUDE_CODE";
|
|
246
|
+
AgentCLIType2["OPENCODE"] = "OPENCODE";
|
|
247
|
+
})(AgentCLIType || (AgentCLIType = {}));
|
|
248
|
+
var AgentSessionStatus;
|
|
249
|
+
(function(AgentSessionStatus2) {
|
|
250
|
+
AgentSessionStatus2["STARTING"] = "STARTING";
|
|
251
|
+
AgentSessionStatus2["RUNNING"] = "RUNNING";
|
|
252
|
+
AgentSessionStatus2["STOPPING"] = "STOPPING";
|
|
253
|
+
AgentSessionStatus2["STOPPED"] = "STOPPED";
|
|
254
|
+
AgentSessionStatus2["ERROR"] = "ERROR";
|
|
255
|
+
})(AgentSessionStatus || (AgentSessionStatus = {}));
|
|
213
256
|
|
|
214
257
|
// ../../packages/core/dist/constants/state-machine.js
|
|
215
258
|
var VALID_TRANSITIONS = {
|
|
@@ -233,6 +276,62 @@ var VALID_TRANSITIONS = {
|
|
|
233
276
|
[TaskState.DONE]: []
|
|
234
277
|
};
|
|
235
278
|
|
|
279
|
+
// ../../packages/core/dist/constants/oauth.js
|
|
280
|
+
var OAuthScopes = {
|
|
281
|
+
/** Read-only access to MCP resources */
|
|
282
|
+
READ: "mcp:read",
|
|
283
|
+
/** Read and write access to MCP resources */
|
|
284
|
+
WRITE: "mcp:write",
|
|
285
|
+
/** Full administrative access */
|
|
286
|
+
ADMIN: "mcp:admin"
|
|
287
|
+
};
|
|
288
|
+
var VALID_OAUTH_SCOPES = [
|
|
289
|
+
OAuthScopes.READ,
|
|
290
|
+
OAuthScopes.WRITE,
|
|
291
|
+
OAuthScopes.ADMIN
|
|
292
|
+
];
|
|
293
|
+
var DEFAULT_OAUTH_SCOPES = `${OAuthScopes.READ} ${OAuthScopes.WRITE}`;
|
|
294
|
+
var OAUTH_SCOPE_TO_PERMISSION = {
|
|
295
|
+
[OAuthScopes.READ]: ApiKeyPermission.READ,
|
|
296
|
+
[OAuthScopes.WRITE]: ApiKeyPermission.WRITE,
|
|
297
|
+
[OAuthScopes.ADMIN]: ApiKeyPermission.ADMIN
|
|
298
|
+
};
|
|
299
|
+
var PERMISSION_TO_OAUTH_SCOPE = {
|
|
300
|
+
[ApiKeyPermission.READ]: OAuthScopes.READ,
|
|
301
|
+
[ApiKeyPermission.WRITE]: OAuthScopes.WRITE,
|
|
302
|
+
[ApiKeyPermission.ADMIN]: OAuthScopes.ADMIN
|
|
303
|
+
};
|
|
304
|
+
var OAuthTokenLifetimes = {
|
|
305
|
+
/** Access token lifetime: 1 hour */
|
|
306
|
+
ACCESS_TOKEN_MS: 60 * 60 * 1e3,
|
|
307
|
+
/** Refresh token lifetime: 30 days */
|
|
308
|
+
REFRESH_TOKEN_MS: 30 * 24 * 60 * 60 * 1e3,
|
|
309
|
+
/** Authorization code lifetime: 10 minutes */
|
|
310
|
+
AUTHORIZATION_CODE_MS: 10 * 60 * 1e3
|
|
311
|
+
};
|
|
312
|
+
var OAuthGrantTypes = {
|
|
313
|
+
AUTHORIZATION_CODE: "authorization_code",
|
|
314
|
+
REFRESH_TOKEN: "refresh_token"
|
|
315
|
+
};
|
|
316
|
+
var SUPPORTED_GRANT_TYPES = [
|
|
317
|
+
OAuthGrantTypes.AUTHORIZATION_CODE,
|
|
318
|
+
OAuthGrantTypes.REFRESH_TOKEN
|
|
319
|
+
];
|
|
320
|
+
var OAuthResponseTypes = {
|
|
321
|
+
CODE: "code"
|
|
322
|
+
};
|
|
323
|
+
var OAuthCodeChallengeMethods = {
|
|
324
|
+
S256: "S256"
|
|
325
|
+
};
|
|
326
|
+
var OAuthRateLimits = {
|
|
327
|
+
/** /oauth/token: 30 requests per minute per client */
|
|
328
|
+
TOKEN_ENDPOINT: { limit: 30, windowMs: 60 * 1e3 },
|
|
329
|
+
/** /oauth/authorize: 10 requests per minute per user */
|
|
330
|
+
AUTHORIZE_ENDPOINT: { limit: 10, windowMs: 60 * 1e3 },
|
|
331
|
+
/** /oauth/register: 5 requests per minute per IP */
|
|
332
|
+
REGISTER_ENDPOINT: { limit: 5, windowMs: 60 * 1e3 }
|
|
333
|
+
};
|
|
334
|
+
|
|
236
335
|
// ../../packages/core/dist/config/deployment.js
|
|
237
336
|
var config = {
|
|
238
337
|
deploymentMode: process.env.DEPLOYMENT_MODE || "saas"
|
|
@@ -240,20 +339,24 @@ var config = {
|
|
|
240
339
|
var isSaas = config.deploymentMode === "saas";
|
|
241
340
|
var isOnPrem = config.deploymentMode === "onprem";
|
|
242
341
|
|
|
243
|
-
// ../../packages/core/dist/
|
|
244
|
-
var
|
|
342
|
+
// ../../packages/core/dist/versions.js
|
|
343
|
+
var VERSIONS = {
|
|
344
|
+
core: "0.4.0",
|
|
345
|
+
web: "0.4.0",
|
|
346
|
+
mcp: "0.5.0"
|
|
347
|
+
};
|
|
348
|
+
var VERSION2 = VERSIONS.core;
|
|
245
349
|
|
|
246
350
|
// ../../packages/core/dist/config/index.js
|
|
247
351
|
var DEPLOYMENT_MODE = process.env.DEPLOYMENT_MODE || "saas";
|
|
248
352
|
var config2 = {
|
|
249
353
|
version: VERSION2,
|
|
354
|
+
packages: VERSIONS,
|
|
250
355
|
deploymentMode: DEPLOYMENT_MODE,
|
|
251
356
|
billing: {
|
|
252
357
|
enabled: DEPLOYMENT_MODE === "saas",
|
|
253
358
|
revenuecat: {
|
|
254
|
-
publicKey: process.env.
|
|
255
|
-
stripeKey: process.env.STRIPE_SECRET_KEY
|
|
256
|
-
// Required by RevenueCat Web Billing
|
|
359
|
+
publicKey: process.env.NEXT_PUBLIC_REVENUECAT_PUBLIC_KEY
|
|
257
360
|
}
|
|
258
361
|
},
|
|
259
362
|
licensing: {
|
|
@@ -321,6 +424,18 @@ var config2 = {
|
|
|
321
424
|
requestsPerHour: 1e3
|
|
322
425
|
}
|
|
323
426
|
},
|
|
427
|
+
agent: {
|
|
428
|
+
defaultModel: "SONNET",
|
|
429
|
+
sessionTimeoutMs: 30 * 60 * 1e3,
|
|
430
|
+
// 30 minutes
|
|
431
|
+
maxSessionDurationMs: 4 * 60 * 60 * 1e3,
|
|
432
|
+
// 4 hours
|
|
433
|
+
maxConcurrentSessions: {
|
|
434
|
+
FREE: 1,
|
|
435
|
+
PRO: 5,
|
|
436
|
+
ENTERPRISE: -1
|
|
437
|
+
}
|
|
438
|
+
},
|
|
324
439
|
limits: {
|
|
325
440
|
projectNameMaxLength: 100,
|
|
326
441
|
taskDescriptionMaxLength: 5e3,
|
|
@@ -359,7 +474,6 @@ var OrganizationIdSchema = import_zod.z.string().regex(/^org_[a-zA-Z0-9]+$/);
|
|
|
359
474
|
var OrganizationSchema = import_zod.z.object({
|
|
360
475
|
id: OrganizationIdSchema,
|
|
361
476
|
name: import_zod.z.string().min(1).max(255),
|
|
362
|
-
slug: import_zod.z.string().min(1).max(100).regex(/^[a-z0-9-]+$/),
|
|
363
477
|
logoUrl: import_zod.z.string().url().nullable(),
|
|
364
478
|
accentColor: import_zod.z.string().regex(/^#[0-9A-Fa-f]{6}$/).nullable(),
|
|
365
479
|
tenantName: import_zod.z.string().nullable(),
|
|
@@ -487,239 +601,376 @@ var ProjectCollaboratorSchema = import_zod.z.object({
|
|
|
487
601
|
});
|
|
488
602
|
|
|
489
603
|
// ../../packages/core/dist/validation/index.js
|
|
604
|
+
var import_zod3 = require("zod");
|
|
605
|
+
|
|
606
|
+
// ../../packages/core/dist/validation/oauth.js
|
|
490
607
|
var import_zod2 = require("zod");
|
|
491
|
-
var
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
var
|
|
608
|
+
var scopeString = import_zod2.z.string().optional().transform((val) => {
|
|
609
|
+
if (!val)
|
|
610
|
+
return void 0;
|
|
611
|
+
const scopes = val.split(" ").filter(Boolean);
|
|
612
|
+
const validScopes = scopes.filter((s) => VALID_OAUTH_SCOPES.includes(s));
|
|
613
|
+
return validScopes.length > 0 ? validScopes.join(" ") : void 0;
|
|
614
|
+
});
|
|
615
|
+
var redirectUri = import_zod2.z.string().url().refine((uri) => {
|
|
616
|
+
const url = new URL(uri);
|
|
617
|
+
return url.protocol === "https:" || url.hostname === "localhost" || url.hostname === "127.0.0.1";
|
|
618
|
+
}, { message: "redirect_uri must use HTTPS or be localhost" });
|
|
619
|
+
var codeVerifier = import_zod2.z.string().min(43).max(128).regex(/^[A-Za-z0-9._~-]+$/, "code_verifier must only contain unreserved characters");
|
|
620
|
+
var codeChallenge = import_zod2.z.string().min(43).max(128).regex(/^[A-Za-z0-9_-]+$/, "code_challenge must be base64url encoded (no padding)");
|
|
621
|
+
var DynamicClientRegistrationSchema = import_zod2.z.object({
|
|
622
|
+
redirect_uris: import_zod2.z.array(redirectUri).min(1),
|
|
623
|
+
client_name: import_zod2.z.string().min(1).max(255),
|
|
624
|
+
client_uri: import_zod2.z.string().url().optional(),
|
|
625
|
+
logo_uri: import_zod2.z.string().url().optional(),
|
|
626
|
+
// Accept lowercase OAuth spec values
|
|
627
|
+
grant_types: import_zod2.z.array(import_zod2.z.enum(["authorization_code", "refresh_token"])).default(["authorization_code", "refresh_token"]),
|
|
628
|
+
response_types: import_zod2.z.array(import_zod2.z.enum([OAuthResponseTypes.CODE])).default([OAuthResponseTypes.CODE]),
|
|
629
|
+
scope: scopeString,
|
|
630
|
+
// Accept lowercase OAuth spec values
|
|
631
|
+
token_endpoint_auth_method: import_zod2.z.enum(["none", "client_secret_post", "client_secret_basic"]).default("none")
|
|
632
|
+
});
|
|
633
|
+
var DynamicClientRegistrationResponseSchema = import_zod2.z.object({
|
|
634
|
+
client_id: import_zod2.z.string(),
|
|
635
|
+
client_secret: import_zod2.z.string().optional(),
|
|
636
|
+
client_id_issued_at: import_zod2.z.number(),
|
|
637
|
+
client_secret_expires_at: import_zod2.z.number().optional(),
|
|
638
|
+
redirect_uris: import_zod2.z.array(import_zod2.z.string()),
|
|
639
|
+
client_name: import_zod2.z.string(),
|
|
640
|
+
client_uri: import_zod2.z.string().optional(),
|
|
641
|
+
logo_uri: import_zod2.z.string().optional(),
|
|
642
|
+
grant_types: import_zod2.z.array(import_zod2.z.string()),
|
|
643
|
+
response_types: import_zod2.z.array(import_zod2.z.string()),
|
|
644
|
+
scope: import_zod2.z.string(),
|
|
645
|
+
token_endpoint_auth_method: import_zod2.z.string(),
|
|
646
|
+
registration_access_token: import_zod2.z.string().optional(),
|
|
647
|
+
registration_client_uri: import_zod2.z.string().optional()
|
|
648
|
+
});
|
|
649
|
+
var AuthorizationRequestSchema = import_zod2.z.object({
|
|
650
|
+
response_type: import_zod2.z.literal(OAuthResponseTypes.CODE),
|
|
651
|
+
client_id: import_zod2.z.string().min(1),
|
|
652
|
+
redirect_uri: redirectUri,
|
|
653
|
+
scope: scopeString,
|
|
654
|
+
state: import_zod2.z.string().max(255).optional(),
|
|
655
|
+
// PKCE is mandatory in OAuth 2.1
|
|
656
|
+
code_challenge: codeChallenge,
|
|
657
|
+
code_challenge_method: import_zod2.z.literal(OAuthCodeChallengeMethods.S256)
|
|
658
|
+
});
|
|
659
|
+
var TokenRequestAuthorizationCodeSchema = import_zod2.z.object({
|
|
660
|
+
grant_type: import_zod2.z.literal(OAuthGrantTypes.AUTHORIZATION_CODE),
|
|
661
|
+
code: import_zod2.z.string().min(1),
|
|
662
|
+
redirect_uri: redirectUri,
|
|
663
|
+
client_id: import_zod2.z.string().min(1),
|
|
664
|
+
// PKCE code verifier is mandatory
|
|
665
|
+
code_verifier: codeVerifier,
|
|
666
|
+
// Client secret is optional (for confidential clients)
|
|
667
|
+
client_secret: import_zod2.z.string().optional()
|
|
668
|
+
});
|
|
669
|
+
var TokenRequestRefreshTokenSchema = import_zod2.z.object({
|
|
670
|
+
grant_type: import_zod2.z.literal(OAuthGrantTypes.REFRESH_TOKEN),
|
|
671
|
+
refresh_token: import_zod2.z.string().min(1),
|
|
672
|
+
client_id: import_zod2.z.string().min(1),
|
|
673
|
+
// Optional: request reduced scope
|
|
674
|
+
scope: scopeString,
|
|
675
|
+
// Client secret is optional (for confidential clients)
|
|
676
|
+
client_secret: import_zod2.z.string().optional()
|
|
677
|
+
});
|
|
678
|
+
var TokenRequestSchema = import_zod2.z.discriminatedUnion("grant_type", [
|
|
679
|
+
TokenRequestAuthorizationCodeSchema,
|
|
680
|
+
TokenRequestRefreshTokenSchema
|
|
681
|
+
]);
|
|
682
|
+
var TokenResponseSchema = import_zod2.z.object({
|
|
683
|
+
access_token: import_zod2.z.string(),
|
|
684
|
+
token_type: import_zod2.z.literal("Bearer"),
|
|
685
|
+
expires_in: import_zod2.z.number(),
|
|
686
|
+
refresh_token: import_zod2.z.string().optional(),
|
|
687
|
+
scope: import_zod2.z.string()
|
|
688
|
+
});
|
|
689
|
+
var TokenRevocationRequestSchema = import_zod2.z.object({
|
|
690
|
+
token: import_zod2.z.string().min(1),
|
|
691
|
+
token_type_hint: import_zod2.z.enum(["access_token", "refresh_token"]).optional(),
|
|
692
|
+
client_id: import_zod2.z.string().min(1),
|
|
693
|
+
client_secret: import_zod2.z.string().optional()
|
|
694
|
+
});
|
|
695
|
+
var OAuthErrorResponseSchema = import_zod2.z.object({
|
|
696
|
+
error: import_zod2.z.string(),
|
|
697
|
+
error_description: import_zod2.z.string().optional(),
|
|
698
|
+
error_uri: import_zod2.z.string().url().optional(),
|
|
699
|
+
state: import_zod2.z.string().optional()
|
|
700
|
+
});
|
|
701
|
+
var AuthorizationServerMetadataSchema = import_zod2.z.object({
|
|
702
|
+
issuer: import_zod2.z.string().url(),
|
|
703
|
+
authorization_endpoint: import_zod2.z.string().url(),
|
|
704
|
+
token_endpoint: import_zod2.z.string().url(),
|
|
705
|
+
registration_endpoint: import_zod2.z.string().url().optional(),
|
|
706
|
+
revocation_endpoint: import_zod2.z.string().url().optional(),
|
|
707
|
+
scopes_supported: import_zod2.z.array(import_zod2.z.string()),
|
|
708
|
+
response_types_supported: import_zod2.z.array(import_zod2.z.string()),
|
|
709
|
+
grant_types_supported: import_zod2.z.array(import_zod2.z.string()),
|
|
710
|
+
token_endpoint_auth_methods_supported: import_zod2.z.array(import_zod2.z.string()),
|
|
711
|
+
code_challenge_methods_supported: import_zod2.z.array(import_zod2.z.string()),
|
|
712
|
+
service_documentation: import_zod2.z.string().url().optional()
|
|
713
|
+
});
|
|
714
|
+
var ProtectedResourceMetadataSchema = import_zod2.z.object({
|
|
715
|
+
resource: import_zod2.z.string().url(),
|
|
716
|
+
authorization_servers: import_zod2.z.array(import_zod2.z.string().url()),
|
|
717
|
+
scopes_supported: import_zod2.z.array(import_zod2.z.string()).optional(),
|
|
718
|
+
bearer_methods_supported: import_zod2.z.array(import_zod2.z.string()).optional(),
|
|
719
|
+
resource_signing_alg_values_supported: import_zod2.z.array(import_zod2.z.string()).optional(),
|
|
720
|
+
resource_documentation: import_zod2.z.string().url().optional()
|
|
721
|
+
});
|
|
722
|
+
var InternalTokenValidationRequestSchema = import_zod2.z.object({
|
|
723
|
+
access_token: import_zod2.z.string().min(1)
|
|
724
|
+
});
|
|
725
|
+
var InternalTokenValidationResponseSchema = import_zod2.z.object({
|
|
726
|
+
valid: import_zod2.z.boolean(),
|
|
727
|
+
userId: import_zod2.z.string().optional(),
|
|
728
|
+
userEmail: import_zod2.z.string().optional(),
|
|
729
|
+
userName: import_zod2.z.string().optional(),
|
|
730
|
+
scope: import_zod2.z.string().optional(),
|
|
731
|
+
permissions: import_zod2.z.string().optional(),
|
|
732
|
+
clientId: import_zod2.z.string().optional(),
|
|
733
|
+
expiresAt: import_zod2.z.string().optional()
|
|
734
|
+
});
|
|
735
|
+
|
|
736
|
+
// ../../packages/core/dist/validation/index.js
|
|
737
|
+
var ListProjectsInputSchema = import_zod3.z.object({
|
|
738
|
+
workspaceType: import_zod3.z.preprocess((val) => typeof val === "string" ? val.toUpperCase() : val, import_zod3.z.enum(["TEAM", "PERSONAL", "ALL"]).optional())
|
|
739
|
+
});
|
|
740
|
+
var ListTasksInputSchema = import_zod3.z.object({
|
|
741
|
+
projectId: import_zod3.z.string().optional(),
|
|
742
|
+
state: import_zod3.z.nativeEnum(TaskState).optional(),
|
|
743
|
+
assigneeId: import_zod3.z.string().optional(),
|
|
744
|
+
includeArchived: import_zod3.z.boolean().optional()
|
|
745
|
+
});
|
|
746
|
+
var cuidOrPrefixedId = import_zod3.z.string().regex(/^([a-z0-9]+|[a-z]+_[a-zA-Z0-9]+)$/);
|
|
747
|
+
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");
|
|
748
|
+
var GetTaskInputSchema = import_zod3.z.object({
|
|
503
749
|
taskId: cuidOrPrefixedId
|
|
504
750
|
});
|
|
505
|
-
var AssignTaskInputSchema =
|
|
751
|
+
var AssignTaskInputSchema = import_zod3.z.object({
|
|
506
752
|
projectId: cuidOrPrefixedId,
|
|
507
753
|
taskId: cuidOrPrefixedId,
|
|
508
|
-
expectedState:
|
|
754
|
+
expectedState: import_zod3.z.nativeEnum(TaskState).default(TaskState.TODO)
|
|
509
755
|
});
|
|
510
|
-
var UpdateProgressInputSchema =
|
|
756
|
+
var UpdateProgressInputSchema = import_zod3.z.object({
|
|
511
757
|
taskId: cuidOrPrefixedId,
|
|
512
|
-
statusMessage:
|
|
513
|
-
completedCheckpointIds:
|
|
514
|
-
currentCheckpointIndex:
|
|
758
|
+
statusMessage: import_zod3.z.string().max(1e3).optional(),
|
|
759
|
+
completedCheckpointIds: import_zod3.z.array(import_zod3.z.string()).optional(),
|
|
760
|
+
currentCheckpointIndex: import_zod3.z.number().int().optional()
|
|
515
761
|
});
|
|
516
|
-
var CompleteTaskInputSchema =
|
|
762
|
+
var CompleteTaskInputSchema = import_zod3.z.object({
|
|
517
763
|
projectId: cuidOrPrefixedId,
|
|
518
764
|
taskId: cuidOrPrefixedId,
|
|
519
|
-
pullRequestTitle:
|
|
520
|
-
pullRequestBody:
|
|
765
|
+
pullRequestTitle: import_zod3.z.string().min(1).max(300).optional(),
|
|
766
|
+
pullRequestBody: import_zod3.z.string().max(1e4).optional()
|
|
521
767
|
});
|
|
522
|
-
var ReportErrorInputSchema =
|
|
768
|
+
var ReportErrorInputSchema = import_zod3.z.object({
|
|
523
769
|
taskId: cuidOrPrefixedId,
|
|
524
|
-
errorType:
|
|
525
|
-
errorMessage:
|
|
526
|
-
context:
|
|
770
|
+
errorType: import_zod3.z.nativeEnum(ErrorType),
|
|
771
|
+
errorMessage: import_zod3.z.string().min(1).max(1e3),
|
|
772
|
+
context: import_zod3.z.string().max(2e3).optional()
|
|
527
773
|
});
|
|
528
|
-
var GetProjectContextInputSchema =
|
|
774
|
+
var GetProjectContextInputSchema = import_zod3.z.object({
|
|
529
775
|
projectId: cuidOrPrefixedId
|
|
530
776
|
});
|
|
531
|
-
var AddNoteInputSchema =
|
|
777
|
+
var AddNoteInputSchema = import_zod3.z.object({
|
|
532
778
|
taskId: cuidOrPrefixedId,
|
|
533
|
-
content:
|
|
779
|
+
content: import_zod3.z.string().min(1).max(500)
|
|
534
780
|
});
|
|
535
|
-
var AbandonTaskInputSchema =
|
|
781
|
+
var AbandonTaskInputSchema = import_zod3.z.object({
|
|
536
782
|
projectId: cuidOrPrefixedId,
|
|
537
783
|
taskId: cuidOrPrefixedId,
|
|
538
|
-
deleteBranch:
|
|
784
|
+
deleteBranch: import_zod3.z.boolean().optional()
|
|
539
785
|
});
|
|
540
|
-
var RequestChangesInputSchema =
|
|
786
|
+
var RequestChangesInputSchema = import_zod3.z.object({
|
|
541
787
|
projectId: cuidOrPrefixedId,
|
|
542
788
|
taskId: cuidOrPrefixedId,
|
|
543
|
-
reviewComments:
|
|
544
|
-
requestedChanges:
|
|
789
|
+
reviewComments: import_zod3.z.string().min(1).max(5e3),
|
|
790
|
+
requestedChanges: import_zod3.z.array(import_zod3.z.string().min(1).max(500)).optional()
|
|
545
791
|
});
|
|
546
|
-
var ApproveTaskInputSchema =
|
|
792
|
+
var ApproveTaskInputSchema = import_zod3.z.object({
|
|
547
793
|
projectId: cuidOrPrefixedId,
|
|
548
794
|
taskId: cuidOrPrefixedId,
|
|
549
|
-
reviewComments:
|
|
795
|
+
reviewComments: import_zod3.z.string().max(2e3).optional()
|
|
550
796
|
});
|
|
551
|
-
var ArchiveTaskInputSchema =
|
|
797
|
+
var ArchiveTaskInputSchema = import_zod3.z.object({
|
|
552
798
|
projectId: cuidOrPrefixedId,
|
|
553
799
|
taskId: cuidOrPrefixedId
|
|
554
800
|
});
|
|
555
|
-
var UnarchiveTaskInputSchema =
|
|
801
|
+
var UnarchiveTaskInputSchema = import_zod3.z.object({
|
|
556
802
|
projectId: cuidOrPrefixedId,
|
|
557
803
|
taskId: cuidOrPrefixedId
|
|
558
804
|
});
|
|
559
|
-
var CreatePersonalProjectInputSchema =
|
|
560
|
-
name:
|
|
561
|
-
description:
|
|
562
|
-
repositoryUrl:
|
|
805
|
+
var CreatePersonalProjectInputSchema = import_zod3.z.object({
|
|
806
|
+
name: import_zod3.z.string().min(1).max(100),
|
|
807
|
+
description: import_zod3.z.string().max(500).optional(),
|
|
808
|
+
repositoryUrl: import_zod3.z.string().url()
|
|
563
809
|
});
|
|
564
|
-
var CheckActiveTaskInputSchema =
|
|
565
|
-
var CreateTaskMCPInputSchema =
|
|
810
|
+
var CheckActiveTaskInputSchema = import_zod3.z.object({});
|
|
811
|
+
var CreateTaskMCPInputSchema = import_zod3.z.object({
|
|
566
812
|
projectId: cuidOrPrefixedId,
|
|
567
813
|
epicId: cuidOrPrefixedId.nullable().optional(),
|
|
568
|
-
title:
|
|
569
|
-
description:
|
|
570
|
-
priority:
|
|
571
|
-
acceptanceCriteria:
|
|
572
|
-
description:
|
|
814
|
+
title: import_zod3.z.string().min(1).max(200),
|
|
815
|
+
description: import_zod3.z.string().max(5e3),
|
|
816
|
+
priority: import_zod3.z.nativeEnum(TaskPriority).default(TaskPriority.MEDIUM),
|
|
817
|
+
acceptanceCriteria: import_zod3.z.array(import_zod3.z.object({
|
|
818
|
+
description: import_zod3.z.string().min(1).max(500)
|
|
573
819
|
})).min(1)
|
|
574
820
|
});
|
|
575
|
-
var CreateOrganizationInputSchema =
|
|
576
|
-
name:
|
|
577
|
-
slug: import_zod2.z.string().min(1).max(100).regex(/^[a-z0-9-]+$/).optional()
|
|
821
|
+
var CreateOrganizationInputSchema = import_zod3.z.object({
|
|
822
|
+
name: import_zod3.z.string().min(1).max(255)
|
|
578
823
|
});
|
|
579
|
-
var UpdateOrganizationInputSchema =
|
|
824
|
+
var UpdateOrganizationInputSchema = import_zod3.z.object({
|
|
580
825
|
organizationId: cuidOrPrefixedId,
|
|
581
|
-
name:
|
|
582
|
-
logoUrl:
|
|
583
|
-
accentColor:
|
|
584
|
-
tenantName:
|
|
585
|
-
});
|
|
586
|
-
var CreateProjectInputSchema =
|
|
587
|
-
name:
|
|
588
|
-
description:
|
|
589
|
-
type:
|
|
590
|
-
repositoryUrl:
|
|
591
|
-
baseBranch:
|
|
592
|
-
tags:
|
|
593
|
-
});
|
|
594
|
-
var UpdateProjectInputSchema =
|
|
595
|
-
projectId:
|
|
596
|
-
name:
|
|
597
|
-
description:
|
|
598
|
-
repositoryUrl:
|
|
599
|
-
baseBranch:
|
|
600
|
-
tags:
|
|
601
|
-
allowMemberArchive:
|
|
602
|
-
|
|
603
|
-
|
|
826
|
+
name: import_zod3.z.string().min(1).max(255).optional(),
|
|
827
|
+
logoUrl: import_zod3.z.string().url().nullable().optional(),
|
|
828
|
+
accentColor: import_zod3.z.string().regex(/^#[0-9A-Fa-f]{6}$/, "Invalid hex color format. Expected #RRGGBB").nullable().optional(),
|
|
829
|
+
tenantName: import_zod3.z.string().max(255).nullable().optional()
|
|
830
|
+
});
|
|
831
|
+
var CreateProjectInputSchema = import_zod3.z.object({
|
|
832
|
+
name: import_zod3.z.string().min(1).max(100),
|
|
833
|
+
description: import_zod3.z.string().max(500).optional(),
|
|
834
|
+
type: import_zod3.z.nativeEnum(ProjectType),
|
|
835
|
+
repositoryUrl: import_zod3.z.string().url(),
|
|
836
|
+
baseBranch: import_zod3.z.string().default("develop").optional(),
|
|
837
|
+
tags: import_zod3.z.array(import_zod3.z.string()).default([])
|
|
838
|
+
});
|
|
839
|
+
var UpdateProjectInputSchema = import_zod3.z.object({
|
|
840
|
+
projectId: import_zod3.z.string().min(1).optional(),
|
|
841
|
+
name: import_zod3.z.string().min(1).max(100).optional(),
|
|
842
|
+
description: import_zod3.z.string().max(500).optional(),
|
|
843
|
+
repositoryUrl: import_zod3.z.string().url().optional(),
|
|
844
|
+
baseBranch: import_zod3.z.string().optional(),
|
|
845
|
+
tags: import_zod3.z.array(import_zod3.z.string()).optional(),
|
|
846
|
+
allowMemberArchive: import_zod3.z.boolean().optional(),
|
|
847
|
+
localRepoPath: import_zod3.z.string().max(500).optional()
|
|
848
|
+
});
|
|
849
|
+
var CreateEpicInputSchema = import_zod3.z.object({
|
|
604
850
|
projectId: cuidOrPrefixedId,
|
|
605
|
-
name:
|
|
606
|
-
description:
|
|
607
|
-
});
|
|
608
|
-
var CreateTaskInputSchema =
|
|
609
|
-
projectId:
|
|
610
|
-
epicId:
|
|
611
|
-
title:
|
|
612
|
-
description:
|
|
613
|
-
priority:
|
|
614
|
-
acceptanceCriteria:
|
|
615
|
-
description:
|
|
851
|
+
name: import_zod3.z.string().min(1).max(200),
|
|
852
|
+
description: import_zod3.z.string().max(2e3).optional()
|
|
853
|
+
});
|
|
854
|
+
var CreateTaskInputSchema = import_zod3.z.object({
|
|
855
|
+
projectId: import_zod3.z.string().min(1),
|
|
856
|
+
epicId: import_zod3.z.string().min(1).nullable().optional(),
|
|
857
|
+
title: import_zod3.z.string().min(1).max(200),
|
|
858
|
+
description: import_zod3.z.string().max(5e3),
|
|
859
|
+
priority: import_zod3.z.nativeEnum(TaskPriority).default(TaskPriority.MEDIUM),
|
|
860
|
+
acceptanceCriteria: import_zod3.z.array(import_zod3.z.object({
|
|
861
|
+
description: import_zod3.z.string().min(1).max(500)
|
|
616
862
|
})).min(1)
|
|
617
863
|
});
|
|
618
|
-
var UpdateTaskInputSchema =
|
|
619
|
-
taskId:
|
|
620
|
-
title:
|
|
621
|
-
description:
|
|
622
|
-
priority:
|
|
623
|
-
state:
|
|
624
|
-
assigneeId:
|
|
625
|
-
acceptanceCriteria:
|
|
626
|
-
id:
|
|
627
|
-
description:
|
|
628
|
-
completed:
|
|
864
|
+
var UpdateTaskInputSchema = import_zod3.z.object({
|
|
865
|
+
taskId: import_zod3.z.string().min(1),
|
|
866
|
+
title: import_zod3.z.string().min(1).max(200).optional(),
|
|
867
|
+
description: import_zod3.z.string().max(5e3).optional(),
|
|
868
|
+
priority: import_zod3.z.nativeEnum(TaskPriority).optional(),
|
|
869
|
+
state: import_zod3.z.nativeEnum(TaskState).optional(),
|
|
870
|
+
assigneeId: import_zod3.z.string().nullable().optional(),
|
|
871
|
+
acceptanceCriteria: import_zod3.z.array(import_zod3.z.object({
|
|
872
|
+
id: import_zod3.z.string().optional(),
|
|
873
|
+
description: import_zod3.z.string().min(1).max(500),
|
|
874
|
+
completed: import_zod3.z.boolean().optional()
|
|
629
875
|
})).optional()
|
|
630
876
|
});
|
|
631
|
-
var AssignTaskWebappInputSchema =
|
|
632
|
-
taskId:
|
|
633
|
-
userId:
|
|
877
|
+
var AssignTaskWebappInputSchema = import_zod3.z.object({
|
|
878
|
+
taskId: import_zod3.z.string().min(1),
|
|
879
|
+
userId: import_zod3.z.string().min(1)
|
|
634
880
|
});
|
|
635
|
-
var CreateTagInputSchema =
|
|
881
|
+
var CreateTagInputSchema = import_zod3.z.object({
|
|
636
882
|
organizationId: cuidOrPrefixedId,
|
|
637
|
-
name:
|
|
883
|
+
name: import_zod3.z.string().min(1).max(50).regex(/^[a-zA-Z0-9\s-]+$/)
|
|
638
884
|
});
|
|
639
|
-
var UpdateTagInputSchema =
|
|
640
|
-
name:
|
|
885
|
+
var UpdateTagInputSchema = import_zod3.z.object({
|
|
886
|
+
name: import_zod3.z.string().min(1).max(50).regex(/^[a-zA-Z0-9\s-]+$/)
|
|
641
887
|
});
|
|
642
|
-
var UpdateOrganizationSettingsInputSchema =
|
|
888
|
+
var UpdateOrganizationSettingsInputSchema = import_zod3.z.object({
|
|
643
889
|
organizationId: cuidOrPrefixedId,
|
|
644
|
-
ldapEnabled:
|
|
645
|
-
ldapUrl:
|
|
646
|
-
ldapBindDN:
|
|
647
|
-
ldapSearchBase:
|
|
648
|
-
deleteMergedBranches:
|
|
649
|
-
enforceConventionalCommits:
|
|
650
|
-
maxPersonalProjectsPerUser:
|
|
651
|
-
logoUrl:
|
|
652
|
-
accentColor:
|
|
653
|
-
tenantName:
|
|
654
|
-
});
|
|
655
|
-
var InviteUserInputSchema =
|
|
890
|
+
ldapEnabled: import_zod3.z.boolean().optional(),
|
|
891
|
+
ldapUrl: import_zod3.z.string().url().nullable().optional(),
|
|
892
|
+
ldapBindDN: import_zod3.z.string().nullable().optional(),
|
|
893
|
+
ldapSearchBase: import_zod3.z.string().nullable().optional(),
|
|
894
|
+
deleteMergedBranches: import_zod3.z.boolean().optional(),
|
|
895
|
+
enforceConventionalCommits: import_zod3.z.boolean().optional(),
|
|
896
|
+
maxPersonalProjectsPerUser: import_zod3.z.number().int().min(0).optional(),
|
|
897
|
+
logoUrl: import_zod3.z.string().url().nullable().optional(),
|
|
898
|
+
accentColor: import_zod3.z.string().regex(/^#[0-9A-Fa-f]{6}$/, "Invalid hex color format. Expected #RRGGBB").nullable().optional(),
|
|
899
|
+
tenantName: import_zod3.z.string().max(255).nullable().optional()
|
|
900
|
+
});
|
|
901
|
+
var InviteUserInputSchema = import_zod3.z.object({
|
|
656
902
|
organizationId: cuidOrPrefixedId,
|
|
657
|
-
email:
|
|
658
|
-
role:
|
|
659
|
-
tags:
|
|
903
|
+
email: import_zod3.z.string().email(),
|
|
904
|
+
role: import_zod3.z.nativeEnum(UserRole).default(UserRole.MEMBER),
|
|
905
|
+
tags: import_zod3.z.array(import_zod3.z.string()).default([])
|
|
660
906
|
});
|
|
661
|
-
var AssignUserTagsInputSchema =
|
|
907
|
+
var AssignUserTagsInputSchema = import_zod3.z.object({
|
|
662
908
|
userId: cuidOrPrefixedId,
|
|
663
|
-
tags:
|
|
909
|
+
tags: import_zod3.z.array(import_zod3.z.string()).min(0)
|
|
664
910
|
});
|
|
665
|
-
var InviteCollaboratorInputSchema =
|
|
911
|
+
var InviteCollaboratorInputSchema = import_zod3.z.object({
|
|
666
912
|
projectId: cuidOrPrefixedId,
|
|
667
|
-
email:
|
|
913
|
+
email: import_zod3.z.string().email()
|
|
668
914
|
});
|
|
669
|
-
var PublishProjectInputSchema =
|
|
915
|
+
var PublishProjectInputSchema = import_zod3.z.object({
|
|
670
916
|
projectId: cuidOrPrefixedId,
|
|
671
|
-
transferOwnership:
|
|
672
|
-
tags:
|
|
917
|
+
transferOwnership: import_zod3.z.boolean().default(false),
|
|
918
|
+
tags: import_zod3.z.array(import_zod3.z.string()).min(1)
|
|
919
|
+
});
|
|
920
|
+
var GenerateApiKeyInputSchema = import_zod3.z.object({
|
|
921
|
+
name: import_zod3.z.string().min(1).max(100),
|
|
922
|
+
publicNickname: import_zod3.z.string().max(50).optional(),
|
|
923
|
+
expiresInDays: import_zod3.z.number().int().min(1).max(365).default(90),
|
|
924
|
+
permissions: import_zod3.z.nativeEnum(ApiKeyPermission).default(ApiKeyPermission.WRITE)
|
|
673
925
|
});
|
|
674
|
-
var
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
926
|
+
var UpdateApiKeyInputSchema = import_zod3.z.object({
|
|
927
|
+
publicNickname: import_zod3.z.string().max(50).nullable().optional(),
|
|
928
|
+
scopedOrganizationId: import_zod3.z.string().optional().nullable(),
|
|
929
|
+
scopedProjectIds: import_zod3.z.array(import_zod3.z.string()).optional()
|
|
678
930
|
});
|
|
679
|
-
var RevokeApiKeyInputSchema =
|
|
931
|
+
var RevokeApiKeyInputSchema = import_zod3.z.object({
|
|
680
932
|
keyId: cuidOrPrefixedId
|
|
681
933
|
});
|
|
682
|
-
var LoginInputSchema =
|
|
683
|
-
email:
|
|
684
|
-
password:
|
|
934
|
+
var LoginInputSchema = import_zod3.z.object({
|
|
935
|
+
email: import_zod3.z.string().email(),
|
|
936
|
+
password: import_zod3.z.string().min(8).max(255)
|
|
685
937
|
});
|
|
686
|
-
var RegisterInputSchema =
|
|
687
|
-
email:
|
|
688
|
-
password:
|
|
689
|
-
name:
|
|
690
|
-
organizationSlug: import_zod2.z.string().min(1).max(100).regex(/^[a-z0-9-]+$/).optional()
|
|
938
|
+
var RegisterInputSchema = import_zod3.z.object({
|
|
939
|
+
email: import_zod3.z.string().email(),
|
|
940
|
+
password: import_zod3.z.string().min(8).max(255),
|
|
941
|
+
name: import_zod3.z.string().min(1).max(255)
|
|
691
942
|
});
|
|
692
|
-
var VerifyTaskInputSchema =
|
|
943
|
+
var VerifyTaskInputSchema = import_zod3.z.object({
|
|
693
944
|
projectId: cuidOrPrefixedId,
|
|
694
945
|
taskId: cuidOrPrefixedId,
|
|
695
|
-
approved:
|
|
696
|
-
feedback:
|
|
946
|
+
approved: import_zod3.z.boolean(),
|
|
947
|
+
feedback: import_zod3.z.string().max(5e3).optional()
|
|
697
948
|
});
|
|
698
|
-
var GetTaskPromptInputSchema =
|
|
949
|
+
var GetTaskPromptInputSchema = import_zod3.z.object({
|
|
699
950
|
projectId: cuidOrPrefixedId,
|
|
700
951
|
taskId: cuidOrPrefixedId
|
|
701
952
|
});
|
|
702
|
-
var UpdateTaskMCPInputSchema =
|
|
953
|
+
var UpdateTaskMCPInputSchema = import_zod3.z.object({
|
|
703
954
|
projectId: cuidOrPrefixedId,
|
|
704
955
|
taskId: cuidOrPrefixedId,
|
|
705
|
-
title:
|
|
706
|
-
description:
|
|
707
|
-
priority:
|
|
708
|
-
acceptanceCriteria:
|
|
709
|
-
id:
|
|
710
|
-
description:
|
|
956
|
+
title: import_zod3.z.string().min(1).max(200).optional(),
|
|
957
|
+
description: import_zod3.z.string().max(5e3).optional(),
|
|
958
|
+
priority: import_zod3.z.nativeEnum(TaskPriority).optional(),
|
|
959
|
+
acceptanceCriteria: import_zod3.z.array(import_zod3.z.object({
|
|
960
|
+
id: import_zod3.z.string().optional(),
|
|
961
|
+
description: import_zod3.z.string().min(1).max(500)
|
|
711
962
|
})).optional()
|
|
712
963
|
});
|
|
713
|
-
var ReportBranchInputSchema =
|
|
964
|
+
var ReportBranchInputSchema = import_zod3.z.object({
|
|
714
965
|
projectId: cuidOrPrefixedId,
|
|
715
966
|
taskId: cuidOrPrefixedId,
|
|
716
967
|
branchName: gitBranchName
|
|
717
968
|
});
|
|
718
|
-
var ReportPRInputSchema =
|
|
969
|
+
var ReportPRInputSchema = import_zod3.z.object({
|
|
719
970
|
projectId: cuidOrPrefixedId,
|
|
720
971
|
taskId: cuidOrPrefixedId,
|
|
721
|
-
pullRequestUrl:
|
|
722
|
-
pullRequestNumber:
|
|
972
|
+
pullRequestUrl: import_zod3.z.string().url(),
|
|
973
|
+
pullRequestNumber: import_zod3.z.number().int().positive()
|
|
723
974
|
});
|
|
724
975
|
|
|
725
976
|
// ../../packages/core/dist/logging/metrics.js
|
|
@@ -800,23 +1051,20 @@ function createHistogram(name, help, buckets = [5e-3, 0.01, 0.025, 0.05, 0.1, 0.
|
|
|
800
1051
|
var httpRequestsTotal = createCounter("mtaap_http_requests_total", "Total number of HTTP requests");
|
|
801
1052
|
var httpRequestDuration = createHistogram("mtaap_http_request_duration_seconds", "HTTP request duration in seconds");
|
|
802
1053
|
var activeUsers = createGauge("mtaap_active_users", "Number of active users");
|
|
803
|
-
var tasksTotal = createCounter("mtaap_tasks_total", "Total number of tasks by state");
|
|
804
|
-
var taskStateChanges = createCounter("mtaap_task_state_changes_total", "Total number of task state changes");
|
|
805
1054
|
var httpErrorsTotal = createCounter("mtaap_http_errors_total", "Total number of HTTP errors");
|
|
806
1055
|
var httpActiveConnections = createGauge("mtaap_http_active_connections", "Number of active HTTP connections");
|
|
807
1056
|
var newSignupsTotal = createCounter("mtaap_new_signups_total", "Total number of new user signups");
|
|
808
1057
|
var loginSuccessTotal = createCounter("mtaap_login_success_total", "Total number of successful logins");
|
|
809
1058
|
var loginFailureTotal = createCounter("mtaap_login_failure_total", "Total number of failed logins");
|
|
810
|
-
var dbConnectionPoolActive = createGauge("mtaap_db_connection_pool_active", "Number of active database connections");
|
|
811
|
-
var dbConnectionPoolIdle = createGauge("mtaap_db_connection_pool_idle", "Number of idle database connections");
|
|
812
|
-
var dbConnectionPoolMax = createGauge("mtaap_db_connection_pool_max", "Maximum number of database connections");
|
|
813
1059
|
var dbQueryDuration = createHistogram("mtaap_db_query_duration_seconds", "Database query duration in seconds");
|
|
814
1060
|
var dbSlowQueriesTotal = createCounter("mtaap_db_slow_queries_total", "Total number of slow database queries (>1s)");
|
|
815
|
-
var dbErrorsTotal = createCounter("mtaap_db_errors_total", "Total number of database errors");
|
|
816
1061
|
var tasksCreatedTotal = createCounter("mtaap_tasks_created_total", "Total number of tasks created");
|
|
817
1062
|
var tasksAssignedTotal = createCounter("mtaap_tasks_assigned_total", "Total number of tasks assigned");
|
|
818
1063
|
var tasksCompletedTotal = createCounter("mtaap_tasks_completed_total", "Total number of tasks completed");
|
|
819
|
-
var
|
|
1064
|
+
var agentSessionsTotal = createCounter("mtaap_agent_sessions_total", "Total number of agent sessions started");
|
|
1065
|
+
var agentErrorsTotal = createCounter("mtaap_agent_errors_total", "Total number of agent errors");
|
|
1066
|
+
var agentSessionDuration = createHistogram("mtaap_agent_session_duration_seconds", "Agent session duration in seconds", [1, 5, 15, 30, 60, 120, 300, 600, 1800, 3600]);
|
|
1067
|
+
var agentSessionsActive = createGauge("mtaap_agent_sessions_active", "Number of currently active agent sessions");
|
|
820
1068
|
|
|
821
1069
|
// ../../packages/core/dist/logging/performance-monitor.js
|
|
822
1070
|
var MAX_SAMPLES = 1e3;
|
|
@@ -1020,6 +1268,9 @@ var errorTrackerInstance = new NoOpErrorTracker();
|
|
|
1020
1268
|
|
|
1021
1269
|
// src/api-client.ts
|
|
1022
1270
|
var DEFAULT_TIMEOUT = 3e4;
|
|
1271
|
+
var DEFAULT_CACHE_TTL = 3e4;
|
|
1272
|
+
var MAX_RETRIES = 2;
|
|
1273
|
+
var INITIAL_RETRY_DELAY = 500;
|
|
1023
1274
|
function sanitizeForLogging(str) {
|
|
1024
1275
|
let sanitized = str.replace(/\bcollab_[a-zA-Z0-9_-]+\b/gi, "[REDACTED_API_KEY]");
|
|
1025
1276
|
sanitized = sanitized.replace(/\bBearer\s+[a-zA-Z0-9._-]+\b/gi, "Bearer [REDACTED]");
|
|
@@ -1034,42 +1285,113 @@ var ApiError = class extends Error {
|
|
|
1034
1285
|
this.details = details;
|
|
1035
1286
|
this.name = "ApiError";
|
|
1036
1287
|
}
|
|
1288
|
+
/**
|
|
1289
|
+
* Whether this error is transient and the request can be retried.
|
|
1290
|
+
* Retries on network errors (status 0), timeouts (408), and server errors (5xx).
|
|
1291
|
+
*/
|
|
1292
|
+
get isRetryable() {
|
|
1293
|
+
return this.status === 0 || this.status === 408 || this.status >= 500;
|
|
1294
|
+
}
|
|
1037
1295
|
};
|
|
1296
|
+
function sleep(ms) {
|
|
1297
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
1298
|
+
}
|
|
1038
1299
|
var MCPApiClient = class {
|
|
1039
1300
|
baseUrl;
|
|
1040
1301
|
apiKey;
|
|
1302
|
+
oauthToken;
|
|
1041
1303
|
timeout;
|
|
1042
1304
|
debug;
|
|
1043
1305
|
authContext = null;
|
|
1306
|
+
cache = /* @__PURE__ */ new Map();
|
|
1044
1307
|
constructor(config3) {
|
|
1308
|
+
if (!config3.apiKey && !config3.oauthToken) {
|
|
1309
|
+
throw new Error("Either apiKey or oauthToken must be provided");
|
|
1310
|
+
}
|
|
1045
1311
|
this.baseUrl = config3.baseUrl.replace(/\/$/, "");
|
|
1046
1312
|
this.apiKey = config3.apiKey;
|
|
1313
|
+
this.oauthToken = config3.oauthToken;
|
|
1047
1314
|
this.timeout = config3.timeout ?? DEFAULT_TIMEOUT;
|
|
1048
1315
|
this.debug = config3.debug ?? false;
|
|
1049
1316
|
}
|
|
1050
1317
|
/**
|
|
1051
|
-
*
|
|
1318
|
+
* Get a cached value if it exists and hasn't expired.
|
|
1319
|
+
*/
|
|
1320
|
+
getCached(key) {
|
|
1321
|
+
const entry = this.cache.get(key);
|
|
1322
|
+
if (!entry) return void 0;
|
|
1323
|
+
if (Date.now() > entry.expiresAt) {
|
|
1324
|
+
this.cache.delete(key);
|
|
1325
|
+
return void 0;
|
|
1326
|
+
}
|
|
1327
|
+
return entry.data;
|
|
1328
|
+
}
|
|
1329
|
+
/**
|
|
1330
|
+
* Store a value in cache with a TTL.
|
|
1331
|
+
*/
|
|
1332
|
+
setCache(key, data, ttl = DEFAULT_CACHE_TTL) {
|
|
1333
|
+
this.cache.set(key, { data, expiresAt: Date.now() + ttl });
|
|
1334
|
+
}
|
|
1335
|
+
/**
|
|
1336
|
+
* Make an HTTP request to the API with automatic retry on transient failures.
|
|
1337
|
+
*/
|
|
1338
|
+
async request(method, path2, body) {
|
|
1339
|
+
let lastError;
|
|
1340
|
+
for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
|
|
1341
|
+
try {
|
|
1342
|
+
return await this.requestOnce(method, path2, body);
|
|
1343
|
+
} catch (error) {
|
|
1344
|
+
if (!(error instanceof ApiError) || !error.isRetryable || attempt === MAX_RETRIES) {
|
|
1345
|
+
throw error;
|
|
1346
|
+
}
|
|
1347
|
+
lastError = error;
|
|
1348
|
+
const delay = INITIAL_RETRY_DELAY * Math.pow(2, attempt);
|
|
1349
|
+
if (this.debug) {
|
|
1350
|
+
console.error(`[mcp-api] Retry ${attempt + 1}/${MAX_RETRIES} after ${delay}ms (${lastError.code})`);
|
|
1351
|
+
}
|
|
1352
|
+
await sleep(delay);
|
|
1353
|
+
}
|
|
1354
|
+
}
|
|
1355
|
+
throw lastError;
|
|
1356
|
+
}
|
|
1357
|
+
/**
|
|
1358
|
+
* Execute a single HTTP request to the API.
|
|
1052
1359
|
*/
|
|
1053
|
-
async
|
|
1054
|
-
const url = `${this.baseUrl}${
|
|
1360
|
+
async requestOnce(method, path2, body) {
|
|
1361
|
+
const url = `${this.baseUrl}${path2}`;
|
|
1055
1362
|
const controller = new AbortController();
|
|
1056
1363
|
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
1057
1364
|
if (this.debug) {
|
|
1058
|
-
console.error(`[mcp-api] ${method} ${sanitizeForLogging(
|
|
1365
|
+
console.error(`[mcp-api] ${method} ${sanitizeForLogging(path2)}`);
|
|
1059
1366
|
}
|
|
1060
1367
|
try {
|
|
1368
|
+
const headers = {
|
|
1369
|
+
"Content-Type": "application/json"
|
|
1370
|
+
};
|
|
1371
|
+
if (this.oauthToken) {
|
|
1372
|
+
headers["Authorization"] = `Bearer ${this.oauthToken}`;
|
|
1373
|
+
} else if (this.apiKey) {
|
|
1374
|
+
headers["X-API-Key"] = this.apiKey;
|
|
1375
|
+
}
|
|
1061
1376
|
const response = await fetch(url, {
|
|
1062
1377
|
method,
|
|
1063
|
-
headers
|
|
1064
|
-
"Content-Type": "application/json",
|
|
1065
|
-
"X-API-Key": this.apiKey
|
|
1066
|
-
},
|
|
1378
|
+
headers,
|
|
1067
1379
|
body: body ? JSON.stringify(body) : void 0,
|
|
1068
1380
|
signal: controller.signal
|
|
1069
1381
|
});
|
|
1070
1382
|
clearTimeout(timeoutId);
|
|
1071
1383
|
const data = await response.json();
|
|
1072
1384
|
if (!response.ok) {
|
|
1385
|
+
if (response.status === 403 && data.code === "EMAIL_NOT_VERIFIED" && data.verificationUrl) {
|
|
1386
|
+
throw new ApiError(
|
|
1387
|
+
`${data.error}
|
|
1388
|
+
|
|
1389
|
+
To verify your email, visit: ${data.verificationUrl}
|
|
1390
|
+
${data.hint ? `Hint: ${data.hint}` : ""}`,
|
|
1391
|
+
"EMAIL_NOT_VERIFIED",
|
|
1392
|
+
403
|
|
1393
|
+
);
|
|
1394
|
+
}
|
|
1073
1395
|
throw new ApiError(
|
|
1074
1396
|
data.error || "API request failed",
|
|
1075
1397
|
data.code || "UNKNOWN_ERROR",
|
|
@@ -1116,14 +1438,19 @@ var MCPApiClient = class {
|
|
|
1116
1438
|
return this.authenticate();
|
|
1117
1439
|
}
|
|
1118
1440
|
/**
|
|
1119
|
-
* List accessible projects
|
|
1441
|
+
* List accessible projects (cached for 30s)
|
|
1120
1442
|
*/
|
|
1121
1443
|
async listProjects(workspaceType) {
|
|
1122
1444
|
const type = workspaceType || "ALL";
|
|
1123
|
-
|
|
1445
|
+
const cacheKey = `listProjects:${type}`;
|
|
1446
|
+
const cached = this.getCached(cacheKey);
|
|
1447
|
+
if (cached) return cached;
|
|
1448
|
+
const result = await this.request(
|
|
1124
1449
|
"GET",
|
|
1125
1450
|
`/api/mcp/projects?workspaceType=${encodeURIComponent(type)}`
|
|
1126
1451
|
);
|
|
1452
|
+
this.setCache(cacheKey, result);
|
|
1453
|
+
return result;
|
|
1127
1454
|
}
|
|
1128
1455
|
/**
|
|
1129
1456
|
* Get single project details
|
|
@@ -1132,13 +1459,18 @@ var MCPApiClient = class {
|
|
|
1132
1459
|
return this.request("GET", `/api/mcp/projects/${projectId}`);
|
|
1133
1460
|
}
|
|
1134
1461
|
/**
|
|
1135
|
-
* Get project context (README, stack, conventions)
|
|
1462
|
+
* Get project context (README, stack, conventions) (cached for 60s)
|
|
1136
1463
|
*/
|
|
1137
1464
|
async getProjectContext(projectId) {
|
|
1138
|
-
|
|
1465
|
+
const cacheKey = `projectContext:${projectId}`;
|
|
1466
|
+
const cached = this.getCached(cacheKey);
|
|
1467
|
+
if (cached) return cached;
|
|
1468
|
+
const result = await this.request(
|
|
1139
1469
|
"GET",
|
|
1140
1470
|
`/api/mcp/projects/${projectId}/context`
|
|
1141
1471
|
);
|
|
1472
|
+
this.setCache(cacheKey, result, 6e4);
|
|
1473
|
+
return result;
|
|
1142
1474
|
}
|
|
1143
1475
|
/**
|
|
1144
1476
|
* Create a personal project
|
|
@@ -1166,8 +1498,8 @@ var MCPApiClient = class {
|
|
|
1166
1498
|
if (filters.assigneeId) params.set("assigneeId", filters.assigneeId);
|
|
1167
1499
|
if (filters.includeArchived) params.set("includeArchived", "true");
|
|
1168
1500
|
const queryString = params.toString();
|
|
1169
|
-
const
|
|
1170
|
-
return this.request("GET",
|
|
1501
|
+
const path2 = queryString ? `/api/mcp/tasks?${queryString}` : "/api/mcp/tasks";
|
|
1502
|
+
return this.request("GET", path2);
|
|
1171
1503
|
}
|
|
1172
1504
|
/**
|
|
1173
1505
|
* Get full task details
|
|
@@ -1300,7 +1632,8 @@ var MCPApiClient = class {
|
|
|
1300
1632
|
);
|
|
1301
1633
|
}
|
|
1302
1634
|
/**
|
|
1303
|
-
* Update task details (DRAFT/TODO states only)
|
|
1635
|
+
* Update task details (DRAFT/TODO states only).
|
|
1636
|
+
* Task stays in its current state.
|
|
1304
1637
|
*/
|
|
1305
1638
|
async updateTask(taskId, projectId, data) {
|
|
1306
1639
|
return this.request("PATCH", `/api/mcp/tasks/${taskId}`, {
|
|
@@ -1332,7 +1665,7 @@ var PERMISSION_RANK = {
|
|
|
1332
1665
|
ADMIN: 3
|
|
1333
1666
|
};
|
|
1334
1667
|
function assertApiKeyPermission(apiKey, required, toolName) {
|
|
1335
|
-
const actualRank = PERMISSION_RANK[apiKey.permissions] ?? 0;
|
|
1668
|
+
const actualRank = apiKey.permissions ? PERMISSION_RANK[apiKey.permissions] ?? 0 : 0;
|
|
1336
1669
|
const requiredRank = PERMISSION_RANK[required] ?? 0;
|
|
1337
1670
|
if (actualRank >= requiredRank) {
|
|
1338
1671
|
return;
|
|
@@ -1350,6 +1683,454 @@ function assertApiKeyPermission(apiKey, required, toolName) {
|
|
|
1350
1683
|
throw error;
|
|
1351
1684
|
}
|
|
1352
1685
|
|
|
1686
|
+
// src/apps/task-details.ts
|
|
1687
|
+
var import_server2 = require("@modelcontextprotocol/ext-apps/server");
|
|
1688
|
+
var import_zod4 = require("zod");
|
|
1689
|
+
|
|
1690
|
+
// src/apps/helpers.ts
|
|
1691
|
+
var import_server = require("@modelcontextprotocol/ext-apps/server");
|
|
1692
|
+
var import_promises = __toESM(require("fs/promises"));
|
|
1693
|
+
var import_node_path = __toESM(require("path"));
|
|
1694
|
+
var import_node_url = require("url");
|
|
1695
|
+
var import_meta = {};
|
|
1696
|
+
var getDirname = () => {
|
|
1697
|
+
try {
|
|
1698
|
+
return import_node_path.default.dirname((0, import_node_url.fileURLToPath)(import_meta.url));
|
|
1699
|
+
} catch {
|
|
1700
|
+
return __dirname;
|
|
1701
|
+
}
|
|
1702
|
+
};
|
|
1703
|
+
function getAppHtmlPath(htmlFileName) {
|
|
1704
|
+
return import_node_path.default.join(getDirname(), "apps", htmlFileName);
|
|
1705
|
+
}
|
|
1706
|
+
function registerAppHtmlResource(server, config3) {
|
|
1707
|
+
(0, import_server.registerAppResource)(
|
|
1708
|
+
server,
|
|
1709
|
+
config3.name,
|
|
1710
|
+
config3.uri,
|
|
1711
|
+
{
|
|
1712
|
+
mimeType: import_server.RESOURCE_MIME_TYPE,
|
|
1713
|
+
description: config3.description
|
|
1714
|
+
},
|
|
1715
|
+
async () => {
|
|
1716
|
+
const htmlPath = getAppHtmlPath(config3.htmlFileName);
|
|
1717
|
+
try {
|
|
1718
|
+
const html = await import_promises.default.readFile(htmlPath, "utf-8");
|
|
1719
|
+
return {
|
|
1720
|
+
contents: [
|
|
1721
|
+
{
|
|
1722
|
+
uri: config3.uri,
|
|
1723
|
+
mimeType: import_server.RESOURCE_MIME_TYPE,
|
|
1724
|
+
text: html
|
|
1725
|
+
}
|
|
1726
|
+
]
|
|
1727
|
+
};
|
|
1728
|
+
} catch {
|
|
1729
|
+
return {
|
|
1730
|
+
contents: [
|
|
1731
|
+
{
|
|
1732
|
+
uri: config3.uri,
|
|
1733
|
+
mimeType: import_server.RESOURCE_MIME_TYPE,
|
|
1734
|
+
text: `<!DOCTYPE html><html><body><p>${config3.fallbackLabel} UI not available. Build the UI apps first.</p></body></html>`
|
|
1735
|
+
}
|
|
1736
|
+
]
|
|
1737
|
+
};
|
|
1738
|
+
}
|
|
1739
|
+
}
|
|
1740
|
+
);
|
|
1741
|
+
}
|
|
1742
|
+
|
|
1743
|
+
// src/apps/task-details.ts
|
|
1744
|
+
var RESOURCE_URI = "ui://collab/task-details.html";
|
|
1745
|
+
function registerTaskDetailsApp(server, apiClient, _authContext) {
|
|
1746
|
+
(0, import_server2.registerAppTool)(
|
|
1747
|
+
server,
|
|
1748
|
+
"view_task_details",
|
|
1749
|
+
{
|
|
1750
|
+
title: "Task Details",
|
|
1751
|
+
description: "View interactive task details with acceptance criteria, notes, and progress. Opens a rich UI panel.",
|
|
1752
|
+
inputSchema: {
|
|
1753
|
+
taskId: import_zod4.z.string().describe("The task ID to view"),
|
|
1754
|
+
projectId: import_zod4.z.string().describe("The project ID")
|
|
1755
|
+
},
|
|
1756
|
+
_meta: { ui: { resourceUri: RESOURCE_URI } }
|
|
1757
|
+
},
|
|
1758
|
+
async ({ taskId, projectId }) => {
|
|
1759
|
+
try {
|
|
1760
|
+
const task = await apiClient.getTask(taskId);
|
|
1761
|
+
let project = null;
|
|
1762
|
+
try {
|
|
1763
|
+
project = await apiClient.getProject(projectId);
|
|
1764
|
+
} catch {
|
|
1765
|
+
}
|
|
1766
|
+
return {
|
|
1767
|
+
content: [
|
|
1768
|
+
{
|
|
1769
|
+
type: "text",
|
|
1770
|
+
text: `Viewing task: ${task.title}`
|
|
1771
|
+
}
|
|
1772
|
+
],
|
|
1773
|
+
structuredContent: {
|
|
1774
|
+
task,
|
|
1775
|
+
project
|
|
1776
|
+
}
|
|
1777
|
+
};
|
|
1778
|
+
} catch (error) {
|
|
1779
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1780
|
+
return {
|
|
1781
|
+
content: [{ type: "text", text: `Error loading task: ${message}` }],
|
|
1782
|
+
isError: true
|
|
1783
|
+
};
|
|
1784
|
+
}
|
|
1785
|
+
}
|
|
1786
|
+
);
|
|
1787
|
+
registerAppHtmlResource(server, {
|
|
1788
|
+
name: "Task Details UI",
|
|
1789
|
+
uri: RESOURCE_URI,
|
|
1790
|
+
description: "Interactive task details view with acceptance criteria and notes",
|
|
1791
|
+
htmlFileName: "task-details.html",
|
|
1792
|
+
fallbackLabel: "Task Details"
|
|
1793
|
+
});
|
|
1794
|
+
}
|
|
1795
|
+
|
|
1796
|
+
// src/apps/kanban.ts
|
|
1797
|
+
var import_server3 = require("@modelcontextprotocol/ext-apps/server");
|
|
1798
|
+
var import_zod5 = require("zod");
|
|
1799
|
+
var RESOURCE_URI2 = "ui://collab/kanban.html";
|
|
1800
|
+
function registerKanbanApp(server, apiClient, _authContext) {
|
|
1801
|
+
(0, import_server3.registerAppTool)(
|
|
1802
|
+
server,
|
|
1803
|
+
"view_kanban_board",
|
|
1804
|
+
{
|
|
1805
|
+
title: "Kanban Board",
|
|
1806
|
+
description: "View interactive drag-and-drop Kanban board for a project. Drag tasks between columns to change their state.",
|
|
1807
|
+
inputSchema: {
|
|
1808
|
+
projectId: import_zod5.z.string().describe("The project ID to display")
|
|
1809
|
+
},
|
|
1810
|
+
_meta: { ui: { resourceUri: RESOURCE_URI2 } }
|
|
1811
|
+
},
|
|
1812
|
+
async ({ projectId }) => {
|
|
1813
|
+
try {
|
|
1814
|
+
const [project, tasks] = await Promise.all([
|
|
1815
|
+
apiClient.getProject(projectId),
|
|
1816
|
+
apiClient.listTasks({ projectId })
|
|
1817
|
+
]);
|
|
1818
|
+
return {
|
|
1819
|
+
content: [
|
|
1820
|
+
{
|
|
1821
|
+
type: "text",
|
|
1822
|
+
text: `Kanban board for ${project.name} (${tasks.length} tasks)`
|
|
1823
|
+
}
|
|
1824
|
+
],
|
|
1825
|
+
structuredContent: {
|
|
1826
|
+
project,
|
|
1827
|
+
tasks
|
|
1828
|
+
}
|
|
1829
|
+
};
|
|
1830
|
+
} catch (error) {
|
|
1831
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1832
|
+
return {
|
|
1833
|
+
content: [{ type: "text", text: `Error loading kanban: ${message}` }],
|
|
1834
|
+
isError: true
|
|
1835
|
+
};
|
|
1836
|
+
}
|
|
1837
|
+
}
|
|
1838
|
+
);
|
|
1839
|
+
registerAppHtmlResource(server, {
|
|
1840
|
+
name: "Kanban Board UI",
|
|
1841
|
+
uri: RESOURCE_URI2,
|
|
1842
|
+
description: "Interactive drag-and-drop Kanban board for task management",
|
|
1843
|
+
htmlFileName: "kanban.html",
|
|
1844
|
+
fallbackLabel: "Kanban"
|
|
1845
|
+
});
|
|
1846
|
+
}
|
|
1847
|
+
|
|
1848
|
+
// src/apps/activity.ts
|
|
1849
|
+
var import_server4 = require("@modelcontextprotocol/ext-apps/server");
|
|
1850
|
+
var import_zod6 = require("zod");
|
|
1851
|
+
var RESOURCE_URI3 = "ui://collab/activity.html";
|
|
1852
|
+
function registerActivityApp(server, apiClient, _authContext) {
|
|
1853
|
+
(0, import_server4.registerAppTool)(
|
|
1854
|
+
server,
|
|
1855
|
+
"view_activity",
|
|
1856
|
+
{
|
|
1857
|
+
title: "User Activity",
|
|
1858
|
+
description: "View who is working on what across the team. Shows IN_PROGRESS and REVIEW tasks per user.",
|
|
1859
|
+
inputSchema: {
|
|
1860
|
+
projectId: import_zod6.z.string().optional().describe("Optional project ID to filter by")
|
|
1861
|
+
},
|
|
1862
|
+
_meta: { ui: { resourceUri: RESOURCE_URI3 } }
|
|
1863
|
+
},
|
|
1864
|
+
async ({ projectId }) => {
|
|
1865
|
+
try {
|
|
1866
|
+
const [inProgressTasks, reviewTasks] = await Promise.all([
|
|
1867
|
+
apiClient.listTasks({
|
|
1868
|
+
projectId,
|
|
1869
|
+
state: TaskState.IN_PROGRESS
|
|
1870
|
+
}),
|
|
1871
|
+
apiClient.listTasks({
|
|
1872
|
+
projectId,
|
|
1873
|
+
state: TaskState.REVIEW
|
|
1874
|
+
})
|
|
1875
|
+
]);
|
|
1876
|
+
const userMap = /* @__PURE__ */ new Map();
|
|
1877
|
+
for (const task of inProgressTasks) {
|
|
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).activeTasks.push(task);
|
|
1889
|
+
}
|
|
1890
|
+
}
|
|
1891
|
+
for (const task of reviewTasks) {
|
|
1892
|
+
if (task.assigneeId) {
|
|
1893
|
+
if (!userMap.has(task.assigneeId)) {
|
|
1894
|
+
userMap.set(task.assigneeId, {
|
|
1895
|
+
id: task.assigneeId,
|
|
1896
|
+
name: task.assigneeName || "Unknown",
|
|
1897
|
+
email: task.assigneeEmail || "",
|
|
1898
|
+
activeTasks: [],
|
|
1899
|
+
reviewTasks: []
|
|
1900
|
+
});
|
|
1901
|
+
}
|
|
1902
|
+
userMap.get(task.assigneeId).reviewTasks.push(task);
|
|
1903
|
+
}
|
|
1904
|
+
}
|
|
1905
|
+
const users = Array.from(userMap.values());
|
|
1906
|
+
return {
|
|
1907
|
+
content: [
|
|
1908
|
+
{
|
|
1909
|
+
type: "text",
|
|
1910
|
+
text: `Activity: ${users.length} users with active work`
|
|
1911
|
+
}
|
|
1912
|
+
],
|
|
1913
|
+
structuredContent: {
|
|
1914
|
+
users,
|
|
1915
|
+
projectId
|
|
1916
|
+
}
|
|
1917
|
+
};
|
|
1918
|
+
} catch (error) {
|
|
1919
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1920
|
+
return {
|
|
1921
|
+
content: [
|
|
1922
|
+
{ type: "text", text: `Error loading activity: ${message}` }
|
|
1923
|
+
],
|
|
1924
|
+
isError: true
|
|
1925
|
+
};
|
|
1926
|
+
}
|
|
1927
|
+
}
|
|
1928
|
+
);
|
|
1929
|
+
registerAppHtmlResource(server, {
|
|
1930
|
+
name: "User Activity UI",
|
|
1931
|
+
uri: RESOURCE_URI3,
|
|
1932
|
+
description: "Dashboard showing team member activity and workload",
|
|
1933
|
+
htmlFileName: "activity.html",
|
|
1934
|
+
fallbackLabel: "Activity"
|
|
1935
|
+
});
|
|
1936
|
+
}
|
|
1937
|
+
|
|
1938
|
+
// src/apps/project-overview.ts
|
|
1939
|
+
var import_server5 = require("@modelcontextprotocol/ext-apps/server");
|
|
1940
|
+
var import_zod7 = require("zod");
|
|
1941
|
+
var RESOURCE_URI4 = "ui://collab/project-overview.html";
|
|
1942
|
+
function registerProjectOverviewApp(server, apiClient, _authContext) {
|
|
1943
|
+
(0, import_server5.registerAppTool)(
|
|
1944
|
+
server,
|
|
1945
|
+
"view_project_overview",
|
|
1946
|
+
{
|
|
1947
|
+
title: "Project Overview",
|
|
1948
|
+
description: "View project health dashboard with task metrics, state distribution, and conventions.",
|
|
1949
|
+
inputSchema: {
|
|
1950
|
+
projectId: import_zod7.z.string().describe("The project ID to display")
|
|
1951
|
+
},
|
|
1952
|
+
_meta: { ui: { resourceUri: RESOURCE_URI4 } }
|
|
1953
|
+
},
|
|
1954
|
+
async ({ projectId }) => {
|
|
1955
|
+
try {
|
|
1956
|
+
const [project, context, tasks] = await Promise.all([
|
|
1957
|
+
apiClient.getProject(projectId),
|
|
1958
|
+
apiClient.getProjectContext(projectId).catch(() => null),
|
|
1959
|
+
apiClient.listTasks({ projectId })
|
|
1960
|
+
]);
|
|
1961
|
+
const activeTasks = tasks.filter((t) => !t.isArchived);
|
|
1962
|
+
const inProgress = activeTasks.filter(
|
|
1963
|
+
(t) => t.state === TaskState.IN_PROGRESS
|
|
1964
|
+
).length;
|
|
1965
|
+
const done = activeTasks.filter(
|
|
1966
|
+
(t) => t.state === TaskState.DONE
|
|
1967
|
+
).length;
|
|
1968
|
+
const blocked = activeTasks.filter((t) => t.errorType).length;
|
|
1969
|
+
const tasksByState = {
|
|
1970
|
+
DRAFT: 0,
|
|
1971
|
+
TODO: 0,
|
|
1972
|
+
IN_PROGRESS: 0,
|
|
1973
|
+
REVIEW: 0,
|
|
1974
|
+
DONE: 0
|
|
1975
|
+
};
|
|
1976
|
+
for (const task of activeTasks) {
|
|
1977
|
+
tasksByState[task.state]++;
|
|
1978
|
+
}
|
|
1979
|
+
const tasksByPriority = {
|
|
1980
|
+
LOW: 0,
|
|
1981
|
+
MEDIUM: 0,
|
|
1982
|
+
HIGH: 0,
|
|
1983
|
+
CRITICAL: 0
|
|
1984
|
+
};
|
|
1985
|
+
for (const task of activeTasks) {
|
|
1986
|
+
tasksByPriority[task.priority]++;
|
|
1987
|
+
}
|
|
1988
|
+
const recentCompleted = activeTasks.filter((t) => t.state === TaskState.DONE).sort(
|
|
1989
|
+
(a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime()
|
|
1990
|
+
).slice(0, 5);
|
|
1991
|
+
return {
|
|
1992
|
+
content: [
|
|
1993
|
+
{
|
|
1994
|
+
type: "text",
|
|
1995
|
+
text: `Project overview for ${project.name}: ${activeTasks.length} tasks`
|
|
1996
|
+
}
|
|
1997
|
+
],
|
|
1998
|
+
structuredContent: {
|
|
1999
|
+
project,
|
|
2000
|
+
context,
|
|
2001
|
+
metrics: {
|
|
2002
|
+
totalTasks: activeTasks.length,
|
|
2003
|
+
inProgress,
|
|
2004
|
+
blocked,
|
|
2005
|
+
done
|
|
2006
|
+
},
|
|
2007
|
+
tasksByState,
|
|
2008
|
+
tasksByPriority,
|
|
2009
|
+
recentCompleted
|
|
2010
|
+
}
|
|
2011
|
+
};
|
|
2012
|
+
} catch (error) {
|
|
2013
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2014
|
+
return {
|
|
2015
|
+
content: [
|
|
2016
|
+
{ type: "text", text: `Error loading project overview: ${message}` }
|
|
2017
|
+
],
|
|
2018
|
+
isError: true
|
|
2019
|
+
};
|
|
2020
|
+
}
|
|
2021
|
+
}
|
|
2022
|
+
);
|
|
2023
|
+
registerAppHtmlResource(server, {
|
|
2024
|
+
name: "Project Overview UI",
|
|
2025
|
+
uri: RESOURCE_URI4,
|
|
2026
|
+
description: "Project health dashboard with metrics and visualizations",
|
|
2027
|
+
htmlFileName: "project-overview.html",
|
|
2028
|
+
fallbackLabel: "Project Overview"
|
|
2029
|
+
});
|
|
2030
|
+
}
|
|
2031
|
+
|
|
2032
|
+
// src/apps/agent-sessions.ts
|
|
2033
|
+
var import_server6 = require("@modelcontextprotocol/ext-apps/server");
|
|
2034
|
+
var import_zod8 = require("zod");
|
|
2035
|
+
var RESOURCE_URI5 = "ui://collab/agent-sessions.html";
|
|
2036
|
+
function registerAgentSessionsApp(server, apiClient, authContext) {
|
|
2037
|
+
(0, import_server6.registerAppTool)(
|
|
2038
|
+
server,
|
|
2039
|
+
"view_agent_sessions",
|
|
2040
|
+
{
|
|
2041
|
+
title: "Agent Sessions",
|
|
2042
|
+
description: "View active AI agent sessions working on tasks. Monitor real-time progress and session status.",
|
|
2043
|
+
inputSchema: {
|
|
2044
|
+
projectId: import_zod8.z.string().optional().describe("Optional project ID to filter by")
|
|
2045
|
+
},
|
|
2046
|
+
_meta: { ui: { resourceUri: RESOURCE_URI5 } }
|
|
2047
|
+
},
|
|
2048
|
+
async ({ projectId }) => {
|
|
2049
|
+
try {
|
|
2050
|
+
const [inProgressTasks, reviewTasks] = await Promise.all([
|
|
2051
|
+
apiClient.listTasks({
|
|
2052
|
+
projectId,
|
|
2053
|
+
state: TaskState.IN_PROGRESS
|
|
2054
|
+
}),
|
|
2055
|
+
apiClient.listTasks({
|
|
2056
|
+
projectId,
|
|
2057
|
+
state: TaskState.REVIEW
|
|
2058
|
+
})
|
|
2059
|
+
]);
|
|
2060
|
+
const sessions = [];
|
|
2061
|
+
for (const task of inProgressTasks) {
|
|
2062
|
+
if (task.assigneeId) {
|
|
2063
|
+
const totalCriteria = task.acceptanceCriteria?.length || 0;
|
|
2064
|
+
const completedCriteria = task.acceptanceCriteria?.filter((c) => c.completed).length || 0;
|
|
2065
|
+
const progress = totalCriteria > 0 ? Math.round(completedCriteria / totalCriteria * 100) : 0;
|
|
2066
|
+
const latestUpdate = task.progressUpdates?.[task.progressUpdates.length - 1];
|
|
2067
|
+
sessions.push({
|
|
2068
|
+
id: `session-${task.id}`,
|
|
2069
|
+
taskId: task.id,
|
|
2070
|
+
taskTitle: task.title,
|
|
2071
|
+
agentName: task.assigneeName || "Agent",
|
|
2072
|
+
status: "RUNNING",
|
|
2073
|
+
startedAt: task.updatedAt,
|
|
2074
|
+
lastCheckpoint: latestUpdate?.timestamp,
|
|
2075
|
+
currentStep: latestUpdate?.statusMessage,
|
|
2076
|
+
progress
|
|
2077
|
+
});
|
|
2078
|
+
}
|
|
2079
|
+
}
|
|
2080
|
+
for (const task of reviewTasks) {
|
|
2081
|
+
if (task.assigneeId) {
|
|
2082
|
+
sessions.push({
|
|
2083
|
+
id: `session-${task.id}`,
|
|
2084
|
+
taskId: task.id,
|
|
2085
|
+
taskTitle: task.title,
|
|
2086
|
+
agentName: task.assigneeName || "Agent",
|
|
2087
|
+
status: "STOPPED",
|
|
2088
|
+
startedAt: task.updatedAt,
|
|
2089
|
+
progress: 100
|
|
2090
|
+
});
|
|
2091
|
+
}
|
|
2092
|
+
}
|
|
2093
|
+
return {
|
|
2094
|
+
content: [
|
|
2095
|
+
{
|
|
2096
|
+
type: "text",
|
|
2097
|
+
text: `Agent sessions: ${sessions.length} active`
|
|
2098
|
+
}
|
|
2099
|
+
],
|
|
2100
|
+
structuredContent: {
|
|
2101
|
+
sessions,
|
|
2102
|
+
projectId
|
|
2103
|
+
}
|
|
2104
|
+
};
|
|
2105
|
+
} catch (error) {
|
|
2106
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2107
|
+
return {
|
|
2108
|
+
content: [
|
|
2109
|
+
{ type: "text", text: `Error loading agent sessions: ${message}` }
|
|
2110
|
+
],
|
|
2111
|
+
isError: true
|
|
2112
|
+
};
|
|
2113
|
+
}
|
|
2114
|
+
}
|
|
2115
|
+
);
|
|
2116
|
+
registerAppHtmlResource(server, {
|
|
2117
|
+
name: "Agent Sessions UI",
|
|
2118
|
+
uri: RESOURCE_URI5,
|
|
2119
|
+
description: "Real-time view of AI agent sessions and their progress",
|
|
2120
|
+
htmlFileName: "agent-sessions.html",
|
|
2121
|
+
fallbackLabel: "Agent Sessions"
|
|
2122
|
+
});
|
|
2123
|
+
}
|
|
2124
|
+
|
|
2125
|
+
// src/apps/index.ts
|
|
2126
|
+
function registerMCPApps(server, apiClient, authContext) {
|
|
2127
|
+
registerTaskDetailsApp(server, apiClient, authContext);
|
|
2128
|
+
registerKanbanApp(server, apiClient, authContext);
|
|
2129
|
+
registerActivityApp(server, apiClient, authContext);
|
|
2130
|
+
registerProjectOverviewApp(server, apiClient, authContext);
|
|
2131
|
+
registerAgentSessionsApp(server, apiClient, authContext);
|
|
2132
|
+
}
|
|
2133
|
+
|
|
1353
2134
|
// src/index.ts
|
|
1354
2135
|
var COLLAB_SERVER_INSTRUCTIONS = `Collab - AI-assisted software development task management platform.
|
|
1355
2136
|
|
|
@@ -1401,7 +2182,7 @@ Review Workflow:
|
|
|
1401
2182
|
list_tasks(state=REVIEW) -> get_task -> approve_task OR request_changes
|
|
1402
2183
|
|
|
1403
2184
|
Task Editing:
|
|
1404
|
-
update_task (DRAFT/TODO only) ->
|
|
2185
|
+
update_task (DRAFT/TODO only) -> task stays in current state
|
|
1405
2186
|
|
|
1406
2187
|
Error Recovery:
|
|
1407
2188
|
report_error -> abandon_task -> list_tasks -> assign_task (retry or pick different task)
|
|
@@ -1420,7 +2201,7 @@ GIT OPERATIONS NOTE:
|
|
|
1420
2201
|
TASK STATE FLOW:
|
|
1421
2202
|
DRAFT -> TODO -> IN_PROGRESS -> REVIEW -> DONE
|
|
1422
2203
|
(verify_task: DRAFT -> TODO)
|
|
1423
|
-
(update_task
|
|
2204
|
+
(update_task: DRAFT/TODO only, state unchanged)
|
|
1424
2205
|
(request_changes: REVIEW -> IN_PROGRESS)
|
|
1425
2206
|
(abandon_task: IN_PROGRESS -> TODO)
|
|
1426
2207
|
|
|
@@ -1453,7 +2234,7 @@ function initializeMCPServer(apiClient, authContext) {
|
|
|
1453
2234
|
{
|
|
1454
2235
|
description: "Discover all accessible projects. Use first to find project IDs. Filter by TEAM, PERSONAL, or ALL workspaces.",
|
|
1455
2236
|
inputSchema: {
|
|
1456
|
-
workspaceType:
|
|
2237
|
+
workspaceType: import_zod9.z.enum(["TEAM", "PERSONAL", "ALL"]).optional().describe("Filter by workspace type")
|
|
1457
2238
|
}
|
|
1458
2239
|
},
|
|
1459
2240
|
async (args) => {
|
|
@@ -1483,10 +2264,10 @@ function initializeMCPServer(apiClient, authContext) {
|
|
|
1483
2264
|
{
|
|
1484
2265
|
description: "Query tasks with filters. Use state=TODO for assignable tasks, state=REVIEW for pending reviews.",
|
|
1485
2266
|
inputSchema: {
|
|
1486
|
-
projectId:
|
|
1487
|
-
state:
|
|
1488
|
-
assigneeId:
|
|
1489
|
-
includeArchived:
|
|
2267
|
+
projectId: import_zod9.z.string().optional().describe("Filter by project ID"),
|
|
2268
|
+
state: import_zod9.z.nativeEnum(TaskState).optional().describe("Filter by task state"),
|
|
2269
|
+
assigneeId: import_zod9.z.string().optional().describe("Filter by assignee ID"),
|
|
2270
|
+
includeArchived: import_zod9.z.boolean().optional().describe("Include archived tasks (default: false)")
|
|
1490
2271
|
}
|
|
1491
2272
|
},
|
|
1492
2273
|
async (args) => {
|
|
@@ -1517,7 +2298,7 @@ function initializeMCPServer(apiClient, authContext) {
|
|
|
1517
2298
|
{
|
|
1518
2299
|
description: "Get complete task details with acceptance criteria and notes. Call before assign_task to understand requirements.",
|
|
1519
2300
|
inputSchema: {
|
|
1520
|
-
taskId:
|
|
2301
|
+
taskId: import_zod9.z.string().describe("The task ID to retrieve")
|
|
1521
2302
|
}
|
|
1522
2303
|
},
|
|
1523
2304
|
async (args) => {
|
|
@@ -1543,9 +2324,9 @@ function initializeMCPServer(apiClient, authContext) {
|
|
|
1543
2324
|
{
|
|
1544
2325
|
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.",
|
|
1545
2326
|
inputSchema: {
|
|
1546
|
-
projectId:
|
|
1547
|
-
taskId:
|
|
1548
|
-
expectedState:
|
|
2327
|
+
projectId: import_zod9.z.string().describe("The project ID"),
|
|
2328
|
+
taskId: import_zod9.z.string().describe("The task ID to assign"),
|
|
2329
|
+
expectedState: import_zod9.z.nativeEnum(TaskState).optional().describe("Expected task state (default: TODO)")
|
|
1549
2330
|
}
|
|
1550
2331
|
},
|
|
1551
2332
|
async (args) => {
|
|
@@ -1579,10 +2360,10 @@ function initializeMCPServer(apiClient, authContext) {
|
|
|
1579
2360
|
{
|
|
1580
2361
|
description: "Report progress and checkpoint work. Call frequently during execution. Marks acceptance criteria complete.",
|
|
1581
2362
|
inputSchema: {
|
|
1582
|
-
taskId:
|
|
1583
|
-
statusMessage:
|
|
1584
|
-
completedCheckpointIds:
|
|
1585
|
-
currentCheckpointIndex:
|
|
2363
|
+
taskId: import_zod9.z.string().describe("The task ID to update"),
|
|
2364
|
+
statusMessage: import_zod9.z.string().optional().describe("Status message (max 1000 chars)"),
|
|
2365
|
+
completedCheckpointIds: import_zod9.z.array(import_zod9.z.string()).optional().describe("Array of completed checkpoint IDs"),
|
|
2366
|
+
currentCheckpointIndex: import_zod9.z.number().optional().describe("Current checkpoint index")
|
|
1586
2367
|
}
|
|
1587
2368
|
},
|
|
1588
2369
|
async (args) => {
|
|
@@ -1616,10 +2397,10 @@ function initializeMCPServer(apiClient, authContext) {
|
|
|
1616
2397
|
{
|
|
1617
2398
|
description: "Prepare task for PR creation. Returns PR suggestions. After creating PR locally, call report_pr to transition to REVIEW. Requires IN_PROGRESS state.",
|
|
1618
2399
|
inputSchema: {
|
|
1619
|
-
projectId:
|
|
1620
|
-
taskId:
|
|
1621
|
-
pullRequestTitle:
|
|
1622
|
-
pullRequestBody:
|
|
2400
|
+
projectId: import_zod9.z.string().describe("The project ID"),
|
|
2401
|
+
taskId: import_zod9.z.string().describe("The task ID to complete"),
|
|
2402
|
+
pullRequestTitle: import_zod9.z.string().optional().describe("PR title (max 300 chars)"),
|
|
2403
|
+
pullRequestBody: import_zod9.z.string().optional().describe("PR body/description (max 10000 chars)")
|
|
1623
2404
|
}
|
|
1624
2405
|
},
|
|
1625
2406
|
async (args) => {
|
|
@@ -1676,10 +2457,10 @@ function initializeMCPServer(apiClient, authContext) {
|
|
|
1676
2457
|
{
|
|
1677
2458
|
description: "Report unrecoverable errors (BUILD_FAILURE, TEST_FAILURE, CONFLICT, AUTH_ERROR). Consider abandon_task after.",
|
|
1678
2459
|
inputSchema: {
|
|
1679
|
-
taskId:
|
|
1680
|
-
errorType:
|
|
1681
|
-
errorMessage:
|
|
1682
|
-
context:
|
|
2460
|
+
taskId: import_zod9.z.string().describe("The task ID"),
|
|
2461
|
+
errorType: import_zod9.z.nativeEnum(ErrorType).describe("Error type: BUILD_FAILURE, TEST_FAILURE, CONFLICT, AUTH_ERROR, OTHER"),
|
|
2462
|
+
errorMessage: import_zod9.z.string().describe("Error message (max 1000 chars)"),
|
|
2463
|
+
context: import_zod9.z.string().optional().describe("Additional context (max 2000 chars)")
|
|
1683
2464
|
}
|
|
1684
2465
|
},
|
|
1685
2466
|
async (args) => {
|
|
@@ -1714,7 +2495,7 @@ function initializeMCPServer(apiClient, authContext) {
|
|
|
1714
2495
|
{
|
|
1715
2496
|
description: "Load project README, tech stack, and coding conventions. Call after selecting project.",
|
|
1716
2497
|
inputSchema: {
|
|
1717
|
-
projectId:
|
|
2498
|
+
projectId: import_zod9.z.string().describe("The project ID")
|
|
1718
2499
|
}
|
|
1719
2500
|
},
|
|
1720
2501
|
async (args) => {
|
|
@@ -1744,8 +2525,8 @@ function initializeMCPServer(apiClient, authContext) {
|
|
|
1744
2525
|
{
|
|
1745
2526
|
description: "Document implementation decisions. Notes persist for future reference and handoff.",
|
|
1746
2527
|
inputSchema: {
|
|
1747
|
-
taskId:
|
|
1748
|
-
content:
|
|
2528
|
+
taskId: import_zod9.z.string().describe("The task ID"),
|
|
2529
|
+
content: import_zod9.z.string().describe("Note content (max 500 chars)")
|
|
1749
2530
|
}
|
|
1750
2531
|
},
|
|
1751
2532
|
async (args) => {
|
|
@@ -1774,9 +2555,9 @@ function initializeMCPServer(apiClient, authContext) {
|
|
|
1774
2555
|
{
|
|
1775
2556
|
description: "Release task assignment and optionally clean up branch. Task returns to TODO. Use after errors.",
|
|
1776
2557
|
inputSchema: {
|
|
1777
|
-
projectId:
|
|
1778
|
-
taskId:
|
|
1779
|
-
deleteBranch:
|
|
2558
|
+
projectId: import_zod9.z.string().describe("The project ID"),
|
|
2559
|
+
taskId: import_zod9.z.string().describe("The task ID to abandon"),
|
|
2560
|
+
deleteBranch: import_zod9.z.boolean().optional().describe("Whether to delete the associated branch")
|
|
1780
2561
|
}
|
|
1781
2562
|
},
|
|
1782
2563
|
async (args) => {
|
|
@@ -1810,9 +2591,9 @@ function initializeMCPServer(apiClient, authContext) {
|
|
|
1810
2591
|
{
|
|
1811
2592
|
description: "Report a branch created by the agent. Call after using git to create and push a branch. Task must be IN_PROGRESS.",
|
|
1812
2593
|
inputSchema: {
|
|
1813
|
-
projectId:
|
|
1814
|
-
taskId:
|
|
1815
|
-
branchName:
|
|
2594
|
+
projectId: import_zod9.z.string().describe("The project ID"),
|
|
2595
|
+
taskId: import_zod9.z.string().describe("The task ID"),
|
|
2596
|
+
branchName: import_zod9.z.string().describe("Name of the branch created (e.g., feature/TASK-123-fix-login)")
|
|
1816
2597
|
}
|
|
1817
2598
|
},
|
|
1818
2599
|
async (args) => {
|
|
@@ -1846,10 +2627,10 @@ function initializeMCPServer(apiClient, authContext) {
|
|
|
1846
2627
|
{
|
|
1847
2628
|
description: "Report a PR created by the agent. Call after using gh pr create. Transitions task to REVIEW state.",
|
|
1848
2629
|
inputSchema: {
|
|
1849
|
-
projectId:
|
|
1850
|
-
taskId:
|
|
1851
|
-
pullRequestUrl:
|
|
1852
|
-
pullRequestNumber:
|
|
2630
|
+
projectId: import_zod9.z.string().describe("The project ID"),
|
|
2631
|
+
taskId: import_zod9.z.string().describe("The task ID"),
|
|
2632
|
+
pullRequestUrl: import_zod9.z.string().describe("Full URL of the created PR (e.g., https://github.com/owner/repo/pull/123)"),
|
|
2633
|
+
pullRequestNumber: import_zod9.z.number().describe("PR number (e.g., 123)")
|
|
1853
2634
|
}
|
|
1854
2635
|
},
|
|
1855
2636
|
async (args) => {
|
|
@@ -1884,8 +2665,8 @@ function initializeMCPServer(apiClient, authContext) {
|
|
|
1884
2665
|
{
|
|
1885
2666
|
description: "Soft-delete a task. Hidden but restorable via unarchive_task.",
|
|
1886
2667
|
inputSchema: {
|
|
1887
|
-
projectId:
|
|
1888
|
-
taskId:
|
|
2668
|
+
projectId: import_zod9.z.string().describe("The project ID"),
|
|
2669
|
+
taskId: import_zod9.z.string().describe("The task ID to archive")
|
|
1889
2670
|
}
|
|
1890
2671
|
},
|
|
1891
2672
|
async (args) => {
|
|
@@ -1918,8 +2699,8 @@ function initializeMCPServer(apiClient, authContext) {
|
|
|
1918
2699
|
{
|
|
1919
2700
|
description: "Restore previously archived task to original state.",
|
|
1920
2701
|
inputSchema: {
|
|
1921
|
-
projectId:
|
|
1922
|
-
taskId:
|
|
2702
|
+
projectId: import_zod9.z.string().describe("The project ID"),
|
|
2703
|
+
taskId: import_zod9.z.string().describe("The task ID to restore")
|
|
1923
2704
|
}
|
|
1924
2705
|
},
|
|
1925
2706
|
async (args) => {
|
|
@@ -1952,9 +2733,9 @@ function initializeMCPServer(apiClient, authContext) {
|
|
|
1952
2733
|
{
|
|
1953
2734
|
description: "Create new project in personal workspace linked to GitHub repository.",
|
|
1954
2735
|
inputSchema: {
|
|
1955
|
-
name:
|
|
1956
|
-
description:
|
|
1957
|
-
repositoryUrl:
|
|
2736
|
+
name: import_zod9.z.string().describe("Project name (max 100 chars)"),
|
|
2737
|
+
description: import_zod9.z.string().optional().describe("Project description (max 500 chars)"),
|
|
2738
|
+
repositoryUrl: import_zod9.z.string().describe("GitHub repository URL")
|
|
1958
2739
|
}
|
|
1959
2740
|
},
|
|
1960
2741
|
async (args) => {
|
|
@@ -1988,14 +2769,14 @@ function initializeMCPServer(apiClient, authContext) {
|
|
|
1988
2769
|
{
|
|
1989
2770
|
description: "Create task with title, description, acceptance criteria. Starts in DRAFT. Priority: LOW/MEDIUM/HIGH/CRITICAL.",
|
|
1990
2771
|
inputSchema: {
|
|
1991
|
-
projectId:
|
|
1992
|
-
epicId:
|
|
1993
|
-
title:
|
|
1994
|
-
description:
|
|
1995
|
-
priority:
|
|
1996
|
-
acceptanceCriteria:
|
|
1997
|
-
|
|
1998
|
-
description:
|
|
2772
|
+
projectId: import_zod9.z.string().describe("The project ID to create the task in"),
|
|
2773
|
+
epicId: import_zod9.z.string().nullable().optional().describe("Optional epic ID to associate the task with"),
|
|
2774
|
+
title: import_zod9.z.string().describe("Task title (max 200 chars)"),
|
|
2775
|
+
description: import_zod9.z.string().describe("Task description (max 5000 chars)"),
|
|
2776
|
+
priority: import_zod9.z.nativeEnum(TaskPriority).optional().describe("Task priority: LOW, MEDIUM, HIGH, CRITICAL (default: MEDIUM)"),
|
|
2777
|
+
acceptanceCriteria: import_zod9.z.array(
|
|
2778
|
+
import_zod9.z.object({
|
|
2779
|
+
description: import_zod9.z.string().describe("Acceptance criterion description (max 500 chars)")
|
|
1999
2780
|
})
|
|
2000
2781
|
).describe("Array of acceptance criteria (at least 1 required)")
|
|
2001
2782
|
}
|
|
@@ -2034,10 +2815,10 @@ function initializeMCPServer(apiClient, authContext) {
|
|
|
2034
2815
|
{
|
|
2035
2816
|
description: "Return task from REVIEW to IN_PROGRESS with feedback. Original assignee addresses changes.",
|
|
2036
2817
|
inputSchema: {
|
|
2037
|
-
projectId:
|
|
2038
|
-
taskId:
|
|
2039
|
-
reviewComments:
|
|
2040
|
-
requestedChanges:
|
|
2818
|
+
projectId: import_zod9.z.string().describe("The project ID"),
|
|
2819
|
+
taskId: import_zod9.z.string().describe("The task ID to review"),
|
|
2820
|
+
reviewComments: import_zod9.z.string().describe("Review comments explaining requested changes (max 5000 chars)"),
|
|
2821
|
+
requestedChanges: import_zod9.z.array(import_zod9.z.string()).optional().describe("List of specific changes requested")
|
|
2041
2822
|
}
|
|
2042
2823
|
},
|
|
2043
2824
|
async (args) => {
|
|
@@ -2072,9 +2853,9 @@ function initializeMCPServer(apiClient, authContext) {
|
|
|
2072
2853
|
{
|
|
2073
2854
|
description: "Approve completed work and mark DONE. Only for REVIEW state tasks.",
|
|
2074
2855
|
inputSchema: {
|
|
2075
|
-
projectId:
|
|
2076
|
-
taskId:
|
|
2077
|
-
reviewComments:
|
|
2856
|
+
projectId: import_zod9.z.string().describe("The project ID"),
|
|
2857
|
+
taskId: import_zod9.z.string().describe("The task ID to approve"),
|
|
2858
|
+
reviewComments: import_zod9.z.string().optional().describe("Optional approval comments (max 2000 chars)")
|
|
2078
2859
|
}
|
|
2079
2860
|
},
|
|
2080
2861
|
async (args) => {
|
|
@@ -2108,10 +2889,10 @@ function initializeMCPServer(apiClient, authContext) {
|
|
|
2108
2889
|
{
|
|
2109
2890
|
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.",
|
|
2110
2891
|
inputSchema: {
|
|
2111
|
-
projectId:
|
|
2112
|
-
taskId:
|
|
2113
|
-
approved:
|
|
2114
|
-
feedback:
|
|
2892
|
+
projectId: import_zod9.z.string().describe("The project ID"),
|
|
2893
|
+
taskId: import_zod9.z.string().describe("The task ID to verify"),
|
|
2894
|
+
approved: import_zod9.z.boolean().describe("Whether to approve the task"),
|
|
2895
|
+
feedback: import_zod9.z.string().optional().describe("Feedback for the task (required if not approved)")
|
|
2115
2896
|
}
|
|
2116
2897
|
},
|
|
2117
2898
|
async (args) => {
|
|
@@ -2142,8 +2923,8 @@ function initializeMCPServer(apiClient, authContext) {
|
|
|
2142
2923
|
{
|
|
2143
2924
|
description: "Get state-appropriate prompt for a task. Returns verify prompt for DRAFT, assignment prompt for TODO, or continue prompt for IN_PROGRESS tasks.",
|
|
2144
2925
|
inputSchema: {
|
|
2145
|
-
projectId:
|
|
2146
|
-
taskId:
|
|
2926
|
+
projectId: import_zod9.z.string().describe("The project ID"),
|
|
2927
|
+
taskId: import_zod9.z.string().describe("The task ID")
|
|
2147
2928
|
}
|
|
2148
2929
|
},
|
|
2149
2930
|
async (args) => {
|
|
@@ -2174,17 +2955,17 @@ function initializeMCPServer(apiClient, authContext) {
|
|
|
2174
2955
|
server.registerTool(
|
|
2175
2956
|
"update_task",
|
|
2176
2957
|
{
|
|
2177
|
-
description: "Update task details (title, description, priority, acceptanceCriteria). Only works for DRAFT and TODO states.
|
|
2958
|
+
description: "Update task details (title, description, priority, acceptanceCriteria). Only works for DRAFT and TODO states. Task stays in its current state.",
|
|
2178
2959
|
inputSchema: {
|
|
2179
|
-
projectId:
|
|
2180
|
-
taskId:
|
|
2181
|
-
title:
|
|
2182
|
-
description:
|
|
2183
|
-
priority:
|
|
2184
|
-
acceptanceCriteria:
|
|
2185
|
-
|
|
2186
|
-
id:
|
|
2187
|
-
description:
|
|
2960
|
+
projectId: import_zod9.z.string().describe("The project ID"),
|
|
2961
|
+
taskId: import_zod9.z.string().describe("The task ID to update"),
|
|
2962
|
+
title: import_zod9.z.string().optional().describe("New task title"),
|
|
2963
|
+
description: import_zod9.z.string().optional().describe("New task description"),
|
|
2964
|
+
priority: import_zod9.z.nativeEnum(TaskPriority).optional().describe("New task priority"),
|
|
2965
|
+
acceptanceCriteria: import_zod9.z.array(
|
|
2966
|
+
import_zod9.z.object({
|
|
2967
|
+
id: import_zod9.z.string().optional().describe("Existing criterion ID (for updates)"),
|
|
2968
|
+
description: import_zod9.z.string().describe("Criterion description")
|
|
2188
2969
|
})
|
|
2189
2970
|
).optional().describe("New acceptance criteria (replaces existing)")
|
|
2190
2971
|
}
|
|
@@ -2240,6 +3021,7 @@ function initializeMCPServer(apiClient, authContext) {
|
|
|
2240
3021
|
};
|
|
2241
3022
|
}
|
|
2242
3023
|
);
|
|
3024
|
+
registerMCPApps(server, apiClient, authContext);
|
|
2243
3025
|
return server;
|
|
2244
3026
|
}
|
|
2245
3027
|
async function connectMCPServer(server, transport) {
|
|
@@ -2292,30 +3074,30 @@ function handleApiError(error) {
|
|
|
2292
3074
|
isError: true
|
|
2293
3075
|
};
|
|
2294
3076
|
}
|
|
2295
|
-
var ActiveTaskSchema =
|
|
2296
|
-
taskId:
|
|
2297
|
-
projectId:
|
|
2298
|
-
branchName:
|
|
2299
|
-
worktreePath:
|
|
2300
|
-
startedAt:
|
|
3077
|
+
var ActiveTaskSchema = import_zod9.z.object({
|
|
3078
|
+
taskId: import_zod9.z.string().min(1),
|
|
3079
|
+
projectId: import_zod9.z.string().min(1),
|
|
3080
|
+
branchName: import_zod9.z.string().optional(),
|
|
3081
|
+
worktreePath: import_zod9.z.string().optional(),
|
|
3082
|
+
startedAt: import_zod9.z.string().optional()
|
|
2301
3083
|
});
|
|
2302
3084
|
async function checkActiveTask() {
|
|
2303
|
-
const
|
|
2304
|
-
const
|
|
3085
|
+
const fs2 = await import("fs");
|
|
3086
|
+
const path2 = await import("path");
|
|
2305
3087
|
const cwd = process.cwd();
|
|
2306
|
-
const collabDir =
|
|
2307
|
-
const activeTaskPath =
|
|
3088
|
+
const collabDir = path2.join(cwd, ".collab");
|
|
3089
|
+
const activeTaskPath = path2.join(collabDir, "active-task.json");
|
|
2308
3090
|
try {
|
|
2309
|
-
const resolvedPath =
|
|
2310
|
-
const resolvedCollabDir =
|
|
2311
|
-
if (!resolvedPath.startsWith(resolvedCollabDir +
|
|
3091
|
+
const resolvedPath = path2.resolve(activeTaskPath);
|
|
3092
|
+
const resolvedCollabDir = path2.resolve(collabDir);
|
|
3093
|
+
if (!resolvedPath.startsWith(resolvedCollabDir + path2.sep) && resolvedPath !== resolvedCollabDir) {
|
|
2312
3094
|
return {
|
|
2313
3095
|
hasActiveTask: false,
|
|
2314
3096
|
task: null,
|
|
2315
3097
|
error: "Invalid active task path"
|
|
2316
3098
|
};
|
|
2317
3099
|
}
|
|
2318
|
-
const stats = await
|
|
3100
|
+
const stats = await fs2.promises.lstat(activeTaskPath);
|
|
2319
3101
|
if (stats.isSymbolicLink()) {
|
|
2320
3102
|
return {
|
|
2321
3103
|
hasActiveTask: false,
|
|
@@ -2329,7 +3111,7 @@ async function checkActiveTask() {
|
|
|
2329
3111
|
task: null
|
|
2330
3112
|
};
|
|
2331
3113
|
}
|
|
2332
|
-
const content = await
|
|
3114
|
+
const content = await fs2.promises.readFile(activeTaskPath, "utf-8");
|
|
2333
3115
|
let parsed;
|
|
2334
3116
|
try {
|
|
2335
3117
|
parsed = JSON.parse(content);
|