Skip to content

Tool functions returning raw lists produce multiple TextContent blocks, breaking most MCP clients #568

@EODWeber

Description

@EODWeber

Problem

Several tool functions return raw Python lists (e.g., return events[:limit]). When FastMCP serializes these, each list element becomes a separate TextContent block in the MCP CallToolResult.content array. Most MCP clients — including mcporter, Claude Code via mcp-remote, and others — only read content[0], so they see a single result instead of the full list.

Functions returning Response objects (like ListCalendarsResponse, ListTodosResponse) are unaffected since they serialize as a single JSON object.

Affected Functions

File Function Line(s) Returns
server/calendar.py nc_calendar_list_events 207, 221 events[:limit] / events
server/calendar.py nc_calendar_get_upcoming_events 455 all_events[:limit]
server/deck.py deck_get_boards 131 list[DeckBoard]
server/deck.py deck_get_stacks 155 list[DeckStack]
server/deck.py deck_get_cards 182 list[DeckCard]
server/deck.py deck_get_labels 209 list[DeckLabel]
server/contacts.py nc_contacts_list_addressbooks 24 list
server/contacts.py nc_contacts_list_contacts 35 list
server/tables.py nc_tables_list_tables 24 list

Reproduction

# Returns only 1 event instead of ~20
mcporter call "nextcloud.nc_calendar_list_events(calendar_name: \"outlookoffice365com\", start_date: \"2026-02-18\", end_date: \"2026-02-20\", limit: 100)"

The same query via Anthropic's Cowork MCP client (which reads all content blocks) returns the full result set, confirming the server produces the data correctly but the response serialization causes client-side truncation.

Suggested Fix

Wrap raw list returns in json.dumps() so the entire result serializes as a single TextContent block:

import json

# Before (creates N TextContent blocks):
return events[:limit]

# After (creates 1 TextContent block containing a JSON array):
return json.dumps(events[:limit], default=str)

Alternatively, wrap these returns in Response objects (consistent with how ListCalendarsResponse, ListTodosResponse, etc. already work) to keep a uniform return pattern across the codebase.

Environment

  • nextcloud-mcp-server: latest Docker image
  • Transport: mcp-remote --transport http-only
  • Clients affected: mcporter 0.7.3, Claude Code (via mcp-remote)
  • Clients unaffected: Anthropic Cowork (native MCP connector)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions