Skip to content

Gate header tabs/sections on server capabilities (Tools tab shows even when unsupported) #1516

Description

@cliffhall

Summary

Header navigation tabs/sections should appear only when the connected server actually advertises the corresponding server capability (from the MCP initialize result capabilities object). Today the Tools tab is always shown when connected — even against a server that doesn't advertise tools. We need to audit every section and gate each on its capability. Client-side features (sampling/elicitation/roots) must not be gated on server capabilities.

Current state (audited on v2/main)

Tab visibility is computed in clients/web/src/components/views/InspectorView/InspectorView.tsx (availableTabs, ~lines 509-534) and rendered by clients/web/src/components/groups/ViewHeader/ViewHeader.tsx. The current filter gates only on content length or transport type, never on the server's advertised capability:

Tab Gated today on… Should gate on capability File:line
Servers always n/a (always) InspectorView.tsx:~130
Tools nothing (always shown when connected) capabilities?.tools InspectorView.tsx:~133
Logs nothing (always shown when connected) capabilities?.logging InspectorView.tsx:~137
Apps appTools.length > 0 derived from tools InspectorView.tsx:~519
Prompts prompts.length > 0 capabilities?.prompts InspectorView.tsx:~520
Resources resources.length || resourceTemplates.length capabilities?.resources InspectorView.tsx:~521
Tasks tasks.length > 0 capabilities?.tasks InspectorView.tsx:~522
History always (when connected) n/a — local/client log InspectorView.tsx:~138
Network hidden for stdio transport n/a — transport-based, correct InspectorView.tsx:~518

The reported bug: Tools (and Logs) are shown regardless of capability. The content-gated tabs (Prompts/Resources/Tasks/Apps) mostly appear correct only because an unsupported capability yields an empty list — but content-gating is a proxy, not the real check: a server that advertises a capability but currently has zero items would incorrectly hide the tab, and the intent (gate on capability) is not expressed.

Capabilities are already available

The capability object is produced by the SDK initialize() and surfaced through core/react/useInspectorClient.ts as capabilities?: ServerCapabilities. The core state managers already short-circuit list RPCs when the capability is absent (core/mcp/state/managedListState.ts:~232, if (!client.getCapabilities()?.[this.config.capabilityKey]) return []). The pattern to follow is already used in App.tsx:

completionsSupported={capabilities?.completions !== undefined}
subscriptionsSupported={capabilities?.resources?.subscribe === true}
serverSupportsTaskToolCalls={!!capabilities?.tasks?.requests?.tools?.call}

So the data is present — it just isn't threaded into availableTabs.

Requirements

  • Thread server capabilities from useInspectorClientApp.tsxInspectorView and gate each server-capability tab on its capability field:
    • Tools → capabilities?.tools
    • Logs → capabilities?.logging
    • Prompts → capabilities?.prompts
    • Resources → capabilities?.resources
    • Tasks → capabilities?.tasks (and Run as Task already keys off tasks.requests.tools.call)
    • Apps → derived from tools (MCP Apps build on tools) + existing content check
  • Keep content-based hiding as a secondary filter if desired (capability present but list empty), but capability must be the primary gate.
  • Do not gate on server capabilities for client-side features: History (local), Network (transport), and any future Sampling / Elicitation / Roots UI (these are inspector-offered client capabilities, not server capabilities).
  • Confirm behavior when reconnecting to a different server: tabs recompute from the new capability set.

Testing

  • Unit/component tests for availableTabs across capability combinations (tools-only server, no-tools server, logging present/absent, etc.).
  • Regression test asserting the Tools tab is hidden when capabilities.tools is undefined.

Reference files

  • clients/web/src/components/views/InspectorView/InspectorView.tsxavailableTabs
  • clients/web/src/components/groups/ViewHeader/ViewHeader.tsx — renders tabs
  • core/react/useInspectorClient.ts — exposes capabilities
  • core/mcp/state/managedListState.ts — existing capability short-circuit (reference pattern)
  • App.tsx — existing completionsSupported / subscriptionsSupported gating pattern

Metadata

Metadata

Assignees

Labels

v2Issues and PRs for v2

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions