Shawarma

MCP serverWeb API

Shawarma API reference.

Shawarma makes instrumental music from words, and changes only the part you ask for. Every song is code, so a change is an edit and every version is kept. Your agent can use it through the MCP server, and your own code through the web API. Both have the same tools.

Addresses

DoorAddressFor
MCP serverhttps://shawarma.studio/mcpFor agents such as Claude Code, Codex, Cursor, Claude.ai and ChatGPT. Streamable HTTP, one POST per request.
Web APIhttps://shawarma.studio/v1For your own code. JSON over HTTPS, the same tools as routes.

Sign-in and keys

  • Every request needs the header Authorization: Bearer <token>.
  • The token is an API key (it starts with shk_) or a sign-in token that Claude.ai or ChatGPT gets when you connect them (OAuth, it starts with sha_).
  • Make a key on the Development page, in your account menu. The key is shown once. You can revoke it at any time, and it stops at once.
  • A key cannot change billing, delete your account, or make other keys.
  • Without a token, or with a bad one, the answer is 401. A token without the scope a call needs gets 403 insufficient_scope.
ScopeAllows
songs:readget_song, list_songs, the versions, list_sounds, guide, check_code
songs:writewrite_song, restore_version, share_song
songs:composemake_song, change_song (uses the AI allowance)
audio:exportexport_audio (Pro)

The tools

Each MCP tool, its arguments, and the same thing on the web API.

make_song

Shawarma’s composer writes a new song from words: style, mood, instruments, tempo, length. Saves it and returns its id, code and a note.

ArgumentTypeWhat it is
description (required)stringWhat the song should be, in words.
titlestringThe song’s name (default: from the description).
length_secondsnumberAbout how long the song should be (5 to 600).
wait_secondsnumberHow long to wait for the result before the answer is a job (default 40, at most 55).

Web API: POST /v1/songs {description, title?, length_seconds?}

Plan: AI allowance (Pro; Free only on its 5 free replies)

change_song

Changes only what you ask for (“make the drums heavier”) and saves a new version.

ArgumentTypeWhat it is
song_id (required)stringThe song’s id, from make_song, write_song or list_songs.
request (required)stringWhat to change, in words.
wait_secondsnumberHow long to wait for the result before the answer is a job (default 40, at most 55).

Web API: POST /v1/songs/:id/changes {request}

Plan: AI allowance

get_song

A song’s name, code, newest versions and share link.

ArgumentTypeWhat it is
song_id (required)stringThe song’s id, from make_song, write_song or list_songs.

Web API: GET /v1/songs/:id

Plan: Free

list_songs

Your songs, newest first, with their ids.

No arguments.

Web API: GET /v1/songs

Plan: Free

restore_version

Makes an earlier version the newest one again. It is saved as a new version, so nothing is lost.

ArgumentTypeWhat it is
song_id (required)stringThe song’s id, from make_song, write_song or list_songs.
version_id (required)stringThe version’s id, from get_song.

Web API: GET /v1/songs/:id/versions, GET /v1/songs/:id/versions/:vid, POST /v1/songs/:id/versions/:vid/restore

Plan: Free

share_song

A public link (shawarma.studio/s/…) that plays in any browser without signing in. Sharing again updates the same link.

ArgumentTypeWhat it is
song_id (required)stringThe song’s id, from make_song, write_song or list_songs.
nicknamestringThe maker’s name on the page. Needed only the first time you share.

Web API: POST /v1/songs/:id/share {nickname?}

Plan: Free

export_audio

Renders the song as an MP3 or WAV file, up to 5 minutes, and returns a download link for the same key.

ArgumentTypeWhat it is
song_id (required)stringThe song’s id, from make_song, write_song or list_songs.
format"mp3" | "wav"mp3 (default) or wav.
version_idstringA version to render (default: the newest).
wait_secondsnumberHow long to wait for the result before the answer is a job (default 40, at most 55).

Web API: POST /v1/songs/:id/exports {format?, version_id?}, GET /v1/jobs/:id/audio

Plan: Pro

list_sounds

The sounds songs can use: drums and drum machines, synths, recorded instruments (darbuka, riq, oud and more), and maqam scales.

ArgumentTypeWhat it is
querystringPart of a sound name to search for, for example "guitar".

Web API: GET /v1/sounds?query=

Plan: Free

write_song

Saves music code your agent wrote, as a new song or a new version. Shawarma checks it first and refuses code that does not play. No AI cost.

ArgumentTypeWhat it is
code (required)stringThe whole song as Shawarma music code (up to 100,000 characters).
titlestringA new song’s name.
song_idstringSave a new version of this song instead.
messagestringWhat changed, for the version list.

Web API: POST /v1/songs {title, code}, PUT /v1/songs/:id/code {code}

Plan: Free

check_code

Checks music code without saving it: whether it plays, the error if not, the sounds it uses and how long it is.

ArgumentTypeWhat it is
code (required)stringShawarma music code to check.

Web API: POST /v1/check {code}

Plan: Free

guide

A short guide to writing Shawarma music code. Read it before write_song.

No arguments.

Web API: GET /v1/guide

Plan: Free

get_job

The state of a long request (make_song, change_song, export_audio): queued, running, done with the result, or failed with why. Can wait for it.

ArgumentTypeWhat it is
job_id (required)stringThe job’s id.
wait_secondsnumberHow long to wait for the result before the answer is a job (default 40, at most 55).

Web API: GET /v1/jobs/:id?wait=

Plan: Free

An example

Make a song

curl https://shawarma.studio/v1/songs \
  -H "Authorization: Bearer shk_…" \
  -H "Content-Type: application/json" \
  -d '{"description": "calm 20-second intro for a podcast"}'

The answer (shortened)

{
  "song": { "id": "calm-20-second-intro", "name": "Calm 20-second intro", "app_url": "https://shawarma.studio/open?song=…" },
  "version": { "n": 1 },
  "reply": "A soft piano intro with light drums, 20 seconds.",
  "job": { "id": "…", "status": "done" }
}

Long work

  • Composing and audio can take a while. A request waits up to wait_seconds (default 40, at most 55) for the result.
  • If it is not ready, the web API answers 202 with { job }, a Location header and Retry-After. The MCP server answers with the job and says to call get_job.
  • A release of Shawarma does not lose the work: the job finishes on the next server.
  • You have one AI reply running at a time, shared with the app’s chat. A second one while one runs gets 409 busy with Retry-After.

Free and Pro

ToolFreePro
make_song, change_songOnly on the 5 free replies, then 402 pro_requiredThe monthly AI allowance, and top-ups
write_song, restore_version30 new songs a day (within your 3 projects), 300 saves a day1000 new songs and 3000 saves a day
check_code300 a day3000 a day
export_audio402 pro_exportYes, up to 5 minutes of audio

See pricing

Limits

  • Per key or connection: 300 requests in 10 minutes, and 30 compositions an hour.
  • Code up to 100,000 characters. At most 20 keys per person.
  • Over a limit, the answer is 429 with Retry-After.

Connect your agent

The setup for Claude Code, Codex, Cursor, Claude.ai and ChatGPT is on the Developers page.