Skip to content

Transcribe local files: create_upload_url + /upload/<token> - #7

Open
hsingh-aai wants to merge 2 commits into
mainfrom
file-upload
Open

hsingh-aai wants to merge 2 commits into
mainfrom
file-upload

Conversation

@hsingh-aai

Copy link
Copy Markdown
Collaborator

What & why

submit_transcript only takes a public URL. An agent in Claude Code, Cursor or Codex can see a file on the user's computer, but our server can't, and an agent signed in with OAuth never sees an API key it could upload with. So today "transcribe this file on my Mac" fails.

How it works

  1. The agent calls create_upload_url. It returns a link, https://mcp.assemblyai.com/upload/<token>, and a ready curl command.
  2. The agent runs curl --data-binary @file <link>.
  3. /upload/<token> decrypts the token, forwards the bytes to AssemblyAI's private POST /v2/upload with the caller's key, and returns { "upload_url": ... }.
  4. The agent passes that upload_url to submit_transcript as usual.

The token is the caller's API key plus an expiry, encrypted with AES-256-GCM under UPLOAD_TOKEN_SECRET. The agent never sees the key, and the server stores nothing.

Security notes (for review)

  • Leaked link: lets someone upload files into the user's AssemblyAI storage for up to 10 minutes. It can't read transcripts or start transcriptions. Links aren't single-use, because that would need storage.
  • Key exposure: the key is never in the link in plain text, and never in logs (only keyHash). Tampered, expired or other-secret tokens get a 401 without calling AssemblyAI.
  • Not doing: reading files from the server's own disk (the hole in the old community server).
  • Off by default: the tool only registers when UPLOAD_TOKEN_SECRET is set, so merging changes nothing in production until we add the secret.

Limits

  • 4.5 MB per file: Vercel's request body limit. That's a few minutes of MP3. Bigger files need a direct-to-AssemblyAI upload link from the API (follow-up, platform team).
  • Needs a shell: the agent runs curl, so ChatGPT and Claude.ai are not covered. ChatGPT uploads get their own change (fileParams).

Rollout

  1. Security review (Miki).
  2. Add UPLOAD_TOKEN_SECRET (32+ random characters) to Production and Preview in Vercel.
  3. Merge. Then upload a short real clip on production and transcribe it.

How it was tested

  • npm run typecheck and npm run build pass.
  • npm test: 114 smoke tests (13 new, #45–48) + 32 OAuth tests. The new tests cover:
    • the tool hidden without the secret, and shown with a title and read-only annotation;
    • the link not containing the key;
    • fresh, expired, tampered, garbage and other-secret tokens;
    • the route forwarding to /v2/upload with the raw key and application/octet-stream;
    • a bad token → 401, an empty body → 400, AssemblyAI's 401 → 401.
  • Locally over HTTP (next start + a fake AssemblyAI): tools/call create_upload_url returned a link on the request's host; curl uploaded a 396 KB file and got upload_url back; the fake API received all 396,000 bytes with the raw key; a bogus link got a 401; logs held only the key hash.
  • Real upload + transcription on a preview (needs the secret on Preview and a working API key).

🤖 Generated with Claude Code

The server can't read files on the user's computer, and an agent signed in
with OAuth never sees an API key to upload with. create_upload_url returns a
10-minute link whose token is the caller's key encrypted with AES-256-GCM;
the agent POSTs the file there with curl, and the route forwards it to
AssemblyAI's private /v2/upload and returns upload_url. Nothing is stored.

The tool only registers when UPLOAD_TOKEN_SECRET is set. Files are capped at
4.5 MB by Vercel's request body limit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@vercel

vercel Bot commented Oct 30, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
assemblyai-mcp Ready Ready Preview Oct 30, 2026 9:05pm UTC

Request Review

- submit_transcript only mentions create_upload_url when it's offered
- 4.5 MB limit uses Vercel's decimal cap; the tool tells agents what a
  plain-text 413 means and how to shrink the file
- Upload route maps AssemblyAI errors in one small helper; 5xx becomes 502

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@hsingh-aai
hsingh-aai marked this pull request as ready for review October 30, 2026 21:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant