@schoolai/shipyard-mcp 0.4.0 → 0.4.1-nightly.20260127

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 CHANGED
@@ -47,7 +47,11 @@ Shipyard is just an MCP server. One command or a simple JSON config—works with
47
47
  Full experience with hooks, skills, and auto-task creation:
48
48
 
49
49
  ```bash
50
- /plugin install SchoolAI/shipyard
50
+ # Step 1: Add the marketplace
51
+ /plugin marketplace add https://github.com/SchoolAI/shipyard.git
52
+
53
+ # Step 2: Install the plugin
54
+ /plugin install shipyard@schoolai-shipyard
51
55
  ```
52
56
 
53
57
  ### Cursor
@@ -59,7 +63,7 @@ Add to `~/.cursor/mcp.json`:
59
63
  "mcpServers": {
60
64
  "shipyard": {
61
65
  "command": "npx",
62
- "args": ["-y", "@schoolai/shipyard-mcp@latest"]
66
+ "args": ["-y", "-p", "@schoolai/shipyard-mcp@latest", "mcp-server-shipyard"]
63
67
  }
64
68
  }
65
69
  }
@@ -70,7 +74,7 @@ Add to `~/.cursor/mcp.json`:
70
74
  Add via CLI:
71
75
 
72
76
  ```bash
73
- codex mcp add shipyard -- npx -y @schoolai/shipyard-mcp@latest
77
+ codex mcp add shipyard -- npx -y -p @schoolai/shipyard-mcp@latest mcp-server-shipyard
74
78
  ```
75
79
 
76
80
  Or add to `~/.codex/config.toml`:
@@ -78,13 +82,13 @@ Or add to `~/.codex/config.toml`:
78
82
  ```toml
79
83
  [mcp_servers.shipyard]
80
84
  command = "npx"
81
- args = ["-y", "@schoolai/shipyard-mcp@latest"]
85
+ args = ["-y", "-p", "@schoolai/shipyard-mcp@latest", "mcp-server-shipyard"]
82
86
  ```
83
87
 
84
88
  ### VS Code / GitHub Copilot
85
89
 
86
90
  ```bash
87
- code --add-mcp '{"name":"shipyard","command":"npx","args":["-y","@schoolai/shipyard-mcp@latest"]}'
91
+ code --add-mcp '{"name":"shipyard","command":"npx","args":["-y","-p","@schoolai/shipyard-mcp@latest","mcp-server-shipyard"]}'
88
92
  ```
89
93
 
90
94
  <details>
@@ -102,7 +106,7 @@ Add to your config file:
102
106
  "mcpServers": {
103
107
  "shipyard": {
104
108
  "command": "npx",
105
- "args": ["-y", "@schoolai/shipyard-mcp@latest"]
109
+ "args": ["-y", "-p", "@schoolai/shipyard-mcp@latest", "mcp-server-shipyard"]
106
110
  }
107
111
  }
108
112
  }
@@ -117,7 +121,7 @@ Add to `~/.codeium/windsurf/mcp_config.json`:
117
121
  "mcpServers": {
118
122
  "shipyard": {
119
123
  "command": "npx",
120
- "args": ["-y", "@schoolai/shipyard-mcp@latest"]
124
+ "args": ["-y", "-p", "@schoolai/shipyard-mcp@latest", "mcp-server-shipyard"]
121
125
  }
122
126
  }
123
127
  }
@@ -139,7 +143,7 @@ Add to `~/.config/zed/settings.json`:
139
143
  "shipyard": {
140
144
  "command": {
141
145
  "path": "npx",
142
- "args": ["-y", "@schoolai/shipyard-mcp@latest"]
146
+ "args": ["-y", "-p", "@schoolai/shipyard-mcp@latest", "mcp-server-shipyard"]
143
147
  }
144
148
  }
145
149
  }
@@ -154,7 +158,7 @@ Create `.continue/mcpServers/shipyard.yaml`:
154
158
  mcpServers:
155
159
  - name: Shipyard
156
160
  command: npx
