@stacknext/cli 0.6.1 → 0.8.0
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/dist/collector/server.d.ts +3 -1
- package/dist/collector/server.d.ts.map +1 -1
- package/dist/collector/server.js +385 -15
- package/dist/collector/server.js.map +1 -1
- package/dist/commands/dev.d.ts.map +1 -1
- package/dist/commands/dev.js +87 -19
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/diagnose.d.ts.map +1 -1
- package/dist/commands/diagnose.js +36 -3
- package/dist/commands/diagnose.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +1 -0
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/skill.d.ts +34 -0
- package/dist/commands/skill.d.ts.map +1 -0
- package/dist/commands/skill.js +121 -0
- package/dist/commands/skill.js.map +1 -0
- package/dist/commands/snapshot.d.ts +36 -0
- package/dist/commands/snapshot.d.ts.map +1 -0
- package/dist/commands/snapshot.js +286 -0
- package/dist/commands/snapshot.js.map +1 -0
- package/dist/commands/uninstall.d.ts.map +1 -1
- package/dist/commands/uninstall.js +18 -5
- package/dist/commands/uninstall.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/program.d.ts.map +1 -1
- package/dist/program.js +4 -0
- package/dist/program.js.map +1 -1
- package/dist/runtime.d.ts +17 -0
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +148 -4
- package/dist/runtime.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +8 -7
- package/skills/stacknext-debugging/SKILL.md +306 -0
- package/skills/stacknext-debugging/references/setup.md +228 -0
- package/skills/stacknext-debugging/references/tools.md +369 -0
- package/skills/stacknext-debugging/references/workflows.md +332 -0
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: stacknext-debugging
|
|
3
|
+
description: Investigate Next.js App Router runtime behavior with StackNext's local telemetry. Use when debugging server errors, slow requests, database query activity, request traces or deterministic diagnostic findings, or when comparing captured Playwright runs against baselines or inspecting saved snapshots, in a Next.js 15/16 app that has StackNext installed; when asked to use StackNext, its MCP tools or dashboard; or when runtime evidence is needed before changing code. Covers the twenty read-only MCP tools, evidence-first workflows, finding verification, runtime regression evidence, saved snapshot evidence, redaction limits and missing-telemetry troubleshooting.
|
|
4
|
+
license: MIT
|
|
5
|
+
compatibility: Next.js 15 or 16 App Router on the Node.js runtime, with a local StackNext collector. No cloud account, AI API key, or remote service is required.
|
|
6
|
+
metadata:
|
|
7
|
+
version: "0.8.0"
|
|
8
|
+
author: StackNext
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# StackNext debugging
|
|
12
|
+
|
|
13
|
+
Use StackNext as the runtime evidence source for a Next.js App Router app. The
|
|
14
|
+
collector, dashboard and MCP server run on the developer's machine. The MCP
|
|
15
|
+
server is read-only: it can inspect captured telemetry, saved regression records
|
|
16
|
+
and saved snapshots but cannot change the app, replay requests, capture runs,
|
|
17
|
+
save baselines, run comparisons, save or delete snapshots, read source files,
|
|
18
|
+
run SQL or call an AI service.
|
|
19
|
+
|
|
20
|
+
## Before investigating
|
|
21
|
+
|
|
22
|
+
1. Confirm the StackNext MCP tools are available. If they are not, read
|
|
23
|
+
`references/setup.md` and ask the user to start `stacknext dev`.
|
|
24
|
+
2. Call `get_project_summary` first. It reports the project, connection state,
|
|
25
|
+
counts, latency, recent errors, instrumentation coverage and the current
|
|
26
|
+
retention window.
|
|
27
|
+
3. If `meta.connection.instrumentation` is `waiting`, no app is connected. Ask
|
|
28
|
+
the user to start the app through `stacknext dev` and make a request. Do not
|
|
29
|
+
invent telemetry or diagnose from an empty store.
|
|
30
|
+
4. If the collector is unreachable, stop and report the exact error. Do not
|
|
31
|
+
retry indefinitely or switch to guessing.
|
|
32
|
+
5. For deterministic candidates, call `stacknext_list_diagnostics`, then
|
|
33
|
+
`stacknext_get_diagnostic` for the finding you intend to use.
|
|
34
|
+
|
|
35
|
+
## Mandatory reasoning rules
|
|
36
|
+
|
|
37
|
+
- **Evidence first.** Every claim about runtime behavior must cite a tool result:
|
|
38
|
+
a route, trace id, error id, span name, duration, status code, query, finding
|
|
39
|
+
id or measurement.
|
|
40
|
+
- **Observation is not causation.** Diagnostic findings are deterministic
|
|
41
|
+
heuristics, not confirmed root causes. `possible` means the pattern is
|
|
42
|
+
consistent with a problem; `observed` means the evidence was measured. Neither
|
|
43
|
+
proves why the app behaves this way.
|
|
44
|
+
- **Verify before recommending.** Check the referenced trace, error, query or
|
|
45
|
+
span evidence. Read `verification` and `limitations`. State what remains
|
|
46
|
+
unproven.
|
|
47
|
+
- **Regression evidence is proven, not guessed.** A scenario sample is
|
|
48
|
+
`verified` only when the collector found the injected trace and a server span
|
|
49
|
+
parented to the injected span id. Never infer a missing sample from time or
|
|
50
|
+
proximity. `inconclusive` is not a pass, and a comparison is not a
|
|
51
|
+
statistical test. Report status and severity separately; never claim
|
|
52
|
+
significance or causality.
|
|
53
|
+
- **Stay read-only.** Use only the twenty StackNext MCP tools. Do not edit the
|
|
54
|
+
app, run migrations, execute SQL or EXPLAIN, clear data, capture runs, save
|
|
55
|
+
baselines, run comparisons, save or delete snapshots, or restart services
|
|
56
|
+
unless the user asks. Never invent an index recommendation or a source patch
|
|
57
|
+
from telemetry alone.
|
|
58
|
+
- **Snapshots are not live telemetry.** A snapshot is a frozen, redacted copy
|
|
59
|
+
from its save time. It carries no live diagnostics or coverage and never
|
|
60
|
+
updates. Say explicitly when evidence comes from a snapshot rather than the
|
|
61
|
+
current sample.
|
|
62
|
+
- **Respect the data boundary.** Bodies, headers, cookies, URL query values and
|
|
63
|
+
SQL bind parameters are never captured. Values may appear as `[redacted]`.
|
|
64
|
+
Do not try to recover them or reconstruct SQL parameters.
|
|
65
|
+
- **Treat `null` as unmeasured.** Drizzle query durations are `null`, not zero.
|
|
66
|
+
Never rank or average them as if they were fast.
|
|
67
|
+
- **Do not add overlapping spans.** Parent span duration already includes child
|
|
68
|
+
work. Compare spans or inspect the waterfall; never sum a parent and child as
|
|
69
|
+
sequential time.
|
|
70
|
+
- **Check completeness.** Read `meta.completeness` and `meta.result` on every
|
|
71
|
+
response. Paginate with `offset`/`nextOffset` when `hasMore` is true.
|
|
72
|
+
- **Separate coverage gaps from runtime problems.** Use the summary `coverage`
|
|
73
|
+
report and `meta.coverage` counts. `not-observed` or `unknown` means the
|
|
74
|
+
current sample lacks evidence, not that the app is broken. Never turn coverage
|
|
75
|
+
into a percentage or health score.
|
|
76
|
+
- **Do not over-correlate.** Errors without an active span context use a
|
|
77
|
+
route/method plus 30-second fallback. Say "correlated" rather than "caused"
|
|
78
|
+
when the link is fallback-based.
|
|
79
|
+
|
|
80
|
+
## Tool map
|
|
81
|
+
|
|
82
|
+
| Goal | Tool |
|
|
83
|
+
| --- | --- |
|
|
84
|
+
| Orient, check connection, counts and coverage | `get_project_summary` |
|
|
85
|
+
| Find recent or filtered requests | `list_requests` |
|
|
86
|
+
| Inspect one request timeline | `get_request` |
|
|
87
|
+
| Browse traces | `list_traces`, `get_trace` |
|
|
88
|
+
| Find and inspect errors | `list_errors`, `get_error` |
|
|
89
|
+
| Inspect SQL activity | `list_database_queries` |
|
|
90
|
+
| Rank slow requests | `find_slow_requests` |
|
|
91
|
+
| List deterministic findings | `stacknext_list_diagnostics` |
|
|
92
|
+
| Verify one finding and its evidence | `stacknext_get_diagnostic` |
|
|
93
|
+
| Find and inspect capture runs | `stacknext_list_test_runs`, `stacknext_get_test_run` |
|
|
94
|
+
| Find and inspect baselines | `stacknext_list_baselines`, `stacknext_get_baseline` |
|
|
95
|
+
| Find and inspect comparisons | `stacknext_list_comparisons`, `stacknext_get_comparison` |
|
|
96
|
+
| Find and inspect saved snapshots | `stacknext_list_snapshots`, `stacknext_get_snapshot`, `stacknext_get_snapshot_trace` |
|
|
97
|
+
|
|
98
|
+
All list tools accept `limit` (1-200) and `offset`. The default limit is 50.
|
|
99
|
+
`list_errors` omits stacks unless `includeStack: true`; use `get_error` for the
|
|
100
|
+
full stack. See `references/tools.md` for every argument and response field.
|
|
101
|
+
|
|
102
|
+
If the client supports MCP prompts, these guided entry points are available:
|
|
103
|
+
`diagnose-error`, `investigate-slow-request`, `inspect-database-activity`,
|
|
104
|
+
`investigate-trace` and `diagnose-runtime-issue`. They only shape the
|
|
105
|
+
investigation; the same evidence rules apply.
|
|
106
|
+
|
|
107
|
+
## Workflow A: runtime error
|
|
108
|
+
|
|
109
|
+
1. `get_project_summary` to confirm errors exist and note the time window.
|
|
110
|
+
2. `list_errors` filtered by `route`, `name` or `q`. Start without
|
|
111
|
+
`includeStack` to keep context small.
|
|
112
|
+
3. Pick the latest matching error and call `get_error` with its `id`.
|
|
113
|
+
4. Read the redacted message, stack, route and `resolvedTraceId`.
|
|
114
|
+
5. If a trace is present, inspect it with `get_trace` or `get_request`: find the
|
|
115
|
+
failing span, status message, and any database query that failed.
|
|
116
|
+
6. Call `stacknext_list_diagnostics` with `category: "errors"` or the trace id to
|
|
117
|
+
check whether the error belongs to a repeated group. Verify the group with
|
|
118
|
+
`stacknext_get_diagnostic`; grouping does not prove a shared cause.
|
|
119
|
+
7. Separate the application failure from telemetry gaps. Report what is proven,
|
|
120
|
+
what is correlated, and what remains unknown.
|
|
121
|
+
|
|
122
|
+
## Workflow B: slow request
|
|
123
|
+
|
|
124
|
+
1. `get_project_summary` for baseline latency and the slow threshold.
|
|
125
|
+
2. `find_slow_requests` with a threshold appropriate to the question
|
|
126
|
+
(default 500 ms), then `list_requests` with `sort: "slowest"` if you need a
|
|
127
|
+
broader set.
|
|
128
|
+
3. Call `get_request` for the slowest relevant trace.
|
|
129
|
+
4. Break down the timeline: total duration, longest spans, route/render spans,
|
|
130
|
+
fetch spans, and database queries inside the request.
|
|
131
|
+
5. Call `stacknext_list_diagnostics` with `category: "performance"` or the trace
|
|
132
|
+
id. A `slow-request` finding groups requests by route and lists self-time
|
|
133
|
+
contributors. A `slow-span` finding names a non-root span whose self time
|
|
134
|
+
crossed its category threshold and is suppressed when the request is already
|
|
135
|
+
reported as slow. Verify the contributor in the trace before calling it the
|
|
136
|
+
bottleneck.
|
|
137
|
+
6. Compare similar routes or requests. Use `list_requests` with `q`, `method`,
|
|
138
|
+
`status` and `minDurationMs` to test whether the slowdown is isolated.
|
|
139
|
+
7. Report the measured bottleneck. If query durations are `null`, say the
|
|
140
|
+
database time is unmeasured rather than blaming the database.
|
|
141
|
+
|
|
142
|
+
## Workflow C: database investigation
|
|
143
|
+
|
|
144
|
+
1. `get_project_summary` to see whether queries were captured at all.
|
|
145
|
+
2. `list_database_queries` with `q`, `databaseSystem`, `traceId` or
|
|
146
|
+
`minDurationMs` as needed.
|
|
147
|
+
3. Note `source`, `success`, `durationMs` and `resolvedTraceId`. A query with a
|
|
148
|
+
`null` duration is unmeasured.
|
|
149
|
+
4. Call `stacknext_list_diagnostics` with `category: "database"` and inspect any
|
|
150
|
+
`n-plus-one-queries` finding. It requires the normalized SQL shape to repeat
|
|
151
|
+
within a trace, then aggregates matching traces by canonical Next.js route;
|
|
152
|
+
it does not prove an ORM loading bug.
|
|
153
|
+
5. For failures, read `errorMessage` and open the correlated request with
|
|
154
|
+
`get_request`.
|
|
155
|
+
6. For slow requests, compare query counts and SQL shapes across traces. Do not
|
|
156
|
+
claim a query is slow when its duration is `null`.
|
|
157
|
+
7. Report query text only as the redacted SQL that StackNext returned.
|
|
158
|
+
|
|
159
|
+
## Workflow D: general runtime investigation
|
|
160
|
+
|
|
161
|
+
Use this when the question is broad ("what is happening in this app?") or the
|
|
162
|
+
symptom is unclear.
|
|
163
|
+
|
|
164
|
+
1. `get_project_summary`: counts, error rate, latency, recent errors.
|
|
165
|
+
2. `stacknext_list_diagnostics` with no filters or a narrow category/severity.
|
|
166
|
+
Read the sample window, counts, notes and limitations before the items.
|
|
167
|
+
3. `list_requests` sorted by `recent` and by `slowest` to find outliers.
|
|
168
|
+
4. `list_traces` if you need traces without request roots.
|
|
169
|
+
5. `list_errors` and `list_database_queries` to cover failures and data access.
|
|
170
|
+
6. Open one representative trace with `get_trace`; check span tree,
|
|
171
|
+
`missingParentSpanIds`, errors and queries.
|
|
172
|
+
7. Form at most three hypotheses. Test each with a targeted filter or a second
|
|
173
|
+
trace. Stop when evidence is sufficient; do not keep browsing.
|
|
174
|
+
|
|
175
|
+
## Workflow E: diagnostic findings
|
|
176
|
+
|
|
177
|
+
Use this when the user asks what StackNext found, or when a finding may explain a
|
|
178
|
+
symptom.
|
|
179
|
+
|
|
180
|
+
1. `get_project_summary` to confirm the sample and connection state.
|
|
181
|
+
2. `stacknext_list_diagnostics` with the narrowest useful filters:
|
|
182
|
+
`category`, `severity`, `status`, `ruleId`, `route`, `traceId`, `since`,
|
|
183
|
+
`until`, `q`, `limit` and `offset`.
|
|
184
|
+
3. Read `counts`, `sample`, `notes` and `limitations`. `total` is the number of
|
|
185
|
+
matching findings; only `items` are on this page.
|
|
186
|
+
4. Pick one finding and call `stacknext_get_diagnostic` with its id. It returns
|
|
187
|
+
bounded finding evidence plus a related trace reference.
|
|
188
|
+
5. Verify the evidence:
|
|
189
|
+
- `n-plus-one-queries`: check `affectedTraceCount`, the per-trace query count
|
|
190
|
+
and normalized SQL shape, then inspect the calling code separately. Do not
|
|
191
|
+
guess bind values.
|
|
192
|
+
- `slow-request`: check the route-level duration distribution and the
|
|
193
|
+
self-time contributors. Self time subtracts direct children; it attributes
|
|
194
|
+
time but does not prove causality.
|
|
195
|
+
- `slow-span`: check the measured self time, inclusive duration and Next.js
|
|
196
|
+
phase in the trace. It is only emitted when the enclosing request stayed
|
|
197
|
+
below the request threshold.
|
|
198
|
+
- `repeated-external-http`: check the endpoint shape and whether the calls are
|
|
199
|
+
independent or retries; findings aggregate matching traces by route.
|
|
200
|
+
- `error-fingerprint`: check the latest error, its Next.js context and the
|
|
201
|
+
deepest error span. Findings group by canonical route over a route-
|
|
202
|
+
independent signature; control-flow errors are excluded.
|
|
203
|
+
- `server-error-response`: the request root returned 5xx without a correlated
|
|
204
|
+
non-control-flow error. The status is proven; the cause is not.
|
|
205
|
+
6. If the trace is truncated in the detail response, call `get_trace` with the
|
|
206
|
+
returned trace id. If the evidence is insufficient, say so.
|
|
207
|
+
7. Report the finding id, rule, status, severity, evidence checked, what remains
|
|
208
|
+
unproven and one concrete next step.
|
|
209
|
+
|
|
210
|
+
## Workflow F: runtime regression evidence
|
|
211
|
+
|
|
212
|
+
Use this when the user asks whether a Playwright-covered flow regressed, or asks
|
|
213
|
+
about a capture run, baseline or comparison.
|
|
214
|
+
|
|
215
|
+
1. `get_project_summary` to confirm the collector state. Regression records are
|
|
216
|
+
local files under `.stacknext`, not retention-window telemetry; an empty
|
|
217
|
+
telemetry store does not imply the records are missing.
|
|
218
|
+
2. `stacknext_list_test_runs` to find the run, then `stacknext_get_test_run`.
|
|
219
|
+
Read its `status`, `stats`, scenarios and samples. A sample is verified only
|
|
220
|
+
when the collector found the injected trace and a server span parented to the
|
|
221
|
+
injected span id. Report incomplete correlation with its reason; never infer
|
|
222
|
+
a missing sample from time or proximity.
|
|
223
|
+
3. `stacknext_list_baselines` and `stacknext_get_baseline` for the immutable
|
|
224
|
+
baseline. Check `sourceRunId`, environment, scenarios and limitations.
|
|
225
|
+
4. `stacknext_list_comparisons`, then `stacknext_get_comparison` for the
|
|
226
|
+
deterministic result. Read `environment.compatible` and differences,
|
|
227
|
+
top-level `status`/`severity`, per-scenario `reasons`, metrics and warnings.
|
|
228
|
+
5. Explain status and severity separately: `improved`, `regressed`, `unchanged`
|
|
229
|
+
or `inconclusive`, with `high`/`medium`/`low`/`none` severity. `inconclusive`
|
|
230
|
+
is not a pass. A `regressed` metric is not a confirmed cause and is not
|
|
231
|
+
statistically significant.
|
|
232
|
+
6. If the records are missing, say so. The MCP tools are read-only: do not
|
|
233
|
+
capture runs, save baselines or compare records yourself. Point the user to
|
|
234
|
+
`stacknext capture`, `stacknext baseline save` and `stacknext compare`, and
|
|
235
|
+
never fabricate a comparison from telemetry.
|
|
236
|
+
|
|
237
|
+
## Workflow G: saved snapshot evidence
|
|
238
|
+
|
|
239
|
+
Use this when the live retention window no longer contains the reproduction, or
|
|
240
|
+
the user asks about a saved snapshot.
|
|
241
|
+
|
|
242
|
+
1. `stacknext_list_snapshots` to find the snapshot by source, label, time and
|
|
243
|
+
sample window. `manual` and `import` records never rotate; `exit` and `error`
|
|
244
|
+
records keep the newest ten by default.
|
|
245
|
+
2. `stacknext_get_snapshot` with the `snapshotId`. Read `snapshot.sample`,
|
|
246
|
+
`snapshot.stats`, `config`, `limitations` and the first traces/errors/queries.
|
|
247
|
+
3. Pick a trace and call `stacknext_get_snapshot_trace` with both the
|
|
248
|
+
`snapshotId` and `traceId`. This is a scoped read from the frozen sample and
|
|
249
|
+
intentionally has no `diagnostics` array.
|
|
250
|
+
4. If no snapshot exists, say so. The MCP tools cannot save, import, rotate or
|
|
251
|
+
delete one; point the user to `stacknext snapshot save` or the dashboard
|
|
252
|
+
`/snapshots` page and do not create a file yourself.
|
|
253
|
+
5. If the question is about current behavior, say that the snapshot cannot
|
|
254
|
+
answer it and inspect the live sample instead. Never replay a snapshot or
|
|
255
|
+
treat it as current telemetry.
|
|
256
|
+
|
|
257
|
+
## Coverage checks
|
|
258
|
+
|
|
259
|
+
Use this when telemetry is missing, or the user asks whether a feature is
|
|
260
|
+
instrumented.
|
|
261
|
+
|
|
262
|
+
1. `get_project_summary` and read `coverage.sample`, `coverage.items` and
|
|
263
|
+
`meta.coverage`.
|
|
264
|
+
2. Separate the cases:
|
|
265
|
+
- `observed`: evidence exists in this sample.
|
|
266
|
+
- `active`: the app is connected but no request has exercised it yet.
|
|
267
|
+
- `configured`: no app is connected; this is setup intent, not runtime proof.
|
|
268
|
+
- `not-observed`: requests were captured but no matching evidence appeared,
|
|
269
|
+
or the feature is disabled.
|
|
270
|
+
- `unknown`: the sample and config cannot determine the state.
|
|
271
|
+
- `unsupported`: an intentional boundary.
|
|
272
|
+
3. Check the item `limitations` and `evidence` fields. Do not recommend code
|
|
273
|
+
changes from absence alone.
|
|
274
|
+
4. If the feature is enabled but not exercised, ask the user for a request that
|
|
275
|
+
uses it (for example a page render, fetch, action or database query), then
|
|
276
|
+
call `get_project_summary` again.
|
|
277
|
+
5. Report the status, sample window, evidence count/last-seen time and the
|
|
278
|
+
concrete next step. Say "not observed in this sample" rather than "broken".
|
|
279
|
+
|
|
280
|
+
## Reporting
|
|
281
|
+
|
|
282
|
+
Use a compact evidence-first structure:
|
|
283
|
+
|
|
284
|
+
```text
|
|
285
|
+
Finding: <one sentence; include finding id/rule if one was used>
|
|
286
|
+
Evidence: <tool, route/trace/error id, duration/status/count/query/finding id>
|
|
287
|
+
Correlation: exact span context | route+time fallback | unknown
|
|
288
|
+
Completeness: <pagination, drops, missing parents, null durations>
|
|
289
|
+
Coverage: <observed/not-observed/unknown/unsupported, or "not relevant">
|
|
290
|
+
Regression: <status/severity and verified sample counts, or "not relevant">
|
|
291
|
+
Snapshot: <snapshot id, source and save time, or "live sample">
|
|
292
|
+
Unproven: <what the evidence cannot establish>
|
|
293
|
+
Next step: <single concrete action, or "none">
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
If no telemetry matches, say so and list the checks performed. A missing result
|
|
297
|
+
is evidence about the collector window or instrumentation, not proof that the
|
|
298
|
+
bug does not exist. Never present a diagnostic finding as a confirmed root cause,
|
|
299
|
+
never present an inconclusive comparison as a pass, and never present a snapshot
|
|
300
|
+
as current live telemetry.
|
|
301
|
+
|
|
302
|
+
## References
|
|
303
|
+
|
|
304
|
+
- `references/tools.md` — tool arguments, response shapes and `meta`.
|
|
305
|
+
- `references/workflows.md` — detailed investigation playbooks and report examples.
|
|
306
|
+
- `references/setup.md` — install, MCP configuration, skill locations and troubleshooting.
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
# Setup and troubleshooting
|
|
2
|
+
|
|
3
|
+
StackNext is local-first. It needs no cloud account, AI subscription or API key.
|
|
4
|
+
The collector and MCP server run on the developer's machine and only talk over
|
|
5
|
+
loopback. The MCP server is read-only.
|
|
6
|
+
|
|
7
|
+
## 1. Start StackNext
|
|
8
|
+
|
|
9
|
+
From the Next.js app directory:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
pnpm exec stacknext dev
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
`dev` starts the collector and the app's own `dev` script, then writes
|
|
16
|
+
`.stacknext/run.json` with a short-lived bearer token. Leave it running.
|
|
17
|
+
|
|
18
|
+
If the project is not set up yet, see the repository's
|
|
19
|
+
[docs/getting-started.md](../../../docs/getting-started.md). In a source
|
|
20
|
+
checkout, run `pnpm install && pnpm build` first.
|
|
21
|
+
|
|
22
|
+
Check the collector and instrumentation:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pnpm exec stacknext status
|
|
26
|
+
pnpm exec stacknext doctor
|
|
27
|
+
pnpm exec stacknext coverage
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## 2. Install the skill
|
|
31
|
+
|
|
32
|
+
From the app project root, run the command for your client:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
pnpm exec stacknext skill install --client opencode
|
|
36
|
+
pnpm exec stacknext skill install --client codex
|
|
37
|
+
pnpm exec stacknext skill install --client claude-code
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
The skill ships inside `@stacknext/cli`. The command copies the whole directory,
|
|
41
|
+
including `references/`, into the client's project skill path. Use `--force` to
|
|
42
|
+
replace an existing copy; `stacknext skill path` prints the bundled location.
|
|
43
|
+
|
|
44
|
+
| Client | Project skill location |
|
|
45
|
+
| --- | --- |
|
|
46
|
+
| OpenCode | `.opencode/skills/stacknext-debugging/`, `.claude/skills/...` or `.agents/skills/...` |
|
|
47
|
+
| Codex | `.agents/skills/stacknext-debugging/` |
|
|
48
|
+
| Claude Code | `.claude/skills/stacknext-debugging/` |
|
|
49
|
+
|
|
50
|
+
For a project that uses more than one client, keep one copy in
|
|
51
|
+
`.agents/skills/stacknext-debugging/` for OpenCode and Codex, and copy it to
|
|
52
|
+
`.claude/skills/stacknext-debugging/` for Claude Code. Reload or restart the
|
|
53
|
+
client if it does not discover the new skill automatically.
|
|
54
|
+
|
|
55
|
+
When working from a source checkout before packing, `skill install` also falls
|
|
56
|
+
back to the repository's `skills/stacknext-debugging` directory.
|
|
57
|
+
|
|
58
|
+
Do not modify a user's global skill directory or global instructions without
|
|
59
|
+
asking. Project-level files are easier to review and remove.
|
|
60
|
+
|
|
61
|
+
## 3. Configure MCP
|
|
62
|
+
|
|
63
|
+
Use an absolute path to the app. The MCP process must start in (or be pointed
|
|
64
|
+
at) the app directory so it can read `.stacknext/run.json`.
|
|
65
|
+
|
|
66
|
+
### OpenCode
|
|
67
|
+
|
|
68
|
+
Add to `opencode.json` (project root) or the global OpenCode config. OpenCode V2
|
|
69
|
+
stores servers under `mcp.servers`:
|
|
70
|
+
|
|
71
|
+
```json
|
|
72
|
+
{
|
|
73
|
+
"$schema": "https://opencode.ai/config.json",
|
|
74
|
+
"mcp": {
|
|
75
|
+
"servers": {
|
|
76
|
+
"stacknext": {
|
|
77
|
+
"type": "local",
|
|
78
|
+
"command": [
|
|
79
|
+
"pnpm",
|
|
80
|
+
"--dir",
|
|
81
|
+
"/absolute/path/to/your-app",
|
|
82
|
+
"exec",
|
|
83
|
+
"stacknext",
|
|
84
|
+
"mcp"
|
|
85
|
+
],
|
|
86
|
+
"codemode": false
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
`codemode: false` exposes the twenty tools directly. If you leave Code Mode
|
|
94
|
+
on, the tools are grouped as `tools.stacknext.<tool>`.
|
|
95
|
+
|
|
96
|
+
### Codex
|
|
97
|
+
|
|
98
|
+
Add to `~/.codex/config.toml` or a trusted project's `.codex/config.toml`:
|
|
99
|
+
|
|
100
|
+
```toml
|
|
101
|
+
[mcp_servers.stacknext]
|
|
102
|
+
command = "pnpm"
|
|
103
|
+
args = ["--dir", "/absolute/path/to/your-app", "exec", "stacknext", "mcp"]
|
|
104
|
+
cwd = "/absolute/path/to/your-app"
|
|
105
|
+
startup_timeout_sec = 20
|
|
106
|
+
tool_timeout_sec = 30
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Codex reads the server's `instructions` during initialization and discovers
|
|
110
|
+
repository skills in `.agents/skills/`.
|
|
111
|
+
|
|
112
|
+
### Claude Code
|
|
113
|
+
|
|
114
|
+
Add the server with the CLI:
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
claude mcp add --scope project stacknext -- \
|
|
118
|
+
pnpm --dir /absolute/path/to/your-app exec stacknext mcp
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Or add a project `.mcp.json`:
|
|
122
|
+
|
|
123
|
+
```json
|
|
124
|
+
{
|
|
125
|
+
"mcpServers": {
|
|
126
|
+
"stacknext": {
|
|
127
|
+
"command": "pnpm",
|
|
128
|
+
"args": [
|
|
129
|
+
"--dir",
|
|
130
|
+
"/absolute/path/to/your-app",
|
|
131
|
+
"exec",
|
|
132
|
+
"stacknext",
|
|
133
|
+
"mcp"
|
|
134
|
+
]
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Verify with `claude mcp list` and `claude mcp get stacknext`. Claude Code
|
|
141
|
+
discovers project skills in `.claude/skills/`.
|
|
142
|
+
|
|
143
|
+
### Other MCP clients
|
|
144
|
+
|
|
145
|
+
Use the stdio command form:
|
|
146
|
+
|
|
147
|
+
```json
|
|
148
|
+
{
|
|
149
|
+
"command": "pnpm",
|
|
150
|
+
"args": ["--dir", "/absolute/path/to/your-app", "exec", "stacknext", "mcp"]
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
If `stacknext` is installed globally, `"command": "stacknext"` with
|
|
155
|
+
`"args": ["mcp"]` also works. Do not use SSE, HTTP or a remote proxy: the MCP
|
|
156
|
+
server is designed for local stdio and refuses non-loopback collector URLs.
|
|
157
|
+
|
|
158
|
+
## 4. Verify the connection
|
|
159
|
+
|
|
160
|
+
Ask the client to call `get_project_summary`. A healthy response has
|
|
161
|
+
`meta.connection.instrumentation: "connected"` and a non-empty project name.
|
|
162
|
+
Then make a request to the app and call `list_requests`.
|
|
163
|
+
|
|
164
|
+
The six regression tools read saved records from `.stacknext/runs`,
|
|
165
|
+
`.stacknext/baselines` and `.stacknext/comparisons`. They do not create records.
|
|
166
|
+
Capture runs, baselines and comparisons are written by the CLI:
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
pnpm exec stacknext capture --name before -- pnpm exec playwright test --workers=1
|
|
170
|
+
pnpm exec stacknext baseline save --run <run-id> --name main
|
|
171
|
+
pnpm exec stacknext compare <baseline-id> <candidate-run-id>
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
See [runtime regression testing](../../../docs/regression-testing.md) and
|
|
175
|
+
[Playwright integration](../../../docs/playwright-integration.md).
|
|
176
|
+
|
|
177
|
+
The three snapshot tools read frozen records from `.stacknext/snapshots`. They
|
|
178
|
+
cannot save, import, rotate or delete a snapshot. Save one from the dashboard
|
|
179
|
+
`/snapshots` page or the CLI while the collector is running:
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
pnpm exec stacknext snapshot save --label "before change"
|
|
183
|
+
pnpm exec stacknext snapshot list
|
|
184
|
+
pnpm exec stacknext snapshot export snap-0123456789abcdef -o sample.json
|
|
185
|
+
pnpm exec stacknext snapshot import sample.json --label "reported issue"
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
Snapshots contain no live diagnostics or coverage and never update. Automatic
|
|
189
|
+
exit/error snapshots keep the newest ten by default; manual and imported
|
|
190
|
+
snapshots are never rotated away.
|
|
191
|
+
|
|
192
|
+
## Troubleshooting
|
|
193
|
+
|
|
194
|
+
| Symptom | Check | Fix |
|
|
195
|
+
| --- | --- | --- |
|
|
196
|
+
| MCP tools do not appear | Client config path and connection status | Fix the absolute path, then reload the client |
|
|
197
|
+
| `Cannot reach the StackNext collector` | `stacknext status` | Start `stacknext dev`; remove a stale `.stacknext/run.json` if the pid is dead |
|
|
198
|
+
| `rejected the token` | Collector restarted after the client started | Restart the MCP client or pass `--token` explicitly |
|
|
199
|
+
| Summary is empty, instrumentation `waiting` | Is the app running through `stacknext dev`? | Restart the app with `stacknext dev`, make a request |
|
|
200
|
+
| Requests appear but no database queries | Adapter registration | Follow the Drizzle/Prisma setup in the getting-started guide |
|
|
201
|
+
| Query durations are `null` | Drizzle logger limitation | Expected; do not treat as zero |
|
|
202
|
+
| Error has no trace | Fallback found no match | Use the route and timestamp; label the correlation as inferred |
|
|
203
|
+
| Coverage says `not-observed` | The sample did not exercise the feature, or capture is disabled | Check `configured` and item limitations; make a request that uses it |
|
|
204
|
+
| Coverage says `unknown` | Adapter/config state cannot be inferred | Report uncertainty; check the config and registration manually |
|
|
205
|
+
| No successful Server Action spans | Actions are not wrapped | Use `withStackNextAction`; failures may still reach `onRequestError` |
|
|
206
|
+
| Old data disappeared | In-memory retention (10 minutes by default) | Reproduce the request, or inspect/export a saved snapshot before restarting |
|
|
207
|
+
| No regression records | No capture/baseline/comparison has been saved for this project directory | Run `stacknext capture`, `baseline save` and `compare`; MCP is read-only |
|
|
208
|
+
| No snapshots | No manual/exit/error snapshot has been saved for this project directory | Save one with `stacknext snapshot save` or the dashboard; MCP is read-only |
|
|
209
|
+
| Comparison is `inconclusive` | Environment mismatch, incomplete correlation or too few samples | Fix the evidence; do not report it as a pass |
|
|
210
|
+
| Scenario has no baseline | The annotation or scenario id changed | Re-baseline the intended scenario |
|
|
211
|
+
|
|
212
|
+
## Privacy boundary
|
|
213
|
+
|
|
214
|
+
StackNext never captures request/response bodies, headers, cookies, URL query
|
|
215
|
+
values or SQL bind parameters. Redaction runs in the app and again in the
|
|
216
|
+
collector. Error messages and stacks are text-redacted, and resource attributes
|
|
217
|
+
are allowlisted. The MCP server receives the same redacted data as the dashboard.
|
|
218
|
+
|
|
219
|
+
Captured runs, baselines, comparisons and snapshots are redacted local JSON
|
|
220
|
+
files under `.stacknext`. They can include scenario titles, file paths, routes,
|
|
221
|
+
span and query evidence, environment facts and a sanitized command line. They
|
|
222
|
+
never include Playwright screenshots, video or trace archives. Review them
|
|
223
|
+
before sharing or uploading them as CI artifacts.
|
|
224
|
+
|
|
225
|
+
The bearer token stays in `.stacknext/run.json` (mode `0600`) and is read by the
|
|
226
|
+
MCP process. Tool callers never receive it. The client you connect may log or
|
|
227
|
+
transmit tool results according to its own policy; review that policy before
|
|
228
|
+
using StackNext with a hosted model.
|