@tonyclaw/agent-inspector 3.0.43 → 3.0.45

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 (80) hide show
  1. package/.output/cli.js +20744 -16945
  2. package/.output/nitro.json +1 -1
  3. package/.output/public/assets/{CompareDrawer-BAXxwTwT.js → CompareDrawer-B3_TLTJh.js} +1 -1
  4. package/.output/public/assets/{InspectorPet-xYuGV4Qz.js → InspectorPet-Cpn6hv4P.js} +1 -1
  5. package/.output/public/assets/{ProxyViewerContainer-B6GZnUWi.js → ProxyViewerContainer-BEAhuGOJ.js} +27 -27
  6. package/.output/public/assets/{ReplayDialog-D73pyIg3.js → ReplayDialog-B3EKVdJk.js} +1 -1
  7. package/.output/public/assets/{RequestAnatomy-CSDta_nu.js → RequestAnatomy-COOQjyUC.js} +1 -1
  8. package/.output/public/assets/{ResponseView-C4aIUPby.js → ResponseView-DBCjkwye.js} +1 -1
  9. package/.output/public/assets/{StreamingChunkSequence-D4xxosLx.js → StreamingChunkSequence-CuXhDgMo.js} +1 -1
  10. package/.output/public/assets/{_sessionId-CZHbJyWO.js → _sessionId-BJlM3nmt.js} +1 -1
  11. package/.output/public/assets/{_sessionId-DvuNLzSE.js → _sessionId-zbgYl7ZJ.js} +1 -1
  12. package/.output/public/assets/{index-DZ_wpqQM.js → index-BIK4bPTv.js} +1 -1
  13. package/.output/public/assets/{index-B17u7JMC.js → index-BZo_8koU.js} +15 -15
  14. package/.output/public/assets/{index-C0g79BAs.js → index-D2Qw6Ri2.js} +1 -1
  15. package/.output/public/assets/{index-BWjeqxbk.css → index-ZWschkCh.css} +1 -1
  16. package/.output/public/assets/{index-CmEO8ykj.js → index-xF_NY8Yb.js} +5 -5
  17. package/.output/public/assets/{json-viewer-CuWU-H6K.js → json-viewer-B-Ao6pwW.js} +1 -1
  18. package/.output/public/assets/{jszip.min-DPJI_UKW.js → jszip.min-B_rfAUCe.js} +1 -1
  19. package/.output/server/_libs/modelcontextprotocol__core.mjs +25 -25
  20. package/.output/server/_libs/modelcontextprotocol__server.mjs +2 -2
  21. package/.output/server/_libs/zod.mjs +6 -6
  22. package/.output/server/{_sessionId-Cun21KZF.mjs → _sessionId-CJ99gZFV.mjs} +3 -1
  23. package/.output/server/{_sessionId-CoFyeOti.mjs → _sessionId-DEjScBpK.mjs} +5 -3
  24. package/.output/server/_ssr/{CompareDrawer-Bgc2TZh_.mjs → CompareDrawer-DtOIMeQB.mjs} +4 -2
  25. package/.output/server/_ssr/{InspectorPet-DyK2ojeh.mjs → InspectorPet-CXc4oCBQ.mjs} +3 -1
  26. package/.output/server/_ssr/{ProxyViewerContainer-hvn6oVWD.mjs → ProxyViewerContainer-DVPlwfkt.mjs} +52 -27
  27. package/.output/server/_ssr/{ReplayDialog-KpnrGtZ-.mjs → ReplayDialog-BQEA95qC.mjs} +6 -4
  28. package/.output/server/_ssr/{RequestAnatomy-uCsfucn8.mjs → RequestAnatomy-BMyd8B7Q.mjs} +4 -2
  29. package/.output/server/_ssr/{ResponseView-C8UPqoPO.mjs → ResponseView-qrTaEIM8.mjs} +4 -2
  30. package/.output/server/_ssr/{StreamingChunkSequence-BP28I9sh.mjs → StreamingChunkSequence-BFTL8mIy.mjs} +5 -3
  31. package/.output/server/_ssr/{index-Du3YNDKx.mjs → index-Bcj1Hcy4.mjs} +4 -2
  32. package/.output/server/_ssr/{index-BVwVoQlZ.mjs → index-DW-M7XUG.mjs} +3 -1
  33. package/.output/server/_ssr/index.mjs +4 -3
  34. package/.output/server/_ssr/{json-viewer-DrE0vtlB.mjs → json-viewer-DiI0Yjsn.mjs} +4 -2
  35. package/.output/server/_ssr/publicBasePathContext-5264L3rX.mjs +148 -0
  36. package/.output/server/_ssr/{router-C6nWUZHK.mjs → router-BJ_ltLim.mjs} +2432 -475
  37. package/.output/server/_ssr/start-C6MjPjxp.mjs +57 -0
  38. package/.output/server/_tanstack-start-manifest_v-C6pXXX9R.mjs +4 -0
  39. package/.output/server/index.mjs +99 -99
  40. package/.output/workers/logFinalizer.worker.js +4 -0
  41. package/.output/workers/sessionWorkerEntry.js +4 -0
  42. package/README.md +221 -25
  43. package/docs/instance-control.openapi.yaml +306 -0
  44. package/package.json +4 -1
  45. package/src/cli/alias.ts +440 -0
  46. package/src/cli/instance.ts +1037 -0
  47. package/src/cli/instanceArgs.ts +266 -0
  48. package/src/cli/instanceControl.ts +183 -0
  49. package/src/cli/instanceModel.ts +275 -0
  50. package/src/cli/instanceRegistry.ts +740 -0
  51. package/src/cli/onboard.ts +123 -35
  52. package/src/cli/onboardTarget.ts +179 -0
  53. package/src/cli/templates/codex-skill-onboard.ts +76 -28
  54. package/src/cli/templates/skill-onboard.ts +93 -59
  55. package/src/cli.ts +154 -16
  56. package/src/components/ProxyViewer.tsx +13 -5
  57. package/src/components/providers/SettingsDialog.tsx +13 -8
  58. package/src/lib/basePath.ts +8 -2
  59. package/src/lib/codingAgentEndpoints.ts +16 -0
  60. package/src/lib/instanceContract.ts +220 -0
  61. package/src/lib/managedInstance.ts +104 -0
  62. package/src/lib/publicBasePathContext.ts +107 -0
  63. package/src/mcp/instanceHandlers.ts +149 -0
  64. package/src/mcp/loopback.ts +16 -5
  65. package/src/mcp/mode.ts +25 -0
  66. package/src/mcp/server.ts +258 -18
  67. package/src/mcp/toolHandlers.ts +2 -2
  68. package/src/proxy/identityProxy.ts +656 -36
  69. package/src/proxy/runtimeShutdown.ts +73 -1
  70. package/src/proxy/sessionInfo.ts +5 -4
  71. package/src/routes/api/-instances.ts +109 -0
  72. package/src/routes/api/instances.$name.connection.ts +12 -0
  73. package/src/routes/api/instances.$name.restart.ts +23 -0
  74. package/src/routes/api/instances.$name.start.ts +18 -0
  75. package/src/routes/api/instances.$name.stop.ts +23 -0
  76. package/src/routes/api/instances.$name.ts +12 -0
  77. package/src/routes/api/instances.ts +16 -0
  78. package/src/start.ts +10 -0
  79. package/.output/server/_ssr/start-HYkvq4Ni.mjs +0 -4
  80. package/.output/server/_tanstack-start-manifest_v-rshlRaiN.mjs +0 -4