157
- args: ["-y", "@schoolai/shipyard-mcp@latest"]
161
+ args: ["-y", "-p", "@schoolai/shipyard-mcp@latest", "mcp-server-shipyard"]
158
162
  ```
159
163
 
160
164
  </details>
@@ -81,7 +81,7 @@ import * as os from "os";
81
81
  import * as path from "path";
82
82
  import * as vm from "vm";
83
83
  import ffmpegInstaller from "@ffmpeg-installer/ffmpeg";
84
- import { z as z12 } from "zod";
84
+ import { z as z13 } from "zod";
85
85
 
86
86
  // src/tools/add-artifact.ts
87
87
  import { writeFile as writeFile2 } from "fs/promises";
@@ -1360,8 +1360,63 @@ Make sure:
1360
1360
  }
1361
1361
  };
1362
1362
 
1363
- // src/tools/read-diff-comments.ts
1363
+ // src/tools/post-update.ts
1364
1364
  import { z as z6 } from "zod";
1365
+ var PostUpdateInput = z6.object({
1366
+ taskId: z6.string().describe("The task ID"),
1367
+ sessionToken: z6.string().describe("Session token from plan approval"),
1368
+ message: z6.string().describe("Update content (markdown)")
1369
+ });
1370
+ function errorResponse2(message) {
1371
+ return { content: [{ type: "text", text: message }], isError: true };
1372
+ }
1373
+ function successResponse2(message) {
1374
+ return { content: [{ type: "text", text: message }] };
1375
+ }
1376
+ var postUpdateTool = {
1377
+ definition: {
1378
+ name: TOOL_NAMES.POST_UPDATE,
1379
+ description: `Post a progress update to the task timeline.
1380
+
1381
+ Use this to communicate status updates to humans watching your work:
1382
+ - "Starting work on authentication module"
1383
+ - "Milestone: API integration complete"
1384
+ - "Found edge case with rate limiting, investigating"
1385
+
1386
+ Updates appear in the Activity tab and keep reviewers informed.`,
1387
+ inputSchema: {
1388
+ type: "object",
1389
+ properties: {
1390
+ taskId: { type: "string", description: "The task ID" },
1391
+ sessionToken: { type: "string", description: "Session token from plan approval" },
1392
+ message: { type: "string", description: "Update content (markdown supported)" }
1393
+ },
1394
+ required: ["taskId", "sessionToken", "message"]
1395
+ }
1396
+ },
1397
+ handler: async (args) => {
1398
+ const input = PostUpdateInput.parse(args);
1399
+ const { taskId, sessionToken, message } = input;
1400
+ const doc = await getOrCreateDoc(taskId);
1401
+ const metadata = getPlanMetadata(doc);
1402
+ if (!metadata) {
1403
+ return errorResponse2(`Task "${taskId}" not found.`);
1404
+ }
1405
+ if (!metadata.sessionTokenHash || !verifySessionToken(sessionToken, metadata.sessionTokenHash)) {
1406
+ return errorResponse2(`Invalid session token for task "${taskId}".`);
1407
+ }
1408
+ const actorName = await getGitHubUsername();
1409
+ const eventId = logPlanEvent(doc, "agent_activity", actorName, {
1410
+ activityType: "update",
1411
+ message
1412
+ });
1413
+ logger.info({ taskId, eventId, messageLength: message.length }, "Agent update posted");
1414
+ return successResponse2(`Update posted to task "${taskId}".`);
1415
+ }
1416
+ };
1417
+
1418
+ // src/tools/read-diff-comments.ts
1419
+ import { z as z7 } from "zod";
1365
1420
  function getStalenessContext(doc) {
1366
1421
  const planMetadata = getPlanMetadata(doc);
1367
1422
  const cwd = extractCwdFromMetadata(planMetadata);
@@ -1389,12 +1444,12 @@ function extractCwdFromMetadata(metadata) {
1389
1444
  }
1390
1445
  return void 0;
1391
1446
  }
1392
- var ReadDiffCommentsInput = z6.object({
1393
- taskId: z6.string().describe("The task ID to read diff comments from"),
1394
- sessionToken: z6.string().describe("Session token from create_task"),
1395
- includeLocal: z6.boolean().optional().describe("Include local (uncommitted) diff comments (default: true)"),
1396
- includePR: z6.boolean().optional().describe("Include PR review diff comments (default: true)"),
1397
- includeResolved: z6.boolean().optional().describe("Include resolved comments (default: false)")
1447
+ var ReadDiffCommentsInput = z7.object({
1448
+ taskId: z7.string().describe("The task ID to read diff comments from"),
1449
+ sessionToken: z7.string().describe("Session token from create_task"),
1450
+ includeLocal: z7.boolean().optional().describe("Include local (uncommitted) diff comments (default: true)"),
1451
+ includePR: z7.boolean().optional().describe("Include PR review diff comments (default: true)"),
1452
+ includeResolved: z7.boolean().optional().describe("Include resolved comments (default: false)")
1398
1453
  });
1399
1454
  var readDiffCommentsTool = {
1400
1455
  definition: {
@@ -1495,7 +1550,7 @@ OUTPUT FORMAT:
1495
1550
  };
1496
1551
 
1497
1552
  // src/tools/read-task.ts
1498
- import { z as z7 } from "zod";
1553
+ import { z as z8 } from "zod";
1499
1554
 
1500
1555
  // src/export-markdown.ts
1501
1556
  import { ServerBlockNoteEditor as ServerBlockNoteEditor4 } from "@blocknote/server-util";
@@ -1757,12 +1812,12 @@ function formatResponseValue(response) {
1757
1812
  }
1758
1813
 
1759
1814
  // src/tools/read-task.ts
1760
- var ReadTaskInput = z7.object({
1761
- taskId: z7.string().describe("The task ID to read"),
1762
- sessionToken: z7.string().describe("Session token from create_task"),
1763
- includeAnnotations: z7.boolean().optional().describe("Include comment threads/annotations in the response (default: false)"),
1764
- includeLinkedPRs: z7.boolean().optional().describe("Include linked PRs section in the response (default: false)"),
1765
- includePRComments: z7.boolean().optional().describe(
1815
+ var ReadTaskInput = z8.object({
1816
+ taskId: z8.string().describe("The task ID to read"),
1817
+ sessionToken: z8.string().describe("Session token from create_task"),
1818
+ includeAnnotations: z8.boolean().optional().describe("Include comment threads/annotations in the response (default: false)"),
1819
+ includeLinkedPRs: z8.boolean().optional().describe("Include linked PRs section in the response (default: false)"),
1820
+ includePRComments: z8.boolean().optional().describe(
1766
1821
  "Include inline PR review comments (diff line comments) in the response (default: false)"
1767
1822
  )
1768
1823
  });
@@ -1887,9 +1942,9 @@ OUTPUT INCLUDES:
1887
1942
  };
1888
1943
 
1889
1944
  // src/tools/regenerate-session-token.ts
1890
- import { z as z8 } from "zod";
1891
- var RegenerateSessionTokenInput = z8.object({
1892
- taskId: z8.string().describe("The task ID to regenerate token for")
1945
+ import { z as z9 } from "zod";
1946
+ var RegenerateSessionTokenInput = z9.object({
1947
+ taskId: z9.string().describe("The task ID to regenerate token for")
1893
1948
  });
1894
1949
  var regenerateSessionTokenTool = {
1895
1950
  definition: {
@@ -2022,10 +2077,10 @@ Use this token for add_artifact, read_task, link_pr, and other task operations.`
2022
2077
  };
