@mtaap/mcp 0.2.7 → 0.2.8
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 +71 -9
- package/dist/cli.js.map +1 -1
- package/dist/index.js +71 -9
- 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
|
@@ -420,6 +420,7 @@ var ListTasksInputSchema = import_zod2.z.object({
|
|
|
420
420
|
includeArchived: import_zod2.z.boolean().optional()
|
|
421
421
|
});
|
|
422
422
|
var cuidOrPrefixedId = import_zod2.z.string().regex(/^([a-z0-9]+|[a-z]+_[a-zA-Z0-9]+)$/);
|
|
423
|
+
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
424
|
var GetTaskInputSchema = import_zod2.z.object({
|
|
424
425
|
taskId: cuidOrPrefixedId
|
|
425
426
|
});
|
|
@@ -634,7 +635,7 @@ var UpdateTaskMCPInputSchema = import_zod2.z.object({
|
|
|
634
635
|
var ReportBranchInputSchema = import_zod2.z.object({
|
|
635
636
|
projectId: cuidOrPrefixedId,
|
|
636
637
|
taskId: cuidOrPrefixedId,
|
|
637
|
-
branchName:
|
|
638
|
+
branchName: gitBranchName
|
|
638
639
|
});
|
|
639
640
|
var ReportPRInputSchema = import_zod2.z.object({
|
|
640
641
|
projectId: cuidOrPrefixedId,
|
|
@@ -941,6 +942,12 @@ var errorTrackerInstance = new NoOpErrorTracker();
|
|
|
941
942
|
|
|
942
943
|
// src/api-client.ts
|
|
943
944
|
var DEFAULT_TIMEOUT = 3e4;
|
|
945
|
+
function sanitizeForLogging(str) {
|
|
946
|
+
let sanitized = str.replace(/\bcollab_[a-zA-Z0-9_-]+\b/gi, "[REDACTED_API_KEY]");
|
|
947
|
+
sanitized = sanitized.replace(/\bBearer\s+[a-zA-Z0-9._-]+\b/gi, "Bearer [REDACTED]");
|
|
948
|
+
sanitized = sanitized.replace(/([?&](api_?key|token|auth|key|secret)=)[^&\s]+/gi, "$1[REDACTED]");
|
|
949
|
+
return sanitized;
|
|
950
|
+
}
|
|
944
951
|
var ApiError = class extends Error {
|
|
945
952
|
constructor(message, code, status, details) {
|
|
946
953
|
super(message);
|
|
@@ -970,7 +977,7 @@ var MCPApiClient = class {
|
|
|
970
977
|
const controller = new AbortController();
|
|
971
978
|
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
972
979
|
if (this.debug) {
|
|
973
|
-
console.error(`[mcp-api] ${method} ${
|
|
980
|
+
console.error(`[mcp-api] ${method} ${sanitizeForLogging(path)}`);
|
|
974
981
|
}
|
|
975
982
|
try {
|
|
976
983
|
const response = await fetch(url, {
|
|
@@ -1005,8 +1012,9 @@ var MCPApiClient = class {
|
|
|
1005
1012
|
408
|
|
1006
1013
|
);
|
|
1007
1014
|
}
|
|
1015
|
+
const rawMessage = error instanceof Error ? error.message : "Unknown error";
|
|
1008
1016
|
throw new ApiError(
|
|
1009
|
-
|
|
1017
|
+
sanitizeForLogging(rawMessage),
|
|
1010
1018
|
"NETWORK_ERROR",
|
|
1011
1019
|
0
|
|
1012
1020
|
);
|
|
@@ -2192,22 +2200,76 @@ function handleApiError(error) {
|
|
|
2192
2200
|
isError: true
|
|
2193
2201
|
};
|
|
2194
2202
|
}
|
|
2203
|
+
var ActiveTaskSchema = import_zod3.z.object({
|
|
2204
|
+
taskId: import_zod3.z.string().min(1),
|
|
2205
|
+
projectId: import_zod3.z.string().min(1),
|
|
2206
|
+
branchName: import_zod3.z.string().optional(),
|
|
2207
|
+
startedAt: import_zod3.z.string().optional()
|
|
2208
|
+
});
|
|
2195
2209
|
async function checkActiveTask() {
|
|
2196
2210
|
const fs = await import("fs");
|
|
2197
2211
|
const path = await import("path");
|
|
2198
|
-
const
|
|
2212
|
+
const cwd = process.cwd();
|
|
2213
|
+
const collabDir = path.join(cwd, ".collab");
|
|
2214
|
+
const activeTaskPath = path.join(collabDir, "active-task.json");
|
|
2199
2215
|
try {
|
|
2200
|
-
|
|
2216
|
+
const resolvedPath = path.resolve(activeTaskPath);
|
|
2217
|
+
const resolvedCollabDir = path.resolve(collabDir);
|
|
2218
|
+
if (!resolvedPath.startsWith(resolvedCollabDir + path.sep) && resolvedPath !== resolvedCollabDir) {
|
|
2219
|
+
return {
|
|
2220
|
+
hasActiveTask: false,
|
|
2221
|
+
task: null,
|
|
2222
|
+
error: "Invalid active task path"
|
|
2223
|
+
};
|
|
2224
|
+
}
|
|
2225
|
+
const stats = await fs.promises.lstat(activeTaskPath);
|
|
2226
|
+
if (stats.isSymbolicLink()) {
|
|
2227
|
+
return {
|
|
2228
|
+
hasActiveTask: false,
|
|
2229
|
+
task: null,
|
|
2230
|
+
error: "Symlinks not allowed for active task file"
|
|
2231
|
+
};
|
|
2232
|
+
}
|
|
2233
|
+
if (!stats.isFile()) {
|
|
2234
|
+
return {
|
|
2235
|
+
hasActiveTask: false,
|
|
2236
|
+
task: null
|
|
2237
|
+
};
|
|
2238
|
+
}
|
|
2201
2239
|
const content = await fs.promises.readFile(activeTaskPath, "utf-8");
|
|
2202
|
-
|
|
2240
|
+
let parsed;
|
|
2241
|
+
try {
|
|
2242
|
+
parsed = JSON.parse(content);
|
|
2243
|
+
} catch {
|
|
2244
|
+
return {
|
|
2245
|
+
hasActiveTask: false,
|
|
2246
|
+
task: null,
|
|
2247
|
+
error: "Invalid JSON in active task file"
|
|
2248
|
+
};
|
|
2249
|
+
}
|
|
2250
|
+
const validationResult = ActiveTaskSchema.safeParse(parsed);
|
|
2251
|
+
if (!validationResult.success) {
|
|
2252
|
+
return {
|
|
2253
|
+
hasActiveTask: false,
|
|
2254
|
+
task: null,
|
|
2255
|
+
error: "Active task file has invalid structure"
|
|
2256
|
+
};
|
|
2257
|
+
}
|
|
2203
2258
|
return {
|
|
2204
2259
|
hasActiveTask: true,
|
|
2205
|
-
task:
|
|
2260
|
+
task: validationResult.data
|
|
2206
2261
|
};
|
|
2207
|
-
} catch {
|
|
2262
|
+
} catch (err) {
|
|
2263
|
+
if (err instanceof Error && "code" in err && err.code === "ENOENT") {
|
|
2264
|
+
return {
|
|
2265
|
+
hasActiveTask: false,
|
|
2266
|
+
task: null
|
|
2267
|
+
};
|
|
2268
|
+
}
|
|
2208
2269
|
return {
|
|
2209
2270
|
hasActiveTask: false,
|
|
2210
|
-
task: null
|
|
2271
|
+
task: null,
|
|
2272
|
+
error: "Failed to read active task file"
|
|
2211
2273
|
};
|
|
2212
2274
|
}
|
|
2213
2275
|
}
|