@mtaap/mcp 0.2.12 → 0.4.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/dist/cli.js CHANGED
@@ -30,7 +30,7 @@ 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.2.11",
33
+ version: "0.4.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: {
@@ -39,7 +39,9 @@ var package_default = {
39
39
  main: "./dist/index.js",
40
40
  types: "./dist/index.d.ts",
41
41
  bin: {
42
- "collab-mcp": "./dist/cli.js"
42
+ mcp: "./dist/cli.js",
43
+ "collab-mcp": "./dist/cli.js",
44
+ "collab-mcp-server": "./dist/server.js"
43
45
  },
44
46
  publishConfig: {
45
47
  access: "public"
@@ -70,11 +72,13 @@ var package_default = {
70
72
  },
71
73
  dependencies: {
72
74
  "@modelcontextprotocol/sdk": "^1.0.0",
75
+ express: "^5.0.1",
73
76
  zod: "^4.3.5"
74
77
  },
75
78
  devDependencies: {
76
79
  "@mtaap/config-typescript": "workspace:*",
77
80
  "@mtaap/core": "workspace:*",
81
+ "@types/express": "^5.0.0",
78
82
  "@types/node": "^22.0.0",
79
83
  tsup: "^8.5.1",
80
84
  typescript: "^5.4.0"
@@ -85,7 +89,7 @@ var package_default = {
85
89
  var VERSION = package_default.version;
86
90
 
87
91
  // src/index.ts
88
- var import_zod3 = require("zod");
92
+ var import_zod4 = require("zod");
89
93
 
90
94
  // ../../packages/core/dist/constants/enums.js
91
95
  var TaskState;
@@ -172,12 +176,6 @@ var WebSocketEventType;
172
176
  WebSocketEventType2["TASK_DELETED"] = "task.deleted";
173
177
  WebSocketEventType2["MEMBER_JOINED"] = "member.joined";
174
178
  })(WebSocketEventType || (WebSocketEventType = {}));
175
- var AuthProvider;
176
- (function(AuthProvider2) {
177
- AuthProvider2["CREDENTIALS"] = "credentials";
178
- AuthProvider2["LDAP"] = "ldap";
179
- AuthProvider2["SSO"] = "sso";
180
- })(AuthProvider || (AuthProvider = {}));
181
179
  var SubscriptionStatus;
182
180
  (function(SubscriptionStatus2) {
183
181
  SubscriptionStatus2["ACTIVE"] = "ACTIVE";
@@ -193,6 +191,12 @@ var EventType;
193
191
  EventType2["ACCESS"] = "ACCESS";
194
192
  EventType2["MODIFICATION"] = "MODIFICATION";
195
193
  })(EventType || (EventType = {}));
194
+ var CreatedVia;
195
+ (function(CreatedVia2) {
196
+ CreatedVia2["UI"] = "UI";
197
+ CreatedVia2["API_KEY"] = "API_KEY";
198
+ CreatedVia2["OAUTH"] = "OAUTH";
199
+ })(CreatedVia || (CreatedVia = {}));
196
200
 
197
201
  // ../../packages/core/dist/constants/state-machine.js
198
202
  var VALID_TRANSITIONS = {
@@ -216,6 +220,62 @@ var VALID_TRANSITIONS = {
216
220
  [TaskState.DONE]: []
217
221
  };
218
222
 
223
+ // ../../packages/core/dist/constants/oauth.js
224
+ var OAuthScopes = {
225
+ /** Read-only access to MCP resources */
226
+ READ: "mcp:read",
227
+ /** Read and write access to MCP resources */
228
+ WRITE: "mcp:write",
229
+ /** Full administrative access */
230
+ ADMIN: "mcp:admin"
231
+ };
232
+ var VALID_OAUTH_SCOPES = [
233
+ OAuthScopes.READ,
234
+ OAuthScopes.WRITE,
235
+ OAuthScopes.ADMIN
236
+ ];
237
+ var DEFAULT_OAUTH_SCOPES = `${OAuthScopes.READ} ${OAuthScopes.WRITE}`;
238
+ var OAUTH_SCOPE_TO_PERMISSION = {
239
+ [OAuthScopes.READ]: ApiKeyPermission.READ,
240
+ [OAuthScopes.WRITE]: ApiKeyPermission.WRITE,
241
+ [OAuthScopes.ADMIN]: ApiKeyPermission.ADMIN
242
+ };
243
+ var PERMISSION_TO_OAUTH_SCOPE = {
244
+ [ApiKeyPermission.READ]: OAuthScopes.READ,
245
+ [ApiKeyPermission.WRITE]: OAuthScopes.WRITE,
246
+ [ApiKeyPermission.ADMIN]: OAuthScopes.ADMIN
247
+ };
248
+ var OAuthTokenLifetimes = {
249
+ /** Access token lifetime: 1 hour */
250
+ ACCESS_TOKEN_MS: 60 * 60 * 1e3,
251
+ /** Refresh token lifetime: 30 days */
252
+ REFRESH_TOKEN_MS: 30 * 24 * 60 * 60 * 1e3,
253
+ /** Authorization code lifetime: 10 minutes */
254
+ AUTHORIZATION_CODE_MS: 10 * 60 * 1e3
255
+ };
256
+ var OAuthGrantTypes = {
257
+ AUTHORIZATION_CODE: "authorization_code",
258
+ REFRESH_TOKEN: "refresh_token"
259
+ };
260
+ var SUPPORTED_GRANT_TYPES = [
261
+ OAuthGrantTypes.AUTHORIZATION_CODE,
262
+ OAuthGrantTypes.REFRESH_TOKEN
263
+ ];
264
+ var OAuthResponseTypes = {
265
+ CODE: "code"
266
+ };
267
+ var OAuthCodeChallengeMethods = {
268
+ S256: "S256"
269
+ };
270
+ var OAuthRateLimits = {
271
+ /** /oauth/token: 30 requests per minute per client */
272
+ TOKEN_ENDPOINT: { limit: 30, windowMs: 60 * 1e3 },
273
+ /** /oauth/authorize: 10 requests per minute per user */
274
+ AUTHORIZE_ENDPOINT: { limit: 10, windowMs: 60 * 1e3 },
275
+ /** /oauth/register: 5 requests per minute per IP */
276
+ REGISTER_ENDPOINT: { limit: 5, windowMs: 60 * 1e3 }
277
+ };
278
+
219
279
  // ../../packages/core/dist/config/deployment.js
220
280
  var config = {
221
281
  deploymentMode: process.env.DEPLOYMENT_MODE || "saas"
@@ -223,20 +283,24 @@ var config = {
223
283
  var isSaas = config.deploymentMode === "saas";
224
284
  var isOnPrem = config.deploymentMode === "onprem";
225
285
 
226
- // ../../packages/core/dist/version.js
227
- var VERSION2 = "0.1.0";
286
+ // ../../packages/core/dist/versions.js
287
+ var VERSIONS = {
288
+ core: "0.3.0",
289
+ web: "0.3.0",
290
+ mcp: "0.4.1"
291
+ };
292
+ var VERSION2 = VERSIONS.core;
228
293
 
229
294
  // ../../packages/core/dist/config/index.js
230
295
  var DEPLOYMENT_MODE = process.env.DEPLOYMENT_MODE || "saas";
231
296
  var config2 = {
232
297
  version: VERSION2,
298
+ packages: VERSIONS,
233
299
  deploymentMode: DEPLOYMENT_MODE,
234
300
  billing: {
235
301
  enabled: DEPLOYMENT_MODE === "saas",
236
302
  revenuecat: {
237
- publicKey: process.env.REVENUECAT_PUBLIC_API_KEY,
238
- stripeKey: process.env.STRIPE_SECRET_KEY
239
- // Required by RevenueCat Web Billing
303
+ publicKey: process.env.NEXT_PUBLIC_REVENUECAT_PUBLIC_KEY
240
304
  }
241
305
  },
242
306
  licensing: {
@@ -342,7 +406,6 @@ var OrganizationIdSchema = import_zod.z.string().regex(/^org_[a-zA-Z0-9]+$/);
342
406
  var OrganizationSchema = import_zod.z.object({
343
407
  id: OrganizationIdSchema,
344
408
  name: import_zod.z.string().min(1).max(255),
345
- slug: import_zod.z.string().min(1).max(100).regex(/^[a-z0-9-]+$/),
346
409
  logoUrl: import_zod.z.string().url().nullable(),
347
410
  accentColor: import_zod.z.string().regex(/^#[0-9A-Fa-f]{6}$/).nullable(),
348
411
  tenantName: import_zod.z.string().nullable(),
@@ -470,239 +533,375 @@ var ProjectCollaboratorSchema = import_zod.z.object({
470
533
  });
471
534
 
472
535
  // ../../packages/core/dist/validation/index.js
536
+ var import_zod3 = require("zod");
537
+
538
+ // ../../packages/core/dist/validation/oauth.js
473
539
  var import_zod2 = require("zod");
474
- var ListProjectsInputSchema = import_zod2.z.object({
475
- workspaceType: import_zod2.z.preprocess((val) => typeof val === "string" ? val.toUpperCase() : val, import_zod2.z.enum(["TEAM", "PERSONAL", "ALL"]).optional())
476
- });
477
- var ListTasksInputSchema = import_zod2.z.object({
478
- projectId: import_zod2.z.string().optional(),
479
- state: import_zod2.z.nativeEnum(TaskState).optional(),
480
- assigneeId: import_zod2.z.string().optional(),
481
- includeArchived: import_zod2.z.boolean().optional()
482
- });
483
- var cuidOrPrefixedId = import_zod2.z.string().regex(/^([a-z0-9]+|[a-z]+_[a-zA-Z0-9]+)$/);
484
- var gitBranchName = import_zod2.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");
485
- var GetTaskInputSchema = import_zod2.z.object({
540
+ var scopeString = import_zod2.z.string().optional().transform((val) => {
541
+ if (!val)
542
+ return void 0;
543
+ const scopes = val.split(" ").filter(Boolean);
544
+ const validScopes = scopes.filter((s) => VALID_OAUTH_SCOPES.includes(s));
545
+ return validScopes.length > 0 ? validScopes.join(" ") : void 0;
546
+ });
547
+ var redirectUri = import_zod2.z.string().url().refine((uri) => {
548
+ const url = new URL(uri);
549
+ return url.protocol === "https:" || url.hostname === "localhost" || url.hostname === "127.0.0.1";
550
+ }, { message: "redirect_uri must use HTTPS or be localhost" });
551
+ var codeVerifier = import_zod2.z.string().min(43).max(128).regex(/^[A-Za-z0-9._~-]+$/, "code_verifier must only contain unreserved characters");
552
+ var codeChallenge = import_zod2.z.string().min(43).max(128).regex(/^[A-Za-z0-9_-]+$/, "code_challenge must be base64url encoded (no padding)");
553
+ var DynamicClientRegistrationSchema = import_zod2.z.object({
554
+ redirect_uris: import_zod2.z.array(redirectUri).min(1),
555
+ client_name: import_zod2.z.string().min(1).max(255),
556
+ client_uri: import_zod2.z.string().url().optional(),
557
+ logo_uri: import_zod2.z.string().url().optional(),
558
+ // Accept lowercase OAuth spec values
559
+ grant_types: import_zod2.z.array(import_zod2.z.enum(["authorization_code", "refresh_token"])).default(["authorization_code", "refresh_token"]),
560
+ response_types: import_zod2.z.array(import_zod2.z.enum([OAuthResponseTypes.CODE])).default([OAuthResponseTypes.CODE]),
561
+ scope: scopeString,
562
+ // Accept lowercase OAuth spec values
563
+ token_endpoint_auth_method: import_zod2.z.enum(["none", "client_secret_post", "client_secret_basic"]).default("none")
564
+ });
565
+ var DynamicClientRegistrationResponseSchema = import_zod2.z.object({
566
+ client_id: import_zod2.z.string(),
567
+ client_secret: import_zod2.z.string().optional(),
568
+ client_id_issued_at: import_zod2.z.number(),
569
+ client_secret_expires_at: import_zod2.z.number().optional(),
570
+ redirect_uris: import_zod2.z.array(import_zod2.z.string()),
571
+ client_name: import_zod2.z.string(),
572
+ client_uri: import_zod2.z.string().optional(),
573
+ logo_uri: import_zod2.z.string().optional(),
574
+ grant_types: import_zod2.z.array(import_zod2.z.string()),
575
+ response_types: import_zod2.z.array(import_zod2.z.string()),
576
+ scope: import_zod2.z.string(),
577
+ token_endpoint_auth_method: import_zod2.z.string(),
578
+ registration_access_token: import_zod2.z.string().optional(),
579
+ registration_client_uri: import_zod2.z.string().optional()
580
+ });
581
+ var AuthorizationRequestSchema = import_zod2.z.object({
582
+ response_type: import_zod2.z.literal(OAuthResponseTypes.CODE),
583
+ client_id: import_zod2.z.string().min(1),
584
+ redirect_uri: redirectUri,
585
+ scope: scopeString,
586
+ state: import_zod2.z.string().max(255).optional(),
587
+ // PKCE is mandatory in OAuth 2.1
588
+ code_challenge: codeChallenge,
589
+ code_challenge_method: import_zod2.z.literal(OAuthCodeChallengeMethods.S256)
590
+ });
591
+ var TokenRequestAuthorizationCodeSchema = import_zod2.z.object({
592
+ grant_type: import_zod2.z.literal(OAuthGrantTypes.AUTHORIZATION_CODE),
593
+ code: import_zod2.z.string().min(1),
594
+ redirect_uri: redirectUri,
595
+ client_id: import_zod2.z.string().min(1),
596
+ // PKCE code verifier is mandatory
597
+ code_verifier: codeVerifier,
598
+ // Client secret is optional (for confidential clients)
599
+ client_secret: import_zod2.z.string().optional()
600
+ });
601
+ var TokenRequestRefreshTokenSchema = import_zod2.z.object({
602
+ grant_type: import_zod2.z.literal(OAuthGrantTypes.REFRESH_TOKEN),
603
+ refresh_token: import_zod2.z.string().min(1),
604
+ client_id: import_zod2.z.string().min(1),
605
+ // Optional: request reduced scope
606
+ scope: scopeString,
607
+ // Client secret is optional (for confidential clients)
608
+ client_secret: import_zod2.z.string().optional()
609
+ });
610
+ var TokenRequestSchema = import_zod2.z.discriminatedUnion("grant_type", [
611
+ TokenRequestAuthorizationCodeSchema,
612
+ TokenRequestRefreshTokenSchema
613
+ ]);
614
+ var TokenResponseSchema = import_zod2.z.object({
615
+ access_token: import_zod2.z.string(),
616
+ token_type: import_zod2.z.literal("Bearer"),
617
+ expires_in: import_zod2.z.number(),
618
+ refresh_token: import_zod2.z.string().optional(),
619
+ scope: import_zod2.z.string()
620
+ });
621
+ var TokenRevocationRequestSchema = import_zod2.z.object({
622
+ token: import_zod2.z.string().min(1),
623
+ token_type_hint: import_zod2.z.enum(["access_token", "refresh_token"]).optional(),
624
+ client_id: import_zod2.z.string().min(1),
625
+ client_secret: import_zod2.z.string().optional()
626
+ });
627
+ var OAuthErrorResponseSchema = import_zod2.z.object({
628
+ error: import_zod2.z.string(),
629
+ error_description: import_zod2.z.string().optional(),
630
+ error_uri: import_zod2.z.string().url().optional(),
631
+ state: import_zod2.z.string().optional()
632
+ });
633
+ var AuthorizationServerMetadataSchema = import_zod2.z.object({
634
+ issuer: import_zod2.z.string().url(),
635
+ authorization_endpoint: import_zod2.z.string().url(),
636
+ token_endpoint: import_zod2.z.string().url(),
637
+ registration_endpoint: import_zod2.z.string().url().optional(),
638
+ revocation_endpoint: import_zod2.z.string().url().optional(),
639
+ scopes_supported: import_zod2.z.array(import_zod2.z.string()),
640
+ response_types_supported: import_zod2.z.array(import_zod2.z.string()),
641
+ grant_types_supported: import_zod2.z.array(import_zod2.z.string()),
642
+ token_endpoint_auth_methods_supported: import_zod2.z.array(import_zod2.z.string()),
643
+ code_challenge_methods_supported: import_zod2.z.array(import_zod2.z.string()),
644
+ service_documentation: import_zod2.z.string().url().optional()
645
+ });
646
+ var ProtectedResourceMetadataSchema = import_zod2.z.object({
647
+ resource: import_zod2.z.string().url(),
648
+ authorization_servers: import_zod2.z.array(import_zod2.z.string().url()),
649
+ scopes_supported: import_zod2.z.array(import_zod2.z.string()).optional(),
650
+ bearer_methods_supported: import_zod2.z.array(import_zod2.z.string()).optional(),
651
+ resource_signing_alg_values_supported: import_zod2.z.array(import_zod2.z.string()).optional(),
652
+ resource_documentation: import_zod2.z.string().url().optional()
653
+ });
654
+ var InternalTokenValidationRequestSchema = import_zod2.z.object({
655
+ access_token: import_zod2.z.string().min(1)
656
+ });
657
+ var InternalTokenValidationResponseSchema = import_zod2.z.object({
658
+ valid: import_zod2.z.boolean(),
659
+ userId: import_zod2.z.string().optional(),
660
+ userEmail: import_zod2.z.string().optional(),
661
+ userName: import_zod2.z.string().optional(),
662
+ scope: import_zod2.z.string().optional(),
663
+ permissions: import_zod2.z.string().optional(),
664
+ clientId: import_zod2.z.string().optional(),
665
+ expiresAt: import_zod2.z.string().optional()
666
+ });
667
+
668
+ // ../../packages/core/dist/validation/index.js
669
+ var ListProjectsInputSchema = import_zod3.z.object({
670
+ workspaceType: import_zod3.z.preprocess((val) => typeof val === "string" ? val.toUpperCase() : val, import_zod3.z.enum(["TEAM", "PERSONAL", "ALL"]).optional())
671
+ });
672
+ var ListTasksInputSchema = import_zod3.z.object({
673
+ projectId: import_zod3.z.string().optional(),
674
+ state: import_zod3.z.nativeEnum(TaskState).optional(),
675
+ assigneeId: import_zod3.z.string().optional(),
676
+ includeArchived: import_zod3.z.boolean().optional()
677
+ });
678
+ var cuidOrPrefixedId = import_zod3.z.string().regex(/^([a-z0-9]+|[a-z]+_[a-zA-Z0-9]+)$/);
679
+ 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");
680
+ var GetTaskInputSchema = import_zod3.z.object({
486
681
  taskId: cuidOrPrefixedId
487
682
  });
488
- var AssignTaskInputSchema = import_zod2.z.object({
683
+ var AssignTaskInputSchema = import_zod3.z.object({
489
684
  projectId: cuidOrPrefixedId,
490
685
  taskId: cuidOrPrefixedId,
491
- expectedState: import_zod2.z.nativeEnum(TaskState).default(TaskState.TODO)
686
+ expectedState: import_zod3.z.nativeEnum(TaskState).default(TaskState.TODO)
492
687
  });
493
- var UpdateProgressInputSchema = import_zod2.z.object({
688
+ var UpdateProgressInputSchema = import_zod3.z.object({
494
689
  taskId: cuidOrPrefixedId,
495
- statusMessage: import_zod2.z.string().max(1e3).optional(),
496
- completedCheckpointIds: import_zod2.z.array(import_zod2.z.string()).optional(),
497
- currentCheckpointIndex: import_zod2.z.number().int().optional()
690
+ statusMessage: import_zod3.z.string().max(1e3).optional(),
691
+ completedCheckpointIds: import_zod3.z.array(import_zod3.z.string()).optional(),
692
+ currentCheckpointIndex: import_zod3.z.number().int().optional()
498
693
  });
499
- var CompleteTaskInputSchema = import_zod2.z.object({
694
+ var CompleteTaskInputSchema = import_zod3.z.object({
500
695
  projectId: cuidOrPrefixedId,
501
696
  taskId: cuidOrPrefixedId,
502
- pullRequestTitle: import_zod2.z.string().min(1).max(300).optional(),
503
- pullRequestBody: import_zod2.z.string().max(1e4).optional()
697
+ pullRequestTitle: import_zod3.z.string().min(1).max(300).optional(),
698
+ pullRequestBody: import_zod3.z.string().max(1e4).optional()
504
699
  });
505
- var ReportErrorInputSchema = import_zod2.z.object({
700
+ var ReportErrorInputSchema = import_zod3.z.object({
506
701
  taskId: cuidOrPrefixedId,
507
- errorType: import_zod2.z.nativeEnum(ErrorType),
508
- errorMessage: import_zod2.z.string().min(1).max(1e3),
509
- context: import_zod2.z.string().max(2e3).optional()
702
+ errorType: import_zod3.z.nativeEnum(ErrorType),
703
+ errorMessage: import_zod3.z.string().min(1).max(1e3),
704
+ context: import_zod3.z.string().max(2e3).optional()
510
705
  });
511
- var GetProjectContextInputSchema = import_zod2.z.object({
706
+ var GetProjectContextInputSchema = import_zod3.z.object({
512
707
  projectId: cuidOrPrefixedId
513
708
  });
514
- var AddNoteInputSchema = import_zod2.z.object({
709
+ var AddNoteInputSchema = import_zod3.z.object({
515
710
  taskId: cuidOrPrefixedId,
516
- content: import_zod2.z.string().min(1).max(500)
711
+ content: import_zod3.z.string().min(1).max(500)
517
712
  });
518
- var AbandonTaskInputSchema = import_zod2.z.object({
713
+ var AbandonTaskInputSchema = import_zod3.z.object({
519
714
  projectId: cuidOrPrefixedId,
520
715
  taskId: cuidOrPrefixedId,
521
- deleteBranch: import_zod2.z.boolean().optional()
716
+ deleteBranch: import_zod3.z.boolean().optional()
522
717
  });
523
- var RequestChangesInputSchema = import_zod2.z.object({
718
+ var RequestChangesInputSchema = import_zod3.z.object({
524
719
  projectId: cuidOrPrefixedId,
525
720
  taskId: cuidOrPrefixedId,
526
- reviewComments: import_zod2.z.string().min(1).max(5e3),
527
- requestedChanges: import_zod2.z.array(import_zod2.z.string().min(1).max(500)).optional()
721
+ reviewComments: import_zod3.z.string().min(1).max(5e3),
722
+ requestedChanges: import_zod3.z.array(import_zod3.z.string().min(1).max(500)).optional()
528
723
  });
529
- var ApproveTaskInputSchema = import_zod2.z.object({
724
+ var ApproveTaskInputSchema = import_zod3.z.object({
530
725
  projectId: cuidOrPrefixedId,
531
726
  taskId: cuidOrPrefixedId,
532
- reviewComments: import_zod2.z.string().max(2e3).optional()
727
+ reviewComments: import_zod3.z.string().max(2e3).optional()
533
728
  });
534
- var ArchiveTaskInputSchema = import_zod2.z.object({
729
+ var ArchiveTaskInputSchema = import_zod3.z.object({
535
730
  projectId: cuidOrPrefixedId,
536
731
  taskId: cuidOrPrefixedId
537
732
  });
538
- var UnarchiveTaskInputSchema = import_zod2.z.object({
733
+ var UnarchiveTaskInputSchema = import_zod3.z.object({
539
734
  projectId: cuidOrPrefixedId,
540
735
  taskId: cuidOrPrefixedId
541
736
  });
542
- var CreatePersonalProjectInputSchema = import_zod2.z.object({
543
- name: import_zod2.z.string().min(1).max(100),
544
- description: import_zod2.z.string().max(500).optional(),
545
- repositoryUrl: import_zod2.z.string().url()
737
+ var CreatePersonalProjectInputSchema = import_zod3.z.object({
738
+ name: import_zod3.z.string().min(1).max(100),
739
+ description: import_zod3.z.string().max(500).optional(),
740
+ repositoryUrl: import_zod3.z.string().url()
546
741
  });
547
- var CheckActiveTaskInputSchema = import_zod2.z.object({});
548
- var CreateTaskMCPInputSchema = import_zod2.z.object({
742
+ var CheckActiveTaskInputSchema = import_zod3.z.object({});
743
+ var CreateTaskMCPInputSchema = import_zod3.z.object({
549
744
  projectId: cuidOrPrefixedId,
550
745
  epicId: cuidOrPrefixedId.nullable().optional(),
551
- title: import_zod2.z.string().min(1).max(200),
552
- description: import_zod2.z.string().max(5e3),
553
- priority: import_zod2.z.nativeEnum(TaskPriority).default(TaskPriority.MEDIUM),
554
- acceptanceCriteria: import_zod2.z.array(import_zod2.z.object({
555
- description: import_zod2.z.string().min(1).max(500)
746
+ title: import_zod3.z.string().min(1).max(200),
747
+ description: import_zod3.z.string().max(5e3),
748
+ priority: import_zod3.z.nativeEnum(TaskPriority).default(TaskPriority.MEDIUM),
749
+ acceptanceCriteria: import_zod3.z.array(import_zod3.z.object({
750
+ description: import_zod3.z.string().min(1).max(500)
556
751
  })).min(1)
557
752
  });
558
- var CreateOrganizationInputSchema = import_zod2.z.object({
559
- name: import_zod2.z.string().min(1).max(255),
560
- slug: import_zod2.z.string().min(1).max(100).regex(/^[a-z0-9-]+$/).optional()
753
+ var CreateOrganizationInputSchema = import_zod3.z.object({
754
+ name: import_zod3.z.string().min(1).max(255)
561
755
  });
562
- var UpdateOrganizationInputSchema = import_zod2.z.object({
756
+ var UpdateOrganizationInputSchema = import_zod3.z.object({
563
757
  organizationId: cuidOrPrefixedId,
564
- name: import_zod2.z.string().min(1).max(255).optional(),
565
- logoUrl: import_zod2.z.string().url().nullable().optional(),
566
- accentColor: import_zod2.z.string().regex(/^#[0-9A-Fa-f]{6}$/, "Invalid hex color format. Expected #RRGGBB").nullable().optional(),
567
- tenantName: import_zod2.z.string().max(255).nullable().optional()
568
- });
569
- var CreateProjectInputSchema = import_zod2.z.object({
570
- name: import_zod2.z.string().min(1).max(100),
571
- description: import_zod2.z.string().max(500).optional(),
572
- type: import_zod2.z.nativeEnum(ProjectType),
573
- repositoryUrl: import_zod2.z.string().url(),
574
- baseBranch: import_zod2.z.string().default("develop").optional(),
575
- tags: import_zod2.z.array(import_zod2.z.string()).default([])
576
- });
577
- var UpdateProjectInputSchema = import_zod2.z.object({
578
- projectId: import_zod2.z.string().min(1).optional(),
579
- name: import_zod2.z.string().min(1).max(100).optional(),
580
- description: import_zod2.z.string().max(500).optional(),
581
- repositoryUrl: import_zod2.z.string().url().optional(),
582
- baseBranch: import_zod2.z.string().optional(),
583
- tags: import_zod2.z.array(import_zod2.z.string()).optional(),
584
- allowMemberArchive: import_zod2.z.boolean().optional()
585
- });
586
- var CreateEpicInputSchema = import_zod2.z.object({
758
+ name: import_zod3.z.string().min(1).max(255).optional(),
759
+ logoUrl: import_zod3.z.string().url().nullable().optional(),
760
+ accentColor: import_zod3.z.string().regex(/^#[0-9A-Fa-f]{6}$/, "Invalid hex color format. Expected #RRGGBB").nullable().optional(),
761
+ tenantName: import_zod3.z.string().max(255).nullable().optional()
762
+ });
763
+ var CreateProjectInputSchema = import_zod3.z.object({
764
+ name: import_zod3.z.string().min(1).max(100),
765
+ description: import_zod3.z.string().max(500).optional(),
766
+ type: import_zod3.z.nativeEnum(ProjectType),
767
+ repositoryUrl: import_zod3.z.string().url(),
768
+ baseBranch: import_zod3.z.string().default("develop").optional(),
769
+ tags: import_zod3.z.array(import_zod3.z.string()).default([])
770
+ });
771
+ var UpdateProjectInputSchema = import_zod3.z.object({
772
+ projectId: import_zod3.z.string().min(1).optional(),
773
+ name: import_zod3.z.string().min(1).max(100).optional(),
774
+ description: import_zod3.z.string().max(500).optional(),
775
+ repositoryUrl: import_zod3.z.string().url().optional(),
776
+ baseBranch: import_zod3.z.string().optional(),
777
+ tags: import_zod3.z.array(import_zod3.z.string()).optional(),
778
+ allowMemberArchive: import_zod3.z.boolean().optional()
779
+ });
780
+ var CreateEpicInputSchema = import_zod3.z.object({
587
781
  projectId: cuidOrPrefixedId,
588
- name: import_zod2.z.string().min(1).max(200),
589
- description: import_zod2.z.string().max(2e3).optional()
590
- });
591
- var CreateTaskInputSchema = import_zod2.z.object({
592
- projectId: import_zod2.z.string().min(1),
593
- epicId: import_zod2.z.string().min(1).nullable().optional(),
594
- title: import_zod2.z.string().min(1).max(200),
595
- description: import_zod2.z.string().max(5e3),
596
- priority: import_zod2.z.nativeEnum(TaskPriority).default(TaskPriority.MEDIUM),
597
- acceptanceCriteria: import_zod2.z.array(import_zod2.z.object({
598
- description: import_zod2.z.string().min(1).max(500)
782
+ name: import_zod3.z.string().min(1).max(200),
783
+ description: import_zod3.z.string().max(2e3).optional()
784
+ });
785
+ var CreateTaskInputSchema = import_zod3.z.object({
786
+ projectId: import_zod3.z.string().min(1),
787
+ epicId: import_zod3.z.string().min(1).nullable().optional(),
788
+ title: import_zod3.z.string().min(1).max(200),
789
+ description: import_zod3.z.string().max(5e3),
790
+ priority: import_zod3.z.nativeEnum(TaskPriority).default(TaskPriority.MEDIUM),
791
+ acceptanceCriteria: import_zod3.z.array(import_zod3.z.object({
792
+ description: import_zod3.z.string().min(1).max(500)
599
793
  })).min(1)
600
794
  });
601
- var UpdateTaskInputSchema = import_zod2.z.object({
602
- taskId: import_zod2.z.string().min(1),
603
- title: import_zod2.z.string().min(1).max(200).optional(),
604
- description: import_zod2.z.string().max(5e3).optional(),
605
- priority: import_zod2.z.nativeEnum(TaskPriority).optional(),
606
- state: import_zod2.z.nativeEnum(TaskState).optional(),
607
- assigneeId: import_zod2.z.string().nullable().optional(),
608
- acceptanceCriteria: import_zod2.z.array(import_zod2.z.object({
609
- id: import_zod2.z.string().optional(),
610
- description: import_zod2.z.string().min(1).max(500),
611
- completed: import_zod2.z.boolean().optional()
795
+ var UpdateTaskInputSchema = import_zod3.z.object({
796
+ taskId: import_zod3.z.string().min(1),
797
+ title: import_zod3.z.string().min(1).max(200).optional(),
798
+ description: import_zod3.z.string().max(5e3).optional(),
799
+ priority: import_zod3.z.nativeEnum(TaskPriority).optional(),
800
+ state: import_zod3.z.nativeEnum(TaskState).optional(),
801
+ assigneeId: import_zod3.z.string().nullable().optional(),
802
+ acceptanceCriteria: import_zod3.z.array(import_zod3.z.object({
803
+ id: import_zod3.z.string().optional(),
804
+ description: import_zod3.z.string().min(1).max(500),
805
+ completed: import_zod3.z.boolean().optional()
612
806
  })).optional()
613
807
  });
614
- var AssignTaskWebappInputSchema = import_zod2.z.object({
615
- taskId: import_zod2.z.string().min(1),
616
- userId: import_zod2.z.string().min(1)
808
+ var AssignTaskWebappInputSchema = import_zod3.z.object({
809
+ taskId: import_zod3.z.string().min(1),
810
+ userId: import_zod3.z.string().min(1)
617
811
  });
618
- var CreateTagInputSchema = import_zod2.z.object({
812
+ var CreateTagInputSchema = import_zod3.z.object({
619
813
  organizationId: cuidOrPrefixedId,
620
- name: import_zod2.z.string().min(1).max(50).regex(/^[a-zA-Z0-9\s-]+$/)
814
+ name: import_zod3.z.string().min(1).max(50).regex(/^[a-zA-Z0-9\s-]+$/)
621
815
  });
622
- var UpdateTagInputSchema = import_zod2.z.object({
623
- name: import_zod2.z.string().min(1).max(50).regex(/^[a-zA-Z0-9\s-]+$/)
816
+ var UpdateTagInputSchema = import_zod3.z.object({
817
+ name: import_zod3.z.string().min(1).max(50).regex(/^[a-zA-Z0-9\s-]+$/)
624
818
  });
625
- var UpdateOrganizationSettingsInputSchema = import_zod2.z.object({
819
+ var UpdateOrganizationSettingsInputSchema = import_zod3.z.object({
626
820
  organizationId: cuidOrPrefixedId,
627
- ldapEnabled: import_zod2.z.boolean().optional(),
628
- ldapUrl: import_zod2.z.string().url().nullable().optional(),
629
- ldapBindDN: import_zod2.z.string().nullable().optional(),
630
- ldapSearchBase: import_zod2.z.string().nullable().optional(),
631
- deleteMergedBranches: import_zod2.z.boolean().optional(),
632
- enforceConventionalCommits: import_zod2.z.boolean().optional(),
633
- maxPersonalProjectsPerUser: import_zod2.z.number().int().min(0).optional(),
634
- logoUrl: import_zod2.z.string().url().nullable().optional(),
635
- accentColor: import_zod2.z.string().regex(/^#[0-9A-Fa-f]{6}$/, "Invalid hex color format. Expected #RRGGBB").nullable().optional(),
636
- tenantName: import_zod2.z.string().max(255).nullable().optional()
637
- });
638
- var InviteUserInputSchema = import_zod2.z.object({
821
+ ldapEnabled: import_zod3.z.boolean().optional(),
822
+ ldapUrl: import_zod3.z.string().url().nullable().optional(),
823
+ ldapBindDN: import_zod3.z.string().nullable().optional(),
824
+ ldapSearchBase: import_zod3.z.string().nullable().optional(),
825
+ deleteMergedBranches: import_zod3.z.boolean().optional(),
826
+ enforceConventionalCommits: import_zod3.z.boolean().optional(),
827
+ maxPersonalProjectsPerUser: import_zod3.z.number().int().min(0).optional(),
828
+ logoUrl: import_zod3.z.string().url().nullable().optional(),
829
+ accentColor: import_zod3.z.string().regex(/^#[0-9A-Fa-f]{6}$/, "Invalid hex color format. Expected #RRGGBB").nullable().optional(),
830
+ tenantName: import_zod3.z.string().max(255).nullable().optional()
831
+ });
832
+ var InviteUserInputSchema = import_zod3.z.object({
639
833
  organizationId: cuidOrPrefixedId,
640
- email: import_zod2.z.string().email(),
641
- role: import_zod2.z.nativeEnum(UserRole).default(UserRole.MEMBER),
642
- tags: import_zod2.z.array(import_zod2.z.string()).default([])
834
+ email: import_zod3.z.string().email(),
835
+ role: import_zod3.z.nativeEnum(UserRole).default(UserRole.MEMBER),
836
+ tags: import_zod3.z.array(import_zod3.z.string()).default([])
643
837
  });
644
- var AssignUserTagsInputSchema = import_zod2.z.object({
838
+ var AssignUserTagsInputSchema = import_zod3.z.object({
645
839
  userId: cuidOrPrefixedId,
646
- tags: import_zod2.z.array(import_zod2.z.string()).min(0)
840
+ tags: import_zod3.z.array(import_zod3.z.string()).min(0)
647
841
  });
648
- var InviteCollaboratorInputSchema = import_zod2.z.object({
842
+ var InviteCollaboratorInputSchema = import_zod3.z.object({
649
843
  projectId: cuidOrPrefixedId,
650
- email: import_zod2.z.string().email()
844
+ email: import_zod3.z.string().email()
651
845
  });
652
- var PublishProjectInputSchema = import_zod2.z.object({
846
+ var PublishProjectInputSchema = import_zod3.z.object({
653
847
  projectId: cuidOrPrefixedId,
654
- transferOwnership: import_zod2.z.boolean().default(false),
655
- tags: import_zod2.z.array(import_zod2.z.string()).min(1)
848
+ transferOwnership: import_zod3.z.boolean().default(false),
849
+ tags: import_zod3.z.array(import_zod3.z.string()).min(1)
850
+ });
851
+ var GenerateApiKeyInputSchema = import_zod3.z.object({
852
+ name: import_zod3.z.string().min(1).max(100),
853
+ publicNickname: import_zod3.z.string().max(50).optional(),
854
+ expiresInDays: import_zod3.z.number().int().min(1).max(365).default(90),
855
+ permissions: import_zod3.z.nativeEnum(ApiKeyPermission).default(ApiKeyPermission.WRITE)
656
856
  });
657
- var GenerateApiKeyInputSchema = import_zod2.z.object({
658
- name: import_zod2.z.string().min(1).max(100),
659
- expiresInDays: import_zod2.z.number().int().min(1).max(365).default(90),
660
- permissions: import_zod2.z.nativeEnum(ApiKeyPermission).default(ApiKeyPermission.WRITE)
857
+ var UpdateApiKeyInputSchema = import_zod3.z.object({
858
+ publicNickname: import_zod3.z.string().max(50).nullable().optional(),
859
+ scopedOrganizationId: import_zod3.z.string().optional().nullable(),
860
+ scopedProjectIds: import_zod3.z.array(import_zod3.z.string()).optional()
661
861
  });
662
- var RevokeApiKeyInputSchema = import_zod2.z.object({
862
+ var RevokeApiKeyInputSchema = import_zod3.z.object({
663
863
  keyId: cuidOrPrefixedId
664
864
  });
665
- var LoginInputSchema = import_zod2.z.object({
666
- email: import_zod2.z.string().email(),
667
- password: import_zod2.z.string().min(8).max(255)
865
+ var LoginInputSchema = import_zod3.z.object({
866
+ email: import_zod3.z.string().email(),
867
+ password: import_zod3.z.string().min(8).max(255)
668
868
  });
669
- var RegisterInputSchema = import_zod2.z.object({
670
- email: import_zod2.z.string().email(),
671
- password: import_zod2.z.string().min(8).max(255),
672
- name: import_zod2.z.string().min(1).max(255),
673
- organizationSlug: import_zod2.z.string().min(1).max(100).regex(/^[a-z0-9-]+$/).optional()
869
+ var RegisterInputSchema = import_zod3.z.object({
870
+ email: import_zod3.z.string().email(),
871
+ password: import_zod3.z.string().min(8).max(255),
872
+ name: import_zod3.z.string().min(1).max(255)
674
873
  });
675
- var VerifyTaskInputSchema = import_zod2.z.object({
874
+ var VerifyTaskInputSchema = import_zod3.z.object({
676
875
  projectId: cuidOrPrefixedId,
677
876
  taskId: cuidOrPrefixedId,
678
- approved: import_zod2.z.boolean(),
679
- feedback: import_zod2.z.string().max(5e3).optional()
877
+ approved: import_zod3.z.boolean(),
878
+ feedback: import_zod3.z.string().max(5e3).optional()
680
879
  });
681
- var GetTaskPromptInputSchema = import_zod2.z.object({
880
+ var GetTaskPromptInputSchema = import_zod3.z.object({
682
881
  projectId: cuidOrPrefixedId,
683
882
  taskId: cuidOrPrefixedId
684
883
  });
685
- var UpdateTaskMCPInputSchema = import_zod2.z.object({
884
+ var UpdateTaskMCPInputSchema = import_zod3.z.object({
686
885
  projectId: cuidOrPrefixedId,
687
886
  taskId: cuidOrPrefixedId,
688
- title: import_zod2.z.string().min(1).max(200).optional(),
689
- description: import_zod2.z.string().max(5e3).optional(),
690
- priority: import_zod2.z.nativeEnum(TaskPriority).optional(),
691
- acceptanceCriteria: import_zod2.z.array(import_zod2.z.object({
692
- id: import_zod2.z.string().optional(),
693
- description: import_zod2.z.string().min(1).max(500)
887
+ title: import_zod3.z.string().min(1).max(200).optional(),
888
+ description: import_zod3.z.string().max(5e3).optional(),
889
+ priority: import_zod3.z.nativeEnum(TaskPriority).optional(),
890
+ acceptanceCriteria: import_zod3.z.array(import_zod3.z.object({
891
+ id: import_zod3.z.string().optional(),
892
+ description: import_zod3.z.string().min(1).max(500)
694
893
  })).optional()
695
894
  });
696
- var ReportBranchInputSchema = import_zod2.z.object({
895
+ var ReportBranchInputSchema = import_zod3.z.object({
697
896
  projectId: cuidOrPrefixedId,
698
897
  taskId: cuidOrPrefixedId,
699
898
  branchName: gitBranchName
700
899
  });
701
- var ReportPRInputSchema = import_zod2.z.object({
900
+ var ReportPRInputSchema = import_zod3.z.object({
702
901
  projectId: cuidOrPrefixedId,
703
902
  taskId: cuidOrPrefixedId,
704
- pullRequestUrl: import_zod2.z.string().url(),
705
- pullRequestNumber: import_zod2.z.number().int().positive()
903
+ pullRequestUrl: import_zod3.z.string().url(),
904
+ pullRequestNumber: import_zod3.z.number().int().positive()
706
905
  });
707
906
 
708
907
  // ../../packages/core/dist/logging/metrics.js
@@ -783,23 +982,16 @@ function createHistogram(name, help, buckets = [5e-3, 0.01, 0.025, 0.05, 0.1, 0.
783
982
  var httpRequestsTotal = createCounter("mtaap_http_requests_total", "Total number of HTTP requests");
784
983
  var httpRequestDuration = createHistogram("mtaap_http_request_duration_seconds", "HTTP request duration in seconds");
785
984
  var activeUsers = createGauge("mtaap_active_users", "Number of active users");
786
- var tasksTotal = createCounter("mtaap_tasks_total", "Total number of tasks by state");
787
- var taskStateChanges = createCounter("mtaap_task_state_changes_total", "Total number of task state changes");
788
985
  var httpErrorsTotal = createCounter("mtaap_http_errors_total", "Total number of HTTP errors");
789
986
  var httpActiveConnections = createGauge("mtaap_http_active_connections", "Number of active HTTP connections");
790
987
  var newSignupsTotal = createCounter("mtaap_new_signups_total", "Total number of new user signups");
791
988
  var loginSuccessTotal = createCounter("mtaap_login_success_total", "Total number of successful logins");
792
989
  var loginFailureTotal = createCounter("mtaap_login_failure_total", "Total number of failed logins");
793
- var dbConnectionPoolActive = createGauge("mtaap_db_connection_pool_active", "Number of active database connections");
794
- var dbConnectionPoolIdle = createGauge("mtaap_db_connection_pool_idle", "Number of idle database connections");
795
- var dbConnectionPoolMax = createGauge("mtaap_db_connection_pool_max", "Maximum number of database connections");
796
990
  var dbQueryDuration = createHistogram("mtaap_db_query_duration_seconds", "Database query duration in seconds");
797
991
  var dbSlowQueriesTotal = createCounter("mtaap_db_slow_queries_total", "Total number of slow database queries (>1s)");
798
- var dbErrorsTotal = createCounter("mtaap_db_errors_total", "Total number of database errors");
799
992
  var tasksCreatedTotal = createCounter("mtaap_tasks_created_total", "Total number of tasks created");
800
993
  var tasksAssignedTotal = createCounter("mtaap_tasks_assigned_total", "Total number of tasks assigned");
801
994
  var tasksCompletedTotal = createCounter("mtaap_tasks_completed_total", "Total number of tasks completed");
802
- var tasksByState = createGauge("mtaap_tasks_by_state", "Number of tasks by state");
803
995
 
804
996
  // ../../packages/core/dist/logging/performance-monitor.js
805
997
  var MAX_SAMPLES = 1e3;
@@ -1021,12 +1213,17 @@ var ApiError = class extends Error {
1021
1213
  var MCPApiClient = class {
1022
1214
  baseUrl;
1023
1215
  apiKey;
1216
+ oauthToken;
1024
1217
  timeout;
1025
1218
  debug;
1026
1219
  authContext = null;
1027
1220
  constructor(config3) {
1221
+ if (!config3.apiKey && !config3.oauthToken) {
1222
+ throw new Error("Either apiKey or oauthToken must be provided");
1223
+ }
1028
1224
  this.baseUrl = config3.baseUrl.replace(/\/$/, "");
1029
1225
  this.apiKey = config3.apiKey;
1226
+ this.oauthToken = config3.oauthToken;
1030
1227
  this.timeout = config3.timeout ?? DEFAULT_TIMEOUT;
1031
1228
  this.debug = config3.debug ?? false;
1032
1229
  }
@@ -1041,18 +1238,33 @@ var MCPApiClient = class {
1041
1238
  console.error(`[mcp-api] ${method} ${sanitizeForLogging(path)}`);
1042
1239
  }
1043
1240
  try {
1241
+ const headers = {
1242
+ "Content-Type": "application/json"
1243
+ };
1244
+ if (this.oauthToken) {
1245
+ headers["Authorization"] = `Bearer ${this.oauthToken}`;
1246
+ } else if (this.apiKey) {
1247
+ headers["X-API-Key"] = this.apiKey;
1248
+ }
1044
1249
  const response = await fetch(url, {
1045
1250
  method,
1046
- headers: {
1047
- "Content-Type": "application/json",
1048
- "X-API-Key": this.apiKey
1049
- },
1251
+ headers,
1050
1252
  body: body ? JSON.stringify(body) : void 0,
1051
1253
  signal: controller.signal
1052
1254
  });
1053
1255
  clearTimeout(timeoutId);
1054
1256
  const data = await response.json();
1055
1257
  if (!response.ok) {
1258
+ if (response.status === 403 && data.code === "EMAIL_NOT_VERIFIED" && data.verificationUrl) {
1259
+ throw new ApiError(
1260
+ `${data.error}
1261
+
1262
+ To verify your email, visit: ${data.verificationUrl}
1263
+ ${data.hint ? `Hint: ${data.hint}` : ""}`,
1264
+ "EMAIL_NOT_VERIFIED",
1265
+ 403
1266
+ );
1267
+ }
1056
1268
  throw new ApiError(
1057
1269
  data.error || "API request failed",
1058
1270
  data.code || "UNKNOWN_ERROR",
@@ -1315,7 +1527,7 @@ var PERMISSION_RANK = {
1315
1527
  ADMIN: 3
1316
1528
  };
1317
1529
  function assertApiKeyPermission(apiKey, required, toolName) {
1318
- const actualRank = PERMISSION_RANK[apiKey.permissions] ?? 0;
1530
+ const actualRank = apiKey.permissions ? PERMISSION_RANK[apiKey.permissions] ?? 0 : 0;
1319
1531
  const requiredRank = PERMISSION_RANK[required] ?? 0;
1320
1532
  if (actualRank >= requiredRank) {
1321
1533
  return;
@@ -1366,14 +1578,16 @@ Task Creation & Verification:
1366
1578
 
1367
1579
  Standard Task Workflow:
1368
1580
  list_projects -> get_project_context -> list_tasks(state=TODO) -> get_task -> get_task_prompt (TODO)
1369
- -> assign_task (returns suggested branch name)
1370
- -> git checkout -b <branchName> (local git command)
1371
- -> git push -u origin <branchName> (local git command)
1372
- -> report_branch (tell server about the branch)
1581
+ -> assign_task (returns suggested branch name and worktree path)
1582
+ -> git worktree add <worktreePath> -b <branchName> <baseBranch>
1583
+ -> cd <worktreePath>
1373
1584
  -> [update_progress...]
1585
+ -> git push -u origin <branchName>
1586
+ -> report_branch (tell server about the branch)
1374
1587
  -> complete_task (returns PR suggestions)
1375
1588
  -> gh pr create (local gh command)
1376
1589
  -> report_pr (tell server about the PR)
1590
+ -> git worktree remove <worktreePath>
1377
1591
 
1378
1592
  Resume Workflow:
1379
1593
  check_active_task -> (if active) get_task -> get_task_prompt (IN_PROGRESS) -> update_progress -> complete_task
@@ -1389,10 +1603,14 @@ Error Recovery:
1389
1603
  (abandon_task returns IN_PROGRESS tasks to TODO state)
1390
1604
 
1391
1605
  GIT OPERATIONS NOTE:
1392
- The agent handles all git operations locally. After assign_task returns a suggested branch name,
1393
- the agent creates the branch with git, pushes it, and reports it via report_branch.
1394
- After complete_task returns PR suggestions, the agent creates the PR with gh, and reports it via report_pr.
1395
- This eliminates the need for GitHub tokens on the server.
1606
+ The agent handles all git operations locally using git worktrees for isolation.
1607
+ After assign_task returns a suggested branch name and worktree path:
1608
+ 1. Create worktree: git worktree add <worktreePath> -b <branchName> <baseBranch>
1609
+ 2. Work in worktree directory: cd <worktreePath>
1610
+ 3. After completing work, push and call report_branch
1611
+ 4. After complete_task, create PR with gh and call report_pr
1612
+ 5. Clean up worktree: git worktree remove <worktreePath>
1613
+ Worktrees enable parallel task execution without git conflicts.
1396
1614
 
1397
1615
  TASK STATE FLOW:
1398
1616
  DRAFT -> TODO -> IN_PROGRESS -> REVIEW -> DONE
@@ -1412,7 +1630,7 @@ CONSTRAINTS:
1412
1630
  - Always check_active_task before starting new work
1413
1631
  - Call update_progress frequently to checkpoint
1414
1632
  - Agent must have git/gh CLI configured for local git operations`;
1415
- async function createMCPServer() {
1633
+ function initializeMCPServer(apiClient, authContext) {
1416
1634
  const server = new import_mcp.McpServer(
1417
1635
  {
1418
1636
  name: "collab",
@@ -1422,16 +1640,6 @@ async function createMCPServer() {
1422
1640
  instructions: COLLAB_SERVER_INSTRUCTIONS
1423
1641
  }
1424
1642
  );
1425
- const apiClient = createApiClientFromEnv();
1426
- let authContext;
1427
- try {
1428
- authContext = await apiClient.authenticate();
1429
- } catch (error) {
1430
- if (error instanceof ApiError) {
1431
- throw new Error(`Authentication failed: ${error.message}`);
1432
- }
1433
- throw error;
1434
- }
1435
1643
  const mockApiKey = {
1436
1644
  permissions: authContext.permissions.includes("ADMIN") ? ApiKeyPermission.ADMIN : authContext.permissions.includes("WRITE") ? ApiKeyPermission.WRITE : ApiKeyPermission.READ
1437
1645
  };
@@ -1440,7 +1648,7 @@ async function createMCPServer() {
1440
1648
  {
1441
1649
  description: "Discover all accessible projects. Use first to find project IDs. Filter by TEAM, PERSONAL, or ALL workspaces.",
1442
1650
  inputSchema: {
1443
- workspaceType: import_zod3.z.enum(["TEAM", "PERSONAL", "ALL"]).optional().describe("Filter by workspace type")
1651
+ workspaceType: import_zod4.z.enum(["TEAM", "PERSONAL", "ALL"]).optional().describe("Filter by workspace type")
1444
1652
  }
1445
1653
  },
1446
1654
  async (args) => {
@@ -1470,10 +1678,10 @@ async function createMCPServer() {
1470
1678
  {
1471
1679
  description: "Query tasks with filters. Use state=TODO for assignable tasks, state=REVIEW for pending reviews.",
1472
1680
  inputSchema: {
1473
- projectId: import_zod3.z.string().optional().describe("Filter by project ID"),
1474
- state: import_zod3.z.nativeEnum(TaskState).optional().describe("Filter by task state"),
1475
- assigneeId: import_zod3.z.string().optional().describe("Filter by assignee ID"),
1476
- includeArchived: import_zod3.z.boolean().optional().describe("Include archived tasks (default: false)")
1681
+ projectId: import_zod4.z.string().optional().describe("Filter by project ID"),
1682
+ state: import_zod4.z.nativeEnum(TaskState).optional().describe("Filter by task state"),
1683
+ assigneeId: import_zod4.z.string().optional().describe("Filter by assignee ID"),
1684
+ includeArchived: import_zod4.z.boolean().optional().describe("Include archived tasks (default: false)")
1477
1685
  }
1478
1686
  },
1479
1687
  async (args) => {
@@ -1504,7 +1712,7 @@ async function createMCPServer() {
1504
1712
  {
1505
1713
  description: "Get complete task details with acceptance criteria and notes. Call before assign_task to understand requirements.",
1506
1714
  inputSchema: {
1507
- taskId: import_zod3.z.string().describe("The task ID to retrieve")
1715
+ taskId: import_zod4.z.string().describe("The task ID to retrieve")
1508
1716
  }
1509
1717
  },
1510
1718
  async (args) => {
@@ -1528,11 +1736,11 @@ async function createMCPServer() {
1528
1736
  server.registerTool(
1529
1737
  "assign_task",
1530
1738
  {
1531
- description: "Atomically claim a task and create git branch. Race-safe - fails if already assigned. Task must be TODO.",
1739
+ 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.",
1532
1740
  inputSchema: {
1533
- projectId: import_zod3.z.string().describe("The project ID"),
1534
- taskId: import_zod3.z.string().describe("The task ID to assign"),
1535
- expectedState: import_zod3.z.nativeEnum(TaskState).optional().describe("Expected task state (default: TODO)")
1741
+ projectId: import_zod4.z.string().describe("The project ID"),
1742
+ taskId: import_zod4.z.string().describe("The task ID to assign"),
1743
+ expectedState: import_zod4.z.nativeEnum(TaskState).optional().describe("Expected task state (default: TODO)")
1536
1744
  }
1537
1745
  },
1538
1746
  async (args) => {
@@ -1566,10 +1774,10 @@ async function createMCPServer() {
1566
1774
  {
1567
1775
  description: "Report progress and checkpoint work. Call frequently during execution. Marks acceptance criteria complete.",
1568
1776
  inputSchema: {
1569
- taskId: import_zod3.z.string().describe("The task ID to update"),
1570
- statusMessage: import_zod3.z.string().optional().describe("Status message (max 1000 chars)"),
1571
- completedCheckpointIds: import_zod3.z.array(import_zod3.z.string()).optional().describe("Array of completed checkpoint IDs"),
1572
- currentCheckpointIndex: import_zod3.z.number().optional().describe("Current checkpoint index")
1777
+ taskId: import_zod4.z.string().describe("The task ID to update"),
1778
+ statusMessage: import_zod4.z.string().optional().describe("Status message (max 1000 chars)"),
1779
+ completedCheckpointIds: import_zod4.z.array(import_zod4.z.string()).optional().describe("Array of completed checkpoint IDs"),
1780
+ currentCheckpointIndex: import_zod4.z.number().optional().describe("Current checkpoint index")
1573
1781
  }
1574
1782
  },
1575
1783
  async (args) => {
@@ -1603,10 +1811,10 @@ async function createMCPServer() {
1603
1811
  {
1604
1812
  description: "Prepare task for PR creation. Returns PR suggestions. After creating PR locally, call report_pr to transition to REVIEW. Requires IN_PROGRESS state.",
1605
1813
  inputSchema: {
1606
- projectId: import_zod3.z.string().describe("The project ID"),
1607
- taskId: import_zod3.z.string().describe("The task ID to complete"),
1608
- pullRequestTitle: import_zod3.z.string().optional().describe("PR title (max 300 chars)"),
1609
- pullRequestBody: import_zod3.z.string().optional().describe("PR body/description (max 10000 chars)")
1814
+ projectId: import_zod4.z.string().describe("The project ID"),
1815
+ taskId: import_zod4.z.string().describe("The task ID to complete"),
1816
+ pullRequestTitle: import_zod4.z.string().optional().describe("PR title (max 300 chars)"),
1817
+ pullRequestBody: import_zod4.z.string().optional().describe("PR body/description (max 10000 chars)")
1610
1818
  }
1611
1819
  },
1612
1820
  async (args) => {
@@ -1663,10 +1871,10 @@ async function createMCPServer() {
1663
1871
  {
1664
1872
  description: "Report unrecoverable errors (BUILD_FAILURE, TEST_FAILURE, CONFLICT, AUTH_ERROR). Consider abandon_task after.",
1665
1873
  inputSchema: {
1666
- taskId: import_zod3.z.string().describe("The task ID"),
1667
- errorType: import_zod3.z.nativeEnum(ErrorType).describe("Error type: BUILD_FAILURE, TEST_FAILURE, CONFLICT, AUTH_ERROR, OTHER"),
1668
- errorMessage: import_zod3.z.string().describe("Error message (max 1000 chars)"),
1669
- context: import_zod3.z.string().optional().describe("Additional context (max 2000 chars)")
1874
+ taskId: import_zod4.z.string().describe("The task ID"),
1875
+ errorType: import_zod4.z.nativeEnum(ErrorType).describe("Error type: BUILD_FAILURE, TEST_FAILURE, CONFLICT, AUTH_ERROR, OTHER"),
1876
+ errorMessage: import_zod4.z.string().describe("Error message (max 1000 chars)"),
1877
+ context: import_zod4.z.string().optional().describe("Additional context (max 2000 chars)")
1670
1878
  }
1671
1879
  },
1672
1880
  async (args) => {
@@ -1701,7 +1909,7 @@ async function createMCPServer() {
1701
1909
  {
1702
1910
  description: "Load project README, tech stack, and coding conventions. Call after selecting project.",
1703
1911
  inputSchema: {
1704
- projectId: import_zod3.z.string().describe("The project ID")
1912
+ projectId: import_zod4.z.string().describe("The project ID")
1705
1913
  }
1706
1914
  },
1707
1915
  async (args) => {
@@ -1731,8 +1939,8 @@ async function createMCPServer() {
1731
1939
  {
1732
1940
  description: "Document implementation decisions. Notes persist for future reference and handoff.",
1733
1941
  inputSchema: {
1734
- taskId: import_zod3.z.string().describe("The task ID"),
1735
- content: import_zod3.z.string().describe("Note content (max 500 chars)")
1942
+ taskId: import_zod4.z.string().describe("The task ID"),
1943
+ content: import_zod4.z.string().describe("Note content (max 500 chars)")
1736
1944
  }
1737
1945
  },
1738
1946
  async (args) => {
@@ -1761,9 +1969,9 @@ async function createMCPServer() {
1761
1969
  {
1762
1970
  description: "Release task assignment and optionally clean up branch. Task returns to TODO. Use after errors.",
1763
1971
  inputSchema: {
1764
- projectId: import_zod3.z.string().describe("The project ID"),
1765
- taskId: import_zod3.z.string().describe("The task ID to abandon"),
1766
- deleteBranch: import_zod3.z.boolean().optional().describe("Whether to delete the associated branch")
1972
+ projectId: import_zod4.z.string().describe("The project ID"),
1973
+ taskId: import_zod4.z.string().describe("The task ID to abandon"),
1974
+ deleteBranch: import_zod4.z.boolean().optional().describe("Whether to delete the associated branch")
1767
1975
  }
1768
1976
  },
1769
1977
  async (args) => {
@@ -1797,9 +2005,9 @@ async function createMCPServer() {
1797
2005
  {
1798
2006
  description: "Report a branch created by the agent. Call after using git to create and push a branch. Task must be IN_PROGRESS.",
1799
2007
  inputSchema: {
1800
- projectId: import_zod3.z.string().describe("The project ID"),
1801
- taskId: import_zod3.z.string().describe("The task ID"),
1802
- branchName: import_zod3.z.string().describe("Name of the branch created (e.g., feature/TASK-123-fix-login)")
2008
+ projectId: import_zod4.z.string().describe("The project ID"),
2009
+ taskId: import_zod4.z.string().describe("The task ID"),
2010
+ branchName: import_zod4.z.string().describe("Name of the branch created (e.g., feature/TASK-123-fix-login)")
1803
2011
  }
1804
2012
  },
1805
2013
  async (args) => {
@@ -1833,10 +2041,10 @@ async function createMCPServer() {
1833
2041
  {
1834
2042
  description: "Report a PR created by the agent. Call after using gh pr create. Transitions task to REVIEW state.",
1835
2043
  inputSchema: {
1836
- projectId: import_zod3.z.string().describe("The project ID"),
1837
- taskId: import_zod3.z.string().describe("The task ID"),
1838
- pullRequestUrl: import_zod3.z.string().describe("Full URL of the created PR (e.g., https://github.com/owner/repo/pull/123)"),
1839
- pullRequestNumber: import_zod3.z.number().describe("PR number (e.g., 123)")
2044
+ projectId: import_zod4.z.string().describe("The project ID"),
2045
+ taskId: import_zod4.z.string().describe("The task ID"),
2046
+ pullRequestUrl: import_zod4.z.string().describe("Full URL of the created PR (e.g., https://github.com/owner/repo/pull/123)"),
2047
+ pullRequestNumber: import_zod4.z.number().describe("PR number (e.g., 123)")
1840
2048
  }
1841
2049
  },
1842
2050
  async (args) => {
@@ -1871,8 +2079,8 @@ async function createMCPServer() {
1871
2079
  {
1872
2080
  description: "Soft-delete a task. Hidden but restorable via unarchive_task.",
1873
2081
  inputSchema: {
1874
- projectId: import_zod3.z.string().describe("The project ID"),
1875
- taskId: import_zod3.z.string().describe("The task ID to archive")
2082
+ projectId: import_zod4.z.string().describe("The project ID"),
2083
+ taskId: import_zod4.z.string().describe("The task ID to archive")
1876
2084
  }
1877
2085
  },
1878
2086
  async (args) => {
@@ -1905,8 +2113,8 @@ async function createMCPServer() {
1905
2113
  {
1906
2114
  description: "Restore previously archived task to original state.",
1907
2115
  inputSchema: {
1908
- projectId: import_zod3.z.string().describe("The project ID"),
1909
- taskId: import_zod3.z.string().describe("The task ID to restore")
2116
+ projectId: import_zod4.z.string().describe("The project ID"),
2117
+ taskId: import_zod4.z.string().describe("The task ID to restore")
1910
2118
  }
1911
2119
  },
1912
2120
  async (args) => {
@@ -1939,9 +2147,9 @@ async function createMCPServer() {
1939
2147
  {
1940
2148
  description: "Create new project in personal workspace linked to GitHub repository.",
1941
2149
  inputSchema: {
1942
- name: import_zod3.z.string().describe("Project name (max 100 chars)"),
1943
- description: import_zod3.z.string().optional().describe("Project description (max 500 chars)"),
1944
- repositoryUrl: import_zod3.z.string().describe("GitHub repository URL")
2150
+ name: import_zod4.z.string().describe("Project name (max 100 chars)"),
2151
+ description: import_zod4.z.string().optional().describe("Project description (max 500 chars)"),
2152
+ repositoryUrl: import_zod4.z.string().describe("GitHub repository URL")
1945
2153
  }
1946
2154
  },
1947
2155
  async (args) => {
@@ -1975,14 +2183,14 @@ async function createMCPServer() {
1975
2183
  {
1976
2184
  description: "Create task with title, description, acceptance criteria. Starts in DRAFT. Priority: LOW/MEDIUM/HIGH/CRITICAL.",
1977
2185
  inputSchema: {
1978
- projectId: import_zod3.z.string().describe("The project ID to create the task in"),
1979
- epicId: import_zod3.z.string().nullable().optional().describe("Optional epic ID to associate the task with"),
1980
- title: import_zod3.z.string().describe("Task title (max 200 chars)"),
1981
- description: import_zod3.z.string().describe("Task description (max 5000 chars)"),
1982
- priority: import_zod3.z.nativeEnum(TaskPriority).optional().describe("Task priority: LOW, MEDIUM, HIGH, CRITICAL (default: MEDIUM)"),
1983
- acceptanceCriteria: import_zod3.z.array(
1984
- import_zod3.z.object({
1985
- description: import_zod3.z.string().describe("Acceptance criterion description (max 500 chars)")
2186
+ projectId: import_zod4.z.string().describe("The project ID to create the task in"),
2187
+ epicId: import_zod4.z.string().nullable().optional().describe("Optional epic ID to associate the task with"),
2188
+ title: import_zod4.z.string().describe("Task title (max 200 chars)"),
2189
+ description: import_zod4.z.string().describe("Task description (max 5000 chars)"),
2190
+ priority: import_zod4.z.nativeEnum(TaskPriority).optional().describe("Task priority: LOW, MEDIUM, HIGH, CRITICAL (default: MEDIUM)"),
2191
+ acceptanceCriteria: import_zod4.z.array(
2192
+ import_zod4.z.object({
2193
+ description: import_zod4.z.string().describe("Acceptance criterion description (max 500 chars)")
1986
2194
  })
1987
2195
  ).describe("Array of acceptance criteria (at least 1 required)")
1988
2196
  }
@@ -2021,10 +2229,10 @@ async function createMCPServer() {
2021
2229
  {
2022
2230
  description: "Return task from REVIEW to IN_PROGRESS with feedback. Original assignee addresses changes.",
2023
2231
  inputSchema: {
2024
- projectId: import_zod3.z.string().describe("The project ID"),
2025
- taskId: import_zod3.z.string().describe("The task ID to review"),
2026
- reviewComments: import_zod3.z.string().describe("Review comments explaining requested changes (max 5000 chars)"),
2027
- requestedChanges: import_zod3.z.array(import_zod3.z.string()).optional().describe("List of specific changes requested")
2232
+ projectId: import_zod4.z.string().describe("The project ID"),
2233
+ taskId: import_zod4.z.string().describe("The task ID to review"),
2234
+ reviewComments: import_zod4.z.string().describe("Review comments explaining requested changes (max 5000 chars)"),
2235
+ requestedChanges: import_zod4.z.array(import_zod4.z.string()).optional().describe("List of specific changes requested")
2028
2236
  }
2029
2237
  },
2030
2238
  async (args) => {
@@ -2059,9 +2267,9 @@ async function createMCPServer() {
2059
2267
  {
2060
2268
  description: "Approve completed work and mark DONE. Only for REVIEW state tasks.",
2061
2269
  inputSchema: {
2062
- projectId: import_zod3.z.string().describe("The project ID"),
2063
- taskId: import_zod3.z.string().describe("The task ID to approve"),
2064
- reviewComments: import_zod3.z.string().optional().describe("Optional approval comments (max 2000 chars)")
2270
+ projectId: import_zod4.z.string().describe("The project ID"),
2271
+ taskId: import_zod4.z.string().describe("The task ID to approve"),
2272
+ reviewComments: import_zod4.z.string().optional().describe("Optional approval comments (max 2000 chars)")
2065
2273
  }
2066
2274
  },
2067
2275
  async (args) => {
@@ -2095,10 +2303,10 @@ async function createMCPServer() {
2095
2303
  {
2096
2304
  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.",
2097
2305
  inputSchema: {
2098
- projectId: import_zod3.z.string().describe("The project ID"),
2099
- taskId: import_zod3.z.string().describe("The task ID to verify"),
2100
- approved: import_zod3.z.boolean().describe("Whether to approve the task"),
2101
- feedback: import_zod3.z.string().optional().describe("Feedback for the task (required if not approved)")
2306
+ projectId: import_zod4.z.string().describe("The project ID"),
2307
+ taskId: import_zod4.z.string().describe("The task ID to verify"),
2308
+ approved: import_zod4.z.boolean().describe("Whether to approve the task"),
2309
+ feedback: import_zod4.z.string().optional().describe("Feedback for the task (required if not approved)")
2102
2310
  }
2103
2311
  },
2104
2312
  async (args) => {
@@ -2129,8 +2337,8 @@ async function createMCPServer() {
2129
2337
  {
2130
2338
  description: "Get state-appropriate prompt for a task. Returns verify prompt for DRAFT, assignment prompt for TODO, or continue prompt for IN_PROGRESS tasks.",
2131
2339
  inputSchema: {
2132
- projectId: import_zod3.z.string().describe("The project ID"),
2133
- taskId: import_zod3.z.string().describe("The task ID")
2340
+ projectId: import_zod4.z.string().describe("The project ID"),
2341
+ taskId: import_zod4.z.string().describe("The task ID")
2134
2342
  }
2135
2343
  },
2136
2344
  async (args) => {
@@ -2163,15 +2371,15 @@ async function createMCPServer() {
2163
2371
  {
2164
2372
  description: "Update task details (title, description, priority, acceptanceCriteria). Only works for DRAFT and TODO states. If task is in TODO state, it reverts to DRAFT and requires re-verification.",
2165
2373
  inputSchema: {
2166
- projectId: import_zod3.z.string().describe("The project ID"),
2167
- taskId: import_zod3.z.string().describe("The task ID to update"),
2168
- title: import_zod3.z.string().optional().describe("New task title"),
2169
- description: import_zod3.z.string().optional().describe("New task description"),
2170
- priority: import_zod3.z.nativeEnum(TaskPriority).optional().describe("New task priority"),
2171
- acceptanceCriteria: import_zod3.z.array(
2172
- import_zod3.z.object({
2173
- id: import_zod3.z.string().optional().describe("Existing criterion ID (for updates)"),
2174
- description: import_zod3.z.string().describe("Criterion description")
2374
+ projectId: import_zod4.z.string().describe("The project ID"),
2375
+ taskId: import_zod4.z.string().describe("The task ID to update"),
2376
+ title: import_zod4.z.string().optional().describe("New task title"),
2377
+ description: import_zod4.z.string().optional().describe("New task description"),
2378
+ priority: import_zod4.z.nativeEnum(TaskPriority).optional().describe("New task priority"),
2379
+ acceptanceCriteria: import_zod4.z.array(
2380
+ import_zod4.z.object({
2381
+ id: import_zod4.z.string().optional().describe("Existing criterion ID (for updates)"),
2382
+ description: import_zod4.z.string().describe("Criterion description")
2175
2383
  })
2176
2384
  ).optional().describe("New acceptance criteria (replaces existing)")
2177
2385
  }
@@ -2227,9 +2435,26 @@ async function createMCPServer() {
2227
2435
  };
2228
2436
  }
2229
2437
  );
2230
- const transport = new import_stdio.StdioServerTransport();
2438
+ return server;
2439
+ }
2440
+ async function connectMCPServer(server, transport) {
2231
2441
  await server.connect(transport);
2232
2442
  }
2443
+ async function createMCPServer() {
2444
+ const apiClient = createApiClientFromEnv();
2445
+ let authContext;
2446
+ try {
2447
+ authContext = await apiClient.authenticate();
2448
+ } catch (error) {
2449
+ if (error instanceof ApiError) {
2450
+ throw new Error(`Authentication failed: ${error.message}`);
2451
+ }
2452
+ throw error;
2453
+ }
2454
+ const server = initializeMCPServer(apiClient, authContext);
2455
+ const transport = new import_stdio.StdioServerTransport();
2456
+ await connectMCPServer(server, transport);
2457
+ }
2233
2458
  function handleApiError(error) {
2234
2459
  if (error instanceof ApiError) {
2235
2460
  return {
@@ -2262,11 +2487,12 @@ function handleApiError(error) {
2262
2487
  isError: true
2263
2488
  };
2264
2489
  }
2265
- var ActiveTaskSchema = import_zod3.z.object({
2266
- taskId: import_zod3.z.string().min(1),
2267
- projectId: import_zod3.z.string().min(1),
2268
- branchName: import_zod3.z.string().optional(),
2269
- startedAt: import_zod3.z.string().optional()
2490
+ var ActiveTaskSchema = import_zod4.z.object({
2491
+ taskId: import_zod4.z.string().min(1),
2492
+ projectId: import_zod4.z.string().min(1),
2493
+ branchName: import_zod4.z.string().optional(),
2494
+ worktreePath: import_zod4.z.string().optional(),
2495
+ startedAt: import_zod4.z.string().optional()
2270
2496
  });
2271
2497
  async function checkActiveTask() {
2272
2498
  const fs = await import("fs");
@@ -2364,7 +2590,7 @@ Example mcp.json configuration:
2364
2590
  "mcpServers": {
2365
2591
  "collab": {
2366
2592
  "command": "npx",
2367
- "args": ["@mtaap/mcp"],
2593
+ "args": ["-p", "@mtaap/mcp", "collab-mcp"],
2368
2594
  "env": {
2369
2595
  "COLLAB_API_KEY": "collab_your_api_key_here",
2370
2596
  "COLLAB_BASE_URL": "https://collab.mtaap.de"
@@ -2399,7 +2625,7 @@ function validateEnvironment() {
2399
2625
  "mcpServers": {
2400
2626
  "collab": {
2401
2627
  "command": "npx",
2402
- "args": ["@mtaap/mcp"],
2628
+ "args": ["-p", "@mtaap/mcp", "collab-mcp"],
2403
2629
  "env": {
2404
2630
  "COLLAB_API_KEY": "collab_your_api_key_here",
2405
2631
  "COLLAB_BASE_URL": "https://collab.mtaap.de"
@@ -2419,15 +2645,17 @@ function validateEnvironment() {
2419
2645
  async function checkConnectivity() {
2420
2646
  const baseUrl = process.env.COLLAB_BASE_URL;
2421
2647
  console.error(`[collab-mcp] Checking connectivity to ${baseUrl}...`);
2648
+ const controller = new AbortController();
2649
+ const timeoutId = setTimeout(() => controller.abort(), 1e4);
2422
2650
  try {
2423
2651
  const response = await fetch(`${baseUrl}/api/mcp/auth`, {
2424
2652
  method: "GET",
2425
2653
  headers: {
2426
2654
  "X-API-Key": process.env.COLLAB_API_KEY
2427
2655
  },
2428
- signal: AbortSignal.timeout(1e4)
2429
- // 10 second timeout
2656
+ signal: controller.signal
2430
2657
  });
2658
+ clearTimeout(timeoutId);
2431
2659
  if (!response.ok) {
2432
2660
  const data = await response.json().catch(() => ({}));
2433
2661
  if (response.status === 401) {
@@ -2439,7 +2667,8 @@ async function checkConnectivity() {
2439
2667
  }
2440
2668
  console.error("[collab-mcp] Connected successfully");
2441
2669
  } catch (error) {
2442
- if (error instanceof Error && error.name === "TimeoutError") {
2670
+ clearTimeout(timeoutId);
2671
+ if (error instanceof Error && error.name === "AbortError") {
2443
2672
  console.error(`[collab-mcp] Error: Connection timed out to ${baseUrl}`);
2444
2673
  } else {
2445
2674
  console.error(`[collab-mcp] Error: Could not connect to ${baseUrl}`);