Postal Developers
MCP server

Tool reference

Every tool the Postal MCP server exposes, with parameters, the REST endpoint behind it and the API key scope it needs.

The server publishes 39 tools. This page is generated from manifest version 2 of REST API v1 (catalog of 2026-10-06, build ca14061), the same catalog the server builds its tools from. The always-current, machine-readable catalog with full JSON schemas is served without auth at https://mcp.postal.music/tools.

Every tool needs an API key carrying the listed scope. A connected key sees only the tools its scopes allow; a call that slips through anyway fails with an error ending in "the API key is missing a required scope for this action".

Tracks

find_duplicate_tracks

Find exact-duplicate tracks in your library, grouped by content hash (cid). Duplicates means the same audio file bytes were uploaded more than once — renamed copies are still caught, re-encoded files are not. Tracks without a content hash (analysis not yet run) cannot be checked and are reported as missingCid; triggering auto-tag/analysis populates the hash.

ParameterTypeRequiredDescription
offsetnumber (≥ 0)noGroups to skip, for paging (default: 0)
limitnumber (1–100)noMax duplicate groups to return (default: 20, max: 100)

Calls GET /api/v1/tracks/duplicates. Scope read:tracks.

get_track

Get a single track with its audio profile and tags. Returns a compact object by default (includes autotagModelVersion, the tagger build behind the applied auto-tags); pass detail:"full" for the raw payload (shareholders, per-tag autotagged/accuracy/modelVersion).

ParameterTypeRequiredDescription
trackIdstringyesThe track ID. Sent to the API as id.
detailcompact | fullnoResponse detail: "compact" (default) returns trimmed objects for low token cost; "full" returns the raw API payload. Default "compact". Sent to the API as view.

Calls GET /api/v1/tracks/single. Scope read:tracks.

Returns compact objects by default; pass detail: "full" for the raw API payload. See Compact mode.

get_track_count

Get the total number of tracks in your library (a cheap count, no paging needed)

No parameters.

Calls GET /api/v1/tracks/count. Scope read:tracks.

list_tracks

Search and list tracks with optional filters (query, tags, date range, sorting). Returns compact track objects by default (tag names per category plus autotagModelVersion, the tagger build behind the applied auto-tags); pass detail:"full" for raw API payloads with per-tag autotagged/accuracy/modelVersion.

ParameterTypeRequiredDescription
cursorstringnoPagination cursor from previous response
limitnumber (1–200)noNumber of results (default: 50, max: 200)
tagsstring[]noFilter by tag names (comma-separated in API)
tagModeany | allnoMatch any or all tags (default: any)
sortstringnoSort field: created_at, -created_at, name, -name
querystringnoSearch query for track name or artist. Sent to the API as q.
detailcompact | fullnoResponse detail: "compact" (default) returns trimmed objects for low token cost; "full" returns the raw API payload. Default "compact". Sent to the API as view.

Calls GET /api/v1/tracks. Scope read:tracks.

Returns compact objects by default; pass detail: "full" for the raw API payload. See Compact mode.

update_track_details

Update track metadata like title, artist, album, BPM, key, etc.

ParameterTypeRequiredDescription
bpmnumbernoBPM (beats per minute)
keystringnoMusical key (e.g. "C#m", "G")
titlestringnoTrack title
albumstringnoAlbum name
yearstringnoRelease year
isrcstringnoISRC code
composerstringnoComposer name
artiststringnoArtist name
coverstringnoCover art image URL
recordLabelstringnoRecord label
trackIdstringyesThe track ID to update. Sent to the API as id.

Calls PATCH /api/v1/tracks/details. Scope update:tracks.

upload_artwork

Upload an image and set it as cover art for a track. Provide either a public image URL or base64-encoded image data.

ParameterTypeRequiredDescription
trackIdstringyesThe track ID to set artwork for
urlstringnoPublic URL of the image to use as cover art
base64stringnoBase64-encoded image data (with or without data:image/... prefix)
filenamestringnoOptional filename for the image (default: cover.jpg)

Calls POST /api/v1/tracks/cover-art. Scope update:tracks.

upload_track_by_url

Upload one or more tracks into your library from public audio URLs. Each item can carry optional metadata (title, artist, etc.) and an audio profile. Returns the created track IDs plus any failures.

