Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .changeset/remove-vendored-inspector.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
'agent-bundle': minor
---

Remove the vendored MCP Inspector from the Workbench. The MCP page now has a
single playground presentation; the only surviving derived code is the
first-party MCP App renderer (`src/mcp/app-renderer.tsx`, MIT-attributed to
the Inspector's AppRenderer). Protocol inspection moves to the standalone
Inspector app: the dev server gains opt-in `/api/inspector/status` and
`/api/inspector/launch` routes that spawn `@modelcontextprotocol/inspector`
via npx on demand and return its tokenized URL. Drops the sync-inspector
machinery and the Mantine/react-icons/syntax-highlighter dependency surface
(~737 kB less workbench JS).
20 changes: 6 additions & 14 deletions docs/architecture/rsc-runtime-workbench.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ packages/
tests/mcp-app-sandbox.test.ts
tests/mcp-session-routes.test.ts
tests/mcp-session-service.test.ts
tests/native-host-smoke-workflow.test.ts
tests/normalization.test.ts
tests/playground-service.test.ts
tests/portable-adapter.test.ts
Expand All @@ -81,19 +80,14 @@ packages/
workbench/
rsbuild.config.ts
scripts/capture-runtime-playground.mjs
src/inspector/adapter/inspector-session-adapter-entry.ts
src/inspector/adapter/inspector-session-adapter-model.ts
src/inspector/adapter/inspector-session-adapter.css
src/inspector/adapter/inspector-session-adapter.tsx
src/inspector/adapter/protocol-screen-without-replay.tsx
src/inspector/adapter/runtime-app-bridge.ts
src/main.tsx
src/mcp/mcp-app-client.ts
src/mcp/mcp-app-frame.tsx
src/mcp/mcp-app-preview.tsx
src/mcp/mcp-page.tsx
src/mcp/mcp-session-controller.ts
src/mcp/mcp-session-model.ts
src/mcp/runtime-app-bridge.ts
src/mcp/runtime-consent-dialog.tsx
src/mcp/runtime-consent-queue.ts
src/mcp/runtime-mcp-handoff.ts
Expand All @@ -105,10 +99,6 @@ packages/
src/runtime-stage.tsx
src/styles.css
tests/helpers/runtime-playground-fixture.ts
tests/inspector-modern-mcp-types.test.ts
tests/inspector-session-adapter-fixture.test.ts
tests/inspector-session-adapter.test.ts
tests/inspector-shell.e2e.test.ts
tests/mcp-app-client.test.ts
tests/mcp-app-frame.test.ts
tests/mcp-app-preview-browser.test.ts
Expand Down Expand Up @@ -215,7 +205,9 @@ and HMR lane. `AgentBundleDevRuntimeConfig.provider` is loaded by

The Workbench has one `Workbench` root and navigation authority. Runtime is the
optional fourth top-level `WorkbenchPage` (`overview`, `skills`, `mcp`,
`runtime`); Inspector is a nested MCP presentation, not a fifth shell sibling.
`runtime`); the MCP page renders a single playground presentation, and protocol
inspection is delegated to the standalone MCP Inspector app that the dev server
spawns on demand via the opt-in `/api/inspector/*` routes.
The root owns one `ProjectClient` and EventSource, one `McpAppClient`, and one
shared `McpSessionController`. It creates one Runtime controller only when the
project status advertises the configured runtime capability. `WorkbenchScreen`
Expand Down Expand Up @@ -268,5 +260,5 @@ flowchart LR
`npm run docs:runtime-topology` regenerates only the marked file tree from a
fixed Git allowlist. `npm run check:runtime-topology` compares bytes without
writing. The generator intentionally excludes generated output, dependencies,
runtime state, unrelated historical tests, and the vendored Inspector source so
the map remains an implementation boundary rather than a repository inventory.
runtime state, and unrelated historical tests so the map remains an
implementation boundary rather than a repository inventory.
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,7 @@
"example:audiobook": "pnpm build && pnpm --filter @agent-bundle-example/audiobook-curator dev",
"example:mcp-app": "pnpm build && pnpm --filter @agent-bundle-example/mcp-app dev",
"example:skills": "pnpm build && pnpm --filter @agent-bundle-example/skills-starter dev",
"examples:check": "pnpm build && pnpm --filter './examples/*' --workspace-concurrency=1 check",
"sync:inspector": "node scripts/sync-inspector.mjs --commit 672f9f41c548487a468b9e7007d2f9de14da5a69 --version 2.2.0 --mcp-sdk-version 2.0.0 --entry clients/web/src/components/screens/ToolsScreen/ToolsScreen.tsx --entry clients/web/src/components/screens/ResourcesScreen/ResourcesScreen.tsx --entry clients/web/src/components/screens/PromptsScreen/PromptsScreen.tsx --entry clients/web/src/components/screens/AppsScreen/AppsScreen.tsx --entry clients/web/src/components/screens/ProtocolScreen/ProtocolScreen.tsx --entry clients/web/src/components/screens/NetworkScreen/NetworkScreen.tsx --entry clients/web/src/components/screens/LoggingScreen/LoggingScreen.tsx --test clients/web/src/utils/inspectorTabs.test.ts --dependency @dnd-kit/core --dependency @dnd-kit/sortable --dependency @dnd-kit/utilities --dependency @emotion/react --dependency @mantine/core --dependency @mantine/form --dependency @mantine/hooks --dependency @mantine/notifications --dependency @modelcontextprotocol/client --dependency @modelcontextprotocol/core --dependency @modelcontextprotocol/ext-apps --dependency ajv --dependency papaparse --dependency pino --dependency react --dependency react-dom --dependency react-icons --dependency react-markdown --dependency react-syntax-highlighter --dependency remark-gfm --dependency zod --test-dependency @rstest/core --test-dependency vitest --public-import @modelcontextprotocol/client/validators/ajv --public-import @modelcontextprotocol/ext-apps/app-bridge --public-import react-icons/md --public-import react-icons/ri --public-import react-icons/tb --public-import react-icons/ti --public-import react-syntax-highlighter/dist/esm/languages/prism/bash --public-import react-syntax-highlighter/dist/esm/languages/prism/css --public-import react-syntax-highlighter/dist/esm/languages/prism/javascript --public-import react-syntax-highlighter/dist/esm/languages/prism/json --public-import react-syntax-highlighter/dist/esm/languages/prism/markdown --public-import react-syntax-highlighter/dist/esm/languages/prism/markup --public-import react-syntax-highlighter/dist/esm/languages/prism/python --public-import react-syntax-highlighter/dist/esm/languages/prism/typescript --public-import react-syntax-highlighter/dist/esm/languages/prism/yaml --public-import react-syntax-highlighter/dist/esm/prism-light --public-import react-syntax-highlighter/dist/esm/styles/prism --public-import react-syntax-highlighter/dist/esm/styles/prism/tomorrow"
"examples:check": "pnpm build && pnpm --filter './examples/*' --workspace-concurrency=1 check"
},
"devDependencies": {
"@changesets/cli": "2.29.7",
Expand Down
10 changes: 10 additions & 0 deletions packages/agent-bundle/src/dev/foreground-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { DevLogRoutes } from './logs/dev-log-routes.ts';
import type { DevLogService } from './logs/dev-log-service.ts';
import { EvalRoutes, type EvalRouteService } from './eval/eval-routes.ts';
import type { ProjectEventHub, ProjectEventSubscription } from './events.ts';
import { InspectorRoutes, type InspectorRouteService } from './inspector-routes.ts';
import { HookPlaygroundRoutes, type HookPlaygroundRouteService } from './playground/hook-playground-routes.ts';
import { McpAppRoutes, type McpAppRoutePreviewService } from './mcp-apps/mcp-app-routes.ts';
import { McpSessionRoutes } from './mcp-session/mcp-session-routes.ts';
Expand Down Expand Up @@ -126,6 +127,8 @@ export interface ForegroundServerOptions {
readonly mcpAppPreviews?: McpAppRoutePreviewService;
/** Epoch-bound hook playground service; the browser never selects a wrapper or artifact path. */
readonly hookPlayground?: HookPlaygroundRouteService;
/** Opt-in standalone MCP Inspector child; never auto-started. */
readonly inspector?: InspectorRouteService;
/** Persistent MCP sessions are supplied by the workbench service, never by browser input. */
readonly mcpSessions?: McpSessionService;
readonly now?: () => Date;
Expand Down Expand Up @@ -421,6 +424,7 @@ export class ForegroundServer {
readonly #eventHub: ProjectEventHub;
readonly #hookPlaygroundRoutes: HookPlaygroundRoutes;
readonly #host: string;
readonly #inspectorRoutes: InspectorRoutes;
readonly #mcpAppPreviews: McpAppRoutePreviewService | undefined;
readonly #mcpAppRoutes: McpAppRoutes;
readonly #runtimeMcpRoutes: RuntimeMcpRoutes;
Expand Down Expand Up @@ -496,6 +500,10 @@ export class ForegroundServer {
authorize: (request) => this.#assertMutationSession(request),
...(options.hookPlayground === undefined ? {} : { service: options.hookPlayground }),
});
this.#inspectorRoutes = new InspectorRoutes({
authorize: (request) => this.#assertMutationSession(request),
...(options.inspector === undefined ? {} : { service: options.inspector }),
});
this.#playgroundRoutes = new PlaygroundRoutes({
authorize: (request) => this.#assertMutationSession(request),
...(options.playground === undefined ? {} : { service: options.playground }),
Expand Down Expand Up @@ -645,6 +653,7 @@ export class ForegroundServer {
// records and reports the same rejection.
void releaseHookPlayground.catch(() => undefined);
this.#playgroundRoutes.close();
this.#inspectorRoutes.close();
this.#artifactRoutes.close();
const releaseEvals = this.#evalRoutes.close();
void releaseEvals.catch(() => undefined);
Expand Down Expand Up @@ -729,6 +738,7 @@ export class ForegroundServer {
if (await this.#runtimeRoutes.handle(request, response)) return;
if (await this.#hookPlaygroundRoutes.handle(request, response)) return;
if (await this.#playgroundRoutes.handle(request, response)) return;
if (await this.#inspectorRoutes.handle(request, response)) return;
if (await this.#artifactRoutes.handle(request, response)) return;
if (await this.#evalRoutes.handle(request, response)) return;
if (await this.#devLogRoutes.handle(request, response)) return;
Expand Down
Loading
Loading