@arii/boomtick-mcp 0.3.3
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/.env.example +6 -0
- package/.mcp/schemas/agent.search_ddgs.json +1 -0
- package/.mcp/schemas/boomtick.health.json +1 -0
- package/.mcp/schemas/github.checkout_branch.json +1 -0
- package/.mcp/schemas/github.comment_triage_summary.json +1 -0
- package/.mcp/schemas/github.create_issue.json +1 -0
- package/.mcp/schemas/github.create_pull_request.json +1 -0
- package/.mcp/schemas/github.get_merge_conflict_files.json +1 -0
- package/.mcp/schemas/github.get_pr.json +1 -0
- package/.mcp/schemas/github.get_pr_diff.json +1 -0
- package/.mcp/schemas/github.issue_comment.json +1 -0
- package/.mcp/schemas/github.issue_update.json +1 -0
- package/.mcp/schemas/github.issue_view.json +1 -0
- package/.mcp/schemas/github.open_replacement_pr.json +1 -0
- package/.mcp/schemas/github.search_open_prs.json +1 -0
- package/.mcp/schemas/jules.cancel_session.json +1 -0
- package/.mcp/schemas/jules.create_session.json +1 -0
- package/.mcp/schemas/jules.get_messages.json +1 -0
- package/.mcp/schemas/jules.get_pr.json +1 -0
- package/.mcp/schemas/jules.get_session.json +1 -0
- package/.mcp/schemas/jules.list_sessions.json +1 -0
- package/.mcp/schemas/jules.send_message.json +1 -0
- package/.mcp/schemas/jules.trigger_feedback.json +1 -0
- package/.mcp/schemas/repo.commit_patch.json +1 -0
- package/.mcp/schemas/repo.create_branch.json +1 -0
- package/.mcp/schemas/repo.create_repair_branch.json +1 -0
- package/.mcp/schemas/repo.get_changed_files.json +1 -0
- package/.mcp/schemas/repo.get_command_schema.json +1 -0
- package/.mcp/schemas/repo.get_package_scripts.json +1 -0
- package/.mcp/schemas/repo.get_route_map.json +1 -0
- package/.mcp/schemas/repo.logs.json +1 -0
- package/.mcp/schemas/repo.read_agent_context.json +1 -0
- package/.mcp/schemas/repo.read_ci_logs.json +1 -0
- package/.mcp/schemas/repo.run_lighthouse.json +1 -0
- package/.mcp/schemas/repo.run_playwright.json +1 -0
- package/.mcp/schemas/repo.run_tests.json +1 -0
- package/CHANGELOG.md +50 -0
- package/README.md +108 -0
- package/actions/ai-review/action.yml +15 -0
- package/actions/audit/action.yml +37 -0
- package/actions/ci-validate/action.yml +9 -0
- package/actions/impact-analysis/action.yml +385 -0
- package/actions/lint-typecheck/action.yml +19 -0
- package/actions/run-project-gate/action.yml +163 -0
- package/actions/setup/action.yml +15 -0
- package/actions/setup-workspace/action.yml +179 -0
- package/actions/test-build/action.yml +71 -0
- package/actions/update-pr-comment/action.yml +101 -0
- package/dist/config.js +110 -0
- package/dist/evals/run-evals.js +38 -0
- package/dist/index.js +10 -0
- package/dist/lib/error_utils.js +8 -0
- package/dist/lib/git.js +33 -0
- package/dist/lib/result.js +21 -0
- package/dist/lib/shell.js +91 -0
- package/dist/lib/shell.test.js +10 -0
- package/dist/lib/td-cli.js +27 -0
- package/dist/lib/test-utils.js +20 -0
- package/dist/mcp/definitions.js +242 -0
- package/dist/mcp/server.js +317 -0
- package/dist/mcp/tools.js +18 -0
- package/dist/tools/contract.js +2069 -0
- package/dist/tools/ddgs.search.js +50 -0
- package/dist/tools/ddgs.search.test.js +67 -0
- package/dist/tools/ddgs_search.py +23 -0
- package/dist/tools/github.checkout_branch.js +20 -0
- package/dist/tools/github.comment_triage_summary.js +25 -0
- package/dist/tools/github.create_issue.js +28 -0
- package/dist/tools/github.create_issue.test.js +54 -0
- package/dist/tools/github.create_pull_request.js +44 -0
- package/dist/tools/github.get_merge_conflict_files.js +26 -0
- package/dist/tools/github.get_pr.js +18 -0
- package/dist/tools/github.get_pr_diff.js +24 -0
- package/dist/tools/github.issue_comment.js +24 -0
- package/dist/tools/github.issue_update.js +29 -0
- package/dist/tools/github.issue_view.js +28 -0
- package/dist/tools/github.open_replacement_pr.js +41 -0
- package/dist/tools/github.search_open_prs.js +31 -0
- package/dist/tools/github.search_open_prs.test.js +51 -0
- package/dist/tools/jules/cancel-session.js +20 -0
- package/dist/tools/jules/create-session.js +20 -0
- package/dist/tools/jules/create-session.test.js +99 -0
- package/dist/tools/jules/get-messages.js +19 -0
- package/dist/tools/jules/get-messages.test.js +45 -0
- package/dist/tools/jules/get-pr.js +14 -0
- package/dist/tools/jules/get-pr.test.js +37 -0
- package/dist/tools/jules/get-session.js +10 -0
- package/dist/tools/jules/list-sessions.js +43 -0
- package/dist/tools/jules/send-message.js +22 -0
- package/dist/tools/jules/send-message.test.js +56 -0
- package/dist/tools/jules/shared.js +26 -0
- package/dist/tools/jules/trigger-feedback.js +16 -0
- package/dist/tools/jules/trigger-feedback.test.js +42 -0
- package/dist/tools/repo.commit_patch.js +33 -0
- package/dist/tools/repo.create_branch.js +21 -0
- package/dist/tools/repo.create_branch.test.js +42 -0
- package/dist/tools/repo.create_repair_branch.js +38 -0
- package/dist/tools/repo.get_changed_files.js +21 -0
- package/dist/tools/repo.get_command_schema.js +27 -0
- package/dist/tools/repo.get_package_scripts.js +35 -0
- package/dist/tools/repo.get_package_scripts.test.js +39 -0
- package/dist/tools/repo.get_route_map.js +37 -0
- package/dist/tools/repo.logs.js +16 -0
- package/dist/tools/repo.read_agent_context.js +20 -0
- package/dist/tools/repo.read_ci_logs.js +18 -0
- package/dist/tools/repo.run_lighthouse.js +37 -0
- package/dist/tools/repo.run_playwright.js +29 -0
- package/dist/tools/repo.run_tests.js +43 -0
- package/dist/tools/types.js +1 -0
- package/docs/testing.md +73 -0
- package/package.json +45 -0
- package/scripts/create_instructions.sh +42 -0
- package/scripts/export-mcp-schema.ts +7 -0
- package/scripts/sync-contracts.ts +74 -0
- package/scripts/sync-mcp-schemas.ts +97 -0
- package/src/agents/conflict-scout.prompt.md +20 -0
- package/src/agents/pr-consolidation.prompt.md +32 -0
- package/src/agents/pr-writer.prompt.md +13 -0
- package/src/agents/repair-agent.prompt.md +18 -0
- package/src/agents/repo-context.prompt.md +20 -0
- package/src/agents/verifier-agent.prompt.md +22 -0
- package/src/config.ts +113 -0
- package/src/evals/fixtures/merge-conflict-simple/README.md +0 -0
- package/src/evals/run-evals.ts +40 -0
- package/src/index.ts +12 -0
- package/src/lib/error_utils.ts +8 -0
- package/src/lib/git.ts +41 -0
- package/src/lib/result.ts +28 -0
- package/src/lib/shell.test.ts +11 -0
- package/src/lib/shell.ts +118 -0
- package/src/lib/td-cli.ts +38 -0
- package/src/lib/test-utils.ts +23 -0
- package/src/mcp/definitions.ts +278 -0
- package/src/mcp/server.ts +359 -0
- package/src/mcp/tools.ts +20 -0
- package/src/tools/contract.ts +2245 -0
- package/src/tools/ddgs.search.test.ts +92 -0
- package/src/tools/ddgs.search.ts +58 -0
- package/src/tools/ddgs_search.py +23 -0
- package/src/tools/github.checkout_branch.ts +25 -0
- package/src/tools/github.comment_triage_summary.ts +30 -0
- package/src/tools/github.create_issue.test.ts +63 -0
- package/src/tools/github.create_issue.ts +34 -0
- package/src/tools/github.create_pull_request.ts +50 -0
- package/src/tools/github.get_merge_conflict_files.ts +31 -0
- package/src/tools/github.get_pr.ts +24 -0
- package/src/tools/github.get_pr_diff.ts +29 -0
- package/src/tools/github.issue_comment.ts +31 -0
- package/src/tools/github.issue_update.ts +31 -0
- package/src/tools/github.issue_view.ts +35 -0
- package/src/tools/github.open_replacement_pr.ts +48 -0
- package/src/tools/github.search_open_prs.test.ts +60 -0
- package/src/tools/github.search_open_prs.ts +40 -0
- package/src/tools/jules/cancel-session.ts +26 -0
- package/src/tools/jules/create-session.test.ts +114 -0
- package/src/tools/jules/create-session.ts +24 -0
- package/src/tools/jules/get-messages.test.ts +52 -0
- package/src/tools/jules/get-messages.ts +24 -0
- package/src/tools/jules/get-pr.test.ts +43 -0
- package/src/tools/jules/get-pr.ts +17 -0
- package/src/tools/jules/get-session.ts +12 -0
- package/src/tools/jules/list-sessions.ts +50 -0
- package/src/tools/jules/send-message.test.ts +66 -0
- package/src/tools/jules/send-message.ts +27 -0
- package/src/tools/jules/shared.ts +28 -0
- package/src/tools/jules/trigger-feedback.test.ts +50 -0
- package/src/tools/jules/trigger-feedback.ts +21 -0
- package/src/tools/repo.commit_patch.ts +41 -0
- package/src/tools/repo.create_branch.test.ts +55 -0
- package/src/tools/repo.create_branch.ts +29 -0
- package/src/tools/repo.create_repair_branch.ts +47 -0
- package/src/tools/repo.get_changed_files.ts +26 -0
- package/src/tools/repo.get_command_schema.ts +30 -0
- package/src/tools/repo.get_package_scripts.test.ts +51 -0
- package/src/tools/repo.get_package_scripts.ts +36 -0
- package/src/tools/repo.get_route_map.ts +41 -0
- package/src/tools/repo.logs.ts +21 -0
- package/src/tools/repo.read_agent_context.ts +22 -0
- package/src/tools/repo.read_ci_logs.ts +21 -0
- package/src/tools/repo.run_lighthouse.ts +40 -0
- package/src/tools/repo.run_playwright.ts +35 -0
- package/src/tools/repo.run_tests.ts +47 -0
- package/src/tools/types.ts +8 -0
- package/start_browsermcp.sh +14 -0
- package/start_github_mcp.sh +6 -0
- package/tsconfig.json +15 -0
- package/vitest.config.ts +9 -0
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
import { Tool, Prompt, Resource } from "@modelcontextprotocol/sdk/types.js";
|
|
2
|
+
import {
|
|
3
|
+
HealthCheckInputJsonSchema,
|
|
4
|
+
SearchPRsInputJsonSchema,
|
|
5
|
+
GetPrDiffInputJsonSchema,
|
|
6
|
+
CheckoutBranchInputJsonSchema,
|
|
7
|
+
GetMergeConflictFilesInputJsonSchema,
|
|
8
|
+
GetChangedFilesInputJsonSchema,
|
|
9
|
+
GetPackageScriptsInputJsonSchema,
|
|
10
|
+
GetRouteMapInputJsonSchema,
|
|
11
|
+
ReadCiLogsInputJsonSchema,
|
|
12
|
+
RepoLogsInputJsonSchema,
|
|
13
|
+
CreateBranchInputJsonSchema,
|
|
14
|
+
CreateRepairBranchInputJsonSchema,
|
|
15
|
+
RunTestsInputJsonSchema,
|
|
16
|
+
RunLighthouseInputJsonSchema,
|
|
17
|
+
RunPlaywrightInputJsonSchema,
|
|
18
|
+
CommitPatchInputJsonSchema,
|
|
19
|
+
OpenReplacementPrInputJsonSchema,
|
|
20
|
+
CreatePullRequestInputJsonSchema,
|
|
21
|
+
CommentTriageSummaryInputJsonSchema,
|
|
22
|
+
GetPrInputJsonSchema,
|
|
23
|
+
IssueViewInputJsonSchema,
|
|
24
|
+
IssueUpdateInputJsonSchema,
|
|
25
|
+
IssueCommentInputJsonSchema,
|
|
26
|
+
CreateIssueInputJsonSchema,
|
|
27
|
+
GetCommandSchemaInputJsonSchema,
|
|
28
|
+
ReadAgentContextInputJsonSchema as ReadAgentContextSchema,
|
|
29
|
+
CreateJulesSessionInputJsonSchema,
|
|
30
|
+
JulesSessionIdInputJsonSchema,
|
|
31
|
+
JulesSendMessageInputJsonSchema,
|
|
32
|
+
JulesListSessionsInputJsonSchema,
|
|
33
|
+
SearchDdgsInputJsonSchema,
|
|
34
|
+
} from "../tools/contract.js";
|
|
35
|
+
|
|
36
|
+
export const MCP_PROMPTS: Prompt[] = [
|
|
37
|
+
{
|
|
38
|
+
name: "conflict-scout",
|
|
39
|
+
description: "Find PRs worth rescuing.",
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
name: "pr-consolidation",
|
|
43
|
+
description: "Guidelines for analyzing and proposing consolidation of overlapping PRs.",
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
name: "repo-context",
|
|
47
|
+
description: "Gather repository context for a PR.",
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
name: "repair-agent",
|
|
51
|
+
description: "Apply the smallest safe fix for a PR.",
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
name: "verifier-agent",
|
|
55
|
+
description: "Verify that a repair works.",
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
name: "pr-writer",
|
|
59
|
+
description: "Write a summary for a replacement PR.",
|
|
60
|
+
},
|
|
61
|
+
];
|
|
62
|
+
|
|
63
|
+
export const MCP_RESOURCES: Resource[] = [
|
|
64
|
+
{
|
|
65
|
+
uri: "repo://package-json",
|
|
66
|
+
name: "package.json",
|
|
67
|
+
mimeType: "application/json",
|
|
68
|
+
description: "The root package.json file of the repository.",
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
uri: "repo://routes",
|
|
72
|
+
name: "Route Map",
|
|
73
|
+
mimeType: "application/json",
|
|
74
|
+
description: "The mapping of application routes to content files.",
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
uri: "repo://design-tokens",
|
|
78
|
+
name: "Design Tokens",
|
|
79
|
+
mimeType: "application/json",
|
|
80
|
+
description: "The design tokens used in the repository.",
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
uri: "repo://repair-report/{branch}",
|
|
84
|
+
name: "Repair Report",
|
|
85
|
+
mimeType: "application/json",
|
|
86
|
+
description: "The validation report for a specific repair branch.",
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
uri: "repo://lighthouse/{branch}",
|
|
90
|
+
name: "Lighthouse Report",
|
|
91
|
+
mimeType: "application/json",
|
|
92
|
+
description: "Lighthouse CI report for a specific branch.",
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
uri: "repo://playwright/{branch}",
|
|
96
|
+
name: "Playwright Report",
|
|
97
|
+
mimeType: "application/json",
|
|
98
|
+
description: "Playwright test report for a specific branch.",
|
|
99
|
+
},
|
|
100
|
+
];
|
|
101
|
+
|
|
102
|
+
export const MCP_TOOLS: Tool[] = [
|
|
103
|
+
{
|
|
104
|
+
name: "boomtick.health",
|
|
105
|
+
description: "Check the health and configuration of the MCP server.",
|
|
106
|
+
inputSchema: HealthCheckInputJsonSchema as any,
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
name: "github.search_open_prs",
|
|
110
|
+
description: "Search for open pull requests in the repository.",
|
|
111
|
+
inputSchema: SearchPRsInputJsonSchema as any,
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
name: "repo.read_agent_context",
|
|
115
|
+
description: "Read the full repository index including file tree, CLI schema, and MCP tools.",
|
|
116
|
+
inputSchema: ReadAgentContextSchema as any,
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
name: "github.get_pr_diff",
|
|
120
|
+
description: "Get the diff and changed files for a pull request.",
|
|
121
|
+
inputSchema: GetPrDiffInputJsonSchema as any,
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
name: "github.checkout_branch",
|
|
125
|
+
description: "Checkout a specific branch in the repository or worktree.",
|
|
126
|
+
inputSchema: CheckoutBranchInputJsonSchema as any,
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
name: "github.get_merge_conflict_files",
|
|
130
|
+
description: "Detect files that conflict when a PR is merged with the base branch.",
|
|
131
|
+
inputSchema: GetMergeConflictFilesInputJsonSchema as any,
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
name: "repo.get_changed_files",
|
|
135
|
+
description: "Get the list of changed files between two refs.",
|
|
136
|
+
inputSchema: GetChangedFilesInputJsonSchema as any,
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
name: "repo.get_command_schema",
|
|
140
|
+
description: "Retrieve a lightweight, targeted schema for a specific td-cli subcommand. Use this instead of reading the entire cli-schema.json to save tokens.",
|
|
141
|
+
inputSchema: GetCommandSchemaInputJsonSchema as any,
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
name: "repo.get_package_scripts",
|
|
145
|
+
description: "Get the scripts defined in package.json.",
|
|
146
|
+
inputSchema: GetPackageScriptsInputJsonSchema as any,
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
name: "repo.get_route_map",
|
|
150
|
+
description: "Get the mapping of routes to content files.",
|
|
151
|
+
inputSchema: GetRouteMapInputJsonSchema as any,
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
name: "repo.read_ci_logs",
|
|
155
|
+
description: "Read CI logs for a given pull request.",
|
|
156
|
+
inputSchema: ReadCiLogsInputJsonSchema as any,
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
name: "repo.logs",
|
|
160
|
+
description: "Stream or grep combined CI logs for all jobs in a pull request.",
|
|
161
|
+
inputSchema: RepoLogsInputJsonSchema as any,
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
name: "repo.create_branch",
|
|
165
|
+
description: "Creates a new clean git branch from a target base branch.",
|
|
166
|
+
inputSchema: CreateBranchInputJsonSchema as any,
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
name: "repo.create_repair_branch",
|
|
170
|
+
description: "Creates a fresh worktree and a new repair branch for an existing PR. This isolates the repair work from the main codebase.",
|
|
171
|
+
inputSchema: CreateRepairBranchInputJsonSchema as any,
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
name: "repo.run_tests",
|
|
175
|
+
description: "Run repository tests and checks.",
|
|
176
|
+
inputSchema: RunTestsInputJsonSchema as any,
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
name: "repo.run_lighthouse",
|
|
180
|
+
description: "Run Lighthouse CI audits.",
|
|
181
|
+
inputSchema: RunLighthouseInputJsonSchema as any,
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
name: "repo.run_playwright",
|
|
185
|
+
description: "Run Playwright E2E tests.",
|
|
186
|
+
inputSchema: RunPlaywrightInputJsonSchema as any,
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
name: "repo.commit_patch",
|
|
190
|
+
description: "Commit verified repair changes in a worktree.",
|
|
191
|
+
inputSchema: CommitPatchInputJsonSchema as any,
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
name: "github.open_replacement_pr",
|
|
195
|
+
description: "Open a new PR that replaces or repairs the original PR.",
|
|
196
|
+
inputSchema: OpenReplacementPrInputJsonSchema as any,
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
name: "github.create_pull_request",
|
|
200
|
+
description: "Creates a pull request on GitHub using the MCP server's integrated credentials. Bypasses terminal CLI constraints.",
|
|
201
|
+
inputSchema: CreatePullRequestInputJsonSchema as any,
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
name: "github.comment_triage_summary",
|
|
205
|
+
description: "Comment on the original PR with a diagnosis and replacement link.",
|
|
206
|
+
inputSchema: CommentTriageSummaryInputJsonSchema as any,
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
name: "github.get_pr",
|
|
210
|
+
description: "Get details of a GitHub PR including title, state, and URLs.",
|
|
211
|
+
inputSchema: GetPrInputJsonSchema as any,
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
name: "github.issue_view",
|
|
215
|
+
description: "View details of a GitHub issue including title, body, and state.",
|
|
216
|
+
inputSchema: IssueViewInputJsonSchema as any,
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
name: "github.issue_update",
|
|
220
|
+
description: "Update a GitHub issue's body, labels, and/or state.",
|
|
221
|
+
inputSchema: IssueUpdateInputJsonSchema as any,
|
|
222
|
+
},
|
|
223
|
+
{
|
|
224
|
+
name: "github.issue_comment",
|
|
225
|
+
description: "Add a new comment to a GitHub issue.",
|
|
226
|
+
inputSchema: IssueCommentInputJsonSchema as any,
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
name: "github.create_issue",
|
|
230
|
+
description: "Create a new GitHub issue.",
|
|
231
|
+
inputSchema: CreateIssueInputJsonSchema as any,
|
|
232
|
+
},
|
|
233
|
+
{
|
|
234
|
+
name: "jules.create_session",
|
|
235
|
+
description: "Create a Jules session that performs work externally and may generate a GitHub pull request.",
|
|
236
|
+
inputSchema: CreateJulesSessionInputJsonSchema as any,
|
|
237
|
+
},
|
|
238
|
+
{
|
|
239
|
+
name: "jules.get_session",
|
|
240
|
+
description: "Get the status and details of a Jules session.",
|
|
241
|
+
inputSchema: JulesSessionIdInputJsonSchema as any,
|
|
242
|
+
},
|
|
243
|
+
{
|
|
244
|
+
name: "jules.send_message",
|
|
245
|
+
description: "Send a message to an active Jules session.",
|
|
246
|
+
inputSchema: JulesSendMessageInputJsonSchema as any,
|
|
247
|
+
},
|
|
248
|
+
{
|
|
249
|
+
name: "jules.get_messages",
|
|
250
|
+
description: "Get the message history of a Jules session.",
|
|
251
|
+
inputSchema: JulesSessionIdInputJsonSchema as any,
|
|
252
|
+
},
|
|
253
|
+
{
|
|
254
|
+
name: "jules.list_sessions",
|
|
255
|
+
description: "List all Jules sessions.",
|
|
256
|
+
inputSchema: JulesListSessionsInputJsonSchema as any,
|
|
257
|
+
},
|
|
258
|
+
{
|
|
259
|
+
name: "jules.cancel_session",
|
|
260
|
+
description: "Cancel an ongoing Jules session.",
|
|
261
|
+
inputSchema: JulesSessionIdInputJsonSchema as any,
|
|
262
|
+
},
|
|
263
|
+
{
|
|
264
|
+
name: "jules.get_pr",
|
|
265
|
+
description: "Get the generated pull request url associated with an active Jules agent session.",
|
|
266
|
+
inputSchema: JulesSessionIdInputJsonSchema as any,
|
|
267
|
+
},
|
|
268
|
+
{
|
|
269
|
+
name: "jules.trigger_feedback",
|
|
270
|
+
description: "Automatically collect CI status/logs for the PR associated with a Jules session and send them back as feedback.",
|
|
271
|
+
inputSchema: JulesSessionIdInputJsonSchema as any,
|
|
272
|
+
},
|
|
273
|
+
{
|
|
274
|
+
name: "agent.search_ddgs",
|
|
275
|
+
description: "Search the web using DuckDuckGo (via ddgs python library).",
|
|
276
|
+
inputSchema: SearchDdgsInputJsonSchema as any,
|
|
277
|
+
},
|
|
278
|
+
];
|
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
2
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
3
|
+
import {
|
|
4
|
+
CallToolRequestSchema,
|
|
5
|
+
ListToolsRequestSchema,
|
|
6
|
+
ListResourcesRequestSchema,
|
|
7
|
+
ReadResourceRequestSchema,
|
|
8
|
+
ListPromptsRequestSchema,
|
|
9
|
+
GetPromptRequestSchema,
|
|
10
|
+
} from "@modelcontextprotocol/sdk/types.js";
|
|
11
|
+
import { config } from "../config.js";
|
|
12
|
+
import { createSuccessResult, createErrorResult } from "../lib/result.js";
|
|
13
|
+
import { MCP_TOOLS, MCP_PROMPTS, MCP_RESOURCES } from "./definitions.js";
|
|
14
|
+
import { healthHandler, HealthCheckInputSchema } from "./tools.js";
|
|
15
|
+
import { searchOpenPrsHandler, SearchOpenPrsInputSchema } from "../tools/github.search_open_prs.js";
|
|
16
|
+
import { getPrDiffHandler, GetPrDiffInputSchema } from "../tools/github.get_pr_diff.js";
|
|
17
|
+
import { getMergeConflictFilesHandler, GetMergeConflictFilesInputSchema } from "../tools/github.get_merge_conflict_files.js";
|
|
18
|
+
import { checkoutBranchHandler, CheckoutBranchInputSchema } from "../tools/github.checkout_branch.js";
|
|
19
|
+
import { getChangedFilesHandler, GetChangedFilesInputSchema } from "../tools/repo.get_changed_files.js";
|
|
20
|
+
import { readAgentContextHandler, ReadAgentContextInputSchema } from "../tools/repo.read_agent_context.js";
|
|
21
|
+
import { getCommandSchemaHandler, GetCommandSchemaInputSchema } from "../tools/repo.get_command_schema.js";
|
|
22
|
+
import { getPackageScriptsHandler, GetPackageScriptsInputSchema } from "../tools/repo.get_package_scripts.js";
|
|
23
|
+
import { getRouteMapHandler, GetRouteMapInputSchema } from "../tools/repo.get_route_map.js";
|
|
24
|
+
import { readCiLogsHandler, ReadCiLogsInputSchema } from "../tools/repo.read_ci_logs.js";
|
|
25
|
+
import { repoLogsHandler, RepoLogsInputSchema } from "../tools/repo.logs.js";
|
|
26
|
+
import { createRepairBranchHandler, CreateRepairBranchInputSchema } from "../tools/repo.create_repair_branch.js";
|
|
27
|
+
import { createBranchHandler, CreateBranchInputSchema } from "../tools/repo.create_branch.js";
|
|
28
|
+
import { runTestsHandler, RunTestsInputSchema } from "../tools/repo.run_tests.js";
|
|
29
|
+
import { runLighthouseHandler, RunLighthouseInputSchema } from "../tools/repo.run_lighthouse.js";
|
|
30
|
+
import { runPlaywrightHandler, RunPlaywrightInputSchema } from "../tools/repo.run_playwright.js";
|
|
31
|
+
import { commitPatchHandler, CommitPatchInputSchema } from "../tools/repo.commit_patch.js";
|
|
32
|
+
import { openReplacementPrHandler, OpenReplacementPrInputSchema } from "../tools/github.open_replacement_pr.js";
|
|
33
|
+
import { commentTriageSummaryHandler, CommentTriageSummaryInputSchema } from "../tools/github.comment_triage_summary.js";
|
|
34
|
+
import { createPullRequestHandler, CreatePullRequestInputSchema } from "../tools/github.create_pull_request.js";
|
|
35
|
+
import { getPrHandler, GetPrInputSchema } from "../tools/github.get_pr.js";
|
|
36
|
+
import { issueViewHandler, IssueViewInputSchema } from "../tools/github.issue_view.js";
|
|
37
|
+
import { issueUpdateHandler, IssueUpdateInputSchema } from "../tools/github.issue_update.js";
|
|
38
|
+
import { issueCommentHandler, IssueCommentInputSchema } from "../tools/github.issue_comment.js";
|
|
39
|
+
import { createIssueHandler, CreateIssueInputSchema } from "../tools/github.create_issue.js";
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
import { createJulesSessionHandler, CreateJulesSessionInputSchema } from "../tools/jules/create-session.js";
|
|
43
|
+
import { getJulesSessionHandler, GetJulesSessionInputSchema } from "../tools/jules/get-session.js";
|
|
44
|
+
import { sendJulesMessageHandler, SendJulesMessageInputSchema } from "../tools/jules/send-message.js";
|
|
45
|
+
import { getJulesMessagesHandler, GetJulesMessagesInputSchema } from "../tools/jules/get-messages.js";
|
|
46
|
+
import { listJulesSessionsHandler, ListJulesSessionsInputSchema } from "../tools/jules/list-sessions.js";
|
|
47
|
+
import { cancelJulesSessionHandler, CancelJulesSessionInputSchema } from "../tools/jules/cancel-session.js";
|
|
48
|
+
import { getJulesPullRequestHandler, GetJulesPullRequestInputSchema } from "../tools/jules/get-pr.js";
|
|
49
|
+
import { triggerJulesFeedbackHandler, TriggerJulesFeedbackInputSchema } from "../tools/jules/trigger-feedback.js";
|
|
50
|
+
import { ddgsSearchHandler, DdgsSearchInputSchema } from "../tools/ddgs.search.js";
|
|
51
|
+
|
|
52
|
+
import fs from "fs/promises";
|
|
53
|
+
import { existsSync, readFileSync } from "fs";
|
|
54
|
+
import path from "path";
|
|
55
|
+
|
|
56
|
+
import { spawnSync } from "child_process";
|
|
57
|
+
import { fileURLToPath } from "url";
|
|
58
|
+
|
|
59
|
+
export class BoomtickMCPServer {
|
|
60
|
+
private server: Server;
|
|
61
|
+
|
|
62
|
+
constructor() {
|
|
63
|
+
this.server = new Server(
|
|
64
|
+
{
|
|
65
|
+
name: "boomtick-mcp",
|
|
66
|
+
version: "0.2.0",
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
capabilities: {
|
|
70
|
+
tools: {},
|
|
71
|
+
resources: {},
|
|
72
|
+
prompts: {},
|
|
73
|
+
},
|
|
74
|
+
}
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
this.setupToolHandlers();
|
|
78
|
+
this.setupResourceHandlers();
|
|
79
|
+
this.setupPromptHandlers();
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
private setupPromptHandlers() {
|
|
83
|
+
this.server.setRequestHandler(ListPromptsRequestSchema, async () => {
|
|
84
|
+
return {
|
|
85
|
+
prompts: MCP_PROMPTS,
|
|
86
|
+
};
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
this.server.setRequestHandler(GetPromptRequestSchema, async (request) => {
|
|
90
|
+
const name = request.params.name;
|
|
91
|
+
|
|
92
|
+
const agentsDir = path.resolve(config.repoPath, "mcp/src/agents");
|
|
93
|
+
// nosemgrep
|
|
94
|
+
const promptPath = path.resolve(agentsDir, `${name}.prompt.md`);
|
|
95
|
+
|
|
96
|
+
if (!promptPath.startsWith(agentsDir + path.sep)) {
|
|
97
|
+
throw new Error("Path traversal detected");
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
try {
|
|
101
|
+
const content = await fs.readFile(promptPath, "utf-8");
|
|
102
|
+
return {
|
|
103
|
+
messages: [
|
|
104
|
+
{
|
|
105
|
+
role: "user",
|
|
106
|
+
content: { type: "text", text: content },
|
|
107
|
+
},
|
|
108
|
+
],
|
|
109
|
+
};
|
|
110
|
+
} catch (e) {
|
|
111
|
+
throw new Error(`Prompt not found: ${name}`);
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
private setupResourceHandlers() {
|
|
117
|
+
this.server.setRequestHandler(ListResourcesRequestSchema, async () => {
|
|
118
|
+
return {
|
|
119
|
+
resources: MCP_RESOURCES,
|
|
120
|
+
};
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
this.server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
124
|
+
const uri = request.params.uri;
|
|
125
|
+
if (uri === "repo://package-json") {
|
|
126
|
+
const content = await fs.readFile(path.join(config.repoPath, "package.json"), "utf-8");
|
|
127
|
+
return {
|
|
128
|
+
contents: [{ uri, mimeType: "application/json", text: content }],
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
if (uri === "repo://routes") {
|
|
132
|
+
const routeMap = await getRouteMapHandler({});
|
|
133
|
+
return {
|
|
134
|
+
contents: [{ uri, mimeType: "application/json", text: JSON.stringify(routeMap, null, 2) }],
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
if (uri === "repo://design-tokens") {
|
|
138
|
+
const tokensPath = path.join(config.repoPath, "src/styles/design-tokens.ts");
|
|
139
|
+
const content = await fs.readFile(tokensPath, "utf-8");
|
|
140
|
+
return {
|
|
141
|
+
contents: [{ uri, mimeType: "text/typescript", text: content }],
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
if (uri.startsWith("repo://diff/")) {
|
|
145
|
+
const prNumber = parseInt(uri.split("/").pop() || "");
|
|
146
|
+
const diff = await getPrDiffHandler({ prNumber });
|
|
147
|
+
return {
|
|
148
|
+
contents: [{ uri, mimeType: "text/plain", text: diff.diffText }],
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
if (uri.startsWith("repo://ci/")) {
|
|
152
|
+
const prNumber = parseInt(uri.split("/").pop() || "");
|
|
153
|
+
const logs = await readCiLogsHandler({ prNumber });
|
|
154
|
+
return {
|
|
155
|
+
contents: [{ uri, mimeType: "application/json", text: JSON.stringify(logs, null, 2) }],
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
if (uri.startsWith("repo://lighthouse/")) {
|
|
159
|
+
const branch = uri.split("/").pop() || "";
|
|
160
|
+
const report = await runLighthouseHandler({ route: "/", worktreePath: `../boomtick-mcp-rescue-${branch}` });
|
|
161
|
+
return {
|
|
162
|
+
contents: [{ uri, mimeType: "application/json", text: JSON.stringify(report, null, 2) }],
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
if (uri.startsWith("repo://playwright/")) {
|
|
166
|
+
const branch = uri.split("/").pop() || "";
|
|
167
|
+
const report = await runPlaywrightHandler({ worktreePath: `../boomtick-mcp-rescue-${branch}` });
|
|
168
|
+
return {
|
|
169
|
+
contents: [{ uri, mimeType: "application/json", text: JSON.stringify(report, null, 2) }],
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
throw new Error(`Resource not found: ${uri}`);
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
private setupToolHandlers() {
|
|
177
|
+
this.server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
178
|
+
return {
|
|
179
|
+
tools: MCP_TOOLS,
|
|
180
|
+
};
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
184
|
+
try {
|
|
185
|
+
switch (request.params.name) {
|
|
186
|
+
case "boomtick.health":
|
|
187
|
+
return createSuccessResult(await healthHandler(HealthCheckInputSchema.parse(request.params.arguments || {})));
|
|
188
|
+
case "github.search_open_prs":
|
|
189
|
+
return createSuccessResult(await searchOpenPrsHandler(SearchOpenPrsInputSchema.parse(request.params.arguments || {})));
|
|
190
|
+
case "repo.read_agent_context":
|
|
191
|
+
return createSuccessResult(await readAgentContextHandler(ReadAgentContextInputSchema.parse(request.params.arguments || {})));
|
|
192
|
+
case "github.get_pr_diff":
|
|
193
|
+
return createSuccessResult(await getPrDiffHandler(GetPrDiffInputSchema.parse(request.params.arguments)));
|
|
194
|
+
case "github.get_merge_conflict_files":
|
|
195
|
+
return createSuccessResult(await getMergeConflictFilesHandler(GetMergeConflictFilesInputSchema.parse(request.params.arguments)));
|
|
196
|
+
case "github.checkout_branch":
|
|
197
|
+
return createSuccessResult(await checkoutBranchHandler(CheckoutBranchInputSchema.parse(request.params.arguments)));
|
|
198
|
+
case "repo.get_changed_files":
|
|
199
|
+
return createSuccessResult(await getChangedFilesHandler(GetChangedFilesInputSchema.parse(request.params.arguments || {})));
|
|
200
|
+
case "repo.get_command_schema":
|
|
201
|
+
return createSuccessResult(await getCommandSchemaHandler(GetCommandSchemaInputSchema.parse(request.params.arguments)));
|
|
202
|
+
case "repo.get_package_scripts":
|
|
203
|
+
return createSuccessResult(await getPackageScriptsHandler(GetPackageScriptsInputSchema.parse(request.params.arguments || {})));
|
|
204
|
+
case "repo.get_route_map":
|
|
205
|
+
return createSuccessResult(await getRouteMapHandler(GetRouteMapInputSchema.parse(request.params.arguments || {})));
|
|
206
|
+
case "repo.read_ci_logs":
|
|
207
|
+
return createSuccessResult(await readCiLogsHandler(ReadCiLogsInputSchema.parse(request.params.arguments)));
|
|
208
|
+
case "repo.logs":
|
|
209
|
+
return createSuccessResult(await repoLogsHandler(RepoLogsInputSchema.parse(request.params.arguments)));
|
|
210
|
+
case "repo.create_branch":
|
|
211
|
+
return createSuccessResult(await createBranchHandler(CreateBranchInputSchema.parse(request.params.arguments)));
|
|
212
|
+
case "repo.create_repair_branch":
|
|
213
|
+
return createSuccessResult(await createRepairBranchHandler(CreateRepairBranchInputSchema.parse(request.params.arguments)));
|
|
214
|
+
case "repo.run_tests":
|
|
215
|
+
return createSuccessResult(await runTestsHandler(RunTestsInputSchema.parse(request.params.arguments || {})));
|
|
216
|
+
case "repo.run_lighthouse":
|
|
217
|
+
return createSuccessResult(await runLighthouseHandler(RunLighthouseInputSchema.parse(request.params.arguments || {})));
|
|
218
|
+
case "repo.run_playwright":
|
|
219
|
+
return createSuccessResult(await runPlaywrightHandler(RunPlaywrightInputSchema.parse(request.params.arguments || {})));
|
|
220
|
+
case "repo.commit_patch":
|
|
221
|
+
return createSuccessResult(await commitPatchHandler(CommitPatchInputSchema.parse(request.params.arguments)));
|
|
222
|
+
case "github.open_replacement_pr":
|
|
223
|
+
return createSuccessResult(await openReplacementPrHandler(OpenReplacementPrInputSchema.parse(request.params.arguments)));
|
|
224
|
+
case "github.comment_triage_summary":
|
|
225
|
+
return createSuccessResult(await commentTriageSummaryHandler(CommentTriageSummaryInputSchema.parse(request.params.arguments)));
|
|
226
|
+
case "github.create_pull_request":
|
|
227
|
+
return createSuccessResult(await createPullRequestHandler(CreatePullRequestInputSchema.parse(request.params.arguments)));
|
|
228
|
+
case "github.get_pr":
|
|
229
|
+
return createSuccessResult(await getPrHandler(GetPrInputSchema.parse(request.params.arguments)));
|
|
230
|
+
case "github.issue_view":
|
|
231
|
+
return createSuccessResult(await issueViewHandler(IssueViewInputSchema.parse(request.params.arguments)));
|
|
232
|
+
case "github.issue_update":
|
|
233
|
+
return createSuccessResult(await issueUpdateHandler(IssueUpdateInputSchema.parse(request.params.arguments)));
|
|
234
|
+
case "github.issue_comment":
|
|
235
|
+
return createSuccessResult(await issueCommentHandler(IssueCommentInputSchema.parse(request.params.arguments)));
|
|
236
|
+
case "github.create_issue":
|
|
237
|
+
return createSuccessResult(await createIssueHandler(CreateIssueInputSchema.parse(request.params.arguments)));
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
case "jules.create_session":
|
|
242
|
+
return createSuccessResult(await createJulesSessionHandler(CreateJulesSessionInputSchema.parse(request.params.arguments)));
|
|
243
|
+
case "jules.get_session":
|
|
244
|
+
return createSuccessResult(await getJulesSessionHandler(GetJulesSessionInputSchema.parse(request.params.arguments)));
|
|
245
|
+
case "jules.send_message":
|
|
246
|
+
return createSuccessResult(await sendJulesMessageHandler(SendJulesMessageInputSchema.parse(request.params.arguments)));
|
|
247
|
+
case "jules.get_messages":
|
|
248
|
+
return createSuccessResult(await getJulesMessagesHandler(GetJulesMessagesInputSchema.parse(request.params.arguments)));
|
|
249
|
+
case "jules.list_sessions":
|
|
250
|
+
return createSuccessResult(await listJulesSessionsHandler(ListJulesSessionsInputSchema.parse(request.params.arguments || {})));
|
|
251
|
+
case "jules.cancel_session":
|
|
252
|
+
return createSuccessResult(await cancelJulesSessionHandler(CancelJulesSessionInputSchema.parse(request.params.arguments)));
|
|
253
|
+
case "jules.get_pr":
|
|
254
|
+
return createSuccessResult(await getJulesPullRequestHandler(GetJulesPullRequestInputSchema.parse(request.params.arguments)));
|
|
255
|
+
case "jules.trigger_feedback":
|
|
256
|
+
return createSuccessResult(await triggerJulesFeedbackHandler(TriggerJulesFeedbackInputSchema.parse(request.params.arguments)));
|
|
257
|
+
case "agent.search_ddgs":
|
|
258
|
+
return createSuccessResult(await ddgsSearchHandler(DdgsSearchInputSchema.parse(request.params.arguments)));
|
|
259
|
+
default:
|
|
260
|
+
return createErrorResult(`Tool not found: ${request.params.name}`);
|
|
261
|
+
}
|
|
262
|
+
} catch (error) {
|
|
263
|
+
return createErrorResult(error instanceof Error ? error.message : String(error));
|
|
264
|
+
}
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
async run() {
|
|
268
|
+
const projectRoot = config.repoPath || process.cwd();
|
|
269
|
+
const homeDir = process.env.HOME || "";
|
|
270
|
+
const extraPaths = [];
|
|
271
|
+
|
|
272
|
+
// 1. DYNAMIC PYTHON PATH (pip / virtualenv discovery)
|
|
273
|
+
const venvDirs = [".venv", "venv", "env"];
|
|
274
|
+
for (const venvDir of venvDirs) {
|
|
275
|
+
const venvBin = path.join(projectRoot, venvDir, "bin");
|
|
276
|
+
if (existsSync(venvBin)) {
|
|
277
|
+
extraPaths.push(venvBin);
|
|
278
|
+
break;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// 2. DYNAMIC NODE PATH (.nvmrc parsing)
|
|
283
|
+
const nvmrcPath = path.join(projectRoot, ".nvmrc");
|
|
284
|
+
let targetNodeVersion = "";
|
|
285
|
+
|
|
286
|
+
if (existsSync(nvmrcPath)) {
|
|
287
|
+
const rawVersion = readFileSync(nvmrcPath, "utf-8").trim();
|
|
288
|
+
targetNodeVersion = rawVersion.startsWith("v") ? rawVersion : `v${rawVersion}`;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
if (homeDir) {
|
|
292
|
+
extraPaths.push(
|
|
293
|
+
path.join(homeDir, ".local", "bin"),
|
|
294
|
+
path.join(homeDir, "miniforge3", "bin"),
|
|
295
|
+
path.join(homeDir, "anaconda3", "bin"),
|
|
296
|
+
path.join(homeDir, "miniconda3", "bin")
|
|
297
|
+
);
|
|
298
|
+
|
|
299
|
+
if (process.env.NVM_BIN) {
|
|
300
|
+
extraPaths.push(process.env.NVM_BIN);
|
|
301
|
+
} else if (targetNodeVersion) {
|
|
302
|
+
extraPaths.push(path.join(homeDir, ".nvm", "versions", "node", targetNodeVersion, "bin"));
|
|
303
|
+
} else {
|
|
304
|
+
extraPaths.push(path.join(homeDir, ".nvm", "versions", "node", process.version, "bin"));
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
extraPaths.push(path.dirname(process.execPath));
|
|
309
|
+
|
|
310
|
+
const currentPath = process.env.PATH || "";
|
|
311
|
+
const updatedPaths = [...extraPaths, ...currentPath.split(path.delimiter)];
|
|
312
|
+
process.env.PATH = Array.from(new Set(updatedPaths))
|
|
313
|
+
.filter(Boolean)
|
|
314
|
+
.join(path.delimiter);
|
|
315
|
+
|
|
316
|
+
// 3. SAFE REPOSITORY RESOLUTION
|
|
317
|
+
const repoPath = config.repoPath || projectRoot;
|
|
318
|
+
|
|
319
|
+
// 4. SECURE, UNIX-ONLY PRE-FLIGHT CHECK FOR TD-CLI
|
|
320
|
+
try {
|
|
321
|
+
const result = spawnSync("td-cli", ["doctor"], {
|
|
322
|
+
encoding: "utf-8",
|
|
323
|
+
cwd: repoPath,
|
|
324
|
+
shell: false // Explicitly disabled to clear Semgrep rules
|
|
325
|
+
});
|
|
326
|
+
|
|
327
|
+
if (result.error) {
|
|
328
|
+
throw result.error;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
if (result.status !== 0) {
|
|
332
|
+
console.error("status:", result.status);
|
|
333
|
+
console.error("stdout:", result.stdout);
|
|
334
|
+
console.error("stderr:", result.stderr);
|
|
335
|
+
throw new Error(`td-cli doctor returned exit code: ${result.status}`);
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
console.error("✅ td-cli verified on PATH securely");
|
|
339
|
+
} catch (error) {
|
|
340
|
+
console.error("❌ Fatal: td-cli is not resolvable on PATH. MCP tools will fail.");
|
|
341
|
+
console.error("Please ensure the project is installed: pip install -e .");
|
|
342
|
+
console.error("❌ Fatal: td-cli pre-flight check failed:", error instanceof Error ? error.message : String(error));
|
|
343
|
+
process.exit(1);
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
347
|
+
const ddgsScriptPath = path.join(__dirname, "..", "tools", "ddgs_search.py");
|
|
348
|
+
try {
|
|
349
|
+
await fs.access(ddgsScriptPath);
|
|
350
|
+
} catch (err) {
|
|
351
|
+
console.error(`❌ Fatal: ddgs_search.py not found at ${ddgsScriptPath}`);
|
|
352
|
+
process.exit(1);
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
const transport = new StdioServerTransport();
|
|
356
|
+
await this.server.connect(transport);
|
|
357
|
+
console.error("Boomtick MCP Server running on stdio");
|
|
358
|
+
}
|
|
359
|
+
}
|
package/src/mcp/tools.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { config } from "../config.js";
|
|
3
|
+
|
|
4
|
+
export const HealthCheckInputSchema = z.object({
|
|
5
|
+
checkDeep: z.boolean().optional().default(false),
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
export async function healthHandler(args: z.infer<typeof HealthCheckInputSchema>) {
|
|
9
|
+
HealthCheckInputSchema.parse(args);
|
|
10
|
+
return {
|
|
11
|
+
status: "ok",
|
|
12
|
+
config: {
|
|
13
|
+
githubOwner: config.githubOwner,
|
|
14
|
+
githubRepo: config.githubRepo,
|
|
15
|
+
repoPath: config.repoPath,
|
|
16
|
+
readOnly: !config.githubToken,
|
|
17
|
+
ghPath: config.ghPath
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
}
|