Skip to content

fix: fail tools-list when tools array is empty#177

Draft
lux999 wants to merge 1 commit intomodelcontextprotocol:mainfrom
lux999:fix/tools-list-fail-on-empty-tools
Draft

fix: fail tools-list when tools array is empty#177
lux999 wants to merge 1 commit intomodelcontextprotocol:mainfrom
lux999:fix/tools-list-fail-on-empty-tools

Conversation

@lux999
Copy link

@lux999 lux999 commented Mar 3, 2026

An empty array ([]) is truthy in TypeScript, so the tools-list check incorrectly passed even when no tools were returned. Also refactor the nested if/else into a flat if/else-if chain for readability.
Please see Additional Context for the decision.

Motivation and Context

The tools-list scenario incorrectly reported success when a server returned an empty tools array ([]). An empty array is truthy in TypeScript, so !result.tools did not catch it, and forEach on [] was a no-op — resulting in zero errors and a passing test. This masked real failures where a server's initialize handshake failed and it returned no tools.

How Has This Been Tested?

Verified locally with vitest — all 84 tests pass. Confirmed manually that a server returning [] for tools/list now produces a failure, while a server returning valid tools still passes.

Breaking Changes

Servers with legitimately zero tools will now fail the tools-list scenario. These servers should add tools-list to their expected-failures baseline.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

Additional context

We understand there are two distinct cases where a server returns [] for tools/list:

  1. Intentional — the server is healthy but has no tools configured.
  2. Error-induced — the server's initialize handshake failed and it returned [] as a result, masking a real failure.

Three approaches to distinguish these cases were considered:

  1. Config parameter (e.g. --min-tools 1 passed to the conformance runner) — explicit but adds complexity to the CLI and every baseline file that needs to opt in.
  2. Separate scenario (e.g. tools-list-nonempty that servers opt into) — more surgical and avoids breaking existing baselines, but duplicates logic from the existing tools-list scenario.
  3. Fail all empty arrays in tools-list — any server returning [] fails. A server with no tools simply adds tools-list to its expected-failures baseline, consistent with the existing convention.

We went with option 3 as the right balance of correctness and simplicity. Raising as a draft for team discussion on the edge-case policy before merging.

An empty array ([]) is truthy in TypeScript, so the tools-list check
incorrectly passed even when no tools were returned. Also refactor the
nested if/else into a flat if/else-if chain for readability.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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.

1 participant