Skip to content

fix(pdf-server): return read_pdf_bytes payload as JSON text content - #782

Open
DLeibner wants to merge 1 commit into
modelcontextprotocol:mainfrom
DLeibner:fix/pdf-server-read-bytes-text-content
Open

DLeibner wants to merge 1 commit into
modelcontextprotocol:mainfrom
DLeibner:fix/pdf-server-read-bytes-text-content

Conversation

@DLeibner

Copy link
Copy Markdown

read_pdf_bytes in examples/pdf-server now also returns its result as serialized JSON in content[0].text, with the same data as structuredContent. Before, the bytes were only in structuredContent.

Fixes #762

Motivation and Context

Clients that only render content[], such as terminal MCP clients, got a size summary like 256 bytes at 0/641720 and never saw the PDF bytes. The MCP spec says a tool that returns structured content SHOULD also return the serialized JSON in a TextContent block, and several other examples in this repo already do (wiki-explorer-server, system-monitor-server, customer-segmentation-server).

The viewer (src/mcp-app.ts) still reads structuredContent, so its behavior is unchanged.

How Has This Been Tested?

  • Added a test in server.test.ts that calls read_pdf_bytes through an in-memory client and checks that content[0].text parses to the same object as structuredContent and decodes to %PDF-1.4. It fails on main with a JSON parse error and passes with this change.
  • Ran the built server over stdio (node examples/pdf-server/dist/index.js --stdio <file>) with a client that reads only content[0].text. It decoded the %PDF-1.7 header of tests/helpers/assets/fw9.pdf, and the parsed text matched structuredContent.
  • npm test passes: all pdf-server tests, 195 passed and 1 skipped. npm run build:all and npm run prettier pass.

Breaking Changes

None. structuredContent is unchanged. The text block changes from a size summary to JSON.

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

Trade-off: each chunk (up to 512 KB) is now sent twice, once as base64 in structuredContent and once inside the text. That also affects the viewer's range requests. If you'd rather keep the viewer path lean, I can include the text copy only when the client doesn't advertise the MCP Apps extension (getUiCapability(server.server.getClientCapabilities())).

This PR doesn't cover the second part of #762, a text-extraction path for headless clients that can't mount the viewer. That seems better as a separate change.

AI disclosure: I used Claude Code to research the issue, write the change and the test, and run the verification. I reviewed the diff and the test results myself.

read_pdf_bytes put the base64 bytes only in structuredContent; its text
block was a size summary like "256 bytes at 0/641720". Clients that only
render content[] (e.g. terminal MCP clients) could not read the data.

Mirror the structured result as serialized JSON in the text block, as the
MCP spec recommends for tools that return structured content. The viewer
keeps reading structuredContent, so its behavior is unchanged.

Fixes modelcontextprotocol#762

This branch has not been deployed

No deployments
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.

server-pdf: read_pdf_bytes hides the byte payload in structuredContent only — text content is a bare size summary, so CLI clients can't read the PDF

1 participant