@bridge_gpt/mcp-server 0.2.25 → 0.2.27

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 (73) hide show
  1. package/README.md +59 -9
  2. package/build/agents.generated.js +1 -1
  3. package/build/bridge-api-urls.js +31 -0
  4. package/build/commands.generated.js +4 -4
  5. package/build/conductor-bin.js +68 -9267
  6. package/build/conductor-bundle-artifacts.js +802 -0
  7. package/build/conductor-bundle-cli.js +256 -0
  8. package/build/conductor-claude-hook-bin.js +2 -172
  9. package/build/decision-page-template.js +2 -31
  10. package/build/docs.generated.js +2 -1
  11. package/build/doctor.js +148 -1
  12. package/build/env-flags.js +31 -0
  13. package/build/index.js +4659 -34836
  14. package/build/init.js +87 -59
  15. package/build/install-bridge.js +380 -22
  16. package/build/mcp-host-config.js +521 -0
  17. package/build/mcp-host-targets.js +194 -0
  18. package/build/mcp-install-state.js +175 -0
  19. package/build/pipelines.generated.js +5 -4
  20. package/build/readme.generated.js +1 -1
  21. package/build/start-tickets.js +118 -5
  22. package/build/tool-surface-gating.js +396 -0
  23. package/build/version.generated.js +1 -1
  24. package/docs/install/mcp-tool-integrations.md +2 -2
  25. package/package.json +5 -7
  26. package/design-assets/favicon/android-chrome-192x192.png +0 -0
  27. package/design-assets/favicon/android-chrome-512x512.png +0 -0
  28. package/design-assets/favicon/apple-touch-icon.png +0 -0
  29. package/design-assets/favicon/favicon-16x16.png +0 -0
  30. package/design-assets/favicon/favicon.ico +0 -0
  31. package/design-assets/favicon/site.webmanifest +0 -1
  32. package/public/css/main.min.css +0 -4971
  33. package/public/css/main.min.css.map +0 -1
  34. package/public/fonts/OFL.txt +0 -93
  35. package/public/fonts/SourceSansPro-Black.ttf +0 -0
  36. package/public/fonts/SourceSansPro-BlackItalic.ttf +0 -0
  37. package/public/fonts/SourceSansPro-Bold.ttf +0 -0
  38. package/public/fonts/SourceSansPro-BoldItalic.ttf +0 -0
  39. package/public/fonts/SourceSansPro-ExtraLight.ttf +0 -0
  40. package/public/fonts/SourceSansPro-ExtraLightItalic.ttf +0 -0
  41. package/public/fonts/SourceSansPro-Italic.ttf +0 -0
  42. package/public/fonts/SourceSansPro-Light.ttf +0 -0
  43. package/public/fonts/SourceSansPro-LightItalic.ttf +0 -0
  44. package/public/fonts/SourceSansPro-Regular.ttf +0 -0
  45. package/public/fonts/SourceSansPro-SemiBold.ttf +0 -0
  46. package/public/fonts/SourceSansPro-SemiBoldItalic.ttf +0 -0
  47. package/public/img/bridge-logo-160x51.webp +0 -0
  48. package/public/img/bridge-logo-300x92.webp +0 -0
  49. package/public/img/favicon/android-chrome-192x192.png +0 -0
  50. package/public/img/favicon/android-chrome-512x512.png +0 -0
  51. package/public/img/favicon/apple-touch-icon.png +0 -0
  52. package/public/img/favicon/favicon-16x16.png +0 -0
  53. package/public/img/favicon/favicon-32x32.png +0 -0
  54. package/public/img/favicon/favicon.ico +0 -0
  55. package/public/img/favicon/site.webmanifest +0 -1
  56. package/public/img/installation/bitbucket/app-password-1.png +0 -0
  57. package/public/img/installation/bitbucket/app-password-2.png +0 -0
  58. package/public/img/installation/bitbucket/create-token-1.png +0 -0
  59. package/public/img/installation/bitbucket/create-token-2.png +0 -0
  60. package/public/img/installation/bitbucket/webhook-1.png +0 -0
  61. package/public/img/installation/github/github-review-webhook.png +0 -0
  62. package/public/img/installation/jira/credentials/api-key.png +0 -0
  63. package/public/img/installation/jira/webhook/create-rule.png +0 -0
  64. package/public/img/installation/jira/webhook/project-settings.png +0 -0
  65. package/public/img/installation/jira/webhook/rule-create-1.png +0 -0
  66. package/public/img/installation/jira/webhook/rule-create-2.png +0 -0
  67. package/public/img/installation/jira/webhook/rule-create-3.png +0 -0
  68. package/public/img/installation/pinecone/pinecone-api-key.png +0 -0
  69. package/public/img/installation/pinecone/pinecone-index.png +0 -0
  70. package/public/js/main.min.js +0 -10427
  71. package/public/js/main.min.js.map +0 -1
  72. package/smoke-test/SMOKE-TEST.md +0 -560
  73. package/smoke-test/smoke-test-mcp.md +0 -23
