@jam-jam/convert-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@@jam-jam/convert-mcp Convert ~/Music/rehearsal.mp3 into a chord sheet and save it to my songbook"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.

@jam-jam/convert-mcp
Turn audio, PDFs, photos, links and pasted text into chord sheets, and manage your Jam Jam songbook, straight from Claude, Cursor, VS Code or any MCP client.
This is the official Model Context Protocol server for the
public Jam Jam API. It gives your assistant 42 typed tools, so you ask in plain language instead of
pasting curl commands:
Convert a recording, a PDF, an image, a web page or pasted lyrics with chords into Jam Jam's songbook format, or export it as ChordPro, PDF, MIDI, MusicXML and more.
Organise your private songbook: list, read, add, edit and delete songs and playlists.
Look up what other accounts have published on their public profiles (read only).
Separate stems (vocals, drums, bass, other) from a song, queue an audio file for chord and lyrics analysis on your own songs, and check a track for AI music signals: the long-running audio tools, each with a start, a status and a result step.
Stay in control: the server shows the assistant only the tools your API key is allowed to use, and it never publishes, follows or likes anything on its own.
Listed in the official MCP Registry as org.jam-jam/convert-mcp. Every tool maps to a real route
of https://jam-jam.org/api/v1.
Quick start
Get an API key. Create a free account on jam-jam.org, then open Settings > API keys and create a key. The secret (
jj_live_...) is shown only once: copy it right away. Give the key only the scopes you need (see Scopes).Declare the server in your MCP client (below). Nothing to install:
npxdownloads and runs it. Node.js 18.17 or later is required.Restart the client and ask in plain language.
If something does not work, ask the assistant to call jj_check_usage: it reports what the key is
allowed to do and how much quota is left.
Related MCP server: suno-mcp
What you can ask
"Convert
~/Music/rehearsal.mp3into a chord sheet and save it in my Jam Jam songbook.""Import
~/Downloads/lead-sheet.pdfinto my songbook.""Here are the lyrics with chords above the words: convert them to ChordPro." (paste the text)
"List the songs of my songbook that have no key or no capo set."
"Create a playlist called Thursday rehearsal and put these five songs in it."
"How many conversions do I have left this week?"
The exact formats the API serves right now, with their limits, are returned by jj_list_formats;
some outputs need an account or Premium, and that tool says which.
Install in your client
Every client below launches the same command, npx -y @jam-jam/convert-mcp, with your key in the
JAM_JAM_API_KEY environment variable.
Claude Code
claude mcp add --env JAM_JAM_API_KEY=jj_live_... --transport stdio jam-jam -- npx -y @jam-jam/convert-mcpAdd --scope user to make it available in every project. This writes the key on a command line,
so it ends up in your shell history. To avoid that, declare the server in a .mcp.json file that
reads the key from your environment, and export JAM_JAM_API_KEY yourself:
{
"mcpServers": {
"jam-jam": {
"command": "npx",
"args": ["-y", "@jam-jam/convert-mcp"],
"env": {
"JAM_JAM_API_KEY": "${JAM_JAM_API_KEY}"
}
}
}
}Claude Desktop
Open Settings > Developer > Edit Config, which opens claude_desktop_config.json
(macOS: ~/Library/Application Support/Claude/, Windows: %APPDATA%\Claude\), and add:
{
"mcpServers": {
"jam-jam": {
"command": "npx",
"args": ["-y", "@jam-jam/convert-mcp"],
"env": {
"JAM_JAM_API_KEY": "jj_live_..."
}
}
}
}Cursor
Add the same mcpServers block as for Claude Desktop to .cursor/mcp.json (one project) or
~/.cursor/mcp.json (all projects). Cursor expands ${env:JAM_JAM_API_KEY} in the env values,
so you can keep the key out of the file.
VS Code
Create .vscode/mcp.json (or run MCP: Add Server from the Command Palette). VS Code uses a
servers key and can prompt for the key and store it for you:
{
"inputs": [
{
"type": "promptString",
"id": "jam-jam-api-key",
"description": "Jam Jam API key (jj_live_...)",
"password": true
}
],
"servers": {
"jam-jam": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@jam-jam/convert-mcp"],
"env": {
"JAM_JAM_API_KEY": "${input:jam-jam-api-key}"
}
}
}
}Windsurf
Open the MCP config file from the Cascade panel (see the
Windsurf MCP documentation) and add the same
mcpServers block as for Claude Desktop. Windsurf expands ${env:JAM_JAM_API_KEY} in the env
values.
Any other MCP client (stdio)
Command npx -y @jam-jam/convert-mcp, with the environment variable JAM_JAM_API_KEY set by the
client. Never pass the key as a command-line argument (see Privacy).
Streamable HTTP mode
For clients that connect to a URL instead of launching a command, run the server yourself in Streamable HTTP mode:
JAM_JAM_API_KEY=jj_live_... JAM_CONVERT_MCP_MODE=http npx -y @jam-jam/convert-mcp
# MCP endpoint: http://127.0.0.1:3466/mcp
# Health and per-tool counters: http://127.0.0.1:3466/healthzThe server listens on the loopback interface only by default. It holds a single API key, so
anything that can reach its port acts as the owner of that key; it is not a multi-user server.
Binding another address without JAM_CONVERT_MCP_HTTP_TOKEN makes startup fail. With the token
set, clients must send it as Authorization: Bearer <token>. DNS-rebinding protection is active:
the Host and Origin headers must match the address being served.
Tools
At startup the server asks the API what your key may do and exposes only the matching tools. A key
with carnet:read alone never shows jj_delete_song to the assistant. 42 tools exist in total.
Your songbook is called the "notebook" in the tool descriptions and carnet in the scope names.
Tool | Required scope | What it does |
| none | Lists the input and output formats served by the API, with their limits and whether an account or Premium is required. Call it before any conversion. |
|
| Converts a local file (path or base64). Returns text directly for small text formats, or a local file path for binary results (PDF, MIDI, MP4...). Can save the result to your songbook with |
|
| Same for pasted text or ChordPro, no file needed (up to 262144 characters). |
|
| State of a conversion job by id, for a job that outlasted the wait. |
|
| Pages through the songs of your private songbook. |
|
| One complete song (chords, lyrics, structure). |
|
| Your playlists, with their ordered content. |
|
| One playlist and its songs, in order. |
|
| Adds a song to your songbook. The id is derived ( |
|
| Changes title, artist, key, capo, tempo, playlist membership, or publishes / unpublishes on your profile. |
|
| Deletes a song. Idempotent, and cannot be undone from the API. |
|
| Creates a playlist with its ordered songs. |
|
| Renames a playlist, changes its cover emoji, replaces or reorders its songs. |
|
| Deletes the playlist only, never its songs. |
|
| Profile card of an account by |
|
| Songs an account has published on its profile. |
|
| Playlists an account has published. |
|
| Your followers ( |
|
| Accounts you follow. |
| none | Scopes of the key and its three independent quota counters (separation and AI music counters are read with their own tools). |
|
| Availability, models, limits and quota (with reset time) of the stem separation. Needs a Premium account for an API key. |
|
| Uploads an audio file and starts its separation into 2 stems (vocals, instrumental) or 4 (vocals, drums, bass, other), as MP3 320 kb/s or FLAC 24-bit ( |
|
| State of one of your separations (queued, running, done...), progress and estimates. |
|
| Your recent separations, 30 per page. |
|
| Downloads one finished stem ( |
|
| Cancels one of your separations. |
|
| Queues an audio file for chord and lyrics analysis, then automatic alignment, for a song that is already in your songbook. Same queue as the Jam Jam app. |
|
| Your audio queue: running, waiting (with rank) and finished in the last 7 days. |
|
| One job of your audio queue: status, stage, progress. |
|
| Cancels one job of your audio queue. |
|
| Availability, limits and quota (with reset times) of the AI music detection. |
|
| Starts an AI music detection on a local file (100 MB, 600 seconds at most) or on one link (Spotify track, ISRC, direct audio link). Returns at once; |
|
| Your current or latest analysis, or none. |
|
| One analysis and, once done, its report. The report is an index of signals, not a probability and not proof of origin. |
|
| Your analyses of the last 90 days, 30 per page. |
|
| Cancels your running analysis (the quota unit is refunded). |
| none | The live contract of the Mastering engine: range and step of each setting, loudness targets, built-in presets, limits, whether your account may render through the API (any account) and the render quota. |
|
| Your saved Mastering presets (50 at most) and the ids of the built-in ones ( |
|
| Saves a named preset (all eight modules, a loudness target, normalize). The API rejects values outside their range or step and names each one. Open to any account. |
|
| Uploads an audio file and renders it on the server with a preset (saved, built-in, or inline settings) into a 48 kHz WAV ( |
|
| State of one of your renders, the loudness before and after, and with |
|
| Cancels one of your renders (the quota unit is refunded only if the render was not finished; a finished render is deleted but stays counted). |
The long-running audio tools
Stem separation, audio analysis and AI music detection take seconds to hours. They all follow the same three steps, so an assistant never blocks on a slow job:
Start:
jj_stems_separate,jj_audio_analyzeorjj_ai_music_analyzereturn at once with a job (passmaxWaitMstojj_stems_separateorjj_ai_music_analyzeto wait for a short one).Follow:
jj_stems_get_job,jj_queue_get_joborjj_ai_music_get_jobgive the state.Collect:
jj_stems_get_filedownloads a stem; the audio analysis lands on the song in your songbook (jj_get_song); the AI music report is injj_ai_music_get_job.
The error messages are specific to these tools: 401 asks for a valid key, 403 names the
missing scope (or says an API key needs a Premium account for stems), 413 states the size and
duration limits, and 429 says which counter is spent and, when the API gives it, when it resets
(read from jj_stems_capabilities or jj_ai_music_availability).
Studio projects are out of reach
The MCP server processes one file at a time (convert, separate, analyse). It never opens, reads,
edits, renders or deletes a project of the Jam Jam Studio, and no tool is named after one. The
rule is enforced by test/contract/studio-rule.test.ts (decision Q109): every route a tool calls
must belong to a unit-processing family, and the complete tool list is written out in that test.
Scopes
A key carries scopes chosen when it is created: convert:read, convert:write, carnet:read,
carnet:write, social:read, stems:write, audio:write, queue:read, mastering:read, mastering:write. The API enforces them; this server additionally hides the tools your
key cannot use. Pick the smallest set for your use:
Use | Scopes |
Convert files |
|
Look at the songbook and answer questions |
|
Import songs and organise the songbook |
|
See what another account published |
|
Separate stems |
|
Queue audio for analysis on your songs |
|
Check tracks for AI music signals |
|
Save and list Mastering presets |
|
Master a file on the server |
|
A key created before the songbook API existed carries only convert:read and convert:write:
create a new key rather than widening an old one. JAM_CONVERT_MCP_READ_ONLY=1 hides the write
tools even when the key allows writing.
What this server does not do
No social writes: following, unfollowing and liking stay in the Jam Jam app.
No audio: the API never serves the soundtrack of a published song.
No Studio projects: see above. This server only runs unit processings.
No deleting of a Mastering preset: it stays in the app. An assistant can create presets and render with them, never remove one.
No erasing of the AI music history and no download of an analysis provider's temporary source: both stay in the app.
No ranking, feed or account suggestions.
Publishing is never a side effect. Adding a song does not publish it, and publishing requires a rights declaration that the assistant must ask you for.
Quotas and retention
Three independent counters, as reported by jj_check_usage. A free account is enough to start;
Premium
raises the limits.
Counter | Free account | Premium |
Conversions | 6 per week | 500 per calendar month |
Reads (songbook and social listing tools) | 2000 per UTC day | 20000 per UTC day |
Writes (songbook) | 200 per UTC day | 5000 per UTC day |
Three more counters belong to the long-running audio tools. Each tool description states them, and
jj_stems_capabilities and jj_ai_music_availability report the exact balance and reset time:
Counter | Free account | Premium |
Stem separation, one counter for both models (API keys: Premium only) | not for API keys | 30 per UTC day and 500 per month (22 h 30 of audio per day, 150 h per month) |
Server audio analysis ( | 5 per ISO week, 50 jobs waiting at most | no limit |
AI music detection | 5 per UTC day and 50 per month (visitor: 2 and 5) | 30 per UTC day and 300 per month |
Mastering renders (jj_master_audio, any account) use the render counter of the Jam Jam app: 3 per
ISO week for a free account, no cap for Premium; jj_mastering_capabilities reports the balance.
Through the API, a render is counted at submission, and refunded if it fails or is cancelled. Listing and creating
presets uses the read and write counters above.
Quota errors state when the counter resets.
Uploaded files and conversion results are deleted by the API 24 hours after the job is created;
separated stems and mastered files are kept 24 hours and AI music reports 90 days (with an account), and no audio is
kept after an AI music analysis. The only files this server writes to your disk are binary
conversion results and downloaded stems, in JAM_CONVERT_MCP_WORKDIR.
Environment variables
Variable | Purpose | Default |
| Your API key ( | none |
| API base URL, no trailing slash. Alias: |
|
|
|
|
| HTTP mode bind address and port (above 1024). Aliases: |
|
| HTTP mode shared secret, required as a Bearer token. Mandatory if the host is not loopback. Alias: | none |
|
| off |
| Comma-separated scopes to use instead of asking the API at startup. Alias: | asked from the API |
| Directory for binary conversion results and downloaded stems. |
|
| Job polling interval. |
|
| Maximum wait for one job (hard cap 600000). |
|
An API key is required in practice. On jam-jam.org, every route except /health,
/formats and /openapi.json is stopped by the edge protection when a request carries no
Authorization header. Without a key the server starts and warns on stderr, but only
jj_list_formats will answer.
Privacy and security
The API key comes from the environment, never from a command-line argument or a tool parameter. A command-line argument leaks into shell history and process listings. No tool accepts a key, token or authorization parameter, so an assistant cannot ask for a different key mid-session.
The server does not log requests, responses or keys. It keeps only in-memory counters per tool (calls, successes, failures), visible on
/healthzin HTTP mode and reset on restart. Only startup messages and fatal errors go to stderr.No telemetry. The only outbound requests are calls to the Jam Jam API at
JAM_JAM_API_BASE_URL.Scoped to your account. The songbook tools only touch the songbook of the account that owns the key, and files you convert are purged by the API after 24 hours (see above). Details: privacy policy.
API errors are passed on as a short actionable sentence built from the error code, without echoing what the caller sent.
Every API call carries the header
User-Agent: jam-mcp/<version>, so MCP traffic can be told apart from browsers and scripts.On stdio, stdout is the protocol channel: all diagnostics go to stderr.
Links
Developer documentation: API reference, engine licences,
curland Python examples.Code examples (curl, JavaScript, Python, MIT) for the REST API this server wraps
Contact: contact@jam-jam.org
Licence
MIT © Jam Jam
Available Tools
42 toolsjj_ai_music_analyzeAnalyse a track for AI music signalsA
Starts an AI music detection (POST /ai-music/jobs) on a local audio file (path, or base64 content: 100 MB and 600 seconds at most), OR on exactly one link: "url" (Spotify track link), "spotifyTrackId", "isrc" or "audioUrl" (direct audio link; YouTube is not supported; a Spotify or ISRC source may only provide an excerpt, see result.primary.audioSource). Links only work when jj_ai_music_availability reports links=true. Asynchronous: returns at once with a job (pass maxWaitMs to wait), then follow it with jj_ai_music_get_job. One unfinished analysis per account at a time (409), results kept 90 days, no audio kept. Needs the audio:write scope. Consumes one unit of the ai-music counter (free 5/day and 50/month, Premium 30/day and 300/month, UTC; failures refunded); a 429 states when it resets, a 413 means the file is too large or too long. The report is an aggregated index of signals, not a probability and not proof of origin: present it as such.
Inputs: url, isrc, path, audioUrl, +4 more.
jj_ai_music_availabilityAI music detection: availability, limits and quotaA
Reports whether the AI music detection is available (GET /ai-music/availability): upload size and duration limits, whether links are accepted, and the remaining daily and monthly quota with exact reset times (quota.daily.resetsAt, quota.monthly.resetsAt, epoch milliseconds, UTC). Quotas: visitor 2/day and 5/month, free account 5/day and 50/month, Premium 30/day and 300/month, shared between website, app and API keys; failures and cancellations are refunded. Call it before jj_ai_music_analyze and after a 429. Costs nothing.
Inputs: no named parameters.
jj_ai_music_cancel_jobCancel an AI music analysisA
Cancels the caller's own AI music analysis and deletes its temporary files (DELETE /ai-music/jobs/{id}). The quota unit is refunded. Needs the audio:write scope. Only call it when the user asked to stop that analysis.
Inputs: id (required).
jj_ai_music_currentFind my current AI music analysisA
Returns the caller's current or most recent AI music analysis, or null when there is none (GET /ai-music/jobs). Use it to find the id of a running analysis, since only one unfinished analysis per account can exist. Needs the queue:read scope. Costs no quota.
Inputs: no named parameters.
jj_ai_music_get_jobGet an AI music analysis and its reportA
Fetches one AI music analysis by id (GET /ai-music/jobs/{id}): state (uploading, queued, running, cancelling, done, failed, cancelled), progress, queue position and, once done, the report in "result" (score 0 to 100, verdict signals-detected / few-signals / inconclusive, per-detector windows, and for the v3 report the classification human / processed-ai / pure-ai). The report is an aggregated index of signals, not a probability and not proof of origin: present it as such. A job of another account answers 404. Needs the queue:read scope. Costs no quota.
Inputs: id (required).
jj_ai_music_historyList my AI music analyses of the last 90 daysA
Lists the caller's own analyses of the last 90 days, newest first, 30 per page (GET /ai-music/history): source label (file name or link), dates, state and report, never any audio. Needs an account and the queue:read scope. Pass the returned "nextBefore" as "before" for the next page. Costs no quota.
Inputs: before.
jj_audio_analyzeQueue an audio file for chord and lyrics analysisA
Uploads a local audio file (path, or base64 content) to the Jam Jam server queue so that its chords and lyrics are analysed, then automatically aligned, for a song of YOUR notebook (POST /audio). Same queue as the Jam Jam app. "songId" must already exist in the caller's notebook (see jj_list_songs), otherwise 404. Needs an account and the audio:write scope. It returns at once with a job: follow it with jj_queue_get_job. Idempotent per (account, song, file content): sending the same file again returns the same job with reused=true and consumes nothing. Quota: counter "audio-analysis", 5 analyses per ISO week on a free account (resets Monday 00:00 UTC), no limit on Premium; at most 50 jobs may wait per account. Errors: 413 file too large, 415 not audio, 429 quota or queue full.
Inputs: songId (required), path, filename, contentBase64.
jj_check_usageCheck quotas and what this key may doA
Returns, in one call, what the calling Jam Jam identity is allowed to do and how much of each allowance is left. THREE INDEPENDENT COUNTERS, they never borrow from one another: conversion (6 per week on a free account, 500 per calendar month on Premium, 3 per 24h anonymous), read (2000 per UTC day free, 20000 Premium, spent by the notebook and social listing tools) and write (200 per UTC day free, 5000 Premium, spent by the notebook writing tools). Stem separation and AI music detection keep their own counters, read with jj_stems_capabilities and jj_ai_music_availability. scopes lists the permissions of the API key in use. Call this before a batch, and after a quota error to learn when it resets. Costs nothing itself.
Inputs: no named parameters.
jj_convert_fileConvert a local fileA
Uploads a local file (path, or base64 content) to the Jam Jam API, waits for the conversion to finish, and returns the result: embedded text for small text formats (ChordPro, .lrc, .lab...), or a local file path for binary formats (PDF, MIDI, MP4...). Call jj_list_formats first to find valid "output" ids for your input. Consumes one unit of the conversion quota (6/week free, 500/month Premium, see jj_check_usage), which is a different counter from notebook reads and writes.
Inputs: output (required), path, deliver, options, +4 more.
jj_convert_textConvert pasted text or ChordProA
Sends plain text or ChordPro (pasted lyrics and chords, no file) to the Jam Jam API, waits for the conversion to finish, and returns the result: embedded text for small text formats, or a local file path for binary formats (PDF, MIDI...). Call jj_list_formats first to find valid "output" ids. Consumes one unit of the conversion quota.
Inputs: text (required), output (required), deliver, options, +2 more.
jj_create_mastering_presetCreate a Mastering presetA
Saves a named Mastering preset on the account (POST /mastering/presets): a name of 1 to 60 characters, unique among the account presets, and the settings (all eight modules with value and enabled, a loudness target, normalize). Each value must be within its range and on its step: read them with jj_mastering_capabilities, or copy the settings of a built-in preset and change a few values. The API answers 422 with the path of every rejected field when the settings are invalid, 409 when the name is taken or the 50-preset cap is reached. Open to any account, free or Premium. Counts one unit of the daily write quota. Only call it when the user asked to save a preset.
Inputs: name (required), settings (required).
jj_create_playlistCreate a notebook playlistA
Creates a playlist in the calling account's notebook. Playlists are flat and allow multi-membership: a song can be in several of them. songIds is the ordered content and every id must be a live song of this account. Consumes one unit of the daily write quota.
Inputs: name (required), songIds, coverEmoji.
jj_create_songAdd a song to my notebookA
Adds a song to the calling account's PRIVATE notebook. song is the canonical pivot payload: exactly the object returned by jj_get_song (song) or by a conversion whose output is "songbook", so converting then filing is a copy with no transformation. The id is DERIVED, never random: song.id if given, otherwise an "artist-title" slug. That means posting the same song twice REPLACES it instead of creating a duplicate, and it is also how you rewrite a song wholesale (read it with jj_get_song, edit the payload, post it back with its id). Adding NEVER publishes anything on the public profile. Consumes one unit of the daily WRITE quota (200/day free, 5000 Premium).
Inputs: song (required), publish, playlistIds.
jj_delete_playlistDelete a notebook playlistA
Deletes a playlist, and ONLY the playlist: its songs stay in the notebook and in their other playlists. Idempotent, and an unknown id succeeds too. If the playlist was published on the profile, that published copy disappears.
Inputs: playlistId (required).
jj_delete_songDelete a notebook songA
Deletes a song from the calling account's notebook. Idempotent: deleting twice succeeds twice, and an unknown id succeeds too (saying "no such song" would leak whether it exists in someone else's notebook). Side effects are the same as deleting in the app: the song leaves all its playlists, its published copy disappears from the profile, and accounts that had imported it are notified. This cannot be undone from the API: confirm with the person before calling it.
Inputs: songId (required).
jj_get_jobGet a conversion job statusA
Fetches the current state of a conversion job by id: phase (queued/running/done/failed/cancelled), per-step progress, and the list of artifacts once done. Use this to check on a job after jj_convert_file or jj_convert_text stopped waiting for it.
Inputs: id (required).
jj_get_playlistGet one notebook playlist and its songsA
Returns one playlist of the calling account's notebook with its songs in summary form, in playlist order, paginated by the same opaque cursor. A song the playlist still references but that has since been deleted from the notebook is simply skipped.
Inputs: playlistId (required), limit, cursor.
jj_get_profileGet a public profile cardA
Returns the profile card of a Jam Jam account designated by its public @handle, seen from the calling account: display name, bio, avatar, visibility (public/private), follower and following counts, and relation (none / following / follower / mutual / requested / self). A PRIVATE account the caller does not follow returns a closed card without bio or counts. An unknown handle returns not-found. Jam Jam is a host: this never ranks or recommends anyone, and never exposes somebody else's audience figures.
Inputs: handle (required).
jj_get_songGet one notebook songA
Returns one song of the calling account's notebook in full: the summary fields AND song, the canonical pivot payload (sections, lines, chords with their offsets, lyrics, detectedKey, metadata). That payload is exactly what jj_create_song and jj_update_song accept, so reading then writing back is a copy, not a translation. An unknown id and an id belonging to another account both return the same not-found error.
Inputs: songId (required).
jj_list_followersList the accounts that follow meA
Lists the calling account's own followers, newest first. status="requested" lists the follow requests it has not accepted yet. Only the caller's own relations are readable; reading somebody else's followers is not offered by this API.
Inputs: limit, cursor, status.
jj_list_followingList the accounts I followA
Lists the accounts the calling account follows, newest first. status="requested" lists the requests it has sent to private accounts and that are still pending. Following and un-following are done in the Jam Jam application, never by API.
Inputs: limit, cursor, status.
jj_list_formatsList conversion formatsA
Lists the input and output formats actually served by the Jam Jam API right now (GET /formats), with their limits (maxBytes, maxPages, maxDurationS) and whether they require an account or Premium. Call this FIRST, before jj_convert_file or jj_convert_text, to know which output ids are valid for a given input. Pass "input" to get the exact list of possible outputs for that one input format. Needs no API key.
Inputs: input, locale.
jj_list_mastering_presetsList Mastering presetsA
Lists the Mastering presets saved on the account, newest first (GET /mastering/presets), with their full settings, plus the ids of the read-only built-in presets (builtin:balanced, ...) which are valid as the preset of jj_master_audio. No pagination: an account keeps 50 presets at most. Open to any account, free or Premium. Counts one unit of the daily read quota.
Inputs: no named parameters.
jj_list_playlistsList my notebook playlistsA
Lists the playlists of the calling account's notebook. Playlists are FLAT and allow multi-membership: songIds is the ORDERED list of song ids, and one song can appear in several playlists. Same cursor pagination and same updatedSince incremental filter as jj_list_songs. Consumes one unit of the daily read quota.
Inputs: limit, cursor, updatedSince.
jj_list_profile_playlistsList playlists published by an accountB
Lists the playlists an account has published on its profile. Same visibility rules as jj_list_profile_songs. songCount already counts only what the caller is allowed to see: a published playlist hides the songs its author did not publish.
Inputs: handle (required), limit, cursor.
jj_list_profile_songsList songs published by an accountA
Lists the songs an account has chosen to publish on its profile, newest first, with cursor pagination. hasAudio and audioPlayable are only ever true between accounts that follow each other MUTUALLY: without that link the very existence of a backing track is withheld, and no endpoint serves audio at all. A private account you do not follow refuses the call; an unknown handle returns not-found. Consumes one unit of the daily read quota.
Inputs: handle (required), limit, cursor.
jj_list_songsList my notebook songsA
Lists the songs in the calling account's PRIVATE Jam Jam notebook, page by page, oldest update first. fields="summary" (default) gives id, title, artist, key, capo, bpm, playlistIds and updatedAt; fields="full" adds the complete pivot payload (chords, lyrics, sections) and lowers the page cap to 25. Use the returned nextCursor to get the next page, and stop when it is null. Consumes one unit of the daily READ quota (2000/day free, 20000 Premium), never a conversion.
Inputs: limit, cursor, fields, updatedSince.
jj_master_audioMaster an audio file with a presetA
Uploads a local audio file (path, or base64 content) and renders it with a Mastering preset on the server (POST /mastering/jobs): the same engine as the Jam Jam web tool. Pass EXACTLY ONE of preset (a preset id from jj_list_mastering_presets, or builtin:) and settings (inline settings, see jj_create_mastering_preset). The result is a 48 kHz WAV (format wav-pcm16 by default, wav-pcm24, or wav-f32). Asynchronous: by default this returns at once with the job, then follow it with jj_mastering_get_job; pass maxWaitMs to wait, and a render that finishes in time is downloaded in the same call (file). Open to any account (3 renders per ISO week for a free account, 429 quota-exhausted beyond; unlimited for Premium) and needs the mastering:write scope. Limits: a file of at most 200 MB and 10 minutes, one or two channels; one render runs and three wait per account. The render consumes the Mastering render counter (shared with the Jam Jam app), counted at submission; a failed or cancelled render is refunded. Results are kept 24 hours. Only call it when the user asked to master that file.
Inputs: path, format, preset, filename, +3 more.
jj_mastering_cancel_jobCancel a Mastering renderA
Cancels one of your own renders and deletes its files (DELETE /mastering/jobs/{id}). The render quota already consumed is refunded when the render was not finished. Needs the mastering:write scope. Only call it when the user asked to stop that render. An unknown id, or a render of another account, answers 404.
Inputs: id (required).
jj_mastering_capabilitiesMastering: limits, setting ranges, targets and render quotaA
Reports the live contract of the Mastering engine (GET /mastering/capabilities): for each of the eight modules the unit, range, step, neutral and initial value, the loudness targets, the built-in presets (builtin:balanced, ... with their full settings, a good starting point for a new preset), the limits (200 MB, 10 minutes, 50 presets of 60 characters), the validation tolerance, whether THIS account may render through the API (renderAllowed: any account with mastering:write) and the render quota balance. Call it before jj_create_mastering_preset or jj_master_audio with inline settings. Needs no scope and costs nothing.
Inputs: no named parameters.
jj_mastering_get_jobGet a Mastering render statusA
Fetches one of your renders by id (GET /mastering/jobs/{id}): status (queued, decoding, analyzing, rendering, done, failed, cancelled, expired), progress, queue position, a copy of the settings used and, once done, the loudness measures before and after (report) and the sha256 of the result. With download=true on a finished render, the mastered WAV (GET /mastering/jobs/{id}/result, free to repeat) is downloaded to a local file and its path returned. A render unknown or belonging to another account answers the same 404; results are kept 24 hours (410 afterwards). Costs no quota (read rate limit): poll no faster than every few seconds.
Inputs: id (required), download.
jj_queue_cancel_jobCancel an audio analysis jobA
Cancels one job of the caller's own audio queue (DELETE /queue/{id}). The unit is refunded ONLY if the analysis had not completed yet; during alignment, the analysis already delivered is kept, without refund. 409 when the job can no longer be cancelled. Needs the audio:write scope. Only call it when the user asked to stop that job.
Inputs: id (required).
jj_queue_get_jobGet an audio analysis jobA
Fetches one job of the caller's audio queue by id (GET /queue/{id}): status (queued, active, done, failed, cancelled), stage (analyze, align), per-step status, progress and rank. An unknown id and a job of another account answer the same 404. Needs the queue:read scope. Costs no quota.
Inputs: id (required).
jj_queue_listList the audio analysis queueA
Lists the caller's audio analysis jobs in three groups (GET /queue): "active" (running), "queued" (waiting, with "rank" = real service order) and "done" (finished, failed or cancelled in the last 7 days). Needs an account and the queue:read scope. Costs no quota.
Inputs: no named parameters.
jj_stems_cancel_jobCancel a stem separationA
Cancels one of your own separations that is still uploading, queued or running (DELETE /stem-tool/jobs/{id}). Needs the stems:write scope. Only call it when the user asked to stop that separation. Costs no quota. An unknown id, or a job of another account, answers 404.
Inputs: id (required).
jj_stems_capabilitiesStem separation: availability, limits and quotaA
Reports whether stem separation is available right now (GET /stem-tool/capabilities), the models this account may use ("fast" and "quality"), the file formats ("mp3", "flac"), the maximum duration and upload size, how long results are kept, and the remaining quota with its reset time (quota.fast and quota.quality, resetsAt in epoch milliseconds, UTC). Call it before jj_stems_separate. Costs no quota (only the read rate limit, 240 per minute). An API key must belong to a Premium account.
Inputs: no named parameters.
jj_stems_get_fileGet a separated stemA
Fetches one result file of a finished separation (GET /stem-tool/jobs/{id}/files/{name}): a stem (vocals, instrumental, drums, bass, other, depending on the number of stems chosen; .mp3, or .flac when the job has format "flac") or all of them as stems.zip. By default the file is downloaded and its local path is returned; with download=false only the signed link is returned, valid for about 60 seconds. Files are kept 24 hours after the separation (410 afterwards); the job must be in state "done" (409 otherwise). Costs no quota (read rate limit).
Inputs: id (required), name (required), download.
jj_stems_get_jobGet a stem separation statusA
Fetches the state of one of your separations by id (GET /stem-tool/jobs/{id}): state (uploading, queued, running, saving, done, failed, cancelled, expired), queue position, processed seconds against duration, time estimates, and, once done, the names of the stems available. A job unknown or belonging to another account answers the same 404. Costs no quota (read rate limit, 240 per minute): poll no faster than every few seconds.
Inputs: id (required).
jj_stems_list_jobsList recent stem separationsA
Lists your recent separations, newest first, 30 per page (GET /stem-tool/jobs). Use it to find a job id again, or to see whether one is still running before starting another (only one can run at a time). Pass the returned "next" as "before" for the next page. Costs no quota (read rate limit).
Inputs: before.
jj_stems_separateSeparate a song into stemsA
Uploads a local audio file (path, or base64 content) and starts its separation into vocals + instrumental (stems=2) or vocals + drums + bass + other (stems=4) (POST /stem-tool/jobs). Asynchronous and slow (minutes, up to hours for a long file): by default this returns at once with the job, then follow it with jj_stems_get_job and fetch the files with jj_stems_get_file; pass maxWaitMs to wait for a short file instead. Needs the stems:write scope and an API key from a Premium account (403 otherwise). Limits on Premium: a file of at most 1 h 30 and under 2 GB (5 minutes and 100 MB without Premium). Quotas, in UTC days and calendar months, with ONE counter per account shared by both models and by the website: 30 jobs/day and 500/month on Premium (81000 s of audio/day, 540000 s/month). Only one separation can run at a time per account. A 429 states when the counter resets; a 413 means the file is too large or too long. Stems come as MP3 320 kb/s by default, or as FLAC 24-bit with format="flac" (lossless, about 4 times larger). Check jj_stems_capabilities first.
Inputs: path, model, stems, format, +3 more.
jj_update_playlistRename, re-cover or reorder a playlistA
Changes one or more fields of a playlist: name, coverEmoji (null removes it), and songIds, which REPLACES the whole content and its order. Only the fields you pass move. To reorder, read the playlist with jj_get_playlist first and send the full list back in the new order.
Inputs: playlistId (required), name, ifMatch, songIds, +1 more.
jj_update_songChange a notebook songA
Changes some fields of one song of the calling account's notebook. Only the fields you pass move; a field set to null erases its value. key is the DISPLAYED key ("G", "Am"). playlistIds is the complete target membership, so it is idempotent. publish: true puts the song on the account's public profile and requires publishDeclaration the first time, plus a public username; publish: false removes it and has no conditions. Publishing is a deliberate act by the account holder: never publish unless they asked. To rewrite lyrics, chords or structure, use jj_create_song with the song's id instead.
Inputs: songId (required), bpm, key, capo, +6 more.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 42 tools
The domains (conversion, notebook, social, stems, audio analysis, AI detection, mastering) are mostly distinct, with domain prefixes helping distinguish similar operations. However, there are several parallel 'get job' tools (jj_get_job, jj_queue_get_job, jj_stems_get_job, jj_ai_music_get_job, jj_mastering_get_job) and parallel capability/availability tools that could be confused at a glance, especially because the conversion tool uses the unqualified jj_get_job.
Most tools follow a jj_verb_noun pattern, but the convention is mixed: some place the domain first (jj_mastering_get_job, jj_stems_get_job), others place the verb first (jj_list_mastering_presets), and the audio analysis domain splits between jj_audio_analyze and jj_queue_* tools. The same concept is also named inconsistently across domains (capabilities vs availability), and jj_get_job lacks a domain prefix unlike its siblings.
42 tools is well beyond the 25-tool threshold and imposes a large selection burden even though the server spans many sub-domains. Each domain is internally coherent and most tools earn their place, but the overall surface is too large for an agent to navigate comfortably without scoping or grouping.
The notebook (songs and playlists) has full CRUD, and stems, AI music detection, and mastering each have discovery, submission, polling, download, and cancellation paths. Minor gaps remain: mastering presets can only be created and listed, not updated or deleted, and there is no way to list past mastering render jobs, while social tools correctly omit follow/unfollow as app-only.
Maintenance
Related MCP Connectors
Write lyrics in 100+ styles, score them, generate full songs with 4 engines, split stems. OAuth.
Create songs from prompts or lyrics, check credits, and access your private library with OAuth.
Audio AI tools: transcription with speakers, stems, noise removal, MIDI, speech, voices and music.
AI music studio: song generation with vocals, covers, stems, voice conversion, mastering, editing.
Related MCP Servers
- AlicenseBqualityDmaintenanceProvides AI-powered audio generation and processing through the MusicGPT API, enabling music creation, voice conversion, audio manipulation, stem extraction, and audio analysis capabilities.2431 npm2MIT
- FlicenseNot gradedqualityDmaintenanceEnables AI music generation and management through the Suno API, supporting text prompts, custom lyrics, track status monitoring, and credit management.16-
- FlicenseNot gradedqualityCmaintenanceEnables musicians and their agents to manage AI licensing, register tracks by ISRC, issue/revoke licences, access compliance audit trails, and run their artist platform (merch, events, subscriptions, crowdfunding) through natural language with 46 tools.13 npm1-
- AlicenseNot gradedqualityCmaintenanceEnables users to turn a description of who a song is for into original lyrics, two complete song versions, and cover art through an AI assistant or compatible MCP/OpenAPI client. It also supports revising song plans, replacing sections, stem separation, and library/credit management.54 npmMIT