nenoDevelopers
⌘K
v1

MCP · Bills

Get an upload URL

WRITEcreate_bill_upload

Prepares an upload for one document and returns a short-lived URL and token. PUT the file's raw bytes to the URL, then pass the token to upload_bill or respond_to_task. Documents never travel inside a tool call.

Scope
bills:write
Upload and edit bills
Permission
neno.manageDocuments
Your role in the company must include it
Annotations
readOnlyHint falseidempotentHint falsedestructiveHint false

Description for models

Get a URL to upload a document to, before calling upload_bill or respond_to_task. This is the path for every invoice and receipt, whatever the file is, and for any document answering a task. It returns a short-lived upload URL and a token: PUT the file to the URL, then call upload_bill or respond_to_task with the token. This keeps the document out of the conversation, so the file arrives at full quality instead of being shrunk to fit, which is what makes extraction work. Files up to 10 MB; a larger one is refused at the PUT, and a bill in the user's own mailbox can be forwarded with get_bill_forwarding_address instead. If you cannot make an HTTP PUT at all, the reply says what to do instead. Be sure which company the bill belongs to first, with list_workspaces if you need to.

Sent verbatim in tools/list. It's written for the model, so it says when to use the tool.

Arguments

filenamestringrequired

The file name of the document you are about to upload, including its extension (.pdf, .jpg, .png, .heic, .heif, .webp or .gif). The extension says how to read the bytes, so it must match what they are.

Added by the server

On every tool that acts on one company
workspacestring

The id of the company this applies to. This connection covers a single company, which is filled in for you, so you can leave this out.

Result

text
Success. The answer as plain text in content[0].text, starting with Company: and the company name.
isError
Refused or failed. A missing permission, an invalid argument or a server failure sets isError: true. The text says what went wrong and what to tell the user.
input
Company needed. With several companies and no workspace argument, the server asks which company the call is for. A client that can't ask gets an error that lists the companies.
POST /mcp · tools/call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "create_bill_upload",
"arguments": {
"filename": "factuur-hendriks-0918.pdf"
}
}
}
Example resultHand-written
content[0].text
Company: Studio Veld BV
Upload it here, then tell us: PUT the file's raw bytes (not base64, no data-URI prefix) to this URL, with no extra headers.
https://mcp.neno.co/mcp/uploads/upl_9Qm2…
Then call upload_bill with upload_token set to "upl_9Qm2…" to file it as a bill, or respond_to_task with the same upload_token to attach it to a task. Add note if the user said anything about the document.
The URL and the token both stop working at 2026-09-28T10:45:00Z; call this again for a fresh pair if that passes.

Tools return plain text with no output schema. This example follows the tool's real format, but the values are made up.