invoke's body is z.record(z.string(), z.unknown()) and is always JSON-stringified; responses are read with res.text() and JSON-parsed when possible (safeBody). A resource operation that takes or returns application/octet-stream cannot be called through the MCP.
secret.agent.coop needs this for putBlob (PUT /messages/{id}/blob, raw AES-GCM ciphertext up to 1 MiB) and getMessage (raw ciphertext back). As a workaround both operations also accept and return {"blob": "<base64url>"} as JSON, which costs a base64 round trip and, on the decrypt side, about 3x the CPU of the raw path (27 ms vs 8 ms for 1 MiB, measured with wrangler tail).
Ask: a body_base64 (or content_type + string body) input on invoke sent as the raw bytes, and a base64 (or file) return for non-text responses.
invoke'sbodyisz.record(z.string(), z.unknown())and is always JSON-stringified; responses are read withres.text()and JSON-parsed when possible (safeBody). A resource operation that takes or returnsapplication/octet-streamcannot be called through the MCP.secret.agent.coop needs this for
putBlob(PUT /messages/{id}/blob, raw AES-GCM ciphertext up to 1 MiB) andgetMessage(raw ciphertext back). As a workaround both operations also accept and return{"blob": "<base64url>"}as JSON, which costs a base64 round trip and, on the decrypt side, about 3x the CPU of the raw path (27 ms vs 8 ms for 1 MiB, measured withwrangler tail).Ask: a
body_base64(orcontent_type+ string body) input oninvokesent as the raw bytes, and a base64 (or file) return for non-text responses.