package/README.md CHANGED
@@ -28,7 +28,7 @@ Optional MCP-first companion package:
28
28
 
29
29
  ```bash
30
30
  npm install -g @tonyclaw/agent-inspector-mcp
31
- agent-inspector-mcp doctor
31
+ agent-inspector-mcp doctor --url http://localhost:9527/inspector/api/mcp
32
32
  ```
33
33
 
34
34
  Agent Inspector requires Node.js 22 or newer. Node.js 24 LTS is recommended for production use.
@@ -84,15 +84,20 @@ agent-inspector onboard
84
84
 
85
85
  The onboarding command installs guided setup skills for local agents:
86
86
 
87
+ The generated instructions and automatically merged MCP entries derive the Inspector Base URL from
88
+ the default CLI origin (`http://localhost:9527`) and `AGENT_INSPECTOR_BASE_PATH`. The default is
89
+ `http://localhost:9527/inspector`. This Inspector Base URL is separate from each Provider's upstream
90
+ Base URL.
91
+
87
92
  - Claude Code: `~/.claude/skills/agent-inspector-onboard/SKILL.md` plus a slash command.
88
93
  - Codex: `~/.codex/skills/agent-inspector-onboard/SKILL.md`, focused on connecting
89
- `http://localhost:9527/api/mcp` through Codex `mcp_servers.agent-inspector`.
94
+ `<inspector-base-url>/api/mcp` through Codex `mcp_servers.agent-inspector`.
90
95
  - OpenCode: run `agent-inspector onboard --opencode-only` to merge
91
96
  `mcp.agent-inspector` into `~/.config/opencode/opencode.json` or `opencode.jsonc`, then verify
92
97
  with `opencode mcp list`.
93
98
  - MiMo Code: run `agent-inspector onboard --mimo-only` to merge `mcp.agent-inspector` into
94
99
  `~/.config/mimocode/mimocode.jsonc` or `mimocode.json`, then route MiMo through the proxy with
95
- `OPENAI_BASE_URL=http://localhost:9527/proxy`.
100
+ `OPENAI_BASE_URL=<inspector-base-url>/proxy/v1`.
96
101
 
97
102
  During npm global install, Agent Inspector also makes a best-effort onboarding skill install for
98
103
  detected local agents. If `~/.claude` exists, it installs the Claude Code skill and slash command.
@@ -116,6 +121,21 @@ edits a real tool config file instead of adding an Agent Inspector generated ski
116
121
  `agent-inspector onboard --status --opencode-only --json` or
117
122
  `agent-inspector onboard --status --mimo-only --json` to inspect those MCP entries.
118
123
 
124
+ For coding agents that must address more than one Inspector, onboarding can target either a
125
+ registered Windows instance or an explicit wrapper URL:
126
+
127
+ ```powershell
128
+ agent-inspector onboard --instance review --force
129
+ agent-inspector onboard --instance review --mcp-name agent-inspector-review --opencode-only --force
130
+ agent-inspector onboard --base-url https://tools.example.test/inspector --mcp-name team-inspector --force
131
+ ```
132
+
133
+ `--instance` resolves the saved instance URL and defaults the MCP config key to
134
+ `agent-inspector-<instance>`. `--base-url` accepts a credential-free HTTP(S) Inspector Base URL and
135
+ is mutually exclusive with `--instance`. `--mcp-name` selects the exact MCP config key, allowing the
136
+ generated config to preserve other Inspector entries. Explicit per-client MCP URL options still
137
+ take precedence over the resolved target.
138
+
119
139
  Before uninstalling the npm package, run `agent-inspector onboard --uninstall` to remove matching
