Summary
@modelcontextprotocol/server-pdf v2.0.0's read_pdf_bytes returns the requested bytes only inside structuredContent. The content[0].text block contains just a size summary like 256 bytes at 0/641720 with no data.
Clients that render only content[] text blocks (e.g. terminal/CLI MCP clients like opencode) never see the bytes — they are silently dropped. The description also warns "The model should NOT call this tool directly", yet it is the only server-side way to get raw PDF content when the interactive viewer path is unavailable.
Reproduction
- Run the server:
npx @modelcontextprotocol/server-pdf --stdio <allowed-dir>
- Send an
initialize handshake, then:
{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"read_pdf_bytes","arguments":{"url":"/path/to/file.pdf","offset":0,"byteCount":256}}}
- Raw server response (verified by talking to the stdio transport directly):
{
"content": [{"type": "text", "text": "256 bytes at 0/641720"}],
"structuredContent": {
"url": "/path/to/file.pdf",
"bytes": "JVBERi0xLjQ...",
"offset": 0,
"byteCount": 256,
"totalBytes": 641720,
"hasMore": true
}
}
The base64 bytes decode to the real %PDF-1.4 header, so the data is correct — it's just unreachable to text-only clients.
Expected behavior
The byte payload should be reachable through the standard content[] text block, e.g. include the JSON payload (or the base64 bytes) in the text content, not only in structuredContent. Any MCP client that renders content[] should be able to consume the data without requiring structured-content support.
Related issue: display_pdf + interact requires an interactive viewer
display_pdf returns a viewUUID and interact get_text waits for the viewer iframe to poll within 8 seconds ("Viewer never connected for viewUUID ... (no poll within 8s)"). In headless/CLI contexts no iframe mounts, so text extraction via this path always fails. There is no non-viewer server-side text-extraction tool, so headless clients have no working path to PDF text today.
Environment
- Package:
@modelcontextprotocol/server-pdf 2.0.0 (installed via npx, run with --stdio under Docker isolation)
- Client: opencode CLI (terminal MCP client)
- The server runs fine: connection, init, and tool discovery all succeed; only content delivery is affected.
Summary
@modelcontextprotocol/server-pdfv2.0.0'sread_pdf_bytesreturns the requested bytes only insidestructuredContent. Thecontent[0].textblock contains just a size summary like256 bytes at 0/641720with no data.Clients that render only
content[]text blocks (e.g. terminal/CLI MCP clients like opencode) never see the bytes — they are silently dropped. The description also warns "The model should NOT call this tool directly", yet it is the only server-side way to get raw PDF content when the interactive viewer path is unavailable.Reproduction
npx @modelcontextprotocol/server-pdf --stdio <allowed-dir>initializehandshake, then:{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"read_pdf_bytes","arguments":{"url":"/path/to/file.pdf","offset":0,"byteCount":256}}}{ "content": [{"type": "text", "text": "256 bytes at 0/641720"}], "structuredContent": { "url": "/path/to/file.pdf", "bytes": "JVBERi0xLjQ...", "offset": 0, "byteCount": 256, "totalBytes": 641720, "hasMore": true } }bytesdecode to the real%PDF-1.4header, so the data is correct — it's just unreachable to text-only clients.Expected behavior
The byte payload should be reachable through the standard
content[]text block, e.g. include the JSON payload (or the base64 bytes) in the text content, not only instructuredContent. Any MCP client that renderscontent[]should be able to consume the data without requiring structured-content support.Related issue:
display_pdf+interactrequires an interactive viewerdisplay_pdfreturns aviewUUIDandinteract get_textwaits for the viewer iframe to poll within 8 seconds ("Viewer never connected for viewUUID ... (no poll within 8s)"). In headless/CLI contexts no iframe mounts, so text extraction via this path always fails. There is no non-viewer server-side text-extraction tool, so headless clients have no working path to PDF text today.Environment
@modelcontextprotocol/server-pdf2.0.0 (installed via npx, run with--stdiounder Docker isolation)