* Extensions: advertised-extensions toggle in Server Settings (Phase 2 of #1633)
Adds the debugging knob from #1633: users choose which extensions the
Inspector advertises to a server, and a server may register different tools
in response. Builds on Phase 1's registry + advertisedExtensions option (#1738).
Settings + persistence (core):
- InspectorServerSettings.advertisedExtensions + StoredMCPServer field, wired
through serverList's read/write converters and INSPECTOR_FIELD_KEY_MAP
(omit-when-empty, byte-stable round-trip).
- validateSettings (remote PUT route): isBooleanRecord guard + carry a
non-empty map; unknown/malformed rejected.
- App.tsx threads savedSettings.advertisedExtensions into the client options.
UI:
- ServerSettingsForm renders an "Advertised Extensions" group of checkboxes
driven by ADVERTISABLE_EXTENSIONS; a per-server override wins over the
registry default. Modal folds a toggle into settings.advertisedExtensions.
Test server + proof:
- composable-test-server extensionGatedTools: a tool registered disabled and
enabled on `initialized` iff the client declared the mapped extension
(getClientCapabilities). Legacy stateful leg. Threaded through
load-config/resolve-config; advertised-extensions-http.json showcase + README.
- Integration test connects legacy with/without the tasks extension advertised
and asserts the gated tool appears/disappears in tools/list — the acceptance
criterion, proven end to end, not asserted.
Tests: serverList round-trip (non-empty/absent/empty), ServerSettingsForm
toggle rows, ServerSettingsModal fold, validateSettings accept/reject, and the
integration gating test. npm run ci green (per-file ≥90 gate held).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XNdjEPKLG637X8YmhDiEk5
* Extensions: add #1739 proof screenshots (advertised-extensions toggle)
End-to-end smoke test in the web client against the legacy
advertised-extensions-http.json test server (port 3220): connecting with the
Tasks extension advertised (default) lists echo + get_weather, unchecking the
Advertised Extensions → Tasks toggle and reconnecting lists only echo — the
server's tool registration changing on the client-declared extension.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XNdjEPKLG637X8YmhDiEk5
* Extensions: reconverge advertisedExtensions to no-override on default (review)
Address Phase 2 review observation #1: toggling an extension back to its
registry default now deletes the override key (and drops the whole map to
undefined when it empties), so the on-disk `advertisedExtensions` reconverges
to the byte-stable "no override" state instead of persisting a redundant
`{ key: <default> }`. Matches the omit-when-default policy the other settings
use. Only a value that differs from the default is persisted.
Adds a modal test asserting the reconvergence (re-checking the sole disabling
override drops advertisedExtensions to undefined).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XNdjEPKLG637X8YmhDiEk5
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>