120
140
  generated onboarding files. The uninstall command only removes Agent Inspector generated files whose
121
141
  metadata version matches the currently installed npm package. npm v7+ does not run package uninstall
@@ -154,6 +174,10 @@ The web UI runs at http://localhost:9527/inspector by default. The public proxy
154
174
  `http://localhost:9527/inspector/proxy`; internally Agent Inspector may run the app on a private
155
175
  helper port, but AI tools should use the public URL printed by the CLI.
156
176
 
177
+ When the dashboard has no captured requests, its copyable Claude, OpenCode, OpenAI, OpenAI `/v1`,
178
+ and MCP examples are derived from the browser origin plus the configured runtime base path. They
179
+ therefore continue to work when the public origin or base path differs from the default.
180
+
157
181
  ### Base path
158
182
 
159
183
  Agent Inspector defaults to the `/inspector` public base path:
@@ -183,26 +207,138 @@ To run at the domain root instead, explicitly set the base path to `/`:
183
207
  AGENT_INSPECTOR_BASE_PATH=/ agent-inspector
184
208
  ```
185
209
 
186
- Reverse proxies should preserve the `/inspector` prefix when forwarding public requests to Agent
187
- Inspector.
210
+ ### Runtime Base Path aliases
188
211
 
189
- The legacy `http://localhost:9527` port is closed by default. If you need a temporary alias for
190
- older AI tool or MCP configs, start with `agent-inspector --legacy-port`.
212
+ An already-running Inspector can expose an additional path without starting a second runtime or
213
+ sharing its data directory with another process. For example, after starting the canonical UI at
214
+ the domain root, add `/inspector` on the same origin and port:
191
215
 
192
- ## v3.0 Port Migration
216
+ ```bash
217
+ AGENT_INSPECTOR_BASE_PATH=/ agent-inspector --background --no-open
218
+ agent-inspector alias add /inspector
219
+ ```
193
220
 
194
- Agent Inspector v3.0 changes the default public port from `9527` to `9527`. The packaged CLI now
195
- opens only `9527` by default. Existing AI coding tool and MCP configs that still point at `9527`
196
- should be moved to `9527`, or you can temporarily start with `agent-inspector --legacy-port`.
221
+ The canonical and alias URLs share the same Providers, logs, sessions, MCP server, workers, and live
222
+ SSE state. Manage the current runtime's aliases with:
197
223
 
198
- Use these default endpoints for new configs:
224
+ ```bash
225
+ agent-inspector alias list
226
+ agent-inspector alias remove /inspector
227
+ ```
199
228
 
