Skip to content

fix: gate resource discovery on the resources capability - #213

Merged
nicobailon merged 2 commits into
nicobailon:mainfrom
kotuke:kotuke/fix/resources-capability-gate
Jul 25, 2026
Merged

fix: gate resource discovery on the resources capability#213
nicobailon merged 2 commits into
nicobailon:mainfrom
kotuke:kotuke/fix/resources-capability-gate

Conversation

@kotuke

@kotuke kotuke commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Problem

Since 2.12.0 moved the client to @modelcontextprotocol/client@2.0.0-beta.5, connecting a server that only advertises tools prints a debug line into the TUI on every Pi start:

Client.listResources() called but server does not advertise resources capability - returning empty list

The SDK v1 client stayed silent in the same situation, so this only became visible with the v2 beta.5 migration (#210).

Cause

server-manager.ts discovers prompts behind a capability gate but asks for resources unconditionally:

// fetchAllPrompts
const capabilities = client.getServerCapabilities?.();
if (!capabilities?.prompts) return { prompts: [], failed: false };

// fetchAllResources
const result = await client.listResources(cursor ? { cursor } : undefined, requestOptions);

The asymmetry dates from the prompts work in 2.12.0 (#203), which added the gate for prompts and left resource discovery as it was.

Fix

Apply the same gate in fetchAllResources. Nothing is functionally broken today — the SDK returns an empty list either way — but a tools-only server no longer causes a wire request or a debug line at startup.

A server that serves resources without advertising the capability is not spec-compliant, and the SDK v2 client already refuses to list them, so the gate does not change what such a server yields.

Tests

  • __tests__/resources-capability.test.ts (new): resources/list is not called when the capability is absent, is called when it is present, and a tools-only server connects with an empty resource list. Mirrors the existing "prompts capability negotiation" case in __tests__/prompts-sdk-integration.test.ts.
  • __tests__/fixtures/tools-only-server.mjs (new): minimal server advertising tools only — the existing fixtures all advertise resources.
  • Three mocked clients that assert on resources/list (abort-signal, proxy-modes-auto-auth, server-manager-sampling) now expose getServerCapabilities, like the real SDK client. Without it the mocks describe a server that advertises nothing, and their assertions would no longer test what they were written for.

Locally on Node 24: npx tsc --noEmit, npm test (738 passed), npm run test:oauth (107 passed) and npm run test:conformance (all scenarios pass or match the baseline) are green.

kotuke added 2 commits July 24, 2026 17:22
fetchAllResources called resources/list unconditionally, while
fetchAllPrompts already short-circuits on the advertised capability.
Under MCP SDK v2 beta.5 the client logs a debug line and returns an
empty list when the server does not advertise `resources`, so every
tools-only server printed noise into the TUI on each connect.

Apply the same capability gate to resource discovery. Mocked clients in
the tests that assert on resources/list now advertise the capability,
matching the real SDK client.
@nicobailon
nicobailon force-pushed the kotuke/fix/resources-capability-gate branch from a9630e8 to 0e5c9fd Compare July 25, 2026 00:27
@nicobailon
nicobailon merged commit 0d46909 into nicobailon:main Jul 25, 2026
@kotuke
kotuke deleted the kotuke/fix/resources-capability-gate branch July 25, 2026 06:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants