Phase 1 of #1633 (Extensions capability UI + MCP Apps alignment). See #1633 for full analysis.
Goal
Collapse the two ad-hoc capabilities.extensions = { ...spread } blocks in core/mcp/inspectorClient.ts into a single first-class advertised-extensions map assembled from a shared registry, so both the client and (in Phase 2) the settings UI draw from one list.
Scope
core/mcp/inspectorClient.ts:~597-612 — replace the two bespoke spreads (EMA, gated on options.oauth?.enterpriseManaged; tasks, TASKS_EXTENSION_KEY, always-on) with one builder. Keep this.clientCapabilities the single source of truth — it is read back at inspectorClient.ts:~1811 for the modern per-request envelope, so the assembled map must remain complete there.
- Add a small constant registry of Inspector-advertisable extension keys (id + human label + default-on flag). Candidate home:
core/mcp/ next to modernTaskSchemas.ts. The registry is the shared list Phase 2's toggles and Phase 3's ui advertisement will extend.
- Thread a new
advertisedExtensions client option through InspectorClientOptions so Phase 2 can drive it (the option can land unused-by-UI here and be wired to the form in Phase 2).
Acceptance
- Client capabilities carry the same extensions as today (tasks always; EMA when enterprise-managed) plus anything enabled via the new option, produced by one code path.
this.clientCapabilities / the modern per-request envelope are unchanged for existing configs (no behavior regression).
- Unit tests cover the map assembly across option combinations (tasks-only, +EMA, +user-enabled). This PR must hold the ≥90% per-file gate on its own — tests ship with the change, not later.
npm run format → npm run ci green.
Notes
No ext-apps SDK-v1 shim expected in this phase (the io.modelcontextprotocol/ui advertisement and its likely cast land in Phase 3).
Phase 1 of #1633 (Extensions capability UI + MCP Apps alignment). See #1633 for full analysis.
Goal
Collapse the two ad-hoc
capabilities.extensions = { ...spread }blocks incore/mcp/inspectorClient.tsinto a single first-class advertised-extensions map assembled from a shared registry, so both the client and (in Phase 2) the settings UI draw from one list.Scope
core/mcp/inspectorClient.ts:~597-612— replace the two bespoke spreads (EMA, gated onoptions.oauth?.enterpriseManaged; tasks,TASKS_EXTENSION_KEY, always-on) with one builder. Keepthis.clientCapabilitiesthe single source of truth — it is read back atinspectorClient.ts:~1811for the modern per-request envelope, so the assembled map must remain complete there.core/mcp/next tomodernTaskSchemas.ts. The registry is the shared list Phase 2's toggles and Phase 3'suiadvertisement will extend.advertisedExtensionsclient option throughInspectorClientOptionsso Phase 2 can drive it (the option can land unused-by-UI here and be wired to the form in Phase 2).Acceptance
this.clientCapabilities/ the modern per-request envelope are unchanged for existing configs (no behavior regression).npm run format→npm run cigreen.Notes
No ext-apps SDK-v1 shim expected in this phase (the
io.modelcontextprotocol/uiadvertisement and its likely cast land in Phase 3).