200
- - Web UI: `http://localhost:9527/inspector`
201
- - Proxy: `http://localhost:9527/inspector/proxy`
202
- - OpenAI-compatible `/v1` proxy: `http://localhost:9527/inspector/proxy/v1`
203
- - MCP: `http://localhost:9527/inspector/api/mcp`
229
+ Use `--port <port>` and `--host <host>` when the running local Inspector does not use
230
+ `localhost:9527`. Runtime aliases are intentionally temporary and are cleared when the Inspector
231
+ supervisor restarts; configure `AGENT_INSPECTOR_BASE_PATH` when a path must remain canonical across
232
+ restarts.
233
+
234
+ ### Windows named instances
235
+
236
+ Use a named instance when the second URL must have its own Providers, runtime configuration, logs,
237
+ sessions, workers, and data directory. Named instances run as hidden background supervisors on
238
+ Windows; the command waits for readiness before returning. The existing `agent-inspector` and
239
+ `agent-inspector start` commands remain the unmanaged default-instance startup path and do not
240
+ create an instance record.
241
+
242
+ ```powershell
243
+ agent-inspector instance start <name> [--port <port>] [--base-path <path>] [--host <host>] [--mode simple|full] [--data-dir <absolute-path>] [--open] [--json]
244
+ agent-inspector instance list [--json]
245
+ agent-inspector instance status <name> [--json]
246
+ agent-inspector instance connect <name> [--json]
247
+ agent-inspector instance stop <name> [--json]
248
+ agent-inspector instance restart <name> [--port <port>] [--base-path <path>] [--host <host>] [--mode simple|full] [--data-dir <absolute-path>] [--open] [--json]
249
+ ```
250
+
251
+ Names use lowercase letters, digits, dots, hyphens, and underscores; `default` is reserved for the
252
+ existing unmanaged runtime. A first start without `--port` allocates an available public/private
253
+ port pair. The pair and the other launch options are saved, so later `start` calls reuse the same
254
+ configuration. Use `restart` with overrides to change a saved value. `--open` opens the UI after the
255
+ background instance is ready, while `--json` produces token-free output suitable for PowerShell:
256
+
257
+ ```powershell
258
+ agent-inspector instance start review --base-path /inspector --json
259
+ $review = agent-inspector instance status review --json | ConvertFrom-Json
260
+ $connection = agent-inspector instance connect review --json | ConvertFrom-Json
261
+ $env:OPENAI_BASE_URL = $connection.environment.OPENAI_BASE_URL
262
+ $review
263
+ ```
264
+
265
+ `connect` (also accepted as `connection`) returns the token-free connection descriptor: UI/API,
266
+ health, Anthropic proxy, OpenAI `/v1` proxy, MCP URL, environment variables, an MCP server name, and
267
+ a Codex Responses provider. In `--json` mode, success writes exactly one JSON document to stdout;
268
+ errors write exactly one `{ "schemaVersion": 1, "error": ... }` document to stderr with empty
269
+ stdout. Exit code `0` means success, `1` means an operational/lifecycle failure or a reported
270
+ conflict, and `2` means invalid command syntax or arguments. A `status`/`connect` conflict remains a
271
+ token-free state document on stdout while returning `1`. This makes the commands safe for coding
272
+ agents and PowerShell without scraping human text.
273
+
274
+ On Windows, instance records default below `%LOCALAPPDATA%\agent-inspector\instances`, and isolated
275
+ runtime data defaults to `%LOCALAPPDATA%\agent-inspector\instances\<name>\data`. A per-user fallback
276
+ is used when `LOCALAPPDATA` is unavailable. Set `AGENT_INSPECTOR_INSTANCES_DIR` before every lifecycle
277
+ command, or set it persistently for the user, to move the registry root. `--data-dir` moves one
278
+ instance's runtime data. Agent Inspector rejects a data directory already registered to another
279
+ name rather than allowing Provider or capture state to be shared accidentally.
280
+
281
+ ```powershell
282
+ [Environment]::SetEnvironmentVariable(
283
+ "AGENT_INSPECTOR_INSTANCES_DIR",
284
+ "$env:LOCALAPPDATA\agent-inspector-work",
285
+ "User"
286
+ )
287
+ ```
288
+
289
+ Runtime aliases and named instances solve different problems:
290
+
291
+ | Feature | Process and storage | Paths | Persistence |
292
+ | --- | --- | --- | --- |
293
+ | `agent-inspector alias add /path` | Same runtime, Providers, and logs | Adds a path on the same port | Cleared on supervisor restart |
294
+ | `agent-inspector instance start <name>` | Separate supervisor, Providers, and logs | Own saved port and Base Path | Saved until explicitly changed |
295
+
296
+ #### External wrapper: root plus `/inspector`
297
+
298
+ An external Windows reverse proxy can give two isolated backends one public origin. Start each
299
+ backend on a distinct public ingress port; the lifecycle manager also reserves a different private
300
+ runtime port for each supervisor:
301
+
302
+ ```powershell
303
+ agent-inspector instance start root-site --port 19527 --base-path /
304
+ agent-inspector instance start review-site --port 19537 --base-path /inspector
305
+ ```
204
306
 
205
- If you intentionally need the old compatibility port, start with `agent-inspector --legacy-port`.
307
+ Configure the wrapper to send `/inspector` and `/inspector/*` to `127.0.0.1:19537` **without
308
+ stripping the `/inspector` prefix**, and send the remaining root traffic to `127.0.0.1:19527`. Point
309
+ the wrapper only at each instance's public ingress port, never its private helper port. Add the
310
+ wrapper hostname to `AGENT_INSPECTOR_TRUSTED_HOSTS` when it differs from the local host.
311
+
312
+ The wrapper is a routing layer only: the two instance data directories and Provider configurations
313
+ remain independent. It also becomes the immediate TCP client seen by Inspector, so original coding
314
+ tool PID attribution can be replaced by the wrapper process's PID. Connect a coding tool directly
315
+ to the appropriate instance ingress when exact client-process attribution is required.
316
+
317
+ A wrapper that forwards to loopback must authenticate and authorize its own remote callers:
318
+ Inspector sees the wrapper as a local peer. Direct non-loopback calls to `/api/instances` always
319
+ require `Authorization: Bearer <AGENT_INSPECTOR_CONTROL_TOKEN>`, even when general remote UI control
320
+ is allowed. Keep that control token separate from `AGENT_INSPECTOR_PROXY_TOKEN`, which protects
321
+ remote model-proxy traffic.
322
+
323
+ Reverse proxies should preserve the configured prefix when forwarding public requests to Agent
324
+ Inspector (`/inspector` by default).
325
+
326
+ Treat the exact public Web UI URL printed by the CLI as `<inspector-base-url>`. Client endpoints are
327
+ always derived from it:
328
+
329
+ - Proxy: `<inspector-base-url>/proxy`
330
+ - OpenAI-compatible `/v1` proxy: `<inspector-base-url>/proxy/v1`
331
+ - MCP: `<inspector-base-url>/api/mcp`
332
+ - Health: `<inspector-base-url>/api/health`
333
+
334
+ For example, keep startup and onboarding aligned when using a custom prefix:
335
+
336
+ ```bash
337
+ AGENT_INSPECTOR_BASE_PATH=/team/inspector agent-inspector
338
+ AGENT_INSPECTOR_BASE_PATH=/team/inspector agent-inspector onboard --force
339
+ AGENT_INSPECTOR_BASE_PATH=/team/inspector agent-inspector onboard --opencode-only --force
340
+ AGENT_INSPECTOR_BASE_PATH=/team/inspector agent-inspector onboard --mimo-only --force
341
+ ```
206
342
 
207
343
  For Codex-style OpenAI Responses clients, configure the proxy as an OpenAI-compatible `/v1` base:
