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.
| Parameter | Type | Required | Description |
|---|---|---|---|
offset | number (≥ 0) | no | Groups to skip, for paging (default: 0) |
limit | number (1–100) | no | Max 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).
| Parameter | Type | Required | Description |
|---|---|---|---|
trackId | string | yes | The track ID. Sent to the API as id. |
detail | compact | full | no | Response 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.
| Parameter | Type | Required | Description |
|---|---|---|---|
cursor | string | no | Pagination cursor from previous response |
limit | number (1–200) | no | Number of results (default: 50, max: 200) |
tags | string[] | no | Filter by tag names (comma-separated in API) |
tagMode | any | all | no | Match any or all tags (default: any) |
sort | string | no | Sort field: created_at, -created_at, name, -name |
query | string | no | Search query for track name or artist. Sent to the API as q. |
detail | compact | full | no | Response 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.
| Parameter | Type | Required | Description |
|---|---|---|---|
bpm | number | no | BPM (beats per minute) |
key | string | no | Musical key (e.g. "C#m", "G") |
title | string | no | Track title |
album | string | no | Album name |
year | string | no | Release year |
isrc | string | no | ISRC code |
composer | string | no | Composer name |
artist | string | no | Artist name |
cover | string | no | Cover art image URL |
recordLabel | string | no | Record label |
trackId | string | yes | The 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.
| Parameter | Type | Required | Description |
|---|---|---|---|
trackId | string | yes | The track ID to set artwork for |
url | string | no | Public URL of the image to use as cover art |
base64 | string | no | Base64-encoded image data (with or without data:image/... prefix) |
filename | string | no | Optional 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.
| Parameter | Type | Required | Description |
|---|---|---|---|
items | object[] (1–25) | yes | Up to 25 tracks to upload from URLs |
items[].fileUrl | string (uri) | yes | Public URL of the audio file (must include protocol) |
items[].visible | boolean | no | Whether the track is visible (default: false) |
items[].audioProfile | object | no | Optional audio profile fields (bpm, key, etc.) |
items[].details | object | no | Optional metadata applied after upload |
items[].details.bpm | number | no | BPM (beats per minute) |
items[].details.key | string | no | Musical key (e.g. "C#m", "G") |
items[].details.title | string | no | Track title |
items[].details.album | string | no | Album name |
items[].details.year | string | no | Release year |
items[].details.isrc | string | no | ISRC code |
items[].details.composer | string | no | Composer name |
items[].details.artist | string | no | Artist name |
items[].details.cover | string | no | Cover art image URL |
items[].details.recordLabel | string | no | Record 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.
| Parameter | Type | Required | Description |
|---|---|---|---|
versionId | string | yes | Version ID to activate |
trackId | string | yes | Track 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.
| Parameter | Type | Required | Description |
|---|---|---|---|
versionId | string | yes | Version ID to delete |
trackId | string | yes | Track 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.
| Parameter | Type | Required | Description |
|---|---|---|---|
trackId | string | yes | Track ID |
detail | compact | full | no | Response 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.
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | no | New display name |
label | string | no | New version label, e.g. "v3" |
visible | boolean | no | Show (true) or hide (false) the version in the app |
versionId | string | yes | Version ID |
trackId | string | yes | Track 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.
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | no | Display name for the version (default: the filename) |
label | string | no | Version label shown in the app, e.g. "v2" or "radio edit" (default: v<n>) |
activate | boolean | no | Make this the active version (default: true) |
fileUrl | string (uri) | yes | Public URL of the audio file (must include protocol) |
trackId | string | yes | Track ID to add the version to |
Calls POST /api/v1/tracks/{trackId}/versions/url. Scope update:tracks.
Search
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.
| Parameter | Type | Required | Description |
|---|---|---|---|
query | string (1–2000) | yes | Plain-language description of the music you want |
limit | number (1–50) | no | Number of tracks to return (default: 20, max: 50) |
bpmMin | number (1–300) | no | Hard filter: minimum BPM |
bpmMax | number (1–300) | no | Hard filter: maximum BPM |
durationMinSec | number (≥ 0) | no | Hard filter: minimum track duration in seconds |
durationMaxSec | number (≥ 0) | no | Hard filter: maximum track duration in seconds |
hasVocals | boolean | no | Hard filter: true for vocal tracks only, false for instrumentals only |
key | string | no | Hard filter: musical key, e.g. "F#m", "C" |
language | string | no | Hard filter: sung language, e.g. "english" |
seedTrackIds | string[] (≤ 50) | no | Track IDs to steer toward — "more like these", combined with the query |
excludeTrackIds | string[] (≤ 200) | no | Track IDs to keep out of the results, e.g. everything already shortlisted |
detail | compact | full | no | Response 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.
| Parameter | Type | Required | Description |
|---|---|---|---|
trackId | string | yes | The 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.
| Parameter | Type | Required | Description |
|---|---|---|---|
trackIds | string[] (≥ 1) | yes | Array 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.
| Parameter | Type | Required | Description |
|---|---|---|---|
trackId | string | yes | The 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).
| Parameter | Type | Required | Description |
|---|---|---|---|
detail | compact | full | no | Response 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.
| Parameter | Type | Required | Description |
|---|---|---|---|
trackId | string | yes | The 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.
| Parameter | Type | Required | Description |
|---|---|---|---|
genres | string[] | no | Genre names/codes to set |
moods | string[] | no | Mood names/codes to set |
types | string[] | no | Audio type names/codes to set |
vocals | string[] | no | Vocal type names/codes to set |
lyricThemes | string[] | no | Lyric theme names/codes to set |
instruments | string[] | no | Instrument names/codes to set |
eras | string[] | no | Era names/codes to set (e.g. decade/period feel) |
characters | string[] | no | Character names/codes to set (sonic character) |
movements | string[] | no | Movement names/codes to set (energy/movement feel) |
additionalTags | string[] | no | Freeform tag strings |
trackId | string | yes | The 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.
| Parameter | Type | Required | Description |
|---|---|---|---|
trackId | string | yes | The track ID to wait for |
trigger | boolean | no | If true, trigger auto-tagging before waiting (default: false) |
timeoutSeconds | number (5–300) | no | Maximum time to wait in seconds (default: 90) |
pollIntervalSeconds | number (2–30) | no | How 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
| Parameter | Type | Required | Description |
|---|---|---|---|
trackIds | string[] (≥ 1) | yes | Track IDs to add |
playlistId | string | yes | The 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
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string (≤ 120) | yes | Playlist name |
description | string (≤ 2000) | no | Playlist description |
trackIds | string[] (≥ 1) | yes | Track IDs to include in the playlist |
dedupe | boolean | no | Remove 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.
| Parameter | Type | Required | Description |
|---|---|---|---|
playlistId | string | yes | The playlist ID. Sent to the API as id. |
detail | compact | full | no | Response 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.
| Parameter | Type | Required | Description |
|---|---|---|---|
cursor | string | no | Pagination cursor |
limit | number (1–200) | no | Number of results (default: 50) |
detail | compact | full | no | Response 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
| Parameter | Type | Required | Description |
|---|---|---|---|
trackId | string | yes | The track ID to remove |
playlistId | string | yes | The 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
| Parameter | Type | Required | Description |
|---|---|---|---|
trackIds | string[] (≥ 1) | yes | Track IDs in the desired order |
playlistId | string | yes | The 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
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string (≤ 120) | no | New playlist name |
description | string (≤ 2000) | no | New playlist description |
playlistId | string | yes | The 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.
| Parameter | Type | Required | Description |
|---|---|---|---|
fullName | string | yes | Full legal name of the composer |
artistName | string | no | Stage / artist name |
email | string (email) | yes | Composer email address |
publisher | string | no | Publisher name |
pro | string | no | Performing rights organisation (e.g. ASCAP, BMI) |
ipi | string | no | IPI / CAE number |
Calls POST /api/v1/composers. Scope create:composer.
delete_composer
Delete a composer / shareholder by ID. This is permanent.
| Parameter | Type | Required | Description |
|---|---|---|---|
composerId | string | yes | The 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.
| Parameter | Type | Required | Description |
|---|---|---|---|
composerId | string | yes | The composer ID. Sent to the API as id. |
detail | compact | full | no | Response 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.
| Parameter | Type | Required | Description |
|---|---|---|---|
cursor | string | no | Pagination cursor (a composer ID from a previous page) |
detail | compact | full | no | Response 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.
| Parameter | Type | Required | Description |
|---|---|---|---|
fullName | string | no | Full legal name |
artistName | string | no | Stage / artist name |
email | string (email) | no | Email address |
publisher | string | no | Publisher name |
pro | string | no | Performing rights organisation |
ipi | string | no | IPI / CAE number |
composerId | string | yes | The 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.
| Parameter | Type | Required | Description |
|---|---|---|---|
entity | track | playlist | yes | Entity type the IDs refer to |
ids | string[] (1–50) | yes | Track or playlist IDs (max 50) |
since | string | no | Only count activity at/after this ISO date (e.g. 2026-01-01) |
until | string | no | Only 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.
| Parameter | Type | Required | Description |
|---|---|---|---|
metric | plays | views | downloads | saved | shares | comments | yes | Metric to rank by |
since | string | no | Only count activity at/after this ISO date |
until | string | no | Only count activity at/before this ISO date |
limit | number (1–50) | no | Number 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.
| Parameter | Type | Required | Description |
|---|---|---|---|
briefId | string | yes | The 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.
| Parameter | Type | Required | Description |
|---|---|---|---|
trackId | string | yes | The 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.