Zoho Books connector: sales-order `doc` (file attachment) sent as query param, not multipart — attachment impossible
Summary
The Anthropic-managed Zoho Books MCP connector (used from Claude Code, tool namespace mcp__claude_ai_Zoho_Books__*) cannot attach files to a sales order. The doc parameter on create_sales_order / update_sales_order is declared format: binary, but it appears to be transmitted as a URL query parameter rather than a multipart/form-data file part, which is what Zoho's attachment API requires. As a result, attaching a document is impossible with any value or encoding.
Affected tools
mcp__claude_ai_Zoho_Books__create_sales_ordermcp__claude_ai_Zoho_Books__update_sales_order
Both expose doc (format: binary) plus sibling query params totalFiles and can_send_in_mail. The same binary-param pattern exists on other entities (invoices, estimates, etc.), so this likely affects those too via the same serialization path.
No connector version string is surfaced to the client, so I can't include one. Org is a US-edition Zoho Books org.
What I was trying to do
Attach a PDF (a source purchase order) to a sales order via the doc parameter.
Steps to reproduce
Call update_sales_order on any existing sales order and vary only the doc value:
| doc value | Zoho result |
|---|---|
| File path string | {"code":2,"message":"Invalid value passed for doc"} |
| Base64 string | {"code":2,"message":"Invalid value passed for doc"} |
| data:application/pdf;base64,… data URI | {"code":2,"message":"Invalid value passed for doc"} |
| Public https URL to a PDF | {"code":2,"message":"Invalid value passed for doc"} |
| Raw ASCII PDF bytes as a string | {"code":2,"message":"Invalid value passed for doc"} |
| Array [{name, content}] | {"code":2,"message":"Invalid value passed for doc"} |
| Object {name, content, mime_type, …} | {"code":0,"message":"The salesorder has been updated."} — but response has "documents": [] and "attachment_name": ""; no file attached |
| Object {type:"base64", media_type, data} (Anthropic doc-source shape) | success, file silently dropped |
| Object {url:"…"} | success, file silently dropped |
Observed behavior
- String / raw-bytes / array forms → forwarded as the query value → Zoho rejects with
code: 2,Invalid value passed for doc(a query string is never a file). - Object forms → the request succeeds (
code: 0, "updated"), but the file is silently discarded: the returned sales order has an emptydocumentsarray and emptyattachment_name. Confirmed in the Zoho UI — the Attachments panel on the sales order stays empty.
Expected behavior
doc should be sent to Zoho as a multipart/form-data file part so the file actually attaches (documents populated, attachment_name set).
Impact
There is no working way to attach a document to a sales order (or, presumably, other supported entities) through the connector, so any workflow that needs the source document on the record has to fall back to manual upload or a separate direct Zoho REST call with its own OAuth token.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