208
344
 
@@ -214,11 +350,18 @@ base_url = "http://127.0.0.1:9527/inspector/proxy/v1"
214
350
  wire_api = "responses"
215
351
  ```
216
352
 
353
+ Use `/proxy` as the base for Anthropic clients (which append `/v1/messages`) and generic
354
+ `LLM_BASE_URL` clients. Use `/proxy/v1` as the OpenAI-compatible base for clients that append
355
+ `/chat/completions` or `/responses`; Codex Responses belongs in this second category. The resulting
356
+ full paths are `/proxy/v1/messages`, `/proxy/v1/chat/completions`, and `/proxy/v1/responses`.
357
+
217
358
  ## Documentation Map
218
359
 
219
360
  - [Installation](docs/Installation.md): install and runtime notes.
220
361
  - [Usage](docs/Usage.md): daily capture, browsing, replay, and export workflows.
221
362
  - [MCP Server](docs/MCP-Server.md): MCP setup plus tools, resources, prompts, and evidence usage for coding agents.
363
+ - [Instance Control OpenAPI](docs/instance-control.openapi.yaml): versioned named-instance REST
364
+ contract for coding agents and external controllers.
222
365
  - [Troubleshooting](docs/TROUBLESHOOTING.md): port, provider, MCP, Replay, Jenkins, and GitCode fixes.
223
366
  - [Jenkins + GitCode WebHook](docs/JENKINS_GITCODE_WEBHOOK_TUNNEL.md): team CI and tunnel setup.
224
367
  - [Local Release Helper](docs/LOCAL_RELEASE.md): local maintainer release helper.
@@ -295,20 +438,49 @@ OpenAI Responses each get separate non-streaming and streaming probes. Test evid
295
438
  a provider-specific Session so the UI can show which exact path, payload shape, status code, and
296
439
  upstream URL failed.
297
440
 
441
+ ## Named Instance Control For Coding Agents
442
+
443
+ Every Inspector Base URL exposes a versioned, token-free Windows named-instance control contract.
444
+ The six endpoints are:
445
+
446
+ | Method | Endpoint | Purpose |
447
+ | --- | --- | --- |
448
+ | `GET` | `/api/instances` | List registered instances and their live state. |
449
+ | `GET` | `/api/instances/{name}` | Read one instance. |
450
+ | `GET` | `/api/instances/{name}/connection` | Read coding-agent URLs, environment, MCP, and Codex settings. |
451
+ | `POST` | `/api/instances/{name}/start` | Create, start, or idempotently reuse an instance. |
452
+ | `POST` | `/api/instances/{name}/stop` | Gracefully stop a sibling instance. |
453
+ | `POST` | `/api/instances/{name}/restart` | Restart with saved or validated replacement settings. |
454
+
455
+ `start` and `restart` accept a strict optional JSON object containing `port`, `basePath`, `host`,
456
+ `captureMode`, and `dataDir`; `stop` accepts only `{}`. Responses use `schemaVersion: 1`, never
457
+ include lifecycle or Provider credentials, and send `Cache-Control: no-store`. Errors use the stable
458
+ shape `{ "schemaVersion": 1, "error": { "code", "message", "retryable" } }` with `400`, `404`,
459
+ `409`, `423`, or `503` according to the failure class. See the checked-in
460
+ [OpenAPI 3.1 contract](docs/instance-control.openapi.yaml) for the complete schemas.
461
+
462
+ Browser mutations require same-origin proof plus `x-agent-inspector-csrf: 1`. Direct non-loopback
463
+ control calls require `Authorization: Bearer <AGENT_INSPECTOR_CONTROL_TOKEN>`. A managed instance
464
+ cannot stop or restart itself through the REST/MCP transport it is currently serving; use the
465
+ external CLI or a different controller/anchor instance. A failed restart reports whether the old
466
+ launch was restored (`restart_failed_rolled_back`) or the instance remained degraded
467
+ (`restart_failed_degraded`).
468
+
298
469
  ## MCP Evidence Workflows
299
470
 
300
- Agent Inspector exposes MCP at:
471
+ Agent Inspector exposes MCP at `<inspector-base-url>/api/mcp`. With the default public Inspector
472
+ Base URL, that is:
301
473
 
302
474
  ```text
303
- http://localhost:9527/api/mcp
475
+ http://localhost:9527/inspector/api/mcp
304
476
  ```
305
477
 
306
478
  Coding agents can connect to this MCP surface directly over Streamable HTTP, or through the
307
479
  companion stdio bridge:
308
480
 
309
481
  ```bash
310
- agent-inspector-mcp stdio
311
- agent-inspector-mcp config codex
482
+ agent-inspector-mcp stdio --url http://localhost:9527/inspector/api/mcp
483
+ agent-inspector-mcp config codex --url http://localhost:9527/inspector/api/mcp
312
484
  ```
313
485
 
314
486
  The companion package is useful for MCP clients that expect a local command. Direct HTTP remains the
@@ -318,13 +490,10 @@ The MCP HTTP surface is also documented as OpenAPI YAML in
318
490
  [`docs/mcp-openapi.yaml`](docs/mcp-openapi.yaml).
319
491
 
320
492
  Use only one transport for the same Inspector instance. If the MCP client supports Streamable HTTP,
321
- configure `http://localhost:9527/api/mcp` directly. If it only supports stdio, configure
493
+ configure `<inspector-base-url>/api/mcp` directly. If it only supports stdio, configure
322
494
  `agent-inspector-mcp stdio`; that command is only a bridge to `/api/mcp`, not a second Inspector