ParameterTypeRequiredDescription
itemsobject[] (1–25)yesUp to 25 tracks to upload from URLs
items[].fileUrlstring (uri)yesPublic URL of the audio file (must include protocol)
items[].visiblebooleannoWhether the track is visible (default: false)
items[].audioProfileobjectnoOptional audio profile fields (bpm, key, etc.)
items[].detailsobjectnoOptional metadata applied after upload
items[].details.bpmnumbernoBPM (beats per minute)
items[].details.keystringnoMusical key (e.g. "C#m", "G")
items[].details.titlestringnoTrack title
items[].details.albumstringnoAlbum name
items[].details.yearstringnoRelease year
items[].details.isrcstringnoISRC code
items[].details.composerstringnoComposer name
items[].details.artiststringnoArtist name
items[].details.coverstringnoCover art image URL
items[].details.recordLabelstringnoRecord label

Calls POST /api/v1/tracks/upload/url. Scope create:tracks.

Track versions

A track keeps every audio file uploaded to it as a version; one is active. These tools replace a track's audio while keeping its ID, tags, playlists and share links. See Track versions for the semantics.

activate_track_version

Make an existing version the active one: the track then plays and shares that file. Use list_track_versions to find version IDs.

ParameterTypeRequiredDescription
versionIdstringyesVersion ID to activate
trackIdstringyesTrack ID

Calls POST /api/v1/tracks/{trackId}/versions/{versionId}/activate. Scope update:tracks.

delete_track_version

Permanently delete an inactive version and its audio file. The active version cannot be deleted — activate another version first.

ParameterTypeRequiredDescription
versionIdstringyesVersion ID to delete
trackIdstringyesTrack ID

Calls DELETE /api/v1/tracks/{trackId}/versions/{versionId}. Scope update:tracks.

list_track_versions

List the audio versions (upload history) of a track: label, name, whether it is the active version, size, and a one-hour download link. Compact by default; pass detail:"full" for the raw payload.

ParameterTypeRequiredDescription
trackIdstringyesTrack ID
detailcompact | fullnoResponse detail: "compact" (default) returns trimmed objects for low token cost; "full" returns the raw API payload. Default "compact". Sent to the API as view.

Calls GET /api/v1/tracks/{trackId}/versions. Scope read:tracks.

Returns compact objects by default; pass detail: "full" for the raw API payload. See Compact mode.

update_track_version

Rename or relabel a version, or hide/show it in the app. Only the fields you pass change.

ParameterTypeRequiredDescription
namestringnoNew display name
labelstringnoNew version label, e.g. "v3"
visiblebooleannoShow (true) or hide (false) the version in the app
versionIdstringyesVersion ID
trackIdstringyesTrack ID

Calls PATCH /api/v1/tracks/{trackId}/versions/{versionId}. Scope update:tracks.

upload_track_version

Add a new audio version to an existing track from a public audio URL (replace the audio while keeping the track ID, tags, playlists and share links). By default the new file becomes the active version and analysis re-runs; pass activate:false to add it to the history only.

ParameterTypeRequiredDescription
namestringnoDisplay name for the version (default: the filename)
labelstringnoVersion label shown in the app, e.g. "v2" or "radio edit" (default: v<n>)
activatebooleannoMake this the active version (default: true)
fileUrlstring (uri)yesPublic URL of the audio file (must include protocol)
trackIdstringyesTrack ID to add the version to

Calls POST /api/v1/tracks/{trackId}/versions/url. Scope update:tracks.

search_tracks

Find tracks in your library by describing the music in plain language — mood, genre, energy, instrumentation, reference artist, or what the music is for ("dark cinematic trap for a chase scene", "warm acoustic bed under a voiceover"). The description is parsed into musical targets and the whole library is ranked against it, so results come back scored and ordered with a short reason for each. Use list_tracks instead when you already know the exact name, tag or date filter, or need to page through everything — that is a plain database filter and is much cheaper. This tool runs an AI ranking pass over the library: it is slower and may consume account credits. Anything that must be strictly true (a BPM window, instrumental only, a key) belongs in the dedicated parameters rather than the query text — they are applied as hard filters, while the query text is matched by similarity and cannot reliably express a negation. The response echoes an interpretation block showing how the query was read; use it to correct a bad reading and search again rather than guessing.

