fix(mcpserver): emit one TextContent block when a tool returns an empty list (issue #3305) - #3319
Conversation
There was a problem hiding this comment.
All reported issues were addressed across 2 files
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
…ty list When a tool function returns an empty list or tuple, `func_metadata` was producing zero content blocks (an empty `CallToolResult.content`). The MCP spec requires at least one content item, so LLM clients that assume the list is non-empty would raise an index error or silently drop the result. Root cause: the branch that handled falsy sequences fell through to the normal `convert_result` path, which converts each element of the sequence into a `TextContent` block. An empty sequence produced nothing. Fix: detect `not result` before the element-wise conversion and return a single `TextContent` containing `[]` (the JSON serialisation of an empty list). Tuple return types are covered by the same branch. Signed-off-by: Radhakrishnan Pachyappan <gingeekrishna@gmail.com>
39aef8c to
25a9532
Compare
|
Thanks for the contribution. This repository only keeps pull requests open when they're linked to an issue that a maintainer has assigned to the author — CONTRIBUTING.md explains why and how we work. This PR has been closed for now because you aren't currently assigned to #3305. If a maintainer would like this change as a PR from you, they'll assign you to #3305 and this PR will reopen automatically — there's nothing more you need to do. (If you opened the issue, this PR already shows up on its timeline.) There's no need to open a new PR — this one will be reopened. While it's closed, please push any updates as new commits rather than force-pushing, since GitHub can't reopen a PR whose branch has been rewritten. Maintainers: reopening this PR, removing the |
Summary
listortuple,_convert_to_contentpreviously produced zero content blocks, making "no results" indistinguishable from "call produced nothing" for clients reading unstructured content.TextContentwhose text is the JSON-serialised empty collection ([]for bothlistandtuple).structuredContentis unaffected in all cases.Root cause
_convert_to_content(src/mcp/server/mcpserver/utilities/func_metadata.py:563) flattens a list by chaining the conversion of each item:With zero items there is nothing to concatenate, so the result is
[]. The same "empty" answer then behaves differently depending on return type:[]''[{...}, {...}]""''Fix
Tests added
Four new tests in
tests/server/mcpserver/test_func_metadata.py:test_empty_list_produces_one_text_content_block— core fix forlisttest_empty_tuple_produces_one_text_content_block— same guarantee fortupletest_non_empty_list_content_blocks_unchanged— non-empty path is byte-identicaltest_empty_list_structured_content_unaffected—structuredContentstill correctAll 46 tests in the file pass.
Test plan
uv run --frozen pytest tests/server/mcpserver/test_func_metadata.py— 46/46 pass[]now delivers one content block with text"[]"to the modelCloses #3305