Skip to content

Conversation

@alantriesagain
Copy link

@alantriesagain alantriesagain commented Sep 30, 2025

This PR resolves issue #929 by implementing a default fallback handler that automatically returns empty arrays for standard MCP list methods when no specific handlers are registered, preventing "Method not found" errors.

Fixes #929

Problem

When a server advertises a capability (prompts, resources, tools) but doesn't register handlers for the corresponding list methods, clients receive -32601: Method not found errors instead of empty arrays.

Reproduction scenario:

const server = new McpServer({
  name: "example",
  version: "0.0.0",
});

// Server advertises prompts capability but registers no prompts
// No call to server.registerPrompt()

await client.listPrompts(); 
// ❌ Throws: MCP error -32601: Method not found
// ✅ Expected: { prompts: [] }

This affects all four list methods:

  • prompts/list → should return { prompts: [] }
  • resources/list → should return { resources: [] }
  • resources/templates/list → should return { resourceTemplates: [] }
  • tools/list → should return { tools: [] }

Root cause: The protocol layer had no default handling for list methods, so servers with capabilities but no registered items would fail with "Method not found" instead of gracefully returning empty collections.

Solution

Added a _defaultFallbackRequestHandler method to the Protocol class that:

  1. Recognizes standard MCP list method patterns
  2. Automatically returns appropriate empty arrays for known list methods
  3. Falls through to "Method not found" only for truly unhandled methods
  4. Respects user-defined fallbackRequestHandler when provided

Implementation approach:

private _defaultFallbackRequestHandler(request: JSONRPCRequest): SendResultT | null {
  const listMethodResponses: Record<string, string> = {
    "prompts/list": "prompts",
    "resources/list": "resources",
    "resources/templates/list": "resourceTemplates",
    "tools/list": "tools",
  };
  
  const responseKey = listMethodResponses[request.method];
  return responseKey ? { [responseKey]: [] } as SendResultT : null;
}

Handler resolution order:

  1. Specific registered handler (if exists)
  2. User-defined fallbackRequestHandler (if set)
  3. Default list method handler (new)
  4. "Method not found" error (only if none of the above match)

Changes

Core Protocol Changes:

  • src/shared/protocol.ts:
    • Added _defaultFallbackRequestHandler method for automatic empty array responses
    • Refactored _onrequest to use layered fallback logic
    • Sends responses directly from default handler to avoid unnecessary handler wrapping

Test Coverage:

  • src/client/index.test.ts:
    • Test for explicit empty handler registration (backward compatibility)
    • Test for servers with actual registered items (regression)
    • new tests covering all four list methods simultaneously
    • Test validating consistent behavior across all capabilities

Testing

Unit Tests (6 new tests):

  1. prompts/list returns empty array when no handler registered
  2. resources/list returns empty array when no handler registered
  3. resources/templates/list returns empty array when no handler registered
  4. tools/list returns empty array when no handler registered
  5. All list methods work with explicit empty handlers (backward compatibility)
  6. All list methods return empty arrays simultaneously without any handlers

Test Results:

npm test  # All tests pass including new ones
npm run build  # Clean build with TypeScript compilation
npm run lint  # Code style compliance verified

Validation scenarios:

  • ✅ Server with capability but no registered items → returns []
  • ✅ Server with explicit empty handler → returns [] (unchanged)
  • ✅ Server with registered items → returns items (unchanged)
  • ✅ Server with custom fallbackRequestHandler → uses custom logic (unchanged)
  • ✅ Unknown methods still return "Method not found" error

Breaking Changes

None. This is a backward-compatible enhancement that:

  • Maintains all existing handler registration patterns
  • Respects user-defined fallbackRequestHandler when present
  • Only adds default behavior for previously failing scenarios
  • All existing tests pass without modification
  • Servers with explicit handlers continue working identically

Types of Changes

  • ✅ Bug fix (non-breaking change which fixes an issue)
  • ✅ New tests added with comprehensive coverage
  • ✅ Documentation via inline comments

Checklist

  • ✅ Code follows repository's style guidelines (ESLint passing)
  • ✅ New and existing tests pass locally
  • ✅ Appropriate error handling maintained
  • ✅ Comprehensive test coverage for all four list methods
  • ✅ Backward compatibility preserved
  • ✅ Clear separation between default behavior and custom handlers

Impact

This fix resolves a critical UX issue affecting MCP server development. Developers can now:

  • Create minimal servers that advertise capabilities without immediately implementing handlers
  • Avoid boilerplate empty handler registration for unused capabilities
  • Get intuitive empty array responses instead of confusing "Method not found" errors
  • Build servers incrementally, adding handlers only when needed

Before (Broken):

// ❌ Throws "Method not found" even though server advertises capability
await client.listPrompts();

After (Fixed):

// ✅ Returns empty array gracefully
const result = await client.listPrompts(); // { prompts: [] }

@alantriesagain alantriesagain requested review from a team and ihrpr September 30, 2025 22:27
@alantriesagain alantriesagain force-pushed the issue-929_listPrompts-methodNotFound branch from 88f9723 to 3cf1c07 Compare September 30, 2025 22:31
@alantriesagain alantriesagain force-pushed the issue-929_listPrompts-methodNotFound branch 2 times, most recently from 46181b8 to 2732797 Compare September 30, 2025 23:36
@alantriesagain alantriesagain changed the title Fix: Return Empty Arrays for List Methods When No Handlers Registered (#929) Fix: Return empty Arrays for List methods when no handlers registered (#929) Oct 1, 2025
@felixweinberger felixweinberger self-assigned this Nov 3, 2025
@felixweinberger felixweinberger added bug Something isn't working needs maintainer action Potentially serious issue - needs proactive fix and maintainer attention labels Nov 3, 2025
@alantriesagain alantriesagain requested a review from a team as a code owner January 12, 2026 00:26
@alantriesagain alantriesagain force-pushed the issue-929_listPrompts-methodNotFound branch from 2732797 to 4f6eced Compare January 12, 2026 00:44
@changeset-bot
Copy link

changeset-bot bot commented Jan 12, 2026

⚠️ No Changeset found

Latest commit: a48c5cd

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@pkg-pr-new
Copy link

pkg-pr-new bot commented Jan 12, 2026

Open in StackBlitz

@modelcontextprotocol/client

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/client@986

@modelcontextprotocol/server

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/server@986

@modelcontextprotocol/express

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/express@986

@modelcontextprotocol/hono

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/hono@986

@modelcontextprotocol/node

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/node@986

commit: a48c5cd

@alantriesagain alantriesagain force-pushed the issue-929_listPrompts-methodNotFound branch from 4f6eced to d4713dc Compare January 12, 2026 01:11
@alantriesagain
Copy link
Author

@felixweinberger just saw that this PR needed some updates, pushed a rebase.

fixes #929

@alantriesagain alantriesagain force-pushed the issue-929_listPrompts-methodNotFound branch from d4713dc to a48c5cd Compare January 18, 2026 01:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working needs maintainer action Potentially serious issue - needs proactive fix and maintainer attention

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Client#listPrompts results in MCP error -32601: Method not found

2 participants