ParameterTypeRequiredDescription
querystring (1–2000)yesPlain-language description of the music you want
limitnumber (1–50)noNumber of tracks to return (default: 20, max: 50)
bpmMinnumber (1–300)noHard filter: minimum BPM
bpmMaxnumber (1–300)noHard filter: maximum BPM
durationMinSecnumber (≥ 0)noHard filter: minimum track duration in seconds
durationMaxSecnumber (≥ 0)noHard filter: maximum track duration in seconds
hasVocalsbooleannoHard filter: true for vocal tracks only, false for instrumentals only
keystringnoHard filter: musical key, e.g. "F#m", "C"
languagestringnoHard filter: sung language, e.g. "english"
seedTrackIdsstring[] (≤ 50)noTrack IDs to steer toward — "more like these", combined with the query
excludeTrackIdsstring[] (≤ 200)noTrack IDs to keep out of the results, e.g. everything already shortlisted
detailcompact | fullnoResponse detail: "compact" (default) returns trimmed objects for low token cost; "full" returns the raw API payload. Default "compact". Sent to the API as view.

Calls POST /api/v1/tracks/search. Scope read:tracks.

Returns compact objects by default; pass detail: "full" for the raw API payload. See Compact mode.

Tagging

apply_suggested_tags

Accept and apply AI-suggested tags to a track. This takes the intelligence analysis results and OVERWRITES the track's tags with them. Review with get_suggested_tags first if unsure.

ParameterTypeRequiredDescription
trackIdstringyesThe track ID whose suggested tags should be applied

Calls POST /api/v1/tracks/apply-suggested-tags. Scope update:tracks.

batch_auto_tag

Queue AI auto-tagging for multiple tracks at once. Each track is processed asynchronously.

ParameterTypeRequiredDescription
trackIdsstring[] (≥ 1)yesArray of track IDs to auto-tag

Calls POST /api/v1/tracks/auto-tag/batch. Scope update:tracks.

get_suggested_tags

Get AI-suggested tags for a track that are pending review. Shows analysis status and intelligence data.

ParameterTypeRequiredDescription
trackIdstringyesThe track ID. Sent to the API as id.

Calls GET /api/v1/tracks/suggested-tags. Scope read:tracks.

get_tag_taxonomy

List all available tag values grouped by category: genres, moods, instruments, vocal types, lyric themes, audio types, tempos, eras, characters, and movements. Use this to discover valid tag values before tagging tracks. Returns plain name arrays by default; pass detail:"full" for raw rows (ids, codes, ordering).

ParameterTypeRequiredDescription
detailcompact | fullnoResponse detail: "compact" (default) returns trimmed objects for low token cost; "full" returns the raw API payload. Default "compact". Sent to the API as view.

Calls GET /api/v1/taxonomy. Scope read:tracks.

Returns compact objects by default; pass detail: "full" for the raw API payload. See Compact mode.

trigger_auto_tag

Trigger AI auto-tagging for a single track. This starts an asynchronous analysis — use wait_for_auto_tag to block until it finishes, or check back with get_suggested_tags after a short wait.

ParameterTypeRequiredDescription
trackIdstringyesThe track ID to auto-tag

Calls POST /api/v1/tracks/auto-tag. Scope update:tracks.

update_track_tags

Update tags on a track. Provide arrays of tag names/codes for each category. Note: this REPLACES the existing tags in each category you provide. Use get_tag_taxonomy first to see available values. Changes are also recorded as tag feedback, which trains the auto-tagging model — so only set tags you are confident about.

ParameterTypeRequiredDescription
genresstring[]noGenre names/codes to set
moodsstring[]noMood names/codes to set
typesstring[]noAudio type names/codes to set
vocalsstring[]noVocal type names/codes to set
lyricThemesstring[]noLyric theme names/codes to set
instrumentsstring[]noInstrument names/codes to set
erasstring[]noEra names/codes to set (e.g. decade/period feel)
charactersstring[]noCharacter names/codes to set (sonic character)
movementsstring[]noMovement names/codes to set (energy/movement feel)
additionalTagsstring[]noFreeform tag strings
trackIdstringyesThe track ID. Sent to the API as id.

