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 registers 39 tools. The always-current, machine-readable catalog with
full JSON schemas is served without auth at
https://mcp.postal.music/tools.
Tools marked compact accept a detail parameter: "compact" (default)
returns trimmed objects for low token cost, "full" returns the raw API
payload. See Compact mode.
Every tool needs an API key carrying the listed scope. A missing scope surfaces as an error ending in "the API key is missing a required scope for this action".
Tracks
list_tracks compact
Search and list tracks with optional filters (query, tags, date range, sorting). Use this when you already know the name, tag or date you want.
| Parameter | Type | Notes |
|---|---|---|
query | string | Name match |
tags | string[] | Tag names |
tagMode | any | all | How multiple tags combine |
limit | 1–200 | |
cursor | string | From the previous page |
sort | created_at, -created_at, name, -name | |
detail | compact | full |
Calls GET /api/v1/tracks. Scope read:tracks.
get_track_count
Total number of tracks in the library. Cheap, no paging. Calls
GET /api/v1/tracks/count. Scope read:tracks.
get_track compact
One track with its audio profile and tags. full adds shareholders and per-tag
metadata.
| Parameter | Type | Notes |
|---|---|---|
trackId | string | required |
detail | compact | full |
Calls GET /api/v1/tracks/single. Scope read:tracks.
update_track_details
Update title, artist, album, BPM, key, year, ISRC, composer, record label or cover.
| Parameter | Type |
|---|---|
trackId | string, required |
title, artist, album, key, year, isrc, composer, recordLabel, cover | string |
bpm | number |
Calls PATCH /api/v1/tracks/details. Scope update:tracks.
upload_track_by_url
Upload up to 25 tracks from public audio URLs in one call. Each item may carry metadata and an audio profile. Returns created track IDs and any per-item failures.
| Parameter | Type | Notes |
|---|---|---|
items | array (1–25) | required |
items[].fileUrl | URL | required |
items[].visible | boolean | |
items[].details | object | title, artist, album, bpm, key, year, isrc, composer, recordLabel |
items[].audioProfile | object |
Calls POST /api/v1/tracks/upload/url. Scope create:tracks.
find_duplicate_tracks
Exact-duplicate tracks grouped by content hash. Renamed copies are caught,
re-encoded files are not. Tracks that have not been analysed yet have no hash
and are reported under missingCid.
| Parameter | Type | Default |
|---|---|---|
limit | 1–100 | 20 |
offset | ≥ 0 | 0 |
Calls GET /api/v1/tracks/duplicates. Scope read: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.
list_track_versions compact
Upload history of a track with the active version flagged and a one-hour download link per version.
| Parameter | Type | Notes |
|---|---|---|
trackId | string | required |
detail | compact / full |
Calls GET /api/v1/tracks/{trackId}/versions. Scope read:tracks.
upload_track_version
Add a new audio version from a public URL. Active by default, which re-runs
analysis on the new audio; activate: false only adds it to the history.
| Parameter | Type | Notes |
|---|---|---|
trackId | string | required |
fileUrl | URL | required |
name | string | defaults to the filename |
label | string | defaults to v<n> |
activate | boolean | default true |
Calls POST /api/v1/tracks/{trackId}/versions/url. Scope update:tracks.
activate_track_version
Make an existing version the file the track plays and shares.
| Parameter | Type |
|---|---|
trackId | string |
versionId | string |
Calls POST /api/v1/tracks/{trackId}/versions/{versionId}/activate. Scope update:tracks.
update_track_version
Rename, relabel or hide a version. Only the fields passed change.
| Parameter | Type |
|---|---|
trackId, versionId | string |
name, label | string |
visible | boolean |
Calls PATCH /api/v1/tracks/{trackId}/versions/{versionId}. Scope update:tracks.
delete_track_version
Permanently delete an inactive version and its file. Deleting the active version fails; activate another one first.
| Parameter | Type |
|---|---|
trackId, versionId | string |
Calls DELETE /api/v1/tracks/{trackId}/versions/{versionId}. Scope update:tracks.
Search
search_tracks compact · uses credits
Find tracks by describing the music in plain language: mood, genre, energy,
instrumentation, a reference artist, or what the music is for. The description
is parsed into musical targets and the whole library is ranked against it. The
response includes an interpretation block showing how the query was read.
Anything that must be strictly true belongs in the dedicated parameters, not the prose.
| Parameter | Type | Notes |
|---|---|---|
query | string (1–2000) | required |
limit | 1–50 | default 20 |
bpmMin, bpmMax | 1–300 | hard filter |
durationMinSec, durationMaxSec | number | hard filter |
hasVocals | boolean | hard filter |
key | string | hard filter |
language | string | hard filter |
seedTrackIds | string[] (≤ 50) | "more like these" |
excludeTrackIds | string[] (≤ 200) | |
detail | compact | full |
Calls POST /api/v1/tracks/search. Scope read:tracks. This tool runs an AI
ranking pass and consumes one account credit per call by default. Use
list_tracks when you already know the exact name, tag or date.
Tagging
get_tag_taxonomy compact
All valid tag values grouped by category: genres, moods, instruments, vocal
types, lyric themes, audio types, tempos, eras, characters and movements. Call
this before writing tags. full returns raw rows with ids and ordering.
Calls GET /api/v1/taxonomy. Scope read:tracks.
update_track_tags
Replace the tags in each category you provide. Categories you omit are left alone. Every change is recorded as tag feedback that trains the auto-tagging model, so only set tags you are confident about.
| Parameter | Type |
|---|---|
trackId | string, required |
genres, moods, types, vocals, instruments, lyricThemes, eras, characters, movements, additionalTags | string[] |
Calls PATCH /api/v1/tracks/tags. Scope update:tracks.
trigger_auto_tag
Start AI tagging for one track. Asynchronous: follow up with
wait_for_auto_tag or get_suggested_tags.
Calls POST /api/v1/tracks/auto-tag. Scope update:tracks.
batch_auto_tag
Queue AI tagging for many tracks. Takes trackIds (string[], at least one).
Calls POST /api/v1/tracks/auto-tag/batch. Scope update:tracks.
get_suggested_tags
AI-suggested tags pending review, plus analysis status and intelligence data.
Takes trackId.
Calls GET /api/v1/tracks/suggested-tags. Scope read:tracks.
wait_for_auto_tag
Block until a track's analysis is completed or failed, then return the
suggested tags. Optionally triggers the analysis first.
| Parameter | Type | Default |
|---|---|---|
trackId | string | required |
trigger | boolean | false |
timeoutSeconds | 5–300 | 90 |
pollIntervalSeconds | 2–30 | 3 |
Scope read:tracks, plus update:tracks when trigger is true.
apply_suggested_tags
Accept the AI suggestions and overwrite the track's tags with them. Review
with get_suggested_tags first if unsure. Takes trackId.
Calls POST /api/v1/tracks/apply-suggested-tags. Scope update:tracks.
upload_artwork
Set cover art for a track from a public image URL or base64 data.
| Parameter | Type | Notes |
|---|---|---|
trackId | string | required |
url | URL | one of url / base64 |
base64 | string | |
filename | string | default cover.jpg |
Calls POST /api/v1/tracks/cover-art. Scope update:tracks.
Playlists
list_playlists compact
Playlists with track counts. Parameters limit (1–200), cursor, detail.
Calls GET /api/v1/playlists. Scope read:playlists.
get_playlist compact
One playlist with its tracks. Compact returns track micro-summaries and the
public share link; full adds download links and full audio profiles.
Parameters playlistId (required), detail.
Calls GET /api/v1/playlists/single/{id}. Scope read:playlists.
create_playlist
| Parameter | Type | Notes |
|---|---|---|
name | string (≤ 120) | required |
description | string (≤ 2000) | |
trackIds | string[] (≥ 1) | required |
dedupe | boolean | drop repeated ids |
Calls POST /api/v1/playlists. Scope create:playlists.
update_playlist
Rename or re-describe a playlist. Parameters playlistId (required), name,
description. Calls PATCH /api/v1/playlists/{id}. Scope update:playlists.
add_tracks_to_playlist
Parameters playlistId, trackIds (both required).
Calls POST /api/v1/playlists/{id}/tracks. Scope create:playlists.
remove_track_from_playlist
Parameters playlistId, trackId (both required).
Calls DELETE /api/v1/playlists/{id}/tracks/{trackId}. Scope update:playlists.
reorder_playlist
Provide trackIds in the desired order. Parameters playlistId, trackIds.
Calls PATCH /api/v1/playlists/{id}/order. Scope update:playlists.
Composers
Composers are the shareholders on a track: writers, producers and publishers with their PRO and IPI details.
list_composers compact
Composers with the tracks linked to each. Compact caps linked tracks at 25 and
sets tracksTruncated. Parameters cursor (a composer id), detail.
Calls GET /api/v1/composers. Scope read:composers.
get_composer_count
Calls GET /api/v1/composers/count. Scope read:composers.
get_composer compact
Parameters composerId (required), detail.
Calls GET /api/v1/composers/single. Scope read:composer (singular; see
scopes).
create_composer
| Parameter | Type |
|---|---|
fullName | string, required |
email | email, required |
artistName, publisher, pro, ipi | string |
Calls POST /api/v1/composers. Scope create:composer.
update_composer
composerId plus any of the fields above.
Calls PATCH /api/v1/composers. Scope update:composer.
delete_composer
Permanent. Takes composerId.
Calls DELETE /api/v1/composers. Scope delete:composer.
Analytics
get_dashboard
This week's summary: tracks uploaded, views and downloads received, recent
activity, library totals, dominant genre and mood.
Calls GET /api/v1/analytics/dashboard. Scope read:analytics.
get_entity_stats
Plays, views, downloads, saves, shares and comments for specific tracks or playlists, optionally within a date range.
| Parameter | Type | Notes |
|---|---|---|
entity | track | playlist | required |
ids | string[] (1–50) | required |
since, until | ISO date |
Calls GET /api/v1/analytics/stats. Scope read:analytics.
get_top_tracks
Rank tracks by one metric.
| Parameter | Type | Notes |
|---|---|---|
metric | plays | views | downloads | saved | shares | comments | required |
since, until | ISO date | |
limit | 1–50 | default 10 |
Calls GET /api/v1/analytics/top. Scope read:analytics.
Briefs
Briefs are calls for submissions: an opportunity you own that other people send tracks to.
list_briefs
Briefs you own with submission and invite counts.
Calls GET /api/v1/briefs. Scope read:briefs.
get_brief_submissions
Every submission a brief received, with the submitted tracks or external links
and who was invited. Takes briefId.
Calls GET /api/v1/briefs/{id}/submissions. Scope read:briefs.
get_track_submissions
Every brief a track was submitted to, with brief status, deadline and whether
it went via an email invite. Takes trackId.
Calls GET /api/v1/tracks/submissions. Scope read:tracks.