Summary
The output_serializer function passed as tool_serializer to FastMCP() doesn't appear to transform the output that MCP clients actually receive. TOON serialization and filter_response() filtering (null removal, links stripping, items_active_record removal) are not reflected in what the client sees.
What I expected
With tool_serializer=output_serializer configured and OUTPUT_FORMAT=toon (the default), I expected MCP tool results to:
- Have null/empty values stripped by
remove_null_and_empty()
- Have
links keys removed
- Have sensitive keys filtered by
filter_sensitive_keys()
- Be serialized in TOON format
What I observed
Tool results arrive at the MCP client as raw JSON dicts with no transformation applied — nulls, items_active_record, and all original fields are present. Tested with FastMCP 2.12.4 on Claude Code (Claude Desktop).
This suggests FastMCP may be returning structured_content (the raw dict) to the client and only applying tool_serializer to the content text representation, which the client ignores when structured content is available.
Impact
filter_response() pipeline in utils.py is effectively dead code
- TOON output format configuration has no observable effect
- The
python-toon dependency is unused in practice
Questions
- Was
tool_serializer intended to transform what MCP clients receive, or only the text fallback?
- If the former, is this a FastMCP bug that should be raised upstream?
- Should the filtering/serialization be restructured to work with how FastMCP actually delivers results?
Additional context
This was discovered while migrating to FastMCP 3.0, which removed tool_serializer entirely. A middleware-based replacement (OutputSerializerMiddleware) has the same limitation — structured_content bypasses the serialized text.
Summary
The
output_serializerfunction passed astool_serializertoFastMCP()doesn't appear to transform the output that MCP clients actually receive. TOON serialization andfilter_response()filtering (null removal,linksstripping,items_active_recordremoval) are not reflected in what the client sees.What I expected
With
tool_serializer=output_serializerconfigured andOUTPUT_FORMAT=toon(the default), I expected MCP tool results to:remove_null_and_empty()linkskeys removedfilter_sensitive_keys()What I observed
Tool results arrive at the MCP client as raw JSON dicts with no transformation applied — nulls,
items_active_record, and all original fields are present. Tested with FastMCP 2.12.4 on Claude Code (Claude Desktop).This suggests FastMCP may be returning
structured_content(the raw dict) to the client and only applyingtool_serializerto thecontenttext representation, which the client ignores when structured content is available.Impact
filter_response()pipeline inutils.pyis effectively dead codepython-toondependency is unused in practiceQuestions
tool_serializerintended to transform what MCP clients receive, or only the text fallback?Additional context
This was discovered while migrating to FastMCP 3.0, which removed
tool_serializerentirely. A middleware-based replacement (OutputSerializerMiddleware) has the same limitation —structured_contentbypasses the serialized text.