@mtaap/mcp 0.2.7 → 0.2.10
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 +0 -23
- package/dist/cli.js +87 -18
- package/dist/cli.js.map +1 -1
- package/dist/index.js +87 -18
- package/dist/index.js.map +1 -1
- package/package.json +7 -27
package/README.md
CHANGED
|
@@ -518,19 +518,6 @@ report_error -> abandon_task -> list_tasks -> assign_task (retry or pick differe
|
|
|
518
518
|
|
|
519
519
|
3. Use the tools from your AI agent
|
|
520
520
|
|
|
521
|
-
## Development
|
|
522
|
-
|
|
523
|
-
```bash
|
|
524
|
-
# Build
|
|
525
|
-
pnpm build
|
|
526
|
-
|
|
527
|
-
# Watch mode
|
|
528
|
-
pnpm dev
|
|
529
|
-
|
|
530
|
-
# Run locally
|
|
531
|
-
COLLAB_API_KEY=your-key COLLAB_BASE_URL=https://collab.mtaap.de pnpm start
|
|
532
|
-
```
|
|
533
|
-
|
|
534
521
|
## Troubleshooting
|
|
535
522
|
|
|
536
523
|
### "COLLAB_API_KEY is required"
|
|
@@ -553,16 +540,6 @@ Ensure your firewall allows outbound connections to your Collab instance. The se
|
|
|
553
540
|
|
|
554
541
|
The MCP API is rate limited to 100 requests per minute. If you exceed this limit, you'll receive a 429 error with a `Retry-After` header indicating when you can retry.
|
|
555
542
|
|
|
556
|
-
## Publishing
|
|
557
|
-
|
|
558
|
-
This package is published as `@mtaap/mcp` to npm.
|
|
559
|
-
|
|
560
|
-
```bash
|
|
561
|
-
# Build and publish
|
|
562
|
-
pnpm build
|
|
563
|
-
npm publish
|
|
564
|
-
```
|
|
565
|
-
|
|
566
543
|
## License
|
|
567
544
|
|
|
568
545
|
Proprietary - See LICENSE file for details.
|
package/dist/cli.js
CHANGED
|
@@ -162,12 +162,19 @@ var VALID_TRANSITIONS = {
|
|
|
162
162
|
[TaskState.DONE]: []
|
|
163
163
|
};
|
|
164
164
|
|
|
165
|
+
// ../../packages/core/dist/config/deployment.js
|
|
166
|
+
var config = {
|
|
167
|
+
deploymentMode: process.env.DEPLOYMENT_MODE || "saas"
|
|
168
|
+
};
|
|
169
|
+
var isSaas = config.deploymentMode === "saas";
|
|
170
|
+
var isOnPrem = config.deploymentMode === "onprem";
|
|
171
|
+
|
|
165
172
|
// ../../packages/core/dist/version.js
|
|
166
173
|
var VERSION2 = "0.1.0";
|
|
167
174
|
|
|
168
175
|
// ../../packages/core/dist/config/index.js
|
|
169
176
|
var DEPLOYMENT_MODE = process.env.DEPLOYMENT_MODE || "saas";
|
|
170
|
-
var
|
|
177
|
+
var config2 = {
|
|
171
178
|
version: VERSION2,
|
|
172
179
|
deploymentMode: DEPLOYMENT_MODE,
|
|
173
180
|
billing: {
|
|
@@ -252,9 +259,9 @@ var config = {
|
|
|
252
259
|
}
|
|
253
260
|
};
|
|
254
261
|
var DEFAULT_SEAT_LIMITS = {
|
|
255
|
-
[PricingTier.FREE]:
|
|
256
|
-
[PricingTier.PRO]:
|
|
257
|
-
[PricingTier.ENTERPRISE]:
|
|
262
|
+
[PricingTier.FREE]: config2.pricing.defaultSeats.FREE,
|
|
263
|
+
[PricingTier.PRO]: config2.pricing.defaultSeats.PRO,
|
|
264
|
+
[PricingTier.ENTERPRISE]: config2.pricing.defaultSeats.ENTERPRISE
|
|
258
265
|
};
|
|
259
266
|
|
|
260
267
|
// ../../packages/core/dist/types/index.js
|
|
@@ -420,6 +427,7 @@ var ListTasksInputSchema = import_zod2.z.object({
|
|
|
420
427
|
includeArchived: import_zod2.z.boolean().optional()
|
|
421
428
|
});
|
|
422
429
|
var cuidOrPrefixedId = import_zod2.z.string().regex(/^([a-z0-9]+|[a-z]+_[a-zA-Z0-9]+)$/);
|
|
430
|
+
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");
|
|
423
431
|
var GetTaskInputSchema = import_zod2.z.object({
|
|
424
432
|
taskId: cuidOrPrefixedId
|
|
425
433
|
});
|
|
@@ -634,7 +642,7 @@ var UpdateTaskMCPInputSchema = import_zod2.z.object({
|
|
|
634
642
|
var ReportBranchInputSchema = import_zod2.z.object({
|
|
635
643
|
projectId: cuidOrPrefixedId,
|
|
636
644
|
taskId: cuidOrPrefixedId,
|
|
637
|
-
branchName:
|
|
645
|
+
branchName: gitBranchName
|
|
638
646
|
});
|
|
639
647
|
var ReportPRInputSchema = import_zod2.z.object({
|
|
640
648
|
projectId: cuidOrPrefixedId,
|
|
@@ -941,6 +949,12 @@ var errorTrackerInstance = new NoOpErrorTracker();
|
|
|
941
949
|
|
|
942
950
|
// src/api-client.ts
|
|
943
951
|
var DEFAULT_TIMEOUT = 3e4;
|
|
952
|
+
function sanitizeForLogging(str) {
|
|
953
|
+
let sanitized = str.replace(/\bcollab_[a-zA-Z0-9_-]+\b/gi, "[REDACTED_API_KEY]");
|
|
954
|
+
sanitized = sanitized.replace(/\bBearer\s+[a-zA-Z0-9._-]+\b/gi, "Bearer [REDACTED]");
|
|
955
|
+
sanitized = sanitized.replace(/([?&](api_?key|token|auth|key|secret)=)[^&\s]+/gi, "$1[REDACTED]");
|
|
956
|
+
return sanitized;
|
|
957
|
+
}
|
|
944
958
|
var ApiError = class extends Error {
|
|
945
959
|
constructor(message, code, status, details) {
|
|
946
960
|
super(message);
|
|
@@ -956,11 +970,11 @@ var MCPApiClient = class {
|
|
|
956
970
|
timeout;
|
|
957
971
|
debug;
|
|
958
972
|
authContext = null;
|
|
959
|
-
constructor(
|
|
960
|
-
this.baseUrl =
|
|
961
|
-
this.apiKey =
|
|
962
|
-
this.timeout =
|
|
963
|
-
this.debug =
|
|
973
|
+
constructor(config3) {
|
|
974
|
+
this.baseUrl = config3.baseUrl.replace(/\/$/, "");
|
|
975
|
+
this.apiKey = config3.apiKey;
|
|
976
|
+
this.timeout = config3.timeout ?? DEFAULT_TIMEOUT;
|
|
977
|
+
this.debug = config3.debug ?? false;
|
|
964
978
|
}
|
|
965
979
|
/**
|
|
966
980
|
* Make an HTTP request to the API
|
|
@@ -970,7 +984,7 @@ var MCPApiClient = class {
|
|
|
970
984
|
const controller = new AbortController();
|
|
971
985
|
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
972
986
|
if (this.debug) {
|
|
973
|
-
console.error(`[mcp-api] ${method} ${
|
|
987
|
+
console.error(`[mcp-api] ${method} ${sanitizeForLogging(path)}`);
|
|
974
988
|
}
|
|
975
989
|
try {
|
|
976
990
|
const response = await fetch(url, {
|
|
@@ -1005,8 +1019,9 @@ var MCPApiClient = class {
|
|
|
1005
1019
|
408
|
|
1006
1020
|
);
|
|
1007
1021
|
}
|
|
1022
|
+
const rawMessage = error instanceof Error ? error.message : "Unknown error";
|
|
1008
1023
|
throw new ApiError(
|
|
1009
|
-
|
|
1024
|
+
sanitizeForLogging(rawMessage),
|
|
1010
1025
|
"NETWORK_ERROR",
|
|
1011
1026
|
0
|
|
1012
1027
|
);
|
|
@@ -2192,22 +2207,76 @@ function handleApiError(error) {
|
|
|
2192
2207
|
isError: true
|
|
2193
2208
|
};
|
|
2194
2209
|
}
|
|
2210
|
+
var ActiveTaskSchema = import_zod3.z.object({
|
|
2211
|
+
taskId: import_zod3.z.string().min(1),
|
|
2212
|
+
projectId: import_zod3.z.string().min(1),
|
|
2213
|
+
branchName: import_zod3.z.string().optional(),
|
|
2214
|
+
startedAt: import_zod3.z.string().optional()
|
|
2215
|
+
});
|
|
2195
2216
|
async function checkActiveTask() {
|
|
2196
2217
|
const fs = await import("fs");
|
|
2197
2218
|
const path = await import("path");
|
|
2198
|
-
const
|
|
2219
|
+
const cwd = process.cwd();
|
|
2220
|
+
const collabDir = path.join(cwd, ".collab");
|
|
2221
|
+
const activeTaskPath = path.join(collabDir, "active-task.json");
|
|
2199
2222
|
try {
|
|
2200
|
-
|
|
2223
|
+
const resolvedPath = path.resolve(activeTaskPath);
|
|
2224
|
+
const resolvedCollabDir = path.resolve(collabDir);
|
|
2225
|
+
if (!resolvedPath.startsWith(resolvedCollabDir + path.sep) && resolvedPath !== resolvedCollabDir) {
|
|
2226
|
+
return {
|
|
2227
|
+
hasActiveTask: false,
|
|
2228
|
+
task: null,
|
|
2229
|
+
error: "Invalid active task path"
|
|
2230
|
+
};
|
|
2231
|
+
}
|
|
2232
|
+
const stats = await fs.promises.lstat(activeTaskPath);
|
|
2233
|
+
if (stats.isSymbolicLink()) {
|
|
2234
|
+
return {
|
|
2235
|
+
hasActiveTask: false,
|
|
2236
|
+
task: null,
|
|
2237
|
+
error: "Symlinks not allowed for active task file"
|
|
2238
|
+
};
|
|
2239
|
+
}
|
|
2240
|
+
if (!stats.isFile()) {
|
|
2241
|
+
return {
|
|
2242
|
+
hasActiveTask: false,
|
|
2243
|
+
task: null
|
|
2244
|
+
};
|
|
2245
|
+
}
|
|
2201
2246
|
const content = await fs.promises.readFile(activeTaskPath, "utf-8");
|
|
2202
|
-
|
|
2247
|
+
let parsed;
|
|
2248
|
+
try {
|
|
2249
|
+
parsed = JSON.parse(content);
|
|
2250
|
+
} catch {
|
|
2251
|
+
return {
|
|
2252
|
+
hasActiveTask: false,
|
|
2253
|
+
task: null,
|
|
2254
|
+
error: "Invalid JSON in active task file"
|
|
2255
|
+
};
|
|
2256
|
+
}
|
|
2257
|
+
const validationResult = ActiveTaskSchema.safeParse(parsed);
|
|
2258
|
+
if (!validationResult.success) {
|
|
2259
|
+
return {
|
|
2260
|
+
hasActiveTask: false,
|
|
2261
|
+
task: null,
|
|
2262
|
+
error: "Active task file has invalid structure"
|
|
2263
|
+
};
|
|
2264
|
+
}
|
|
2203
2265
|
return {
|
|
2204
2266
|
hasActiveTask: true,
|
|
2205
|
-
task:
|
|
2267
|
+
task: validationResult.data
|
|
2206
2268
|
};
|
|
2207
|
-
} catch {
|
|
2269
|
+
} catch (err) {
|
|
2270
|
+
if (err instanceof Error && "code" in err && err.code === "ENOENT") {
|
|
2271
|
+
return {
|
|
2272
|
+
hasActiveTask: false,
|
|
2273
|
+
task: null
|
|
2274
|
+
};
|
|
2275
|
+
}
|
|
2208
2276
|
return {
|
|
2209
2277
|
hasActiveTask: false,
|
|
2210
|
-
task: null
|
|
2278
|
+
task: null,
|
|
2279
|
+
error: "Failed to read active task file"
|
|
2211
2280
|
};
|
|
2212
2281
|
}
|
|
2213
2282
|
}
|