Calls PATCH /api/v1/tracks/tags. Scope update:tracks.

wait_for_auto_tag

Wait for a track's AI auto-tagging to finish, then return the suggested tags. Optionally triggers auto-tagging first. Polls until the analysis is completed or failed, or until the timeout is reached.

ParameterTypeRequiredDescription
trackIdstringyesThe track ID to wait for
triggerbooleannoIf true, trigger auto-tagging before waiting (default: false)
timeoutSecondsnumber (5–300)noMaximum time to wait in seconds (default: 90)
pollIntervalSecondsnumber (2–30)noHow often to poll in seconds (default: 3)

Calls POST /api/v1/tracks/auto-tag/wait. Scope read:tracks.

Playlists

add_tracks_to_playlist

Add one or more tracks to an existing playlist

ParameterTypeRequiredDescription
trackIdsstring[] (≥ 1)yesTrack IDs to add
playlistIdstringyesThe playlist ID. Sent to the API as id.

Calls POST /api/v1/playlists/{id}/tracks. Scope create:playlists.

create_playlist

Create a new playlist, optionally adding tracks to it

ParameterTypeRequiredDescription
namestring (≤ 120)yesPlaylist name
descriptionstring (≤ 2000)noPlaylist description
trackIdsstring[] (≥ 1)yesTrack IDs to include in the playlist
dedupebooleannoRemove duplicate track IDs (default: false)

Calls POST /api/v1/playlists. Scope create:playlists.

get_playlist

Get a single playlist with its tracks. Compact by default (track micro-summaries); pass detail:"full" for the raw payload including download links and full audio profiles.

ParameterTypeRequiredDescription
playlistIdstringyesThe playlist ID. Sent to the API as id.
detailcompact | fullnoResponse detail: "compact" (default) returns trimmed objects for low token cost; "full" returns the raw API payload. Default "compact". Sent to the API as view.

Calls GET /api/v1/playlists/single/{id}. Scope read:playlists.

Returns compact objects by default; pass detail: "full" for the raw API payload. See Compact mode.

list_playlists

List playlists for the authenticated user with track counts. Compact by default; pass detail:"full" for raw API payloads.

ParameterTypeRequiredDescription
cursorstringnoPagination cursor
limitnumber (1–200)noNumber of results (default: 50)
detailcompact | fullnoResponse detail: "compact" (default) returns trimmed objects for low token cost; "full" returns the raw API payload. Default "compact". Sent to the API as view.

Calls GET /api/v1/playlists. Scope read:playlists.

Returns compact objects by default; pass detail: "full" for the raw API payload. See Compact mode.

remove_track_from_playlist

Remove a single track from a playlist

ParameterTypeRequiredDescription
trackIdstringyesThe track ID to remove
playlistIdstringyesThe playlist ID. Sent to the API as id.

Calls DELETE /api/v1/playlists/{id}/tracks/{trackId}. Scope update:playlists.

reorder_playlist

Reorder tracks in a playlist by providing the track IDs in the desired order

ParameterTypeRequiredDescription
trackIdsstring[] (≥ 1)yesTrack IDs in the desired order
playlistIdstringyesThe playlist ID. Sent to the API as id.

Calls PATCH /api/v1/playlists/{id}/order. Scope update:playlists.

update_playlist

Update a playlist name or description

ParameterTypeRequiredDescription
namestring (≤ 120)noNew playlist name
descriptionstring (≤ 2000)noNew playlist description
playlistIdstringyesThe playlist ID. Sent to the API as id.

Calls PATCH /api/v1/playlists/{id}. Scope update:playlists.

Composers

Composers are the shareholders on a track: writers, producers and publishers with their PRO and IPI details.

create_composer

Create a new composer / shareholder. fullName and email are required.

ParameterTypeRequiredDescription
fullNamestringyesFull legal name of the composer
artistNamestringnoStage / artist name
emailstring (email)yesComposer email address
publisherstringnoPublisher name
prostringnoPerforming rights organisation (e.g. ASCAP, BMI)
ipistringnoIPI / CAE number

