MCPUploads

Uploads

Multiple upload methods for cover art and audio files. All uploads require authentication to associate files with your account. Cover art is resized to 3000x3000. Audio is transcoded to WAV.

For large local files in coding agents like Claude Code or Cursor, prefer the local HTTP session flow so the file never needs to be serialized into repeated MCP tool calls.

If your MCP client handles auth natively, you do not need to pass access_token in the JSON-RPC examples below.

Option A: Base64 Upload (Small Files Only)

Use upload_file for small local files (under ~3 MB binary / ~4 MB base64):

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "upload_file",
    "arguments": {
      "type": "coverArt",
      "file_name": "cover.jpg",
      "file_base64": "<base64>"
    }
  }
}

Accepts raw base64 or data: URLs. Optional mime_type parameter.

Note: Due to platform payload limits (~4.5 MB), files larger than ~3 MB binary will fail with FUNCTION_PAYLOAD_TOO_LARGE. Use Option B (URL upload), Option D (local HTTP session), or Option E (legacy chunked MCP tools) instead.

Option B: URL Upload

Use upload_file_from_url for large public files:

{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "tools/call",
  "params": {
    "name": "upload_file_from_url",
    "arguments": {
      "type": "audio",
      "file_url": "https://example.com/track.wav"
    }
  }
}

URL must be publicly accessible (no localhost). The server downloads the file directly, so there is no payload size limit.

Option C: HTTP Multipart

POST /api/mcp/upload with form-data:

FieldValue
fileBinary file
typecoverArt or audio

Option D: Local HTTP Session (Preferred For Claude Code / Cursor)

For large local files in coding agents, start by creating a local upload session:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "prepare_local_file_upload",
    "arguments": {
      "type": "audio",
      "file_name": "track.wav",
      "file_size": 52428800,
      "file_type": "audio/wav"
    }
  }
}

This returns:

{
  "session_id": "abc-123",
  "upload_header_name": "x-mcp-upload-token",
  "upload_token": "...",
  "chunk_endpoint": "https://beta.once.app/api/mcp/upload/chunk",
  "complete_endpoint": "https://beta.once.app/api/mcp/upload/complete",
  "recommended_chunk_bytes": 5242880,
  "max_chunk_bytes": 6291456,
  "total_chunks": 10
}

1. Upload Chunks Over HTTP

POST /api/mcp/upload/chunk — Three formats supported:

Include the scoped upload token header:

  • x-mcp-upload-token: <upload_token>

Multipart: Form-data fields chunk, chunkIndex, sessionId, type

JSON Base64:

{
  "sessionId": "uuid-v4",
  "chunkIndex": 0,
  "type": "audio",
  "chunkBase64": "<base64>"
}

Raw Bytes: Content-Type: application/octet-stream with headers x-session-id, x-chunk-index, x-upload-type, x-mcp-upload-token

For large files, prefer Raw Bytes or Multipart. JSON base64 adds payload overhead and is mainly there as a compatibility fallback.

2. Complete The Upload

POST /api/mcp/upload/complete

{
  "sessionId": "uuid-v4",
  "fileName": "Track.wav",
  "fileType": "audio/wav",
  "type": "audio"
}

Use the same x-mcp-upload-token header on the completion request.

Option E: Legacy Chunked Upload (MCP Tools, Last Resort)

Only use this when your MCP client truly cannot make direct HTTP requests. Split the file into chunks of ≤ 3 MB binary (≤ 4 MB base64) each.

1. Initialize

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "upload_file_init",
    "arguments": {
      "type": "audio",
      "file_name": "track.mp3",
      "file_size": 4000000,
      "total_chunks": 2
    }
  }
}

Returns session_id for subsequent calls.

2. Upload Chunks

{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "tools/call",
  "params": {
    "name": "upload_file_chunk",
    "arguments": {
      "session_id": "<session_id>",
      "chunk_index": 0,
      "chunk_base64": "<base64 chunk>"
    }
  }
}

Repeat for each chunk (0-indexed).

3. Complete

{
  "jsonrpc": "2.0",
  "id": 3,
  "method": "tools/call",
  "params": {
    "name": "upload_file_complete",
    "arguments": {
      "session_id": "<session_id>",
      "type": "audio",
      "file_name": "track.mp3",
      "file_type": "audio/mpeg"
    }
  }
}

Returns fileUrl for use in release submission, but this flow is much more conversation-heavy than Option D.

Limits

TypeMax SizeNotes
Cover art50 MBMust be an image
Audio200 MBAudio formats or MP4
Base64 upload (upload_file)~3 MB binaryPlatform payload limit
Local HTTP session chunk6 MBUse prepare_local_file_upload first
Chunk (MCP tool)3 MB binaryLegacy fallback; ≤ 4 MB base64 per tool call