323
495
  server.
324
496
 
325
- Legacy MCP configs that still use `http://localhost:9527/api/mcp` require starting the CLI with
326
- `agent-inspector --legacy-port`; new configs should use `http://localhost:9527/api/mcp`.
327
-
328
497
  Coding agents can use the MCP surface in three ways:
329
498
 
330
499
  - Tools: perform actions such as listing logs, reading bounded log details, testing providers,
@@ -333,6 +502,33 @@ Coding agents can use the MCP surface in three ways:
333
502
  paths without invoking a tool call.
334
503
  - Prompts: start common analysis/reporting tasks from reusable templates.
335
504
 
505
+ The current catalog contains 51 tools, 25 resources, and 5 prompts. Named-instance control adds six
506
+ tools—`inspector_list_instances`, `inspector_get_instance`,
507
+ `inspector_get_instance_connection`, `inspector_start_instance`, `inspector_stop_instance`, and
508
+ `inspector_restart_instance`—plus these resources:
509
+
510
+ | Resource URI | Purpose |
511
+ | --- | --- |
512
+ | `inspector://instances` | Token-free list of named instances. |
513
+ | `inspector://instances/{name}` | One named instance and its live state. |
514
+ | `inspector://instances/{name}/connection` | Protocol-correct connection descriptor for a coding agent. |
515
+
516
+ The three discovery tools and resources remain available in read-only mode. Instance start/stop/
517
+ restart require both `AGENT_INSPECTOR_MCP_WRITES=1` and
518
+ `AGENT_INSPECTOR_MCP_INSTANCE_WRITES=1`; their tool descriptions require explicit user approval.
519
+ They cannot stop or restart the instance serving the active MCP connection.
520
+
521
+ For an authenticated remote MCP endpoint, keep the token outside config and pass only its variable
522
+ name to the companion:
523
+
524
+ ```bash
525
+ agent-inspector-mcp doctor --url https://tools.example.test/inspector/api/mcp --token-env INSPECTOR_CONTROL_TOKEN --json
526
+ agent-inspector-mcp stdio --url https://tools.example.test/inspector/api/mcp --token-env INSPECTOR_CONTROL_TOKEN
527
+ ```
528
+
529
+ The companion reads the raw value from `INSPECTOR_CONTROL_TOKEN`, sends it as a Bearer credential,
530
+ and never prints it. `doctor` verifies health, MCP initialization, and `tools/list` before returning.
531
+
336
532
  The evaluation-oriented run flow is:
337
533
 
338
534
  1. Call `inspector_create_run` before a task starts to declare a stable `runId`, optional
