upload
File upload: stream-upload (one-shot — auto-finalizes, no filesize needed), chunked (create-session → chunk → finalize, for files over the 100 MB blob cap), web URL import, and batch (many small files). Call action='describe' for the full action/param reference. Side effects: finalize/stream/stream-upload/web-import/batch create files and consume storage credits. Same-name uploads to a folder OVERWRITE the existing node in place (preserved as a recoverable version). BYTES → SERVER: the DEFAULT for every file/binary is the POST /blob sidecar — a plain HTTP POST outside the MCP pipe (the create-session/blob-info response hands you a ready-to-run curl command) carrying RAW BYTES — no base64 inflation, no MCP size limit, up to 100 MB. stream-upload forwards them to the platform as a raw octet stream; chunk and batch send them as multipart. Either way the bytes never pass through base64. It returns a blob_id you pass to stream-upload/chunk/batch. ⚠️ content_base64 is a LAST RESORT, NOT a peer option — ~33% inflation plus a few-MB MCP transport cap means it FAILS for all but the smallest files. If you cannot reach POST /blob, that is almost always a CLIENT-SIDE FIREWALL/PROXY/EGRESS restriction: tell the user to allow the /blob endpoint rather than degrading to base64. content is for text you are composing ON THE FLY through the MCP (verbatim UTF-8) — not a file-upload fallback. UPLOAD STRATEGY (read top-to-bottom, pick the FIRST that matches): (1) Have a URL? → web-import (single call). (2) EVERYTHING ELSE up to 100 MB → POST /blob, then stream-upload with blob_id (single call, auto-finalizes, NO filesize required). Use this EVEN WHEN THE EXACT BYTE COUNT IS KNOWN — knowing the size does not make the chunked path better, it only makes it possible, and it costs 3+ round-trips plus the 10522 mismatch trap. If /blob seems unreachable, CHECK FIREWALL/SECURITY SETTINGS FIRST — falling back to content_base64 will fail for anything but a tiny file. (3) Over the 100 MB blob cap (must split across several blobs), or you need the session id between calls → create-session + chunk(blob_id) + finalize. filesize must match the bytes you actually upload — mismatch causes finalize to fail with code 10522 and you must cancel the session. (4) Multiple small files (≤4 MB each, ≤200 total) into one folder? → batch. Use blob_id (POST /blob) for every file/binary upload. If /blob is unreachable, raise the client-side firewall/proxy restriction with the user — content_base64 is a last resort that fails above a few MB, not a substitute. Do NOT guess filesize for generated content — use stream-upload. max_size is a hard ceiling that aborts mid-transfer — always overestimate or omit (server uses plan limit).
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| org | No | Org ID for limit resolution. | |
| url | No | Source URL to import from. | |
| hash | No | File hash for verification. | |
| plan | No | Override billing plan to check (e.g. free, pro). | |
| wait | No | Long-poll wait in SECONDS, 1-590 (NOT milliseconds; 0/omitted returns immediately). The server holds the connection until the upload reaches a terminal status. Sending a millisecond value here would hold for minutes and blow past the tool-call timeout. | |
| files | No | Batch manifest (1..200 entries). Each: filename + one of blob_id/content/content_base64. | |
| limit | No | Max results (1-100, default 50). | |
| action | Yes | Operation. Use 'describe' for full action reference. | |
| offset | No | Pagination offset. | |
| status | No | Filter by status. | |
| stream | No | Stream mode — size optional, single POST, auto-finalizes. | |
| blob_id | No | Blob ID from POST /blob — the **default source** for all file & binary uploads (no base64, no MCP size limit, up to 100 MB). Single-use. | |
| content | No | **Text only** — stored verbatim UTF-8. This is for writing content you are composing **on the fly** directly through the MCP (a note, a generated report, a snippet you just produced) — NOT a fallback for uploading an existing file. Do NOT pass base64 here (use content_base64). One of content/content_base64/blob_id. | |
| creator | No | Client identifier echoed back (alphanumeric + hyphens). | |
| file_id | No | File ID for update context. | |
| blob_ref | No | Alias for blob_id (deprecated). Accepted on chunk/stream/stream-upload only. | |
| chunk_id | No | Specific chunk number (omit for all). | |
| filename | No | File name. Optional when target_node_id is set (auto-resolved); pass to rename-on-replace. | |
| filesize | No | Total file size in bytes. | |
| max_size | No | Stream-body byte ceiling — aborts mid-transfer if exceeded. Always overestimate; omit to use plan limit. Stream sessions only. | |
| password | No | File Share link password (profile_type=fileshare only). Forwarded ONLY as the x-ve-password header on every upload phase — never in a URL/log. Supply when the target share is password-protected. | |
| share_id | No | Alias for profile_id when the profile is a share — implies profile_type=share (so profile_type may be omitted). | |
| folder_id | No | Target folder OpaqueId or "root". Omit for instance root. | |
| hash_algo | No | Hash algorithm (e.g. 'sha256'). | |
| upload_id | No | Upload session ID or web upload job ID. | |
| chunk_size | No | Chunk size in bytes (server picks default). | |
| context_id | No | Alias for profile_id (either name works) | |
| profile_id | No | Polymorphic context ID (pair with profile_type=workspace|share|fileshare). Typed aliases let you omit profile_type: workspace_id (⇒ workspace) / share_id (⇒ share); also context_id / instance_id. Target workspace/share ID, or the File Share id for a fileshare write-back. fileshare has NO typed alias — pass profile_type=fileshare explicitly. | |
| instance_id | No | Target workspace/share ID — also the profile_id alias for upload flows; profile_id is canonical. | |
| chunk_number | No | 1-indexed chunk number. | |
| context_type | No | Alias for profile_type (either name works). | |
| include_hash | No | Compute SHA-256 client-side for entries without a hash (default true when omitted). | |
| profile_type | No | Target type: workspace | share | fileshare (alias: context_type). Use `fileshare` ONLY for content write-back to a File Share's bound file (requires target_node_id = the bound node id from `fileshare details`; create-style new-file flows are rejected for fileshare). | |
| workspace_id | No | Alias for profile_id when the profile is a workspace — implies profile_type=workspace (so profile_type may be omitted). | |
| if_version_id | No | Compare-and-swap base for an overwrite. Enforced on EVERY update target — workspace, share and File Share. Pass the version id your edit was based on; record it on create-session/stream-upload (finalize does NOT read it). On a stale base the session ends assembly_failed with CONFLICT_VERSION_MISMATCH:<id> — rebase and retry. Omitting it is last-write-wins. See action=describe. | |
| action_context | No | Context: create or update. | |
| content_base64 | No | Base64-encoded **binary**, server-decoded. ⚠️ **LAST RESORT — expect FAILURE above a few MB** (~33% inflation + MCP transport cap). If POST /blob is unreachable that is almost always a CLIENT-SIDE FIREWALL/PROXY restriction, not a server limit — have the user allow /blob instead of falling back here. Use `blob_id` for any real file. | |
| parent_node_id | No | Parent folder OpaqueId or "root". On create-session, stream-upload, and web-import, folder_id is accepted as an alias (either name works). | |
| target_node_id | No | Overwrite this specific node (preserves node_id; new version). When set, parent_node_id is ignored and filename is optional (auto-resolved). Must be a file node. REQUIRED for profile_type=fileshare write-back — set it to the File Share's bound node id (from `fileshare details` → fileshare.file.id). | |
| describe_action | No | When action='describe', narrow the output to ONE action's full params/notes (e.g. 'chunk'). Omit to get the compact action index. |