@arii/boomtick-mcp 0.6.2 → 0.7.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.
Files changed (109) hide show
  1. package/.mcp/schemas/boomtick.health.json +22 -3
  2. package/.mcp/schemas/boomtick_health.json +22 -3
  3. package/.mcp/schemas/github.checkout_branch.json +16 -3
  4. package/.mcp/schemas/github.comment_triage_summary.json +16 -3
  5. package/.mcp/schemas/github.create_pull_request.json +16 -3
  6. package/.mcp/schemas/github.get_merge_conflict_files.json +55 -5
  7. package/.mcp/schemas/github.get_pr.json +12 -3
  8. package/.mcp/schemas/github.get_pr_commits.json +12 -3
  9. package/.mcp/schemas/github.get_pr_reviews.json +24 -3
  10. package/.mcp/schemas/github.issue_comment.json +19 -3
  11. package/.mcp/schemas/github.issue_view.json +17 -3
  12. package/.mcp/schemas/github.open_replacement_pr.json +16 -3
  13. package/.mcp/schemas/github_checkout_branch.json +16 -3
  14. package/.mcp/schemas/github_comment_triage_summary.json +16 -3
  15. package/.mcp/schemas/github_create_pull_request.json +16 -3
  16. package/.mcp/schemas/github_get_merge_conflict_files.json +55 -5
  17. package/.mcp/schemas/github_get_pr.json +12 -3
  18. package/.mcp/schemas/github_get_pr_commits.json +12 -3
  19. package/.mcp/schemas/github_get_pr_reviews.json +24 -3
  20. package/.mcp/schemas/github_issue_comment.json +19 -3
  21. package/.mcp/schemas/github_issue_view.json +17 -3
  22. package/.mcp/schemas/github_open_replacement_pr.json +16 -3
  23. package/.mcp/schemas/jules.cancel_session.json +38 -3
  24. package/.mcp/schemas/jules.create_session.json +52 -3
  25. package/.mcp/schemas/jules.get_messages.json +19 -3
  26. package/.mcp/schemas/jules.get_pr.json +23 -3
  27. package/.mcp/schemas/jules.get_session.json +38 -3
  28. package/.mcp/schemas/jules.list_sessions.json +53 -3
  29. package/.mcp/schemas/jules.send_message.json +31 -3
  30. package/.mcp/schemas/jules.trigger_feedback.json +28 -3
  31. package/.mcp/schemas/jules_cancel_session.json +38 -3
  32. package/.mcp/schemas/jules_create_session.json +52 -3
  33. package/.mcp/schemas/jules_get_messages.json +19 -3
  34. package/.mcp/schemas/jules_get_pr.json +23 -3
  35. package/.mcp/schemas/jules_get_session.json +38 -3
  36. package/.mcp/schemas/jules_list_sessions.json +53 -3
  37. package/.mcp/schemas/jules_send_message.json +31 -3
  38. package/.mcp/schemas/jules_trigger_feedback.json +28 -3
  39. package/.mcp/schemas/repo.check_jules_status.json +93 -3
  40. package/.mcp/schemas/repo.commit_patch.json +23 -3
  41. package/.mcp/schemas/repo.create_branch.json +91 -3
  42. package/.mcp/schemas/repo.create_repair_branch.json +94 -3
  43. package/.mcp/schemas/repo.get_changed_files.json +50 -3
  44. package/.mcp/schemas/repo.get_command_schema.json +29 -3
  45. package/.mcp/schemas/repo.get_package_scripts.json +11 -3
  46. package/.mcp/schemas/repo.get_workflow_runs.json +12 -3
  47. package/.mcp/schemas/repo.logs.json +14 -3
  48. package/.mcp/schemas/repo.multi_exec.json +89 -0
  49. package/.mcp/schemas/repo.read_agent_context.json +117 -5
  50. package/.mcp/schemas/repo.read_ci_logs.json +46 -3
  51. package/.mcp/schemas/repo_check_jules_status.json +93 -3
  52. package/.mcp/schemas/repo_commit_patch.json +23 -3
  53. package/.mcp/schemas/repo_create_branch.json +91 -3
  54. package/.mcp/schemas/repo_create_repair_branch.json +94 -3
  55. package/.mcp/schemas/repo_get_changed_files.json +50 -3
  56. package/.mcp/schemas/repo_get_command_schema.json +29 -3
  57. package/.mcp/schemas/repo_get_package_scripts.json +11 -3
  58. package/.mcp/schemas/repo_get_workflow_runs.json +12 -3
  59. package/.mcp/schemas/repo_logs.json +14 -3
  60. package/.mcp/schemas/repo_multi_exec.json +89 -0
  61. package/.mcp/schemas/repo_read_agent_context.json +117 -5
  62. package/.mcp/schemas/repo_read_ci_logs.json +46 -3
  63. package/CHANGELOG.md +22 -0
  64. package/README.md +7 -5
  65. package/dist/config/dynamic.js +3 -2
  66. package/dist/config/repo.js +5 -5
  67. package/dist/config.test.js +10 -3
  68. package/dist/lib/git.js +78 -6
  69. package/dist/lib/git.test.js +34 -1
  70. package/dist/mcp/definitions.js +49 -36
  71. package/dist/mcp/http.js +15 -0
  72. package/dist/mcp/http.test.js +8 -0
  73. package/dist/mcp/server.js +34 -0
  74. package/dist/mcp/server.test.js +31 -0
  75. package/dist/tools/contract.js +1264 -92
  76. package/dist/tools/github.get_merge_conflict_files.js +10 -2
  77. package/dist/tools/jules/create-session.js +12 -2
  78. package/dist/tools/jules/create-session.test.js +7 -0
  79. package/dist/tools/repo.create_branch.js +18 -4
  80. package/dist/tools/repo.create_branch.test.js +41 -5
  81. package/dist/tools/repo.create_repair_branch.js +26 -9
  82. package/dist/tools/repo.get_changed_files.js +10 -2
  83. package/dist/tools/repo.multi_exec.js +21 -0
  84. package/dist/tools/repo.multi_exec.test.js +13 -0
  85. package/dist/tools/repo.read_agent_context.js +65 -3
  86. package/dist/tools/repo.read_agent_context.test.js +30 -1
  87. package/package.json +1 -1
  88. package/src/config/dynamic.ts +3 -2
  89. package/src/config/repo.ts +6 -6
  90. package/src/config.test.ts +11 -3
  91. package/src/lib/git.test.ts +45 -1
  92. package/src/lib/git.ts +94 -6
  93. package/src/mcp/definitions.ts +77 -36
  94. package/src/mcp/http.test.ts +10 -0
  95. package/src/mcp/http.ts +20 -0
  96. package/src/mcp/server.test.ts +38 -0
  97. package/src/mcp/server.ts +36 -0
  98. package/src/tools/contract.ts +1355 -67
  99. package/src/tools/github.get_merge_conflict_files.ts +11 -2
  100. package/src/tools/jules/create-session.test.ts +9 -0
  101. package/src/tools/jules/create-session.ts +13 -2
  102. package/src/tools/repo.create_branch.test.ts +73 -5
  103. package/src/tools/repo.create_branch.ts +30 -4
  104. package/src/tools/repo.create_repair_branch.ts +31 -9
  105. package/src/tools/repo.get_changed_files.ts +10 -2
  106. package/src/tools/repo.multi_exec.test.ts +15 -0
  107. package/src/tools/repo.multi_exec.ts +23 -0
  108. package/src/tools/repo.read_agent_context.test.ts +35 -1
  109. package/src/tools/repo.read_agent_context.ts +68 -3