@@ -1,560 +0,0 @@
1
- # Bridge API MCP Cross-Platform Smoke-Test Runbook
2
-
3
- This runbook is executed **by an AI agent running inside a host** (Claude Code,
4
- Cursor, OpenAI Codex, Windsurf, or VS Code/Copilot). The agent calls real Bridge
5
- API MCP tools through the host's own MCP client and records a PASS/FAIL verdict
6
- for each one in a markdown report. The point is to prove that the MCP server
7
- actually works end-to-end *inside this specific host*, not just that the server
8
- process started.
9
-
10
- ## Sequestered, not part of the tool surface
11
-
12
- - This runbook **adds no MCP tool.** It is documentation the host agent reads and
13
- follows; it never registers a `registerTool(...)` call.
14
- - The server's **registered MCP tool set remains unchanged** at its existing
15
- count. Running the smoke test does not add, remove, or rename any tool.
16
- - The companion `/smoke-test-mcp` command is **opt-in**: it is not scaffolded by
17
- the default `--init` flow and must be copied in manually (see
18
- `smoke-test-mcp.md`).
19
-
20
- ## Why protocol-level success is not enough
21
-
22
- **Protocol-level MCP success is insufficient** to judge a tool as passing. The
23
- server's `handleResponse()` helper (`mcp_server/src/index.ts`) does **not throw**
24
- on HTTP errors — it **returns HTTP errors as JSON text content**:
25
-
26
- ```json
27
- { "error": "NOT_FOUND", "status": 404, "message": "..." }
28
- ```
29
-
30
- So an MCP call can "succeed" at the protocol level (the host returns content with
31
- no transport error) while the content itself describes a failure. **Agents must
32
- inspect the returned content** rather than treating invocation success as `PASS`.
33
-
34
- ### Content-based grading
35
-
36
- For every tool result:
37
-
38
- 1. Read the returned text content.
39
- 2. **Parse the JSON text when possible.** If it parses, inspect fields such as
40
- `error`, `status`, `message`, and any known success fields for that tool
41
- (e.g. `status: "decision_page_generated"`, a `file_path`, a `task_id`).
42
- 3. If the content is plain text (e.g. `get_docs_dir` returns a bare path), check
43
- for expected success markers or saved-file path evidence.
44
- 4. Only then assign a verdict from the vocabulary below.
45
-
46
- ---
47
-
48
- ## Phase 0 — Prerequisites
49
-
50
- Before running anything, confirm:
51
-
52
- - The host has the `bridge-api` MCP server configured and connected (the tools
53
- are visible to the agent).
54
- - You can call `ping` and get a non-error result (this is the first metadata
55
- check in Phase 2).
56
- - You have permission to write files under the host's project (the report and
57
- the local-write canary file are written locally).
58
-
59
- ### Environment variables
60
-
61
- The server reads these environment variables:
62
-
63
- | Variable | Meaning |
64
- |---|---|
65
- | `BAPI_BASE_URL` | Bridge API base URL |
66
- | `BAPI_REPO_NAME` | Jira project/repository identifier |
67
- | `BAPI_API_KEY` | API key used for all calls |
68
- | `BAPI_PROJECT_ROOT` | Absolute path to the project root |
69
- | `BAPI_DOCS_DIR` | Local docs directory (default `docs/tmp`) for file output |
70
-
71
- Project-root resolution detail: in the server, `PROJECT_ROOT` **falls back to
72
- `process.cwd()`** when `BAPI_PROJECT_ROOT` is unset, and `BAPI_DOCS_DIR` is then
73
- resolved relative to that root. **Codex-like hosts may need `BAPI_PROJECT_ROOT`
74
- set manually**, because the working directory the host launches the server from
75
- is not guaranteed to be the project root.
76
-
77
- ---
78
-
79
- ## Phase 1 — Input Collection (collect inputs before starting)
80
-
81
- Ask the user for the following before making any tool calls:
82
-
83
- 1. **Required:** a **read-only Jira ticket key** that the configured
84
- `BAPI_API_KEY` can read (used for the Tier 1 read-only checks). It only needs
85
- to be readable — comments, attachments, tracked state, and generated
86
- artifacts are all optional.
87
- 2. **Optional:** a **config field name** (for `config_field` with operation `"get"`).
88
- 3. **Optional:** a **pipeline name** (for `get_pipeline_recipe`) — either a
89
- no-variable pipeline name (e.g. `learn-repository`) or, for a
90
- variable-declaring pipeline, the variable values it needs (e.g. a
91
- `ticket_key`).
92
- 4. **Optional:** an **attachment identifier or filename** (for `attachment` with operation `"download"` or `"list"`).
93
- 5. **Optional:** any **artifact or task IDs** (e.g. a `task_id`, `brainstorm_id`,
94
- or commit ref) for retriever and CI tools.
95
- 6. **Required decision:** explicit **Tier 3 consent** (Tier 3 spends tokens and
96
- is skipped without it).
97
-
98
- ### Optional input omission rule
99
-
100
- If the user does not supply an optional input, **omit that parameter from the MCP
101
- call entirely.** Do **not** send it as `null`, an empty string `""`, or a
102
- placeholder value. Tools whose only input is missing are graded
103
- `SKIP_USER_INPUT`, not `FAIL`.
104
-
105
- ### Report redaction rule
106
-
107
- Never write **`BAPI_API_KEY`**, **authorization headers**, **raw stack traces**,
108
- or **raw protocol noise** into the report. Base URL and repo name may be
109
- recorded; secrets must be redacted. (Repeated in the report template below.)
110
-
111
- ---
112
-
113
- ## Phase 2 — Metadata Discovery
114
-
115
- Run these first; their output populates the report's metadata header and anchors
116
- all local writes:
117
-
118
- 1. `ping` — connectivity + API key validity.
119
- 2. `get_my_role` — the role of the configured key.
120
- 3. **`get_docs_dir` — call this as one of the first calls.** Store the **exact
121
- returned docs path** verbatim. This path is the **root for every local write**
122
- in this run (the report and the local-write canary file). Do not recompute it
123
- from environment variables.
124
-
125
- ### Path discipline
126
-
127
- - Every local write **must be anchored to the exact docs directory returned by
128
- `get_docs_dir`.**
129
- - Before recording any local write as evidence, **verify the path is absolute and
130
- resides under the returned docs directory** (a strict prefix containment
131
- check). A path outside that directory is a `FAIL` for that step.
132
- - The report file path is:
133
-
134
- ```
135
- <docs_dir>/smoke-test/REPORT-<host>-<timestamp>.md
136
- ```
137
-
138
- - `<host>` sanitization: replace every character outside `[A-Za-z0-9._-]` with
139
- `-`, collapse repeated separators, and trim leading/trailing separators.
140
- - `<timestamp>` is a filesystem-safe **UTC** timestamp such as
141
- `YYYYMMDDTHHMMSSZ` (e.g. `20260525T174500Z`).
142
-
143
- ---
144
-
145
- ## Verdict Vocabulary
146
-
147
- ### Per-tool verdicts
148
-
149
- | Verdict | Meaning |
150
- |---|---|
151
- | `PASS` | Content confirms success. |
152
- | `PASS_EXPECTED_404` | Artifact retriever returned a clean 404 indicating the artifact is simply absent. |
153
- | `FAIL` | Content describes an error, or required content is missing. |
154
- | `SKIP_USER_INPUT` | A required input for this tool was not supplied. |
155
- | `SKIP_NOT_APPROVED` | Tier 3 (or another gated tool) was not consented to. |
156
- | `SKIP_NOT_APPLICABLE` | Tool is disabled/not applicable in this environment. |
157
- | `WARN` | Non-blocking anomaly, including host serialization quirks. |
158
-
159
- ### Overall verdicts
160
-
161
- `PASS`, `PASS_WITH_WARNINGS`, `FAIL`, `INCOMPLETE`.
162
-
163
- ### Grading rules
164
-
165
- - Parsed content containing an **`error` key** is a **`FAIL`**, *unless* it is an
166
- explicitly expected clean-empty condition (an empty artifact retriever).
167
- - Parsed **`status >= 400`** is a **`FAIL`**, *except* a clean expected **404**
168
- for an artifact retriever or optional-empty retriever, which is
169
- `PASS_EXPECTED_404`.
170
- - **`401` and `403` are always `FAIL`.**
171
- - **`5xx` is always `FAIL`**, *except* `poll_ci_checks` returning a
172
- `TOOL_DISABLED` / `503` self-disable response, which is `SKIP_NOT_APPLICABLE`.
173
- - **Expected-empty artifact retrievers** that return a clean 404 (no artifact
174
- yet) are **`PASS_EXPECTED_404`**.
175
- - **Artifact retrievers that return valid non-empty content** are **`PASS`**
176
- (not `PASS_EXPECTED_404`).
177
- - **Host/tool invocation errors**, **schema validation failures outside the
178
- documented host-risk probes**, **empty responses where non-empty content is
179
- required**, and **failure-prefixed text** such as `Failed to request ...` are
180
- all **`FAIL`**.
181
- - A **host boolean-serialization rejection during the dedicated boolean probe**
182
- (Phase 7) is a **`WARN`** for host behavior — **not** an MCP server `FAIL`.
183
-
184
- ### Heavy-read truncation grading
185
-
186
- There are **five heavy-read tools** whose successful oversized output is saved to
187
- disk before a truncated inline preview is returned: `get_project_standards`,
188
- `get_tickets`, `get_ticket`, `get_comments`, and `attachment` (operation: `"list"`).
189
-
190
- - When a heavy-read response begins with `[Response truncated. Full response
191
- saved locally.]` and carries a `Saved to <path>` note, grade it **`PASS`** as
192
- long as the saved `<path>` is contained under the `get_docs_dir` result. The
193
- truncation banner is the **expected** large-payload behavior, never a `FAIL`.
194
- - `get_project_standards` is a zero-input read that may exceed the inline
195
- threshold; when it does, the full payload is saved under a `project-standards/`
196
- subdirectory of the docs directory and only a truncated preview is returned
197
- inline.
198
- - To exercise the truncation banner live, point the run at a known-large fixture
199
- — a busy ticket with long comments, a broad `get_tickets` query, or a repo with
200
- large project standards.
201
-
202
- ---
203
-
204
- ## Phase 3 — Default Pass
205
-
206
- The default pass is the release-blocking fast path. It runs all Tier 0 tools by
207
- default plus the read-only ticket checks when a readable ticket was supplied.
208
-
209
- ### All Tier 0 tools run by default
210
-
211
- `ping`, `get_my_role`, `get_docs_dir`, `get_project_standards`,
212
- `list_pipelines`, `get_parse_status`, `list_pipeline_runs`.
213
-
214
- (The "fast-pass" list is the minimum release-blocking subset; the tier
215
- definition is "always run", so do not exclude the other Tier 0 tools.)
216
-
217
- ### Default read-only ticket checks (when a readable ticket is supplied)
218
-
219
- Run `get_ticket`, `get_comments`, and `get_plan` against the user-supplied
220
- ticket.
221
-
222
- - **`get_comments` is preferred**; **`attachment` (operation: `"list"`) is the fallback** if
223
- comments are unavailable for the selected ticket.
224
- - **`get_plan` must be called with a real boolean `save_locally: false`** (a true
225
- JSON boolean, not the string `"false"`).
226
- - Grade `get_plan` as **`PASS`** if it returns valid plan content, or
227
- **`PASS_EXPECTED_404`** if it returns a clean missing-plan 404.
228
-
229
- ### Default overall verdict
230
-
231
- The default run can be overall **`PASS`** when **all required default calls are
232
- `PASS` or `PASS_EXPECTED_404`** and the optional tools are skipped for lack of
233
- input or consent. Add `PASS_WITH_WARNINGS` if any `WARN` was recorded. Reserve
234
- `INCOMPLETE` for missing required metadata, interrupted execution, or a
235
- default-set tool that did not run.
236
-
237
- ---
238
-
239
- ## Phase 4 — Optional Tier 1
240
-
241
- Tier 1 tools are read-only but require an input. Run each only when the user
242
- supplied the relevant input; otherwise record `SKIP_USER_INPUT`.
243
-
244
- - `get_tickets` — a query/filter (a default project query is acceptable).
245
- - `get_ticket_state`, `get_jira_transitions`, `resolve_target_status` — the
246
- ticket key.
247
- - `config_field` (operation: `"get"`) — the optional config field name.
248
- - `get_pipeline_recipe` — a pipeline name. When no variables are supplied, use a
249
- no-variable pipeline such as `learn-repository` as the smoke target. A
250
- variable-declaring pipeline (e.g. a ticket-based pipeline) requires a
251
- `variables` map such as `{ "ticket_key": "<user ticket>" }`. A `400
252
- BAD_REQUEST` with `Missing required variable(s)` is **working as designed**, not
253
- a server fault — rerun with the required variables or pick a no-variable
254
- pipeline.
255
- - `attachment` (operation: `"list"` or `"download"`) — the optional attachment input.
256
- - The clean-empty artifact retrievers `get_architecture`,
257
- `get_clarifying_questions`, `get_ticket_critique` — grade a clean empty result
258
- as `PASS_EXPECTED_404` and valid content as `PASS`.
259
- - `get_reimplement_context` — can return **live-assembled, non-empty content**
260
- even for an untracked or previously unprocessed ticket. Grade valid returned
261
- content as `PASS`; a clean 404 is `PASS_EXPECTED_404`. It is **not** a
262
- clean-empty-only retriever.
263
- - `get_ticket_state` — in a v1 read-only run this can only confirm the clean
264
- "not tracked" 404 path unless a prior state-populating submit has occurred.
265
- Full lifecycle-state coverage requires `track_ticket`, which remains a deferred
266
- Tier 4 mutating tool.
267
- - `get_deep_research` — requires a `task_id` produced by `request_deep_research`.
268
- When Tier 3 is skipped and no ID exists, record `SKIP_USER_INPUT`.
269
- - `get_brainstorm` — requires a `brainstorm_id` produced by `request_brainstorm`.
270
- When Tier 3 is skipped and no ID exists, record `SKIP_USER_INPUT`.
271
- - `poll_ci_checks` — an `available:true` envelope with `checks:[]`,
272
- `all_complete:true`, and `all_passed:true` is a `PASS`. The `TOOL_DISABLED` /
273
- `503` self-disable branch is `SKIP_NOT_APPLICABLE` when CI is not configured.
274
-
275
- ---
276
-
277
- ## Phase 5 — Tier 2 Canary (`generate_decision_page`)
278
-
279
- Tier 2 is the **local-only file-write canary** and **always runs**. It forces a
280
- real HTML file write instead of the no-decision fast path (which writes nothing).
281
-
282
- Call `generate_decision_page` with this **verbatim** payload. It is a fixed,
283
- local-only fixture: the handler validates `ticket_key` against
284
- `^[A-Za-z][A-Za-z0-9_-]*$` (which `BAPI-SMOKE` satisfies) and writes
285
- `<docs_dir>/review/<ticket_key>-decisions.html` **without ever calling Jira**, so
286
- the literal `BAPI-SMOKE` key is safe and deterministic across all hosts. Do not
287
- substitute the user's ticket key.
288
-
289
- ```json
290
- {
291
- "ticket_key": "BAPI-SMOKE",
292
- "actionable_items": [
293
- {
294
- "id": "E-1",
295
- "question": "Should the smoke-test canary write a real decision-page HTML file?",
296
- "original_question": "Does generate_decision_page write a local file when given one actionable item?",
297
- "why_it_matters": "Proves the MCP server's local file-write path works end to end inside this host.",
298
- "recommendation_explanation": "Writing a real file is the only way to verify the disk-write canary instead of taking the no-op no-decisions fast path.",
299
- "codebase_evidence": "generate_decision_page writes <docs_dir>/review/<ticket_key>-decisions.html when actionable_items is non-empty (mcp_server/src/index.ts generate_decision_page handler).",
300
- "source": "BAPI-314 smoke-test runbook — Tier 2 canary",
301
- "recommendation_index": 0,
302
- "options": ["Write the decision page file", "Skip the file write"],
303
- "option_consequences": [
304
- "A real HTML file is created under the docs directory — the desired canary signal.",
305
- "No file is written and the canary cannot prove local writes — undesired."
306
- ]
307
- }
308
- ],
309
- "clear_improvements": [
310
- {
311
- "id": "CI-1",
312
- "title": "Anchor all local writes under get_docs_dir",
313
- "action": "Resolve the report path and the canary file path from the exact get_docs_dir result.",
314
- "confidence": "high",
315
- "source": "BAPI-314 smoke-test runbook — path discipline"
316
- }
317
- ]
318
- }
319
- ```
320
-
321
- ### Tier 2 grading
322
-
323
- - **`PASS`**: the response JSON contains `status: "decision_page_generated"`
324
- **and** an **absolute** `file_path` that resides **under the exact
325
- `get_docs_dir` result**. Verify containment by checking that `file_path`
326
- begins with the stored docs directory prefix.
327
- - **`FAIL`**: the response is `no_decisions_needed`, **or** `file_path` is absent,
328
- **or** the path is **not absolute**, **or** the path is **outside the returned
329
- docs directory**.
330
-
331
- ---
332
-
333
- ## Phase 6 — Optional Tier 3
334
-
335
- **Tier 3 is skipped by default and requires explicit user consent**, because it
336
- **may spend tokens** and can take **up to roughly 15 minutes**. Without consent,
337
- record each Tier 3 tool as `SKIP_NOT_APPROVED`.
338
-
339
- Ask for one explicit Tier 3 consent decision; if granted, the user may pick which
340
- flows to run. Use **bounded polling with increasing intervals and a maximum wait
341
- of about 15 minutes** for any async flow.
342
-
343
- ### Single-call Tier 3 tool
344
-
345
- - **`second_opinion` returns its result in one call and is token-costing.** The
346
- backend is now async (submit → poll → result, so a slow opinion no longer trips
347
- the 30s Heroku request timeout / H12), but the tool **absorbs that polling
348
- internally** — it still returns the reply directly. It is **not** an async
349
- request/get flow: do not try to capture an ID for it. If an opinion is still
350
- processing after ~5 minutes, the tool returns a **recoverable-result message**
351
- (with the `request_id` and a `GET /llm/second-opinion/{id}/result` URL) rather
352
- than failing — treat that as `PASS`, not an error.
353
-
354
- ### Async request/get Tier 3 tools
355
-
356
- | Submit tool | Returns | Retrieve with |
357
- |---|---|---|
358
- | `request_deep_research` | a **`task_id`** | `get_deep_research` |
359
- | `request_brainstorm` | a **`brainstorm_id`** | `get_brainstorm` |
360
- | `request_plan_generation` | (ticket-key based) | `get_plan` |
361
- | `request_architecture` | (ticket-key based) | `get_architecture` |
362
- | `request_clarifying_questions` | (ticket-key based) | `get_clarifying_questions` |
363
- | `request_ticket_critique` | (ticket-key based) | `get_ticket_critique` |
364
- | `request_reimplement_context` | (ticket-key based) | `get_reimplement_context` |
365
-
366
- - **`request_ticket_review`** is the combined submit side for review. There is
367
- **no dedicated `get_*` review-retrieval tool** for it. Retrieve its results
368
- with **`get_clarifying_questions`** and **`get_ticket_critique`**, or pass
369
- `wait_for_result: true` **only if explicitly approved**.
370
-
371
- ---
372
-
373
- ## Phase 7 — Host Probes (host-specific probes)
374
-
375
- Record evidence for the cross-platform risks that differ between Claude Code,
376
- Cursor, Codex, Windsurf, and VS Code/Copilot.
377
-
378
- ### Boolean serialization probe
379
-
380
- Target an artifact retriever with a **real `save_locally` boolean** — preferably
381
- **`get_plan` with `save_locally: false`** when a plan artifact exists.
382
-
383
- - `get_plan`'s `save_locally` is a strict `z.boolean().optional()`; the schema
384
- performs **no string coercion**. If the **host serializes `false` as the string
385
- `"false"`** and Zod rejects it with a 400, record **`WARN`** for the host's
386
- serialization behavior — this is the cross-platform quirk the probe exists to
387
- surface, **not** an MCP server `FAIL`.
388
- - If **no artifact exists** and the probe returns a clean 404, record
389
- **`SKIP_NOT_APPLICABLE`**.
390
- - If content exists and a **file is saved despite `save_locally: false`**, record
391
- **`WARN`**.
392
-
393
- ### Optional-parameter omission probe
394
-
395
- Record whether the agent **avoided sending `null`, empty strings, or
396
- placeholders** for `.optional()` schema fields throughout the run.
397
-
398
- ### Codex project-root probe
399
-
400
- Record whether **`BAPI_PROJECT_ROOT` is set** and whether **`get_docs_dir`
401
- resolves to the expected project-root-relative docs directory**.
402
-
403
- ### Windows separator probe
404
-
405
- Record the **returned path formats** (separator style) and **still perform the
406
- containment checks** against the exact docs directory regardless of separator
407
- differences.
408
-
409
- ### Tier 3 async round-trip probe
410
-
411
- Only with explicit consent, run one `request_*` → `get_*` round trip end-to-end
412
- (bounded polling) to prove the async pattern works in this host.
413
-
414
- ---
415
-
416
- ## Phase 8 — Report Writing
417
-
418
- Write the report to `<docs_dir>/smoke-test/REPORT-<host>-<timestamp>.md` using the
419
- template below. Create the `<docs_dir>/smoke-test/` directory if needed. Use the
420
- host's normal file-write capability (no new MCP tool is involved).
421
-
422
- ### Report template
423
-
424
- ```markdown
425
- # MCP Smoke-Test Report
426
-
427
- ## Metadata
428
- - Host name / version: <host and version>
429
- - OS: <operating system>
430
- - MCP package version: <version if known>
431
- - Base URL: <BAPI_BASE_URL>
432
- - Repo name: <BAPI_REPO_NAME>
433
- - Project root: <BAPI_PROJECT_ROOT or resolved root>
434
- - Docs dir: <exact get_docs_dir result>
435
- - Role: <get_my_role result>
436
- - Test ticket: <user-supplied ticket key>
437
- - Tier 3 consent: <yes/no>
438
-
439
- ## Summary counts
440
- - PASS: <n>
441
- - PASS_EXPECTED_404: <n>
442
- - FAIL: <n>
443
- - SKIP_USER_INPUT: <n>
444
- - SKIP_NOT_APPROVED: <n>
445
- - SKIP_NOT_APPLICABLE: <n>
446
- - WARN: <n>
447
-
448
- ## Overall verdict
449
- <PASS | PASS_WITH_WARNINGS | FAIL | INCOMPLETE>
450
-
451
- ## Per-tool results
452
- | Tier | Tool | Inputs | Expected result | Actual summary | Verdict | Evidence | File paths | Duration | Notes |
453
- |---|---|---|---|---|---|---|---|---|---|
454
- | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
455
-
456
- ## Host-specific probes
457
- - Boolean serialization probe: <result>
458
- - Optional-parameter omission probe: <result>
459
- - Codex project-root probe: <result>
460
- - Windows separator probe: <result>
461
- - Tier 3 async round-trip probe: <result or skipped>
462
-
463
- ## Path evidence
464
- - get_docs_dir: <exact path>
465
- - Tier 2 HTML file path: <absolute path under docs dir>
466
- - Report file path: <absolute path under docs dir>
467
-
468
- ## Cleanup
469
- v1 default execution creates **no Jira/server-side cleanup requirement**. The
470
- Tier 2 generated HTML decision page is **retained as evidence** that local writes
471
- work. (This section is reserved for future Tier 4 runs.)
472
-
473
- ## Redaction note
474
- This report excludes **secrets, authorization headers, API keys, stack traces,
475
- and raw protocol noise.** Sensitive values are redacted.
476
- ```
477
-
478
- ---
479
-
480
- ## Phase 9 — Cleanup
481
-
482
- - v1 default execution requires **no Jira/server-side cleanup**.
483
- - The Tier 2 `generate_decision_page` HTML file is **kept** as evidence; do not
484
- delete it unless the user asks.
485
- - This section is reserved for future Tier 4 (mutating) runs, which are out of
486
- scope for v1.
487
-
488
- ---
489
-
490
- ## Full 62-Tool Smoke Tier Matrix
491
-
492
- Every registered MCP tool appears **exactly once** below with its smoke tier.
493
- Tier 4 (mutating/hazardous) tools are **deferred in v1**.
494
-
495
- Coverage reconciliation: **7 + 19 + 1 + 13 + 22 = 62** (BAPI-443 Phase 3a: `list_config_fields` merged into `config_field`; `get_config_field`/`list_attachments`/`download_attachment` merged into `config_field`/`attachment`; BAPI-474 added `materialize_fresh_base` + `cleanup_fresh_base` to Tier 4; BAPI-563 added `visual_diff` to Tier 4; BAPI-523 added `estimate_epic` to Tier 3).
496
-
497
- | Tier | Tool | Default action / expected-empty / special handling |
498
- |---|---|---|
499
- | Tier 0 | `ping` | Zero-input read; always run. |
500
- | Tier 0 | `get_my_role` | Zero-input read; always run. |
501
- | Tier 0 | `get_docs_dir` | Zero-input read; always run; call first to anchor writes. |
502
- | Tier 0 | `get_project_standards` | Zero-input heavy read; always run; may save/truncate oversized output under `project-standards/`. |
503
- | Tier 0 | `list_pipelines` | Zero-input read; always run. |
504
- | Tier 0 | `get_parse_status` | Zero-input read; always run. |
505
- | Tier 0 | `list_pipeline_runs` | Zero-input read; always run. |
506
- | Tier 1 | `get_tickets` | Read-only; needs a query/filter. |
507
- | Tier 1 | `get_ticket` | Read-only; needs ticket key (default-pass tool). |
508
- | Tier 1 | `get_ticket_model_tier` | Read-only; needs ticket key; returns a coarse model tier (`cheap`/`basic`/`premium`) for start-tickets routing — `source:"fallback"` with a null tier is a clean `PASS`. |
509
- | Tier 1 | `get_comments` | Read-only; needs ticket key (preferred default-pass tool). |
510
- | Tier 1 | `get_plan` | Artifact retriever; `PASS` with content, `PASS_EXPECTED_404` when cleanly empty; boolean probe target. |
511
- | Tier 1 | `get_architecture` | Artifact retriever; `PASS_EXPECTED_404` when cleanly empty. |
512
- | Tier 1 | `get_doc` | Artifact retriever (tdd/fsd/prd via `doc_type`); `PASS_EXPECTED_404` when cleanly empty. |
513
- | Tier 1 | `get_prd` | Artifact retriever (Product Requirements Document); `PASS_EXPECTED_404` when cleanly empty. |
514
- | Tier 1 | `get_install_manifest` | Read-only; returns the easy-install bootstrap manifest + signed snapshot token; a clean 404 (no config row) is `PASS_EXPECTED_404`. |
515
- | Tier 1 | `get_clarifying_questions` | Artifact retriever; `PASS_EXPECTED_404` when cleanly empty. |
516
- | Tier 1 | `get_ticket_critique` | Artifact retriever; `PASS_EXPECTED_404` when cleanly empty. |
517
- | Tier 1 | `get_reimplement_context` | Artifact retriever; valid live-assembled content is `PASS`; a clean 404 is `PASS_EXPECTED_404` — the clean 404 is not the only expected outcome. |
518
- | Tier 1 | `get_deep_research` | Artifact retriever; requires a Tier 3-produced `task_id`; `PASS_EXPECTED_404` when cleanly empty. |
519
- | Tier 1 | `get_brainstorm` | Artifact retriever; requires a Tier 3-produced `brainstorm_id`; `PASS_EXPECTED_404` when cleanly empty. |
520
- | Tier 1 | `get_ticket_state` | Read-only; needs ticket key; v1 read-only reaches the clean "not tracked" 404; full state requires deferred Tier 4 `track_ticket`. |
521
- | Tier 1 | `get_jira_transitions` | Read-only; needs ticket key. |
522
- | Tier 1 | `resolve_target_status` | Read-only; needs ticket key. |
523
- | Tier 1 | `poll_ci_checks` | `available:true` with empty or populated checks is `PASS`; `SKIP_NOT_APPLICABLE` when disabled with `TOOL_DISABLED`/503, or when `resolve_ci_checks` has not populated CI configuration. |
524
- | Tier 1 | `get_pipeline_recipe` | Read-only; needs a pipeline name plus required variables for variable-declaring pipelines; use `learn-repository` as the no-variable smoke target. |
525
- | Tier 2 | `generate_decision_page` | Local-only file-write canary; always run with the verbatim payload above. |
526
- | Tier 3 | `second_opinion` | Single-call (absorbs async polling under the hood — H12-safe); token-costing; opt-in. A ~5-min recoverable-result message is `PASS`, not a failure. |
527
- | Tier 3 | `generate_image` | Synchronous, token/credit-costing; spends provider credits; opt-in. |
528
- | Tier 3 | `request_plan_generation` | Async (ticket-key based); retrieve with `get_plan`; opt-in. |
529
- | Tier 3 | `request_architecture` | Async (ticket-key based); retrieve with `get_architecture`; opt-in. |
530
- | Tier 3 | `create_doc` | Async (ticket-key based; `doc_type` tdd/fsd/prd); retrieve with `get_doc`; opt-in. |
531
- | Tier 3 | `request_prd` | Async (ticket-key based; Product Requirements Document); retrieve with `get_prd`; opt-in. |
532
- | Tier 3 | `request_clarifying_questions` | Async (ticket-key based); retrieve with `get_clarifying_questions`; opt-in. |
533
- | Tier 3 | `request_ticket_critique` | Async (ticket-key based); retrieve with `get_ticket_critique`; opt-in. |
534
- | Tier 3 | `request_ticket_review` | Async submit; retrieve with `get_clarifying_questions` + `get_ticket_critique`; opt-in. |
535
- | Tier 3 | `request_reimplement_context` | Async (ticket-key based); retrieve with `get_reimplement_context`; opt-in. |
536
- | Tier 3 | `request_deep_research` | Async; returns `task_id`; retrieve with `get_deep_research`; opt-in. |
537
- | Tier 3 | `request_brainstorm` | Async; returns `brainstorm_id`; retrieve with `get_brainstorm`; opt-in. |
538
- | Tier 3 | `estimate_epic` | Synchronous, token-costing epic estimation orchestrator (`epic_key` or explicit `ticket_keys`); returns the estimate in one call; opt-in. |
539
- | Tier 4 | `create_ticket` | Mutating; deferred in v1. |
540
- | Tier 4 | `add_comment` | Mutating; deferred in v1. |
541
- | Tier 4 | `update_ticket_description` | Mutating; deferred in v1. |
542
- | Tier 4 | `attachment` | Discriminated-union: `upload`/`download`/`list`; classified Tier 4 (upload is mutating); deferred in v1. |
543
- | Tier 4 | `track_ticket` | Mutating; deferred in v1. |
544
- | Tier 4 | `update_ticket_state` | Mutating; deferred in v1. |
545
- | Tier 4 | `update_jira_status` | Mutating; deferred in v1. |
546
- | Tier 4 | `config_field` | Discriminated-union: `get`/`update`/`list`; classified Tier 4 (update is mutating); deferred in v1. |
547
- | Tier 4 | `create_pull_request` | Mutating; deferred in v1. |
548
- | Tier 4 | `resolve_ci_checks` | Cache-mutating/orchestration; deferred in v1. |
549
- | Tier 4 | `run_pipeline` | Orchestration (can dispatch mutating tools); deferred in v1. |
550
- | Tier 4 | `resume_pipeline` | Orchestration; deferred in v1. |
551
- | Tier 4 | `delete_pipeline_run` | Mutating (deletes run state); deferred in v1. |
552
- | Tier 4 | `parse_repository` | Hazardous (Pinecone index); deferred in v1. |
553
- | Tier 4 | `regenerate_directory_map` | Hazardous; deferred in v1. |
554
- | Tier 4 | `run_full_automation` | Orchestration (dispatches mutating child pipelines / spawns worktrees); deferred in v1. |
555
- | Tier 4 | `resume_full_automation` | Orchestration; deferred in v1. |
556
- | Tier 4 | `apply_install_manifest` | Mutating (atomically writes easy-install config across the four config tables); deferred in v1. |
557
- | Tier 4 | `persist_routing_credential` | Mutating (writes the routing credential to the user-scoped store `~/.config/bridge/credentials.json`); deferred in v1. |
558
- | Tier 4 | `materialize_fresh_base` | Network + filesystem side effects (`git fetch` + `git archive` into a temp dir); deferred in v1. |
559
- | Tier 4 | `cleanup_fresh_base` | Mutating (deletes a review workspace temp directory); deferred in v1. |
560
- | Tier 4 | `visual_diff` | Launches a headless browser, opens `target_url`, and writes a local heatmap artifact (network + browser + filesystem side effects); deferred in v1. |
@@ -1,23 +0,0 @@
1
- # Smoke Test MCP
2
-
3
- Run the Bridge API MCP cross-platform smoke test inside this host. This command
4
- is a **thin pointer** — it does not contain the test logic itself.
5
-
6
- ## What to do
7
-
8
- 1. Locate and read the canonical runbook **`SMOKE-TEST.md`** from the same
9
- `smoke-test/` directory these assets ship in, then execute it step by step.
10
- - **Local repo development:** `mcp_server/smoke-test/SMOKE-TEST.md`
11
- - **Package consumers:** `node_modules/@bridge_gpt/mcp-server/smoke-test/SMOKE-TEST.md`
12
- 2. Follow `SMOKE-TEST.md` exactly: it is **authoritative**. Collect inputs, run
13
- the tiered tool checks, grade each result by inspecting response content, and
14
- write the report.
15
- 3. Write the report **under the docs directory returned by `get_docs_dir`** — at
16
- `<docs_dir>/smoke-test/REPORT-<host>-<timestamp>.md`, as the runbook specifies.
17
-
18
- ## Do not duplicate the runbook
19
-
20
- This command must **not** restate or re-derive the runbook's logic. `SMOKE-TEST.md`
21
- owns the tier model, the verdict rules, the Tier 2 canary payload, the host
22
- probes, the full tool matrix, and the report template. If `SMOKE-TEST.md` and
23
- this file ever disagree, **`SMOKE-TEST.md` wins.**