@mtaap/mcp 0.2.4 → 0.2.5
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 +20 -20
- package/dist/cli.js +118 -66
- package/dist/cli.js.map +1 -1
- package/dist/index.js +82 -30
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Collab MCP Server
|
|
2
2
|
|
|
3
|
-
Model Context Protocol (MCP) server for AI agents to interact with
|
|
3
|
+
Model Context Protocol (MCP) server for AI agents to interact with Collab - the multi-tenant collaborative agent development platform. Enables AI agents to list projects, claim tasks, track progress, create pull requests, and more.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -14,7 +14,7 @@ npx @mtaap/mcp
|
|
|
14
14
|
|
|
15
15
|
## Architecture
|
|
16
16
|
|
|
17
|
-
The MCP server is a thin API client that communicates with the
|
|
17
|
+
The MCP server is a thin API client that communicates with the Collab webapp via REST API. All business logic, database access, and encryption operations are handled server-side by the webapp. This design:
|
|
18
18
|
|
|
19
19
|
- **Simplifies configuration**: Only 2 environment variables required
|
|
20
20
|
- **Improves security**: No encryption keys or database credentials in user configs
|
|
@@ -27,20 +27,20 @@ The MCP server is a thin API client that communicates with the MTAAP webapp via
|
|
|
27
27
|
|
|
28
28
|
| Variable | Description |
|
|
29
29
|
|----------|-------------|
|
|
30
|
-
| `
|
|
31
|
-
| `
|
|
30
|
+
| `COLLAB_API_KEY` | Your Collab API key. Generate one at https://collab.mtaap.de/settings/api-keys |
|
|
31
|
+
| `COLLAB_BASE_URL` | Collab webapp URL (e.g., `https://collab.mtaap.de`) |
|
|
32
32
|
|
|
33
33
|
### Optional Environment Variables
|
|
34
34
|
|
|
35
35
|
| Variable | Description |
|
|
36
36
|
|----------|-------------|
|
|
37
|
-
| `
|
|
37
|
+
| `COLLAB_DEBUG` | Set to `true` to enable debug logging |
|
|
38
38
|
|
|
39
39
|
### Example
|
|
40
40
|
|
|
41
41
|
```bash
|
|
42
|
-
export
|
|
43
|
-
export
|
|
42
|
+
export COLLAB_API_KEY=collab_xxxxx...
|
|
43
|
+
export COLLAB_BASE_URL=https://collab.mtaap.de
|
|
44
44
|
```
|
|
45
45
|
|
|
46
46
|
## Available Tools
|
|
@@ -135,7 +135,7 @@ Mark task as complete and create a pull request.
|
|
|
135
135
|
|
|
136
136
|
### check_active_task
|
|
137
137
|
|
|
138
|
-
Check for a resumable task in `.
|
|
138
|
+
Check for a resumable task in `.collab/active-task.json` in the current working directory.
|
|
139
139
|
|
|
140
140
|
**Parameters:** None
|
|
141
141
|
|
|
@@ -218,7 +218,7 @@ Create a new project in your personal workspace.
|
|
|
218
218
|
|
|
219
219
|
### get_version
|
|
220
220
|
|
|
221
|
-
Get the current
|
|
221
|
+
Get the current Collab MCP server version.
|
|
222
222
|
|
|
223
223
|
**Parameters:** None
|
|
224
224
|
|
|
@@ -232,12 +232,12 @@ Get the current MTAAP MCP server version.
|
|
|
232
232
|
```json
|
|
233
233
|
{
|
|
234
234
|
"mcpServers": {
|
|
235
|
-
"
|
|
235
|
+
"collab": {
|
|
236
236
|
"command": "npx",
|
|
237
237
|
"args": ["@mtaap/mcp"],
|
|
238
238
|
"env": {
|
|
239
|
-
"
|
|
240
|
-
"
|
|
239
|
+
"COLLAB_BASE_URL": "https://collab.mtaap.de",
|
|
240
|
+
"COLLAB_API_KEY": "your-api-key"
|
|
241
241
|
}
|
|
242
242
|
}
|
|
243
243
|
}
|
|
@@ -256,18 +256,18 @@ pnpm build
|
|
|
256
256
|
pnpm dev
|
|
257
257
|
|
|
258
258
|
# Run locally
|
|
259
|
-
|
|
259
|
+
COLLAB_API_KEY=your-key COLLAB_BASE_URL=https://collab.mtaap.de pnpm start
|
|
260
260
|
```
|
|
261
261
|
|
|
262
262
|
## Troubleshooting
|
|
263
263
|
|
|
264
|
-
### "
|
|
264
|
+
### "COLLAB_API_KEY is required"
|
|
265
265
|
|
|
266
|
-
You need to set the `
|
|
266
|
+
You need to set the `COLLAB_API_KEY` environment variable. Generate an API key at https://collab.mtaap.de/settings/api-keys
|
|
267
267
|
|
|
268
|
-
### "
|
|
268
|
+
### "COLLAB_BASE_URL is required"
|
|
269
269
|
|
|
270
|
-
You need to set the `
|
|
270
|
+
You need to set the `COLLAB_BASE_URL` environment variable to your Collab webapp URL (e.g., `https://collab.mtaap.de`).
|
|
271
271
|
|
|
272
272
|
### "Invalid API key" or "Authentication failed"
|
|
273
273
|
|
|
@@ -275,11 +275,11 @@ Your API key may be expired or revoked. Generate a new one at https://collab.mta
|
|
|
275
275
|
|
|
276
276
|
### "GitHub token not configured"
|
|
277
277
|
|
|
278
|
-
Git operations (branch creation, PR creation) require a GitHub token to be configured in your
|
|
278
|
+
Git operations (branch creation, PR creation) require a GitHub token to be configured in your Collab account settings. Go to https://collab.mtaap.de/settings and add your GitHub personal access token.
|
|
279
279
|
|
|
280
280
|
### Connection issues
|
|
281
281
|
|
|
282
|
-
Ensure your firewall allows outbound connections to your
|
|
282
|
+
Ensure your firewall allows outbound connections to your Collab instance. The server performs a connectivity check on startup and will report any connection issues.
|
|
283
283
|
|
|
284
284
|
### Rate limiting
|
|
285
285
|
|
package/dist/cli.js
CHANGED
|
@@ -28,7 +28,7 @@ var import_mcp = require("@modelcontextprotocol/sdk/server/mcp.js");
|
|
|
28
28
|
var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
29
29
|
|
|
30
30
|
// src/version.ts
|
|
31
|
-
var VERSION = "0.2.
|
|
31
|
+
var VERSION = "0.2.5";
|
|
32
32
|
|
|
33
33
|
// src/index.ts
|
|
34
34
|
var import_zod3 = require("zod");
|
|
@@ -504,7 +504,8 @@ var UpdateProjectInputSchema = import_zod2.z.object({
|
|
|
504
504
|
description: import_zod2.z.string().max(500).optional(),
|
|
505
505
|
repositoryUrl: import_zod2.z.string().url().optional(),
|
|
506
506
|
baseBranch: import_zod2.z.string().optional(),
|
|
507
|
-
tags: import_zod2.z.array(import_zod2.z.string()).optional()
|
|
507
|
+
tags: import_zod2.z.array(import_zod2.z.string()).optional(),
|
|
508
|
+
allowMemberArchive: import_zod2.z.boolean().optional()
|
|
508
509
|
});
|
|
509
510
|
var CreateEpicInputSchema = import_zod2.z.object({
|
|
510
511
|
projectId: cuidOrPrefixedId,
|
|
@@ -1135,18 +1136,18 @@ var MCPApiClient = class {
|
|
|
1135
1136
|
}
|
|
1136
1137
|
};
|
|
1137
1138
|
function createApiClientFromEnv() {
|
|
1138
|
-
const baseUrl = process.env.
|
|
1139
|
-
const apiKey = process.env.
|
|
1139
|
+
const baseUrl = process.env.COLLAB_BASE_URL;
|
|
1140
|
+
const apiKey = process.env.COLLAB_API_KEY;
|
|
1140
1141
|
if (!baseUrl) {
|
|
1141
|
-
throw new Error("
|
|
1142
|
+
throw new Error("COLLAB_BASE_URL environment variable is required");
|
|
1142
1143
|
}
|
|
1143
1144
|
if (!apiKey) {
|
|
1144
|
-
throw new Error("
|
|
1145
|
+
throw new Error("COLLAB_API_KEY environment variable is required");
|
|
1145
1146
|
}
|
|
1146
1147
|
return new MCPApiClient({
|
|
1147
1148
|
baseUrl,
|
|
1148
1149
|
apiKey,
|
|
1149
|
-
debug: process.env.
|
|
1150
|
+
debug: process.env.COLLAB_DEBUG === "true"
|
|
1150
1151
|
});
|
|
1151
1152
|
}
|
|
1152
1153
|
|
|
@@ -1176,11 +1177,62 @@ function assertApiKeyPermission(apiKey, required, toolName) {
|
|
|
1176
1177
|
}
|
|
1177
1178
|
|
|
1178
1179
|
// src/index.ts
|
|
1180
|
+
var COLLAB_SERVER_INSTRUCTIONS = `Collab - AI-assisted software development task management platform.
|
|
1181
|
+
|
|
1182
|
+
TOOL CATEGORIES:
|
|
1183
|
+
|
|
1184
|
+
1. Project Discovery (READ):
|
|
1185
|
+
- list_projects, get_project_context, get_version
|
|
1186
|
+
|
|
1187
|
+
2. Task Management (READ/WRITE):
|
|
1188
|
+
- list_tasks, get_task, create_task, archive_task, unarchive_task
|
|
1189
|
+
|
|
1190
|
+
3. Task Execution (WRITE):
|
|
1191
|
+
- assign_task, update_progress, add_note, complete_task, abandon_task, report_error
|
|
1192
|
+
|
|
1193
|
+
4. Code Review (WRITE):
|
|
1194
|
+
- request_changes, approve_task
|
|
1195
|
+
|
|
1196
|
+
5. Session Management (READ):
|
|
1197
|
+
- check_active_task
|
|
1198
|
+
|
|
1199
|
+
WORKFLOWS:
|
|
1200
|
+
|
|
1201
|
+
Standard Task Workflow:
|
|
1202
|
+
list_projects -> get_project_context -> list_tasks(state=READY) -> get_task -> assign_task -> [update_progress...] -> complete_task
|
|
1203
|
+
|
|
1204
|
+
Resume Workflow:
|
|
1205
|
+
check_active_task -> (if active) get_task -> update_progress -> complete_task
|
|
1206
|
+
|
|
1207
|
+
Review Workflow:
|
|
1208
|
+
list_tasks(state=REVIEW) -> get_task -> approve_task OR request_changes
|
|
1209
|
+
|
|
1210
|
+
Error Recovery:
|
|
1211
|
+
report_error -> abandon_task(deleteBranch=false) -> list_tasks -> assign_task (retry or pick different task)
|
|
1212
|
+
(abandon_task returns IN_PROGRESS tasks to READY state)
|
|
1213
|
+
|
|
1214
|
+
TASK STATE FLOW:
|
|
1215
|
+
BACKLOG -> READY -> IN_PROGRESS -> REVIEW -> DONE
|
|
1216
|
+
(request_changes: REVIEW -> IN_PROGRESS)
|
|
1217
|
+
(abandon_task: IN_PROGRESS -> READY)
|
|
1218
|
+
|
|
1219
|
+
CONSTRAINTS:
|
|
1220
|
+
- assign_task is atomic - fails if already claimed
|
|
1221
|
+
- Only READY tasks can be assigned
|
|
1222
|
+
- complete_task requires IN_PROGRESS state
|
|
1223
|
+
- request_changes/approve_task require REVIEW state
|
|
1224
|
+
- Always check_active_task before starting new work
|
|
1225
|
+
- Call update_progress frequently to checkpoint`;
|
|
1179
1226
|
async function createMCPServer() {
|
|
1180
|
-
const server = new import_mcp.McpServer(
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1227
|
+
const server = new import_mcp.McpServer(
|
|
1228
|
+
{
|
|
1229
|
+
name: "collab",
|
|
1230
|
+
version: VERSION
|
|
1231
|
+
},
|
|
1232
|
+
{
|
|
1233
|
+
instructions: COLLAB_SERVER_INSTRUCTIONS
|
|
1234
|
+
}
|
|
1235
|
+
);
|
|
1184
1236
|
const apiClient = createApiClientFromEnv();
|
|
1185
1237
|
let authContext;
|
|
1186
1238
|
try {
|
|
@@ -1197,7 +1249,7 @@ async function createMCPServer() {
|
|
|
1197
1249
|
server.registerTool(
|
|
1198
1250
|
"list_projects",
|
|
1199
1251
|
{
|
|
1200
|
-
description: "
|
|
1252
|
+
description: "Discover all accessible projects. Use first to find project IDs. Filter by TEAM, PERSONAL, or ALL workspaces.",
|
|
1201
1253
|
inputSchema: {
|
|
1202
1254
|
workspaceType: import_zod3.z.enum(["TEAM", "PERSONAL", "ALL"]).optional().describe("Filter by workspace type")
|
|
1203
1255
|
}
|
|
@@ -1227,7 +1279,7 @@ async function createMCPServer() {
|
|
|
1227
1279
|
server.registerTool(
|
|
1228
1280
|
"list_tasks",
|
|
1229
1281
|
{
|
|
1230
|
-
description: "
|
|
1282
|
+
description: "Query tasks with filters. Use state=READY for assignable tasks, state=REVIEW for pending reviews.",
|
|
1231
1283
|
inputSchema: {
|
|
1232
1284
|
projectId: import_zod3.z.string().optional().describe("Filter by project ID"),
|
|
1233
1285
|
state: import_zod3.z.nativeEnum(TaskState).optional().describe("Filter by task state"),
|
|
@@ -1261,7 +1313,7 @@ async function createMCPServer() {
|
|
|
1261
1313
|
server.registerTool(
|
|
1262
1314
|
"get_task",
|
|
1263
1315
|
{
|
|
1264
|
-
description: "
|
|
1316
|
+
description: "Get complete task details with acceptance criteria and notes. Call before assign_task to understand requirements.",
|
|
1265
1317
|
inputSchema: {
|
|
1266
1318
|
taskId: import_zod3.z.string().describe("The task ID to retrieve")
|
|
1267
1319
|
}
|
|
@@ -1287,7 +1339,7 @@ async function createMCPServer() {
|
|
|
1287
1339
|
server.registerTool(
|
|
1288
1340
|
"assign_task",
|
|
1289
1341
|
{
|
|
1290
|
-
description: "
|
|
1342
|
+
description: "Atomically claim a task and create git branch. Race-safe - fails if already assigned. Task must be READY.",
|
|
1291
1343
|
inputSchema: {
|
|
1292
1344
|
projectId: import_zod3.z.string().describe("The project ID"),
|
|
1293
1345
|
taskId: import_zod3.z.string().describe("The task ID to assign"),
|
|
@@ -1323,7 +1375,7 @@ async function createMCPServer() {
|
|
|
1323
1375
|
server.registerTool(
|
|
1324
1376
|
"update_progress",
|
|
1325
1377
|
{
|
|
1326
|
-
description: "
|
|
1378
|
+
description: "Report progress and checkpoint work. Call frequently during execution. Marks acceptance criteria complete.",
|
|
1327
1379
|
inputSchema: {
|
|
1328
1380
|
taskId: import_zod3.z.string().describe("The task ID to update"),
|
|
1329
1381
|
statusMessage: import_zod3.z.string().optional().describe("Status message (max 1000 chars)"),
|
|
@@ -1360,7 +1412,7 @@ async function createMCPServer() {
|
|
|
1360
1412
|
server.registerTool(
|
|
1361
1413
|
"complete_task",
|
|
1362
1414
|
{
|
|
1363
|
-
description: "
|
|
1415
|
+
description: "Finish task and create pull request. Moves task to REVIEW. Requires IN_PROGRESS state.",
|
|
1364
1416
|
inputSchema: {
|
|
1365
1417
|
projectId: import_zod3.z.string().describe("The project ID"),
|
|
1366
1418
|
taskId: import_zod3.z.string().describe("The task ID to complete"),
|
|
@@ -1398,7 +1450,7 @@ async function createMCPServer() {
|
|
|
1398
1450
|
server.registerTool(
|
|
1399
1451
|
"check_active_task",
|
|
1400
1452
|
{
|
|
1401
|
-
description: "Check for resumable
|
|
1453
|
+
description: "Check for resumable work from previous session. Always call before starting new work."
|
|
1402
1454
|
},
|
|
1403
1455
|
async () => {
|
|
1404
1456
|
assertApiKeyPermission(
|
|
@@ -1420,7 +1472,7 @@ async function createMCPServer() {
|
|
|
1420
1472
|
server.registerTool(
|
|
1421
1473
|
"report_error",
|
|
1422
1474
|
{
|
|
1423
|
-
description: "Report unrecoverable
|
|
1475
|
+
description: "Report unrecoverable errors (BUILD_FAILURE, TEST_FAILURE, CONFLICT, AUTH_ERROR). Consider abandon_task after.",
|
|
1424
1476
|
inputSchema: {
|
|
1425
1477
|
taskId: import_zod3.z.string().describe("The task ID"),
|
|
1426
1478
|
errorType: import_zod3.z.nativeEnum(ErrorType).describe("Error type: BUILD_FAILURE, TEST_FAILURE, CONFLICT, AUTH_ERROR, OTHER"),
|
|
@@ -1458,7 +1510,7 @@ async function createMCPServer() {
|
|
|
1458
1510
|
server.registerTool(
|
|
1459
1511
|
"get_project_context",
|
|
1460
1512
|
{
|
|
1461
|
-
description: "
|
|
1513
|
+
description: "Load project README, tech stack, and coding conventions. Call after selecting project.",
|
|
1462
1514
|
inputSchema: {
|
|
1463
1515
|
projectId: import_zod3.z.string().describe("The project ID")
|
|
1464
1516
|
}
|
|
@@ -1488,7 +1540,7 @@ async function createMCPServer() {
|
|
|
1488
1540
|
server.registerTool(
|
|
1489
1541
|
"add_note",
|
|
1490
1542
|
{
|
|
1491
|
-
description: "
|
|
1543
|
+
description: "Document implementation decisions. Notes persist for future reference and handoff.",
|
|
1492
1544
|
inputSchema: {
|
|
1493
1545
|
taskId: import_zod3.z.string().describe("The task ID"),
|
|
1494
1546
|
content: import_zod3.z.string().describe("Note content (max 500 chars)")
|
|
@@ -1518,7 +1570,7 @@ async function createMCPServer() {
|
|
|
1518
1570
|
server.registerTool(
|
|
1519
1571
|
"abandon_task",
|
|
1520
1572
|
{
|
|
1521
|
-
description: "
|
|
1573
|
+
description: "Release task assignment and optionally clean up branch. Task returns to READY. Use after errors.",
|
|
1522
1574
|
inputSchema: {
|
|
1523
1575
|
projectId: import_zod3.z.string().describe("The project ID"),
|
|
1524
1576
|
taskId: import_zod3.z.string().describe("The task ID to abandon"),
|
|
@@ -1554,7 +1606,7 @@ async function createMCPServer() {
|
|
|
1554
1606
|
server.registerTool(
|
|
1555
1607
|
"archive_task",
|
|
1556
1608
|
{
|
|
1557
|
-
description: "
|
|
1609
|
+
description: "Soft-delete a task. Hidden but restorable via unarchive_task.",
|
|
1558
1610
|
inputSchema: {
|
|
1559
1611
|
projectId: import_zod3.z.string().describe("The project ID"),
|
|
1560
1612
|
taskId: import_zod3.z.string().describe("The task ID to archive")
|
|
@@ -1588,7 +1640,7 @@ async function createMCPServer() {
|
|
|
1588
1640
|
server.registerTool(
|
|
1589
1641
|
"unarchive_task",
|
|
1590
1642
|
{
|
|
1591
|
-
description: "Restore
|
|
1643
|
+
description: "Restore previously archived task to original state.",
|
|
1592
1644
|
inputSchema: {
|
|
1593
1645
|
projectId: import_zod3.z.string().describe("The project ID"),
|
|
1594
1646
|
taskId: import_zod3.z.string().describe("The task ID to restore")
|
|
@@ -1622,7 +1674,7 @@ async function createMCPServer() {
|
|
|
1622
1674
|
server.registerTool(
|
|
1623
1675
|
"create_personal_project",
|
|
1624
1676
|
{
|
|
1625
|
-
description: "Create project in
|
|
1677
|
+
description: "Create new project in personal workspace linked to GitHub repository.",
|
|
1626
1678
|
inputSchema: {
|
|
1627
1679
|
name: import_zod3.z.string().describe("Project name (max 100 chars)"),
|
|
1628
1680
|
description: import_zod3.z.string().optional().describe("Project description (max 500 chars)"),
|
|
@@ -1658,7 +1710,7 @@ async function createMCPServer() {
|
|
|
1658
1710
|
server.registerTool(
|
|
1659
1711
|
"create_task",
|
|
1660
1712
|
{
|
|
1661
|
-
description: "Create
|
|
1713
|
+
description: "Create task with title, description, acceptance criteria. Starts in BACKLOG. Priority: LOW/MEDIUM/HIGH/CRITICAL.",
|
|
1662
1714
|
inputSchema: {
|
|
1663
1715
|
projectId: import_zod3.z.string().describe("The project ID to create the task in"),
|
|
1664
1716
|
epicId: import_zod3.z.string().nullable().optional().describe("Optional epic ID to associate the task with"),
|
|
@@ -1704,7 +1756,7 @@ async function createMCPServer() {
|
|
|
1704
1756
|
server.registerTool(
|
|
1705
1757
|
"request_changes",
|
|
1706
1758
|
{
|
|
1707
|
-
description: "
|
|
1759
|
+
description: "Return task from REVIEW to IN_PROGRESS with feedback. Original assignee addresses changes.",
|
|
1708
1760
|
inputSchema: {
|
|
1709
1761
|
projectId: import_zod3.z.string().describe("The project ID"),
|
|
1710
1762
|
taskId: import_zod3.z.string().describe("The task ID to review"),
|
|
@@ -1742,7 +1794,7 @@ async function createMCPServer() {
|
|
|
1742
1794
|
server.registerTool(
|
|
1743
1795
|
"approve_task",
|
|
1744
1796
|
{
|
|
1745
|
-
description: "Approve
|
|
1797
|
+
description: "Approve completed work and mark DONE. Only for REVIEW state tasks.",
|
|
1746
1798
|
inputSchema: {
|
|
1747
1799
|
projectId: import_zod3.z.string().describe("The project ID"),
|
|
1748
1800
|
taskId: import_zod3.z.string().describe("The task ID to approve"),
|
|
@@ -1778,7 +1830,7 @@ async function createMCPServer() {
|
|
|
1778
1830
|
server.registerTool(
|
|
1779
1831
|
"get_version",
|
|
1780
1832
|
{
|
|
1781
|
-
description: "
|
|
1833
|
+
description: "Check MCP server version and connectivity."
|
|
1782
1834
|
},
|
|
1783
1835
|
async () => {
|
|
1784
1836
|
assertApiKeyPermission(mockApiKey, ApiKeyPermission.READ, "get_version");
|
|
@@ -1837,7 +1889,7 @@ function handleApiError(error) {
|
|
|
1837
1889
|
async function checkActiveTask() {
|
|
1838
1890
|
const fs = await import("fs");
|
|
1839
1891
|
const path = await import("path");
|
|
1840
|
-
const activeTaskPath = path.join(process.cwd(), ".
|
|
1892
|
+
const activeTaskPath = path.join(process.cwd(), ".collab", "active-task.json");
|
|
1841
1893
|
try {
|
|
1842
1894
|
await fs.promises.access(activeTaskPath);
|
|
1843
1895
|
const content = await fs.promises.readFile(activeTaskPath, "utf-8");
|
|
@@ -1858,34 +1910,34 @@ async function checkActiveTask() {
|
|
|
1858
1910
|
function handleCliFlags() {
|
|
1859
1911
|
const args = process.argv.slice(2);
|
|
1860
1912
|
if (args.includes("--version") || args.includes("-v")) {
|
|
1861
|
-
console.log(`
|
|
1913
|
+
console.log(`collab-mcp v${VERSION}`);
|
|
1862
1914
|
process.exit(0);
|
|
1863
1915
|
}
|
|
1864
1916
|
if (args.includes("--help") || args.includes("-h")) {
|
|
1865
|
-
console.log(`
|
|
1917
|
+
console.log(`collab-mcp v${VERSION}
|
|
1866
1918
|
|
|
1867
|
-
|
|
1919
|
+
Collab MCP Server - Model Context Protocol server for Collab
|
|
1868
1920
|
|
|
1869
1921
|
Usage:
|
|
1870
|
-
|
|
1922
|
+
collab-mcp [options]
|
|
1871
1923
|
|
|
1872
1924
|
Options:
|
|
1873
1925
|
-v, --version Show version number
|
|
1874
1926
|
-h, --help Show this help message
|
|
1875
1927
|
|
|
1876
1928
|
Environment Variables:
|
|
1877
|
-
|
|
1878
|
-
|
|
1929
|
+
COLLAB_API_KEY Your Collab API key (required)
|
|
1930
|
+
COLLAB_BASE_URL Collab webapp URL (required)
|
|
1879
1931
|
|
|
1880
1932
|
Example mcp.json configuration:
|
|
1881
1933
|
{
|
|
1882
1934
|
"mcpServers": {
|
|
1883
|
-
"
|
|
1935
|
+
"collab": {
|
|
1884
1936
|
"command": "npx",
|
|
1885
1937
|
"args": ["@mtaap/mcp"],
|
|
1886
1938
|
"env": {
|
|
1887
|
-
"
|
|
1888
|
-
"
|
|
1939
|
+
"COLLAB_API_KEY": "collab_your_api_key_here",
|
|
1940
|
+
"COLLAB_BASE_URL": "https://collab.mtaap.de"
|
|
1889
1941
|
}
|
|
1890
1942
|
}
|
|
1891
1943
|
}
|
|
@@ -1895,32 +1947,32 @@ Example mcp.json configuration:
|
|
|
1895
1947
|
}
|
|
1896
1948
|
function validateEnvironment() {
|
|
1897
1949
|
const errors = [];
|
|
1898
|
-
if (!process.env.
|
|
1950
|
+
if (!process.env.COLLAB_API_KEY) {
|
|
1899
1951
|
errors.push(
|
|
1900
|
-
"
|
|
1952
|
+
"COLLAB_API_KEY is required. Generate one at https://collab.mtaap.de/settings/api-keys"
|
|
1901
1953
|
);
|
|
1902
1954
|
}
|
|
1903
|
-
if (!process.env.
|
|
1955
|
+
if (!process.env.COLLAB_BASE_URL) {
|
|
1904
1956
|
errors.push(
|
|
1905
|
-
"
|
|
1957
|
+
"COLLAB_BASE_URL is required. Set to https://collab.mtaap.de for cloud or your self-hosted URL."
|
|
1906
1958
|
);
|
|
1907
1959
|
}
|
|
1908
1960
|
if (errors.length > 0) {
|
|
1909
1961
|
for (const error of errors) {
|
|
1910
|
-
console.error(`[
|
|
1962
|
+
console.error(`[collab-mcp] Error: ${error}`);
|
|
1911
1963
|
}
|
|
1912
1964
|
console.error("\nRequired environment variables:");
|
|
1913
|
-
console.error("
|
|
1914
|
-
console.error("
|
|
1965
|
+
console.error(" COLLAB_API_KEY Your Collab API key");
|
|
1966
|
+
console.error(" COLLAB_BASE_URL Collab webapp URL (e.g., https://collab.mtaap.de)");
|
|
1915
1967
|
console.error("\nExample mcp.json configuration:");
|
|
1916
1968
|
console.error(`{
|
|
1917
1969
|
"mcpServers": {
|
|
1918
|
-
"
|
|
1970
|
+
"collab": {
|
|
1919
1971
|
"command": "npx",
|
|
1920
1972
|
"args": ["@mtaap/mcp"],
|
|
1921
1973
|
"env": {
|
|
1922
|
-
"
|
|
1923
|
-
"
|
|
1974
|
+
"COLLAB_API_KEY": "collab_your_api_key_here",
|
|
1975
|
+
"COLLAB_BASE_URL": "https://collab.mtaap.de"
|
|
1924
1976
|
}
|
|
1925
1977
|
}
|
|
1926
1978
|
}
|
|
@@ -1928,20 +1980,20 @@ function validateEnvironment() {
|
|
|
1928
1980
|
process.exit(1);
|
|
1929
1981
|
}
|
|
1930
1982
|
try {
|
|
1931
|
-
new URL(process.env.
|
|
1983
|
+
new URL(process.env.COLLAB_BASE_URL);
|
|
1932
1984
|
} catch {
|
|
1933
|
-
console.error(`[
|
|
1985
|
+
console.error(`[collab-mcp] Error: COLLAB_BASE_URL is not a valid URL: ${process.env.COLLAB_BASE_URL}`);
|
|
1934
1986
|
process.exit(1);
|
|
1935
1987
|
}
|
|
1936
1988
|
}
|
|
1937
1989
|
async function checkConnectivity() {
|
|
1938
|
-
const baseUrl = process.env.
|
|
1939
|
-
console.error(`[
|
|
1990
|
+
const baseUrl = process.env.COLLAB_BASE_URL;
|
|
1991
|
+
console.error(`[collab-mcp] Checking connectivity to ${baseUrl}...`);
|
|
1940
1992
|
try {
|
|
1941
1993
|
const response = await fetch(`${baseUrl}/api/mcp/auth`, {
|
|
1942
1994
|
method: "GET",
|
|
1943
1995
|
headers: {
|
|
1944
|
-
"X-API-Key": process.env.
|
|
1996
|
+
"X-API-Key": process.env.COLLAB_API_KEY
|
|
1945
1997
|
},
|
|
1946
1998
|
signal: AbortSignal.timeout(1e4)
|
|
1947
1999
|
// 10 second timeout
|
|
@@ -1949,51 +2001,51 @@ async function checkConnectivity() {
|
|
|
1949
2001
|
if (!response.ok) {
|
|
1950
2002
|
const data = await response.json().catch(() => ({}));
|
|
1951
2003
|
if (response.status === 401) {
|
|
1952
|
-
console.error("[
|
|
2004
|
+
console.error("[collab-mcp] Error: Invalid or expired API key");
|
|
1953
2005
|
process.exit(1);
|
|
1954
2006
|
}
|
|
1955
|
-
console.error(`[
|
|
2007
|
+
console.error(`[collab-mcp] Error: API returned ${response.status}: ${data.error || "Unknown error"}`);
|
|
1956
2008
|
process.exit(1);
|
|
1957
2009
|
}
|
|
1958
|
-
console.error("[
|
|
2010
|
+
console.error("[collab-mcp] Connected successfully");
|
|
1959
2011
|
} catch (error) {
|
|
1960
2012
|
if (error instanceof Error && error.name === "TimeoutError") {
|
|
1961
|
-
console.error(`[
|
|
2013
|
+
console.error(`[collab-mcp] Error: Connection timed out to ${baseUrl}`);
|
|
1962
2014
|
} else {
|
|
1963
|
-
console.error(`[
|
|
1964
|
-
console.error(`[
|
|
2015
|
+
console.error(`[collab-mcp] Error: Could not connect to ${baseUrl}`);
|
|
2016
|
+
console.error(`[collab-mcp] Details: ${error instanceof Error ? error.message : String(error)}`);
|
|
1965
2017
|
}
|
|
1966
2018
|
process.exit(1);
|
|
1967
2019
|
}
|
|
1968
2020
|
}
|
|
1969
2021
|
async function main() {
|
|
1970
2022
|
handleCliFlags();
|
|
1971
|
-
console.error("[
|
|
2023
|
+
console.error("[collab-mcp] Starting Collab MCP server...");
|
|
1972
2024
|
validateEnvironment();
|
|
1973
2025
|
await checkConnectivity();
|
|
1974
2026
|
try {
|
|
1975
2027
|
await createMCPServer();
|
|
1976
|
-
console.error("[
|
|
2028
|
+
console.error("[collab-mcp] Server started successfully");
|
|
1977
2029
|
} catch (error) {
|
|
1978
2030
|
const message = error instanceof Error ? error.message : String(error);
|
|
1979
|
-
console.error(`[
|
|
2031
|
+
console.error(`[collab-mcp] Failed to start server: ${message}`);
|
|
1980
2032
|
process.exit(1);
|
|
1981
2033
|
}
|
|
1982
2034
|
}
|
|
1983
2035
|
function setupShutdownHandlers() {
|
|
1984
2036
|
const shutdown = (signal) => {
|
|
1985
|
-
console.error(`[
|
|
2037
|
+
console.error(`[collab-mcp] Received ${signal}, shutting down...`);
|
|
1986
2038
|
process.exit(0);
|
|
1987
2039
|
};
|
|
1988
2040
|
process.on("SIGINT", () => shutdown("SIGINT"));
|
|
1989
2041
|
process.on("SIGTERM", () => shutdown("SIGTERM"));
|
|
1990
2042
|
process.on("uncaughtException", (error) => {
|
|
1991
|
-
console.error("[
|
|
2043
|
+
console.error("[collab-mcp] Uncaught exception:", error.message);
|
|
1992
2044
|
process.exit(1);
|
|
1993
2045
|
});
|
|
1994
2046
|
process.on("unhandledRejection", (reason) => {
|
|
1995
2047
|
const message = reason instanceof Error ? reason.message : String(reason);
|
|
1996
|
-
console.error("[
|
|
2048
|
+
console.error("[collab-mcp] Unhandled rejection:", message);
|
|
1997
2049
|
process.exit(1);
|
|
1998
2050
|
});
|
|
1999
2051
|
}
|