@@ -0,0 +1,306 @@
1
+ openapi: 3.1.0
2
+ info:
3
+ title: Agent Inspector Named Instance Control API
4
+ version: 1.0.0
5
+ description: |
6
+ Local control-plane API for discovering and managing Windows named Agent Inspector instances.
7
+ Paths are relative to the selected Inspector Base URL. Loopback clients are trusted by the
8
+ native ingress; direct non-loopback clients must send the configured control Bearer token.
9
+ Browser mutations also require same-origin CSRF proof. A reverse proxy whose upstream appears
10
+ as loopback must authenticate its own remote clients.
11
+ servers:
12
+ - url: http://127.0.0.1:9527
13
+ description: Root-mounted controller example
14
+ - url: http://127.0.0.1:9530/inspector
15
+ description: Prefixed named-instance controller example
16
+ tags:
17
+ - name: Instances
18
+ paths:
19
+ /api/instances:
20
+ get:
21
+ tags: [Instances]
22
+ operationId: listNamedInstances
23
+ summary: List registered named instances and derived live state
24
+ responses:
25
+ "200":
26
+ description: Versioned instance list
27
+ content:
28
+ application/json:
29
+ schema:
30
+ $ref: "#/components/schemas/InstanceList"
31
+ default:
32
+ $ref: "#/components/responses/InstanceError"
33
+ /api/instances/{name}:
34
+ parameters:
35
+ - $ref: "#/components/parameters/InstanceName"
36
+ get:
37
+ tags: [Instances]
38
+ operationId: getNamedInstance
39
+ summary: Read one named instance and its live state
40
+ responses:
41
+ "200":
42
+ description: Instance view
43
+ content:
44
+ application/json:
45
+ schema:
46
+ $ref: "#/components/schemas/InstanceView"
47
+ default:
48
+ $ref: "#/components/responses/InstanceError"
49
+ /api/instances/{name}/connection:
50
+ parameters:
51
+ - $ref: "#/components/parameters/InstanceName"
52
+ get:
53
+ tags: [Instances]
54
+ operationId: getNamedInstanceConnection
55
+ summary: Read protocol-correct Coding Agent connection settings
56
+ responses:
57
+ "200":
58
+ description: Token-free connection descriptor
59
+ content:
60
+ application/json:
61
+ schema:
62
+ $ref: "#/components/schemas/InstanceConnection"
63
+ default:
64
+ $ref: "#/components/responses/InstanceError"
65
+ /api/instances/{name}/start:
66
+ parameters:
67
+ - $ref: "#/components/parameters/InstanceName"
68
+ post:
69
+ tags: [Instances]
70
+ operationId: startNamedInstance
71
+ summary: Idempotently create, start, or reuse a named instance
72
+ requestBody:
73
+ required: false
74
+ content:
75
+ application/json:
76
+ schema:
77
+ $ref: "#/components/schemas/InstanceStartRequest"
78
+ responses:
79
+ "200":
80
+ description: Existing instance started or reused
81
+ content:
82
+ application/json:
83
+ schema:
84
+ $ref: "#/components/schemas/InstanceOperation"
85
+ "201":
86
+ description: New instance record created and started
87
+ content:
88
+ application/json:
89
+ schema:
90
+ $ref: "#/components/schemas/InstanceOperation"
91
+ default:
92
+ $ref: "#/components/responses/InstanceError"
93
+ /api/instances/{name}/stop:
94
+ parameters:
95
+ - $ref: "#/components/parameters/InstanceName"
96
+ post:
97
+ tags: [Instances]
98
+ operationId: stopNamedInstance
99
+ summary: Gracefully stop a matching sibling instance
100
+ requestBody:
101
+ required: false
102
+ content:
103
+ application/json:
104
+ schema:
105
+ type: object
106
+ additionalProperties: false
107
+ responses:
108
+ "200":
109
+ description: Instance stopped or already stopped
110
+ content:
111
+ application/json:
112
+ schema:
113
+ $ref: "#/components/schemas/InstanceOperation"
114
+ default:
115
+ $ref: "#/components/responses/InstanceError"
116
+ /api/instances/{name}/restart:
117
+ parameters:
118
+ - $ref: "#/components/parameters/InstanceName"
119
+ post:
120
+ tags: [Instances]
121
+ operationId: restartNamedInstance
122
+ summary: Validate configuration, gracefully stop, and relaunch a sibling instance
123
+ requestBody:
124
+ required: false
125
+ content:
126
+ application/json:
127
+ schema:
128
+ $ref: "#/components/schemas/InstanceStartRequest"
129
+ responses:
130
+ "200":
131
+ description: Replacement launch reached readiness
132
+ content:
133
+ application/json:
134
+ schema:
135
+ $ref: "#/components/schemas/InstanceOperation"
136
+ default:
137
+ $ref: "#/components/responses/InstanceError"
138
+ components:
139
+ securitySchemes:
140
+ controlBearer:
141
+ type: http
142
+ scheme: bearer
143
+ description: Value of AGENT_INSPECTOR_CONTROL_TOKEN for direct non-loopback access.
144
+ parameters:
145
+ InstanceName:
146
+ name: name
147
+ in: path
148
+ required: true
149
+ schema:
150
+ type: string
151
+ pattern: "^[a-z0-9._-]{1,64}$"
152
+ example: review
153
+ responses:
154
+ InstanceError:
155
+ description: Versioned machine-readable lifecycle error
156
+ content:
157
+ application/json:
158
+ schema:
159
+ $ref: "#/components/schemas/InstanceError"
160
+ schemas:
161
+ InstanceUrls:
162
+ type: object
163
+ additionalProperties: false
164
+ required: [ui, api, health, proxy, openai, mcp]
165
+ properties:
166
+ ui: { type: string, format: uri, example: "http://127.0.0.1:9530/inspector" }
167
+ api: { type: string, format: uri, example: "http://127.0.0.1:9530/inspector/api" }
168
+ health:
169
+ { type: string, format: uri, example: "http://127.0.0.1:9530/inspector/api/health" }
170
+ proxy:
171
+ { type: string, format: uri, example: "http://127.0.0.1:9530/inspector/proxy" }
172
+ openai:
173
+ { type: string, format: uri, example: "http://127.0.0.1:9530/inspector/proxy/v1" }
174
+ mcp:
175
+ { type: string, format: uri, example: "http://127.0.0.1:9530/inspector/api/mcp" }
176
+ InstanceView:
177
+ type: object
178
+ additionalProperties: false
179
+ required:
180
+ - schemaVersion
181
+ - name
182
+ - instanceId
183
+ - state
184
+ - stateReason
185
+ - checkedAt
186
+ - createdAt
187
+ - updatedAt
188
+ - launch
189
+ - host
190
+ - publicPort
191
+ - upstreamPort
192
+ - basePath
193
+ - captureMode
194
+ - dataDir
195
+ - supervisorPid
196
+ - urls
197
+ properties:
198
+ schemaVersion: { const: 1 }
199
+ name: { type: string, example: review }
200
+ instanceId: { type: string, example: "d8805ce7-5ec7-41fb-a370-c56b57418839" }
201
+ state: { type: string, enum: [running, stopped, conflict] }
202
+ stateReason:
203
+ oneOf:
204
+ - { type: string, enum: [identity_mismatch, port_conflict] }
205
+ - { type: "null" }
206
+ checkedAt: { type: string, format: date-time }
207
+ createdAt: { type: string, format: date-time }
208
+ updatedAt: { type: string, format: date-time }
209
+ launch:
210
+ type: object
211
+ additionalProperties: false
212
+ required: [launchId, startedAt]
213
+ properties:
214
+ launchId: { type: string }
215
+ startedAt: { type: string, format: date-time }
216
+ host: { type: string, example: "127.0.0.1" }
217
+ publicPort: { type: integer, minimum: 1, maximum: 65535, example: 9530 }
218
+ upstreamPort: { type: integer, minimum: 1, maximum: 65535, example: 9532 }
219
+ basePath: { type: string, example: /inspector }
220
+ captureMode: { type: string, enum: [simple, full] }
221
+ dataDir: { type: string, example: "C:\\Users\\me\\AppData\\Local\\agent-inspector\\instances\\review\\data" }
222
+ supervisorPid:
223
+ oneOf:
224
+ - { type: integer, minimum: 1 }
225
+ - { type: "null" }
226
+ urls:
227
+ $ref: "#/components/schemas/InstanceUrls"
228
+ InstanceList:
229
+ type: object
230
+ additionalProperties: false
231
+ required: [schemaVersion, instances]
232
+ properties:
233
+ schemaVersion: { const: 1 }
234
+ instances:
235
+ type: array
236
+ items:
237
+ $ref: "#/components/schemas/InstanceView"
238
+ InstanceStartRequest:
239
+ type: object
240
+ additionalProperties: false
241
+ properties:
242
+ port: { type: integer, minimum: 1, maximum: 65535 }
243
+ basePath: { type: string, example: /inspector }
244
+ host: { type: string, example: "127.0.0.1" }
245
+ captureMode: { type: string, enum: [simple, full] }
246
+ dataDir: { type: string }
247
+ InstanceOperation:
248
+ type: object
249
+ additionalProperties: false
250
+ required: [schemaVersion, operation, outcome, instance]
251
+ properties:
252
+ schemaVersion: { const: 1 }
253
+ operation: { type: string, enum: [start, stop, restart] }
254
+ outcome:
255
+ type: string
256
+ enum: [created, started, already_running, stopped, already_stopped, restarted]
257
+ instance:
258
+ $ref: "#/components/schemas/InstanceView"
259
+ InstanceConnection:
260
+ type: object
261
+ additionalProperties: false
262
+ required: [schemaVersion, instance, baseUrl, endpoints, environment, mcp, codex]
263
+ properties:
264
+ schemaVersion: { const: 1 }
265
+ instance: { $ref: "#/components/schemas/InstanceView" }
266
+ baseUrl: { type: string, format: uri }
267
+ endpoints: { $ref: "#/components/schemas/InstanceUrls" }
268
+ environment:
269
+ type: object
270
+ additionalProperties: false
271
+ required: [ANTHROPIC_BASE_URL, LLM_BASE_URL, OPENAI_BASE_URL, AGENT_INSPECTOR_MCP_URL]
272
+ properties:
273
+ ANTHROPIC_BASE_URL: { type: string, format: uri }
274
+ LLM_BASE_URL: { type: string, format: uri }
275
+ OPENAI_BASE_URL: { type: string, format: uri }
276
+ AGENT_INSPECTOR_MCP_URL: { type: string, format: uri }
277
+ mcp:
278
+ type: object
279
+ additionalProperties: false
280
+ required: [serverName, transport, url]
281
+ properties:
282
+ serverName: { type: string, example: agent-inspector-review }
283
+ transport: { const: streamable-http }
284
+ url: { type: string, format: uri }
285
+ codex:
286
+ type: object
287
+ additionalProperties: false
288
+ required: [providerName, baseUrl, wireApi]
289
+ properties:
290
+ providerName: { type: string, example: agent-inspector-review }
291
+ baseUrl: { type: string, format: uri }
292
+ wireApi: { const: responses }
293
+ InstanceError:
294
+ type: object
295
+ additionalProperties: false
296
+ required: [schemaVersion, error]
297
+ properties:
298
+ schemaVersion: { const: 1 }
299
+ error:
300
+ type: object
301
+ additionalProperties: false
302
+ required: [code, message, retryable]
303
+ properties:
304
+ code: { type: string }
305
+ message: { type: string }
306
+ retryable: { type: boolean }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tonyclaw/agent-inspector",
3
- "version": "3.0.43",
3
+ "version": "3.0.45",
4
4
  "type": "module",