2023
2078
 
2024
2079
  // src/tools/setup-review-notification.ts
2025
- import { z as z9 } from "zod";
2026
- var SetupReviewNotificationInput = z9.object({
2027
- taskId: z9.string().describe("Task ID to monitor"),
2028
- pollIntervalSeconds: z9.number().optional().default(30).describe("Polling interval in seconds (default: 30)")
2080
+ import { z as z10 } from "zod";
2081
+ var SetupReviewNotificationInput = z10.object({
2082
+ taskId: z10.string().describe("Task ID to monitor"),
2083
+ pollIntervalSeconds: z10.number().optional().default(30).describe("Polling interval in seconds (default: 30)")
2029
2084
  });
2030
2085
  var setupReviewNotificationTool = {
2031
2086
  definition: {
@@ -2143,31 +2198,31 @@ The script:
2143
2198
 
2144
2199
  // src/tools/update-block-content.ts
2145
2200
  import { ServerBlockNoteEditor as ServerBlockNoteEditor5 } from "@blocknote/server-util";
2146
- import { z as z10 } from "zod";
2147
- var BlockOperationSchema = z10.discriminatedUnion("type", [
2148
- z10.object({
2149
- type: z10.literal("update"),
2150
- blockId: z10.string().describe("The block ID to update (from read_plan output)"),
2151
- content: z10.string().describe("New markdown content for this block")
2201
+ import { z as z11 } from "zod";
2202
+ var BlockOperationSchema = z11.discriminatedUnion("type", [
2203
+ z11.object({
2204
+ type: z11.literal("update"),
2205
+ blockId: z11.string().describe("The block ID to update (from read_plan output)"),
2206
+ content: z11.string().describe("New markdown content for this block")
2152
2207
  }),
2153
- z10.object({
2154
- type: z10.literal("insert"),
2155
- afterBlockId: z10.string().nullable().describe("Insert after this block ID (null = insert at beginning)"),
2156
- content: z10.string().describe("Markdown content to insert as new block(s)")
2208
+ z11.object({
2209
+ type: z11.literal("insert"),
2210
+ afterBlockId: z11.string().nullable().describe("Insert after this block ID (null = insert at beginning)"),
2211
+ content: z11.string().describe("Markdown content to insert as new block(s)")
2157
2212
  }),
2158
- z10.object({
2159
- type: z10.literal("delete"),
2160
- blockId: z10.string().describe("The block ID to delete")
2213
+ z11.object({
2214
+ type: z11.literal("delete"),
2215
+ blockId: z11.string().describe("The block ID to delete")
2161
2216
  }),
2162
- z10.object({
2163
- type: z10.literal("replace_all"),
2164
- content: z10.string().describe("Complete markdown content to replace the entire plan")
2217
+ z11.object({
2218
+ type: z11.literal("replace_all"),
2219
+ content: z11.string().describe("Complete markdown content to replace the entire plan")
2165
2220
  })
2166
2221
  ]);
2167
- var UpdateBlockContentInput = z10.object({
2168
- taskId: z10.string().describe("The task ID to modify"),
2169
- sessionToken: z10.string().describe("Session token from create_task"),
2170
- operations: z10.array(BlockOperationSchema).min(1).describe("Array of operations to perform atomically")
2222
+ var UpdateBlockContentInput = z11.object({
2223
+ taskId: z11.string().describe("The task ID to modify"),
2224
+ sessionToken: z11.string().describe("Session token from create_task"),
2225
+ operations: z11.array(BlockOperationSchema).min(1).describe("Array of operations to perform atomically")
2171
2226
  });
2172
2227
  var updateBlockContentTool = {
2173
2228
  definition: {
@@ -2429,7 +2484,7 @@ async function applyOperation(blocks, operation, editor) {
2429
2484
  // src/tools/update-task.ts
2430
2485
  import { ServerBlockNoteEditor as ServerBlockNoteEditor6 } from "@blocknote/server-util";
2431
2486
  import { nanoid as nanoid3 } from "nanoid";
2432
- import { z as z11 } from "zod";
2487
+ import { z as z12 } from "zod";
2433
2488
  function buildStatusTransition(targetStatus, actorName) {
2434
2489
  const now = Date.now();
2435
2490
  switch (targetStatus) {
@@ -2462,12 +2517,12 @@ function buildStatusTransition(targetStatus, actorName) {
2462
2517
  return null;
2463
2518
  }
2464
2519
  }
2465
- var UpdateTaskInput = z11.object({
2466
- taskId: z11.string().describe("The task ID to update"),
2467
- sessionToken: z11.string().describe("Session token from create_task"),
2468
- title: z11.string().optional().describe("New title"),
2469
- status: z11.enum(["draft", "pending_review", "changes_requested", "in_progress", "completed"]).optional().describe("New status"),
2470
- tags: z11.array(z11.string()).optional().describe("Updated tags (replaces existing tags)")
2520
+ var UpdateTaskInput = z12.object({
2521
+ taskId: z12.string().describe("The task ID to update"),
2522
+ sessionToken: z12.string().describe("Session token from create_task"),
2523
+ title: z12.string().optional().describe("New title"),
2524
+ status: z12.enum(["draft", "pending_review", "changes_requested", "in_progress", "completed"]).optional().describe("New status"),
2525
+ tags: z12.array(z12.string()).optional().describe("Updated tags (replaces existing tags)")
2471
2526
  });
2472
2527
  var updateTaskTool = {
2473
2528
  definition: {
@@ -2622,15 +2677,50 @@ STATUSES:
2622
2677
 
2623
2678
  // src/tools/execute-code.ts
2624
2679
  function getToolResultText(result) {
2680
+ if (!result || !Array.isArray(result.content)) return "";
2625
2681
  const first = result.content[0];
2626
2682
  if (!first || typeof first !== "object") return "";
2627
2683
  const record = Object.fromEntries(Object.entries(first));
2628
2684
  const text = record.text;
2629
2685
  return typeof text === "string" ? text : "";
2630
2686
  }
2687
+ async function serializeError(error) {
2688
+ const { z: z14 } = await import("zod");
2689
+ if (error instanceof z14.ZodError) {
2690
+ const formattedIssues = error.issues.map((issue) => ` - ${issue.path.join(".")}: ${issue.message}`).join("\n");
2691
+ const message2 = `Validation error:
2692
+ ${formattedIssues}`;
2693
+ return {
2694
+ details: { name: "ZodError", message: message2, issues: error.issues, stack: error.stack },
2695
+ message: message2,
2696
+ stack: error.stack
2697
+ };
2698
+ }
2699
+ if (error instanceof Error) {
2700
+ return {
2701
+ details: {
2702
+ name: error.name,
2703
+ message: error.message,
2704
+ stack: error.stack,
2705
+ cause: error.cause instanceof Error ? error.cause.message : error.cause
2706
+ },
2707
+ message: error.message,
2708
+ stack: error.stack
2709
+ };
2710
+ }
2711
+ if (error && typeof error === "object") {
2712
+ const message2 = "message" in error && typeof error.message === "string" ? error.message : JSON.stringify(error).slice(0, 500) || "Unknown error";
2713
+ return {
2714
+ details: { raw: JSON.stringify(error).slice(0, 1e3) },
2715
+ message: message2
2716
+ };
2717
+ }
2718
+ const message = String(error) || "Unknown error";
2719
+ return { details: { raw: message }, message };
2720
+ }
2631
2721
  var BUNDLED_DOCS = `Execute TypeScript code that calls Shipyard APIs. Use this for multi-step workflows to reduce round-trips.
2632
2722
 
2633
- \u26A0\uFE0F IMPORTANT LIMITATION: Dynamic imports (\`await import()\`) are NOT supported in the VM execution context. Use only the pre-provided functions in the execution environment (createTask, readTask, readDiffComments, updateTask, addArtifact, completeTask, updateBlockContent, linkPR, requestUserInput, regenerateSessionToken). All necessary APIs are already available in the sandbox.
2723
+ \u26A0\uFE0F IMPORTANT LIMITATION: Dynamic imports (\`await import()\`) are NOT supported in the VM execution context. Use only the pre-provided functions in the execution environment (createTask, readTask, readDiffComments, updateTask, addArtifact, completeTask, updateBlockContent, linkPR, requestUserInput, regenerateSessionToken, postUpdate). All necessary APIs are already available in the sandbox.
2634
2724
 
2635
2725
  ## Available APIs
2636
2726
 
@@ -3087,6 +3177,40 @@ await addArtifact({
3087
3177
 
3088
3178
  ---
3089
3179
 
3180
+ ### postUpdate(opts): Promise<{ success, isError?, error? }>
3181
+ Post a progress update to the task timeline.
3182
+
3183
+ Use this to communicate status updates to humans watching your work:
3184
+ - "Starting work on authentication module"
3185
+ - "Milestone: API integration complete"
3186
+ - "Found edge case with rate limiting, investigating"
3187
+
3188
+ Updates appear in the Activity tab and keep reviewers informed.
3189
+
3190
+ Parameters:
3191
+ - taskId (string): The task ID
3192
+ - sessionToken (string): Session token from createTask
3193
+ - message (string): Update content (markdown supported)
3194
+
3195
+ Returns:
3196
+ - success: Boolean indicating update was posted (true on success, false on error)
3197
+ - isError: Boolean indicating if an error occurred
3198
+ - error: Error message (only present when isError is true)
3199
+
3200
+ Example:
3201
+ \`\`\`typescript
3202
+ const result = await postUpdate({
3203
+ taskId,
3204
+ sessionToken,
3205
+ message: "Starting work on authentication module"
3206
+ });
3207
+ if (result.isError) {
3208
+ console.log('Failed:', result.error);
3209
+ }
3210
+ \`\`\`
3211
+
3212
+ ---
3213
+
3090
3214
  ## Common Pattern
3091
3215
 
3092
3216
  \`\`\`typescript
@@ -3126,8 +3250,8 @@ const result = await addArtifact({
3126
3250
  return { taskId: task.taskId, snapshotUrl: result.snapshotUrl };
3127
3251
  \`\`\`
3128
3252
  `;
3129
- var ExecuteCodeInput = z12.object({
3130
- code: z12.string().describe("TypeScript code to execute")
3253
+ var ExecuteCodeInput = z13.object({
3254
+ code: z13.string().describe("TypeScript code to execute")
3131
3255
  });
3132
3256
  var scriptTracker = [];
3133
3257
  async function createTask(opts) {
@@ -3423,6 +3547,14 @@ async function regenerateSessionToken(taskId) {
3423
3547
  taskId
3424
3548
  };
3425
3549
  }
3550
+ async function postUpdate(opts) {
3551
+ const result = await postUpdateTool.handler(opts);
3552
+ const text = getToolResultText(result);
3553
+ if (result.isError) {
3554
+ return { isError: true, error: text, success: false };
3555
+ }
3556
+ return { isError: false, success: true };
3557
+ }
3426
3558
  var executeCodeTool = {
3427
3559
  definition: {
3428
3560
  name: TOOL_NAMES.EXECUTE_CODE,
@@ -3484,6 +3616,7 @@ var executeCodeTool = {
3484
3616
  linkPR: linkPR2,
3485
3617
  requestUserInput,
3486
3618
  regenerateSessionToken,
3619
+ postUpdate,
3487
3620
  encodeVideo,
3488
3621
  child_process,
3489
3622
  fs,
@@ -3528,71 +3661,20 @@ The script will exit when the human approves or requests changes.`
3528
3661
  }
3529
3662
  return { content };
3530
3663
  } catch (error) {
3531
- logger.error({ error, code }, "Code execution failed");
3532
- const message = error instanceof Error ? error.message : "Unknown error";
3664
+ const { details, message, stack } = await serializeError(error);
3665
+ logger.error({ error: details, code }, "Code execution failed");
3666
+ const errorText = stack ? `Execution error: ${message}
3667
+
3668
+ Stack trace:
3669
+ ${stack}` : `Execution error: ${message}`;
3533
3670
  return {
3534
- content: [{ type: "text", text: `Execution error: ${message}` }],
3671
+ content: [{ type: "text", text: errorText }],
3535
3672
  isError: true
3536
3673
  };
3537
3674
  }
3538
3675
  }
3539
3676
  };
3540
3677
 
3541
- // src/tools/post-update.ts
3542
- import { z as z13 } from "zod";
3543
- var PostUpdateInput = z13.object({
3544
- taskId: z13.string().describe("The task ID"),
3545
- sessionToken: z13.string().describe("Session token from plan approval"),
3546
- message: z13.string().describe("Update content (markdown)")
3547
- });
3548
- function errorResponse2(message) {
3549
- return { content: [{ type: "text", text: message }], isError: true };
3550
- }
3551
- function successResponse2(message) {
3552
- return { content: [{ type: "text", text: message }] };
3553
- }
3554
- var postUpdateTool = {
3555
- definition: {
3556
- name: TOOL_NAMES.POST_UPDATE,
3557
- description: `Post a progress update to the task timeline.
3558
-
3559
- Use this to communicate status updates to humans watching your work:
3560
- - "Starting work on authentication module"
3561
- - "Milestone: API integration complete"
3562
- - "Found edge case with rate limiting, investigating"
3563
-
3564
- Updates appear in the Activity tab and keep reviewers informed.`,
3565
- inputSchema: {
3566
- type: "object",
3567
- properties: {
3568
- taskId: { type: "string", description: "The task ID" },
3569
- sessionToken: { type: "string", description: "Session token from plan approval" },
3570
- message: { type: "string", description: "Update content (markdown supported)" }
3571
- },
3572
- required: ["taskId", "sessionToken", "message"]
3573
- }
3574
- },
3575
- handler: async (args) => {
3576
- const input = PostUpdateInput.parse(args);
3577
- const { taskId, sessionToken, message } = input;
3578
- const doc = await getOrCreateDoc(taskId);
3579
- const metadata = getPlanMetadata(doc);
3580
- if (!metadata) {
3581
- return errorResponse2(`Task "${taskId}" not found.`);
3582
- }
3583
- if (!metadata.sessionTokenHash || !verifySessionToken(sessionToken, metadata.sessionTokenHash)) {
3584
- return errorResponse2(`Invalid session token for task "${taskId}".`);
3585
- }
3586
- const actorName = await getGitHubUsername();
3587
- const eventId = logPlanEvent(doc, "agent_activity", actorName, {
3588
- activityType: "update",
3589
- message
3590
- });
3591
- logger.info({ taskId, eventId, messageLength: message.length }, "Agent update posted");
3592
- return successResponse2(`Update posted to task "${taskId}".`);
3593
- }
3594
- };
3595
-
3596
3678
  // src/index.ts
3597
3679
  var registryPort = await isRegistryRunning();
3598
3680
  if (!registryPort) {
@@ -3637,19 +3719,13 @@ var server = new Server(
3637
3719
  }
3638
3720
  );
3639
3721
  server.setRequestHandler(ListToolsRequestSchema, async () => ({
3640
- tools: [executeCodeTool.definition, postUpdateTool.definition, readDiffCommentsTool.definition]
3722
+ tools: [executeCodeTool.definition]
3641
3723
  }));
3642
3724
  server.setRequestHandler(CallToolRequestSchema, async (request) => {
3643
3725
  const { name, arguments: args } = request.params;
3644
3726
  if (name === TOOL_NAMES.EXECUTE_CODE) {
3645
3727
  return await executeCodeTool.handler(args ?? {});
3646
3728
  }
3647
- if (name === TOOL_NAMES.POST_UPDATE) {
3648
- return await postUpdateTool.handler(args ?? {});
3649
- }
3650
- if (name === TOOL_NAMES.READ_DIFF_COMMENTS) {
3651
- return await readDiffCommentsTool.handler(args ?? {});
3652
- }
3653
3729
  throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${name}`);
3654
3730
  });
3655
3731
  var transport = new StdioServerTransport();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@schoolai/shipyard-mcp",
3
- "version": "0.4.0",
3
+ "version": "0.4.1-nightly.20260127",
4
4
  "description": "Shipyard MCP server and CLI tools for distributed planning with CRDTs",
5
5
  "type": "module",
6
6
  "bin": {