diff --git a/clients/web/src/components/groups/ConnectionInfoContent/ConnectionInfoContent.test.tsx b/clients/web/src/components/groups/ConnectionInfoContent/ConnectionInfoContent.test.tsx
index 9320fa21..51565697 100644
--- a/clients/web/src/components/groups/ConnectionInfoContent/ConnectionInfoContent.test.tsx
+++ b/clients/web/src/components/groups/ConnectionInfoContent/ConnectionInfoContent.test.tsx
@@ -216,7 +216,9 @@ describe("ConnectionInfoContent", () => {
protocolEra="legacy"
/>,
);
- expect(screen.getByText("Advertised Extensions")).toBeInTheDocument();
+ expect(
+ screen.getByText("Client Advertised Extensions"),
+ ).toBeInTheDocument();
expect(
screen.getByText(
"io.modelcontextprotocol/tasks, io.modelcontextprotocol/ui",
@@ -234,7 +236,9 @@ describe("ConnectionInfoContent", () => {
/>,
);
expect(screen.getByText("Server Extensions")).toBeInTheDocument();
- expect(screen.getByText("Advertised Extensions")).toBeInTheDocument();
+ expect(
+ screen.getByText("Client Advertised Extensions"),
+ ).toBeInTheDocument();
// Exactly two em dashes: the two extension sections (the server version is
// present in the fixture, so it does not em-dash).
expect(screen.getAllByText("—")).toHaveLength(2);
diff --git a/clients/web/src/components/groups/ConnectionInfoContent/ConnectionInfoContent.tsx b/clients/web/src/components/groups/ConnectionInfoContent/ConnectionInfoContent.tsx
index 66a8e0af..f1dfbd35 100644
--- a/clients/web/src/components/groups/ConnectionInfoContent/ConnectionInfoContent.tsx
+++ b/clients/web/src/components/groups/ConnectionInfoContent/ConnectionInfoContent.tsx
@@ -260,7 +260,7 @@ export function ConnectionInfoContent({
{formatExtensions(capabilities.extensions)}
- Advertised Extensions
+ Client Advertised Extensions
{formatExtensions(clientCapabilities.extensions)}
diff --git a/clients/web/src/components/groups/ServerSettingsForm/ServerSettingsForm.stories.tsx b/clients/web/src/components/groups/ServerSettingsForm/ServerSettingsForm.stories.tsx
index 5fc898ae..f0db4756 100644
--- a/clients/web/src/components/groups/ServerSettingsForm/ServerSettingsForm.stories.tsx
+++ b/clients/web/src/components/groups/ServerSettingsForm/ServerSettingsForm.stories.tsx
@@ -233,6 +233,19 @@ export const WithHeaders: Story = {
},
};
+export const AdvertisedExtensions: Story = {
+ args: {
+ // Expand the standalone Advertised Extensions section so its checkboxes are
+ // documented visually. A per-server override disables one extension, showing
+ // both the default-on and toggled-off states side by side.
+ expandedSections: ["extensions"],
+ settings: {
+ ...defaultSettings,
+ advertisedExtensions: { "io.modelcontextprotocol/tasks": false },
+ },
+ },
+};
+
export const WithOAuth: Story = {
args: {
settings: {
diff --git a/clients/web/src/components/groups/ServerSettingsForm/ServerSettingsForm.test.tsx b/clients/web/src/components/groups/ServerSettingsForm/ServerSettingsForm.test.tsx
index 7351ca48..8a6f81c1 100644
--- a/clients/web/src/components/groups/ServerSettingsForm/ServerSettingsForm.test.tsx
+++ b/clients/web/src/components/groups/ServerSettingsForm/ServerSettingsForm.test.tsx
@@ -458,9 +458,13 @@ describe("ServerSettingsForm", () => {
,
);
+ // Advertised Extensions is now its own accordion section (#1747).
+ expect(
+ screen.getByRole("button", { name: "Advertised Extensions" }),
+ ).toBeInTheDocument();
const tasks = screen.getByRole("checkbox", {
name: /Tasks \(io\.modelcontextprotocol\/tasks\)/,
});
@@ -476,7 +480,7 @@ describe("ServerSettingsForm", () => {
...emptySettings,
advertisedExtensions: { "io.modelcontextprotocol/tasks": false },
}}
- expandedSections={["options"]}
+ expandedSections={["extensions"]}
/>,
);
expect(
@@ -494,7 +498,7 @@ describe("ServerSettingsForm", () => {
{...baseHandlers}
onAdvertisedExtensionChange={onAdvertisedExtensionChange}
settings={emptySettings}
- expandedSections={["options"]}
+ expandedSections={["extensions"]}
/>,
);
// Default is checked; clicking flips it to unadvertised.
diff --git a/clients/web/src/components/groups/ServerSettingsForm/ServerSettingsForm.tsx b/clients/web/src/components/groups/ServerSettingsForm/ServerSettingsForm.tsx
index 55c88970..de582f29 100644
--- a/clients/web/src/components/groups/ServerSettingsForm/ServerSettingsForm.tsx
+++ b/clients/web/src/components/groups/ServerSettingsForm/ServerSettingsForm.tsx
@@ -44,6 +44,7 @@ function isExtensionAdvertised(
export type ServerSettingsSection =
| "options"
+ | "extensions"
| "environment"
| "headers"
| "metadata"
@@ -401,34 +402,6 @@ export function ServerSettingsForm({
checked={settings.paginatedLists ?? false}
onChange={(e) => onPaginatedListsChange(e.currentTarget.checked)}
/>
-
-
- Advertised Extensions
-
-
- Which extensions the Inspector declares to this server in its
- client capabilities. A server may register different tools
- depending on what the client advertises — toggle these to debug
- that. Takes effect on the next connect.
-
- {ADVERTISABLE_EXTENSIONS.map((ext) => (
-
- onAdvertisedExtensionChange(
- ext.key,
- e.currentTarget.checked,
- )
- }
- />
- ))}
-
+
+ Advertised Extensions
+
+
+
+ Which extensions the Inspector declares to this server in its
+ client capabilities. A server may register different tools
+ depending on what the client advertises — toggle these to debug
+ that. Takes effect on the next connect.
+
+ {ADVERTISABLE_EXTENSIONS.map((ext) => (
+
+ onAdvertisedExtensionChange(ext.key, e.currentTarget.checked)
+ }
+ />
+ ))}
+
+
+
+
{isStdio ? (
Environment Variables
diff --git a/clients/web/src/components/groups/ServerSettingsModal/ServerSettingsModal.test.tsx b/clients/web/src/components/groups/ServerSettingsModal/ServerSettingsModal.test.tsx
index c0c51aab..ac68ef1e 100644
--- a/clients/web/src/components/groups/ServerSettingsModal/ServerSettingsModal.test.tsx
+++ b/clients/web/src/components/groups/ServerSettingsModal/ServerSettingsModal.test.tsx
@@ -175,8 +175,11 @@ describe("ServerSettingsModal", () => {
onSettingsChange={onSettingsChange}
/>,
);
- // The Options section is expanded by default; Tasks is checked (registry
- // default), so clicking it toggles the override off.
+ // Advertised Extensions is its own accordion section (#1747), collapsed by
+ // default — open it, then toggle Tasks (checked by the registry default) off.
+ await user.click(
+ screen.getByRole("button", { name: "Advertised Extensions" }),
+ );
await user.click(
screen.getByRole("checkbox", {
name: /Tasks \(io\.modelcontextprotocol\/tasks\)/,
@@ -207,6 +210,10 @@ describe("ServerSettingsModal", () => {
onSettingsChange={onSettingsChange}
/>,
);
+ // Open the Advertised Extensions section (#1747), then re-check Tasks.
+ await user.click(
+ screen.getByRole("button", { name: "Advertised Extensions" }),
+ );
await user.click(
screen.getByRole("checkbox", {
name: /Tasks \(io\.modelcontextprotocol\/tasks\)/,
diff --git a/clients/web/src/components/groups/ServerSettingsModal/ServerSettingsModal.tsx b/clients/web/src/components/groups/ServerSettingsModal/ServerSettingsModal.tsx
index f6f28671..e91d43c8 100644
--- a/clients/web/src/components/groups/ServerSettingsModal/ServerSettingsModal.tsx
+++ b/clients/web/src/components/groups/ServerSettingsModal/ServerSettingsModal.tsx
@@ -26,6 +26,7 @@ function allSectionsFor(
): ServerSettingsSection[] {
return [
"options",
+ "extensions",
...(isStdio ? (["environment"] as const) : []),
"headers",
"metadata",
diff --git a/pr-screenshots/adv-ext-own-section-conninfo.png b/pr-screenshots/adv-ext-own-section-conninfo.png
new file mode 100644
index 00000000..3e9bccc1
Binary files /dev/null and b/pr-screenshots/adv-ext-own-section-conninfo.png differ
diff --git a/pr-screenshots/adv-ext-own-section.png b/pr-screenshots/adv-ext-own-section.png
new file mode 100644
index 00000000..c42945f1
Binary files /dev/null and b/pr-screenshots/adv-ext-own-section.png differ