@@ -1,4 +1,4 @@
1
- import { HealthCheckInputJsonSchema, SearchPRsInputJsonSchema, SearchPRsResponseJsonSchema, GetPrDiffInputJsonSchema, PrDiffResponseJsonSchema, CheckoutBranchInputJsonSchema, GetMergeConflictFilesInputJsonSchema, GetMergeConflictFilesResponseJsonSchema, GetChangedFilesInputJsonSchema, GetPackageScriptsInputJsonSchema, ReadCiLogsInputJsonSchema, RepoLogsInputJsonSchema, CreateBranchInputJsonSchema, CreateRepairBranchInputJsonSchema, RunTestsInputJsonSchema, RunTestsResponseJsonSchema, CommitPatchInputJsonSchema, OpenReplacementPrInputJsonSchema, CreatePullRequestInputJsonSchema, CommentTriageSummaryInputJsonSchema, GetPrInputJsonSchema, IssueViewInputJsonSchema, IssueUpdateInputJsonSchema, IssueUpdateResponseJsonSchema, IssueCommentInputJsonSchema, CreateIssueInputJsonSchema, CreateIssueResponseJsonSchema, GetCommandSchemaInputJsonSchema, ReadAgentContextInputJsonSchema as ReadAgentContextSchema, CreateJulesSessionInputJsonSchema, JulesSessionIdInputJsonSchema, JulesSendMessageInputJsonSchema, JulesListSessionsInputJsonSchema, GetPrReviewsInputJsonSchema, GetPrCommitsInputJsonSchema, GetWorkflowRunsInputJsonSchema, } from "../tools/contract.js";
1
+ import { HealthCheckInputJsonSchema, HealthCheckResponseJsonSchema, SearchPRsInputJsonSchema, SearchPRsResponseJsonSchema, GetPrDiffInputJsonSchema, PrDiffResponseJsonSchema, CheckoutBranchInputJsonSchema, CheckoutBranchResponseJsonSchema, GetMergeConflictFilesInputJsonSchema, GetMergeConflictFilesResponseJsonSchema, GetChangedFilesInputJsonSchema, GetChangedFilesResponseJsonSchema, GetPackageScriptsInputJsonSchema, GetPackageScriptsResponseJsonSchema, ReadCiLogsInputJsonSchema, ReadCiLogsResponseJsonSchema, RepoLogsInputJsonSchema, RepoLogsResponseJsonSchema, CreateBranchInputJsonSchema, CreateBranchResponseJsonSchema, CreateRepairBranchInputJsonSchema, CreateRepairBranchResponseJsonSchema, CheckJulesStatusResponseJsonSchema, RunTestsInputJsonSchema, RunTestsResponseJsonSchema, CommitPatchInputJsonSchema, CommitPatchResponseJsonSchema, OpenReplacementPrInputJsonSchema, OpenReplacementPrResponseJsonSchema, CreatePullRequestInputJsonSchema, CreatePullRequestResponseJsonSchema, CommentTriageSummaryInputJsonSchema, CommentTriageSummaryResponseJsonSchema, GetPrInputJsonSchema, GetPrResponseJsonSchema, IssueViewInputJsonSchema, IssueViewResponseJsonSchema, IssueUpdateInputJsonSchema, IssueUpdateResponseJsonSchema, IssueCommentInputJsonSchema, IssueCommentResponseJsonSchema, CreateIssueInputJsonSchema, CreateIssueResponseJsonSchema, GetCommandSchemaInputJsonSchema, GetCommandSchemaResponseJsonSchema, ReadAgentContextInputJsonSchema as ReadAgentContextSchema, ReadAgentContextResponseJsonSchema, MultiExecInputJsonSchema, MultiExecResponseJsonSchema, CreateJulesSessionInputJsonSchema, JulesSessionIdInputJsonSchema, JulesSendMessageInputJsonSchema, JulesSendMessageResponseJsonSchema, JulesGetMessagesResponseJsonSchema, JulesListSessionsInputJsonSchema, JulesListSessionsResponseJsonSchema, JulesSessionResponseJsonSchema, JulesGetPrResponseJsonSchema, JulesTriggerFeedbackResponseJsonSchema, GetPrReviewsInputJsonSchema, GetPrReviewsResponseJsonSchema, GetPrCommitsInputJsonSchema, GetPrCommitsResponseJsonSchema, GetWorkflowRunsInputJsonSchema, GetWorkflowRunsResponseJsonSchema, } from "../tools/contract.js";
2
2
  export const MCP_PROMPTS = [
3
3
  {
4
4
  name: "conflict-scout",
@@ -38,12 +38,24 @@ export const MCP_RESOURCES = [
38
38
  mimeType: "text/markdown",
39
39
  description: "The agent contract specification file (.agents/AGENT_CONTRACT.md).",
40
40
  },
41
+ {
42
+ uri: "mcp://workspace/project-config",
43
+ name: "Project Configuration",
44
+ mimeType: "application/json",
45
+ description: "The project configuration (project_config.json).",
46
+ },
41
47
  {
42
48
  uri: "mcp://git/changed-files",
43
49
  name: "Git Changed Files",
44
50
  mimeType: "application/json",
45
51
  description: "List of changed files in the repository.",
46
52
  },
53
+ {
54
+ uri: "mcp://git/status",
55
+ name: "Git Status",
56
+ mimeType: "application/json",
57
+ description: "Current working directory git status.",
58
+ },
47
59
  {
48
60
  uri: "mcp://ci/latest-run",
49
61
  name: "Latest CI Run",
@@ -83,17 +95,12 @@ export const MCP_RESOURCE_TEMPLATES = [
83
95
  description: "The validation report for a specific repair branch.",
84
96
  },
85
97
  ];
86
- const DEFAULT_OUTPUT_SCHEMA = {
87
- type: "object",
88
- properties: {},
89
- additionalProperties: true,
90
- };
91
98
  const BASE_MCP_TOOLS = [
92
99
  {
93
100
  name: "boomtick.health",
94
101
  description: "Check the health and configuration of the MCP server.",
95
102
  inputSchema: HealthCheckInputJsonSchema,
96
- outputSchema: DEFAULT_OUTPUT_SCHEMA,
103
+ outputSchema: HealthCheckResponseJsonSchema,
97
104
  },
98
105
  {
99
106
  name: "github.search_open_prs",
@@ -103,9 +110,15 @@ const BASE_MCP_TOOLS = [
103
110
  },
104
111
  {
105
112
  name: "repo.read_agent_context",
106
- description: "Read the full repository index including file tree, CLI schema, and MCP tools.",
113
+ description: "Read the repository index including metadata, model review chains, or multi-repo ecosystem status.",
107
114
  inputSchema: ReadAgentContextSchema,
108
- outputSchema: DEFAULT_OUTPUT_SCHEMA,
115
+ outputSchema: ReadAgentContextResponseJsonSchema,
116
+ },
117
+ {
118
+ name: "repo.multi_exec",
119
+ description: "Execute a shell command sequentially across ecosystem repositories (or a filtered subset).",
120
+ inputSchema: MultiExecInputJsonSchema,
121
+ outputSchema: MultiExecResponseJsonSchema,
109
122
  },
110
123
  {
111
124
  name: "github.get_pr_diff",
@@ -117,7 +130,7 @@ const BASE_MCP_TOOLS = [
117
130
  name: "github.checkout_branch",
118
131
  description: "Checkout a specific branch in the repository or worktree.",
119
132
  inputSchema: CheckoutBranchInputJsonSchema,
120
- outputSchema: DEFAULT_OUTPUT_SCHEMA,
133
+ outputSchema: CheckoutBranchResponseJsonSchema,
121
134
  },
122
135
  {
123
136
  name: "github.get_merge_conflict_files",
@@ -129,43 +142,43 @@ const BASE_MCP_TOOLS = [
129
142
  name: "repo.get_changed_files",
130
143
  description: "Get the list of changed files between two refs.",
131
144
  inputSchema: GetChangedFilesInputJsonSchema,
132
- outputSchema: DEFAULT_OUTPUT_SCHEMA,
145
+ outputSchema: GetChangedFilesResponseJsonSchema,
133
146
  },
134
147
  {
135
148
  name: "repo.get_command_schema",
136
149
  description: "Retrieve a lightweight, targeted schema for a specific td subcommand. Use this instead of reading the entire cli-schema.json to save tokens.",
137
150
  inputSchema: GetCommandSchemaInputJsonSchema,
138
- outputSchema: DEFAULT_OUTPUT_SCHEMA,
151
+ outputSchema: GetCommandSchemaResponseJsonSchema,
139
152
  },
140
153
  {
141
154
  name: "repo.get_package_scripts",
142
155
  description: "Get the scripts defined in package.json.",
143
156
  inputSchema: GetPackageScriptsInputJsonSchema,
144
- outputSchema: DEFAULT_OUTPUT_SCHEMA,
157
+ outputSchema: GetPackageScriptsResponseJsonSchema,
145
158
  },
146
159
  {
147
160
  name: "repo.read_ci_logs",
148
161
  description: "Read CI logs for a given pull request.",
149
162
  inputSchema: ReadCiLogsInputJsonSchema,
150
- outputSchema: DEFAULT_OUTPUT_SCHEMA,
163
+ outputSchema: ReadCiLogsResponseJsonSchema,
151
164
  },
152
165
  {
153
166
  name: "repo.logs",
154
167
  description: "Stream or grep combined CI logs for all jobs in a pull request.",
155
168
  inputSchema: RepoLogsInputJsonSchema,
156
- outputSchema: DEFAULT_OUTPUT_SCHEMA,
169
+ outputSchema: RepoLogsResponseJsonSchema,
157
170
  },
158
171
  {
159
172
  name: "repo.create_branch",
160
173
  description: "Creates a new clean git branch from a target base branch.",
161
174
  inputSchema: CreateBranchInputJsonSchema,
162
- outputSchema: DEFAULT_OUTPUT_SCHEMA,
175
+ outputSchema: CreateBranchResponseJsonSchema,
163
176
  },
164
177
  {
165
178
  name: "repo.create_repair_branch",
166
179
  description: "Creates a fresh worktree and a new repair branch for an existing PR. This isolates the repair work from the main codebase.",
167
180
  inputSchema: CreateRepairBranchInputJsonSchema,
168
- outputSchema: DEFAULT_OUTPUT_SCHEMA,
181
+ outputSchema: CreateRepairBranchResponseJsonSchema,
169
182
  },
170
183
  {
171
184
  name: "repo.check_jules_status",
@@ -181,7 +194,7 @@ const BASE_MCP_TOOLS = [
181
194
  intervalMs: { type: "integer", description: "Polling interval in milliseconds." },
182
195
  },
183
196
  },
184
- outputSchema: DEFAULT_OUTPUT_SCHEMA,
197
+ outputSchema: CheckJulesStatusResponseJsonSchema,
185
198
  },
186
199
  {
187
200
  name: "repo.run_tests",
@@ -193,55 +206,55 @@ const BASE_MCP_TOOLS = [
193
206
  name: "repo.commit_patch",
194
207
  description: "Commit verified repair changes in a worktree.",
195
208
  inputSchema: CommitPatchInputJsonSchema,
196
- outputSchema: DEFAULT_OUTPUT_SCHEMA,
209
+ outputSchema: CommitPatchResponseJsonSchema,
197
210
  },
198
211
  {
199
212
  name: "github.open_replacement_pr",
200
213
  description: "Open a new PR that replaces or repairs the original PR.",
201
214
  inputSchema: OpenReplacementPrInputJsonSchema,
202
- outputSchema: DEFAULT_OUTPUT_SCHEMA,
215
+ outputSchema: OpenReplacementPrResponseJsonSchema,
203
216
  },
204
217
  {
205
218
  name: "github.create_pull_request",
206
219
  description: "Creates a pull request on GitHub using the MCP server's integrated credentials. Bypasses terminal CLI constraints.",
207
220
  inputSchema: CreatePullRequestInputJsonSchema,
208
- outputSchema: DEFAULT_OUTPUT_SCHEMA,
221
+ outputSchema: CreatePullRequestResponseJsonSchema,
209
222
  },
210
223
  {
211
224
  name: "github.comment_triage_summary",
212
225
  description: "Comment on the original PR with a diagnosis and replacement link.",
213
226
  inputSchema: CommentTriageSummaryInputJsonSchema,
214
- outputSchema: DEFAULT_OUTPUT_SCHEMA,
227
+ outputSchema: CommentTriageSummaryResponseJsonSchema,
215
228
  },
216
229
  {
217
230
  name: "github.get_pr",
218
231
  description: "Get details of a GitHub PR including title, state, and URLs.",
219
232
  inputSchema: GetPrInputJsonSchema,
220
- outputSchema: DEFAULT_OUTPUT_SCHEMA,
233
+ outputSchema: GetPrResponseJsonSchema,
221
234
  },
222
235
  {
223
236
  name: "github.get_pr_reviews",
224
237
  description: "Get top-level reviews, verdicts, states, and bodies for a GitHub PR.",
225
238
  inputSchema: GetPrReviewsInputJsonSchema,
226
- outputSchema: DEFAULT_OUTPUT_SCHEMA,
239
+ outputSchema: GetPrReviewsResponseJsonSchema,
227
240
  },
228
241
  {
229
242
  name: "github.get_pr_commits",
230
243
  description: "List commits and commit metadata (SHAs, authors, messages) for a GitHub PR.",
231
244
  inputSchema: GetPrCommitsInputJsonSchema,
232
- outputSchema: DEFAULT_OUTPUT_SCHEMA,
245
+ outputSchema: GetPrCommitsResponseJsonSchema,
233
246
  },
234
247
  {
235
248
  name: "repo.get_workflow_runs",
236
249
  description: "List recent GitHub Actions workflow runs for the repository.",
237
250
  inputSchema: GetWorkflowRunsInputJsonSchema,
238
- outputSchema: DEFAULT_OUTPUT_SCHEMA,
251
+ outputSchema: GetWorkflowRunsResponseJsonSchema,
239
252
  },
240
253
  {
241
254
  name: "github.issue_view",
242
255
  description: "View details of a GitHub issue including title, body, and state.",
243
256
  inputSchema: IssueViewInputJsonSchema,
244
- outputSchema: DEFAULT_OUTPUT_SCHEMA,
257
+ outputSchema: IssueViewResponseJsonSchema,
245
258
  },
246
259
  {
247
260
  name: "github.issue_update",
@@ -253,7 +266,7 @@ const BASE_MCP_TOOLS = [
253
266
  name: "github.issue_comment",
254
267
  description: "Add a new comment to a GitHub issue.",
255
268
  inputSchema: IssueCommentInputJsonSchema,
256
- outputSchema: DEFAULT_OUTPUT_SCHEMA,
269
+ outputSchema: IssueCommentResponseJsonSchema,
257
270
  },
258
271
  {
259
272
  name: "github.create_issue",
@@ -265,49 +278,49 @@ const BASE_MCP_TOOLS = [
265
278
  name: "jules.create_session",
266
279
  description: "Create a Jules session that performs work externally and may generate a GitHub pull request.",
267
280
  inputSchema: CreateJulesSessionInputJsonSchema,
268
- outputSchema: DEFAULT_OUTPUT_SCHEMA,
281
+ outputSchema: JulesSessionResponseJsonSchema,
269
282
  },
270
283
  {
271
284
  name: "jules.get_session",
272
285
  description: "Get the status and details of a Jules session.",
273
286
  inputSchema: JulesSessionIdInputJsonSchema,
274
- outputSchema: DEFAULT_OUTPUT_SCHEMA,
287
+ outputSchema: JulesSessionResponseJsonSchema,
275
288
  },
276
289
  {
277
290
  name: "jules.send_message",
278
291
  description: "Send a message to an active Jules session.",
279
292
  inputSchema: JulesSendMessageInputJsonSchema,
280
- outputSchema: DEFAULT_OUTPUT_SCHEMA,
293
+ outputSchema: JulesSendMessageResponseJsonSchema,
281
294
  },
282
295
  {
283
296
  name: "jules.get_messages",
284
297
  description: "Get the message history of a Jules session.",
285
298
  inputSchema: JulesSessionIdInputJsonSchema,
286
- outputSchema: DEFAULT_OUTPUT_SCHEMA,
299
+ outputSchema: JulesGetMessagesResponseJsonSchema,
287
300
  },
288
301
  {
289
302
  name: "jules.list_sessions",
290
303
  description: "List all Jules sessions.",
291
304
  inputSchema: JulesListSessionsInputJsonSchema,
292
- outputSchema: DEFAULT_OUTPUT_SCHEMA,
305
+ outputSchema: JulesListSessionsResponseJsonSchema,
293
306
  },
294
307
  {
295
308
  name: "jules.cancel_session",
296
309
  description: "Cancel an ongoing Jules session.",
297
310
  inputSchema: JulesSessionIdInputJsonSchema,
298
- outputSchema: DEFAULT_OUTPUT_SCHEMA,
311
+ outputSchema: JulesSessionResponseJsonSchema,
299
312
  },
300
313
  {
301
314
  name: "jules.get_pr",
302
315
  description: "Get the generated pull request url associated with an active Jules agent session.",
303
316
  inputSchema: JulesSessionIdInputJsonSchema,
304
- outputSchema: DEFAULT_OUTPUT_SCHEMA,
317
+ outputSchema: JulesGetPrResponseJsonSchema,
305
318
  },
306
319
  {
307
320
  name: "jules.trigger_feedback",
308
321
  description: "Automatically collect CI status/logs for the PR associated with a Jules session and send them back as feedback.",
309
322
  inputSchema: JulesSessionIdInputJsonSchema,
310
- outputSchema: DEFAULT_OUTPUT_SCHEMA,
323
+ outputSchema: JulesTriggerFeedbackResponseJsonSchema,
311
324
  },
312
325
  ];
313
326
  export const MCP_TOOLS = BASE_MCP_TOOLS.flatMap((tool) => {
package/dist/mcp/http.js CHANGED
@@ -15,6 +15,12 @@ export function createMcpHttpServer(options) {
15
15
  return;
16
16
  }
17
17
  const url = new URL(req.url || "/", `http://${req.headers.host || "localhost"}`);
18
+ // Endpoint 0: Health check endpoint for readiness probes / load balancers
19
+ if (url.pathname === "/health" && req.method === "GET") {
20
+ res.writeHead(200, { "Content-Type": "application/json" });
21
+ res.end(JSON.stringify({ status: "ok", transport: "http" }));
22
+ return;
23
+ }
18
24
  // Endpoint 1: RFC 9728 OAuth Protected Resource Metadata Discovery
19
25
  if (url.pathname === "/.well-known/oauth-protected-resource" && (req.method === "GET" || req.method === "HEAD")) {
20
26
  const metadata = {
@@ -60,9 +66,18 @@ export function createMcpHttpServer(options) {
60
66
  }
61
67
  // Endpoint 2: SSE stream setup
62
68
  if (url.pathname === "/sse" && req.method === "GET") {
69
+ res.setHeader("Cache-Control", "no-cache");
70
+ res.setHeader("Content-Type", "text/event-stream");
71
+ res.setHeader("Connection", "keep-alive");
63
72
  const transport = new SSEServerTransport("/messages", res);
64
73
  transports.set(transport.sessionId, transport);
74
+ const keepAliveInterval = setInterval(() => {
75
+ if (!res.writableEnded) {
76
+ res.write(": keep-alive\n\n");
77
+ }
78
+ }, 15000);
65
79
  transport.onclose = () => {
80
+ clearInterval(keepAliveInterval);
66
81
  transports.delete(transport.sessionId);
67
82
  };
68
83
  await mcpServer.connect(transport);
@@ -14,6 +14,14 @@ describe("createMcpHttpServer", () => {
14
14
  httpServerObj.server.close();
15
15
  }
16
16
  });
17
+ it("should respond with 200 on GET /health endpoint", async () => {
18
+ httpServerObj = createMcpHttpServer({ port: 0, mcpServer });
19
+ port = await httpServerObj.listen(0);
20
+ const res = await fetch(`http://localhost:${port}/health`);
21
+ expect(res.status).toBe(200);
22
+ const body = await res.json();
23
+ expect(body).toEqual({ status: "ok", transport: "http" });
24
+ });
17
25
  it("should respond with RFC 9728 OAuth protected resource metadata on /.well-known/oauth-protected-resource", async () => {
18
26
  httpServerObj = createMcpHttpServer({ port: 0, mcpServer });
19
27
  port = await httpServerObj.listen(0);
@@ -12,6 +12,7 @@ import { getMergeConflictFilesHandler, GetMergeConflictFilesInputSchema } from "
12
12
  import { checkoutBranchHandler, CheckoutBranchInputSchema } from "../tools/github.checkout_branch.js";
13
13
  import { getChangedFilesHandler, GetChangedFilesInputSchema } from "../tools/repo.get_changed_files.js";
14
14
  import { readAgentContextHandler, ReadAgentContextInputSchema } from "../tools/repo.read_agent_context.js";
15
+ import { multiExecHandler, MultiExecInputSchema } from "../tools/repo.multi_exec.js";
15
16
  import { getCommandSchemaHandler, GetCommandSchemaInputSchema } from "../tools/repo.get_command_schema.js";
16
17
  import { getPackageScriptsHandler, GetPackageScriptsInputSchema } from "../tools/repo.get_package_scripts.js";
17
18
  import { readCiLogsHandler, ReadCiLogsInputSchema } from "../tools/repo.read_ci_logs.js";
@@ -114,6 +115,21 @@ export class BoomtickMCPServer {
114
115
  contents: [{ uri, mimeType: "text/markdown", text: content }],
115
116
  };
116
117
  }
118
+ if (uri === "mcp://workspace/project-config" ||
119
+ uri === "mcp://workspace/project_config" ||
120
+ uri === "repo://project-config") {
121
+ const configPath = path.join(config.repoPath, "project_config.json");
122
+ let content = "{}";
123
+ try {
124
+ content = await fs.readFile(configPath, "utf-8");
125
+ }
126
+ catch {
127
+ // Fallback if file doesn't exist
128
+ }
129
+ return {
130
+ contents: [{ uri, mimeType: "application/json", text: content }],
131
+ };
132
+ }
117
133
  if (uri === "mcp://git/changed-files" ||
118
134
  uri === "repo://changed-files") {
119
135
  const changedFiles = await getChangedFilesHandler(GetChangedFilesInputSchema.parse({}));
@@ -121,6 +137,21 @@ export class BoomtickMCPServer {
121
137
  contents: [{ uri, mimeType: "application/json", text: JSON.stringify(changedFiles, null, 2) }],
122
138
  };
123
139
  }
140
+ if (uri === "mcp://git/status" ||
141
+ uri === "repo://git-status" ||
142
+ uri === "repo://status") {
143
+ let statusText = "";
144
+ try {
145
+ const res = spawnSync("git", ["status", "--porcelain"], { cwd: config.repoPath, encoding: "utf-8" });
146
+ statusText = res.stdout || "";
147
+ }
148
+ catch {
149
+ // Fallback if git fails
150
+ }
151
+ return {
152
+ contents: [{ uri, mimeType: "application/json", text: JSON.stringify({ status: statusText.trim() }, null, 2) }],
153
+ };
154
+ }
124
155
  if (uri === "mcp://ci/latest-run" ||
125
156
  uri === "repo://ci/latest-run" ||
126
157
  uri === "repo://ci-latest-run") {
@@ -178,6 +209,9 @@ export class BoomtickMCPServer {
178
209
  case "repo.read.agent.context":
179
210
  case "repo.read_agent_context":
180
211
  return createSuccessResult(await readAgentContextHandler(ReadAgentContextInputSchema.parse(normArgs)));
212
+ case "repo.multi.exec":
213
+ case "repo.multi_exec":
214
+ return createSuccessResult(await multiExecHandler(MultiExecInputSchema.parse(normArgs)));
181
215
  case "github.get.pr.diff":
182
216
  case "github.get_pr_diff":
183
217
  return createSuccessResult(await getPrDiffHandler(GetPrDiffInputSchema.parse(normArgs)));
@@ -166,6 +166,27 @@ describe("BoomtickMCPServer", () => {
166
166
  expect(result.contents[0].mimeType).toBe("application/json");
167
167
  expect(JSON.parse(result.contents[0].text)).toEqual({ files: ["src/index.ts"] });
168
168
  });
169
+ it("should handle mcp://workspace/project-config", async () => {
170
+ const handler = requestHandlers.get("resources/read");
171
+ vi.mocked(fs.readFile).mockResolvedValue('{"packageName": "boomtick"}');
172
+ const result = await handler({
173
+ method: "resources/read",
174
+ params: { uri: "mcp://workspace/project-config" },
175
+ });
176
+ expect(result.contents[0].uri).toBe("mcp://workspace/project-config");
177
+ expect(result.contents[0].mimeType).toBe("application/json");
178
+ expect(JSON.parse(result.contents[0].text)).toEqual({ packageName: "boomtick" });
179
+ });
180
+ it("should handle mcp://git/status", async () => {
181
+ const handler = requestHandlers.get("resources/read");
182
+ const result = await handler({
183
+ method: "resources/read",
184
+ params: { uri: "mcp://git/status" },
185
+ });
186
+ expect(result.contents[0].uri).toBe("mcp://git/status");
187
+ expect(result.contents[0].mimeType).toBe("application/json");
188
+ expect(JSON.parse(result.contents[0].text)).toHaveProperty("status");
189
+ });
169
190
  it("should handle mcp://ci/latest-run", async () => {
170
191
  const handler = requestHandlers.get("resources/read");
171
192
  vi.spyOn(workflowRunsModule, "getWorkflowRunsHandler").mockResolvedValue({ workflowRuns: [{ id: 1, status: "completed", conclusion: "success" }] });
@@ -193,6 +214,16 @@ describe("BoomtickMCPServer", () => {
193
214
  expect(result.tools).toBeDefined();
194
215
  expect(Array.isArray(result.tools)).toBe(true);
195
216
  });
217
+ it("should ensure all tools have typed outputSchema and none are empty or untyped DEFAULT_OUTPUT_SCHEMA", async () => {
218
+ const handler = requestHandlers.get("tools/list");
219
+ const result = await handler({ method: "tools/list" });
220
+ for (const tool of result.tools) {
221
+ expect(tool.outputSchema).toBeDefined();
222
+ expect(tool.outputSchema.type).toBe("object");
223
+ expect(tool.outputSchema.properties).toBeDefined();
224
+ expect(Object.keys(tool.outputSchema.properties).length).toBeGreaterThan(0);
225
+ }
226
+ });
196
227
  });
197
228
  describe("CallTool", () => {
198
229
  it("should execute registered tool handler successfully", async () => {