5
5
  "description": "Agent observability and knowledge capture layer for AI coding tools.",
6
6
  "license": "MIT",
@@ -48,6 +48,7 @@
48
48
  "scripts/setup-windows-runtime.mjs",
49
49
  "scripts/setup-agent-skills.mjs",
50
50
  "scripts/generate-theme-scales.mjs",
51
+ "docs/instance-control.openapi.yaml",
51
52
  "styles",
52
53
  ".output",
53
54
  "!.output/*.exe"
@@ -65,6 +66,8 @@
65
66
  "build:workers": "npx esbuild src/proxy/logFinalizer.worker.ts src/proxy/sessionWorkerEntry.ts --bundle --platform=node --target=node22 --format=esm --outdir=.output/workers --external:better-sqlite3",
66
67
  "smoke:workers": "node scripts/smoke-production-workers.mjs",
67
68
  "smoke:packed-workers": "node scripts/smoke-packed-workers.mjs",
69
+ "smoke:instances": "node scripts/smoke-windows-instances.mjs",
70
+ "smoke:coding-agent-instances": "node scripts/smoke-coding-agent-instances.mjs",
68
71
  "check:bundle": "node scripts/check-client-bundle.mjs",
69
72
  "build:cli": "npx esbuild src/cli.ts --bundle --platform=node --target=node22 --format=esm --outfile=.output/cli.js",
70
73
  "build:mcp": "npx esbuild packages/agent-inspector-mcp/src/cli.ts --bundle --platform=node --target=node22 --format=esm --outfile=packages/agent-inspector-mcp/dist/cli.js",