Calls POST /api/v1/composers. Scope create:composer.

delete_composer

Delete a composer / shareholder by ID. This is permanent.

ParameterTypeRequiredDescription
composerIdstringyesThe composer ID to delete. Sent to the API as id.

Calls DELETE /api/v1/composers. Scope delete:composer.

get_composer

Get a single composer / shareholder by ID, including linked tracks. Compact by default; pass detail:"full" for the raw payload.

ParameterTypeRequiredDescription
composerIdstringyesThe composer ID. Sent to the API as id.
detailcompact | fullnoResponse detail: "compact" (default) returns trimmed objects for low token cost; "full" returns the raw API payload. Default "compact". Sent to the API as view.

Calls GET /api/v1/composers/single. Scope read:composer.

Returns compact objects by default; pass detail: "full" for the raw API payload. See Compact mode.

get_composer_count

Get the total number of composers / shareholders for the authenticated user

No parameters.

Calls GET /api/v1/composers/count. Scope read:composers.

list_composers

List composers / shareholders for the authenticated user, including the tracks linked to each. Compact by default; pass detail:"full" for raw API payloads.

ParameterTypeRequiredDescription
cursorstringnoPagination cursor (a composer ID from a previous page)
detailcompact | fullnoResponse detail: "compact" (default) returns trimmed objects for low token cost; "full" returns the raw API payload. Default "compact". Sent to the API as view.

Calls GET /api/v1/composers. Scope read:composers.

Returns compact objects by default; pass detail: "full" for the raw API payload. See Compact mode.

update_composer

Update an existing composer / shareholder. Provide the composer ID plus any fields to change.

ParameterTypeRequiredDescription
fullNamestringnoFull legal name
artistNamestringnoStage / artist name
emailstring (email)noEmail address
publisherstringnoPublisher name
prostringnoPerforming rights organisation
ipistringnoIPI / CAE number
composerIdstringyesThe composer ID to update. Sent to the API as id.

Calls PATCH /api/v1/composers. Scope update:composer.

Analytics

get_dashboard

Get this week's activity summary: tracks uploaded, views and downloads received, recent activity, library totals, and your dominant genre/mood.

No parameters.

Calls GET /api/v1/analytics/dashboard. Always sends view=compact. Scope read:analytics.

get_entity_stats

Get engagement stats (plays, views, downloads, saves, shares, comments) for specific tracks or playlists, aggregated from the activity log. Optionally limit to a date range.

ParameterTypeRequiredDescription
entitytrack | playlistyesEntity type the IDs refer to
idsstring[] (1–50)yesTrack or playlist IDs (max 50)
sincestringnoOnly count activity at/after this ISO date (e.g. 2026-01-01)
untilstringnoOnly count activity at/before this ISO date

Calls GET /api/v1/analytics/stats. Scope read:analytics.

get_top_tracks

Rank your tracks by a single engagement metric (plays, views, downloads, saves, shares, or comments). Optionally limit to a date range.

ParameterTypeRequiredDescription
metricplays | views | downloads | saved | shares | commentsyesMetric to rank by
sincestringnoOnly count activity at/after this ISO date
untilstringnoOnly count activity at/before this ISO date
limitnumber (1–50)noNumber of tracks to return (default: 10, max: 50)

Calls GET /api/v1/analytics/top. Always sends entity=track. Scope read:analytics.

Briefs

Briefs are calls for submissions: an opportunity you own that other people send tracks to.

get_brief_submissions

List all submissions a brief you own has received, including the submitted tracks (or external links) and who was invited.

ParameterTypeRequiredDescription
briefIdstringyesThe brief ID. Sent to the API as id.

Calls GET /api/v1/briefs/{id}/submissions. Scope read:briefs.

get_track_submissions

Trace where a track has been submitted: lists every brief (opportunity) the track was submitted to, with brief status, deadline, and whether it went via an email invite.

ParameterTypeRequiredDescription
trackIdstringyesThe track ID to trace. Sent to the API as id.

Calls GET /api/v1/tracks/submissions. Scope read:tracks.

list_briefs

List briefs (calls for submissions) you own, with submission and invite counts.

No parameters.

Calls GET /api/v1/briefs. Scope read:briefs.

On this page