SoundCloud MCP Server
This server lets MCP clients search and browse SoundCloud and, when authenticated, manage your library, social actions, playlists, and direct messages.
Search tracks, playlists, and users, with optional filters such as genre, BPM, duration, access, and result limits.
Inspect tracks, users, playlists, related tracks, comments, and time-limited audio stream URLs.
View your SoundCloud profile, liked tracks, playlists, and personalized track recommendations.
Like or unlike tracks, follow or unfollow users, and add comments to tracks.
Create, update, and delete playlists; add or remove tracks.
Read direct-message conversations and messages; send messages, start conversations, and mark conversations read.
Connect via SoundCloud OAuth, check login status, and sign out/revoke stored access.
Provides tools for searching and discovering tracks, playlists, users; managing library (likes, playlists); social actions (follow, like, comment); playlist management; and messaging via the SoundCloud API.
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., "@SoundCloud MCP Server search for lofi hip-hop tracks"
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.
SoundCloud MCP Server
Search SoundCloud, discover music, manage playlists, and use your library from MCP clients like Claude Code and ChatGPT.
Here's an example:
https://github.com/user-attachments/assets/89625322-d329-46ef-9987-e25396b68c23
This integration is unofficial and not affiliated with SoundCloud.
It runs locally over stdio, or on Cloudflare Workers over Streamable HTTP so you can use it from your phone.
You have to deploy the worker yourself. We don't run a shared instance at this time.
Local setup
Requires Node 22.18+ or 24.11+ LTS and pnpm. See package.json for exact versions.
Create an app at https://soundcloud.com/you/apps. Save its client ID and secret. Register
http://localhost:8888/callbackas the redirect URI, or set a matching custom URI below.Install and configure:
pnpm install cp .env.example .envFill in the app credentials in
.env.Build and run:
pnpm build pnpm start
For personal data and writes, run pnpm run auth. It opens a browser and saves
rotating tokens to ~/.soundcloud-mcp/tokens.json with mode 600. Use
pnpm run auth --no-browser to print the login URL. You can also use the
connect_soundcloud and auth_status tools. Public search uses cached
client-credentials tokens without user login. To sign out, run
pnpm run auth --sign-out or call sign_out. Both revoke the app's access at
SoundCloud and delete the token file.
Claude Code
The repo's .mcp.json registers this server as soundcloud-local. Run
pnpm build, fill in .env at the repo root, then start claude in the repo
and approve the project server when prompted. Its paths use
${CLAUDE_PROJECT_DIR:-.}, which falls back to . because Claude Code runs the
server from the project root, so no absolute paths are needed. Login tokens
still live in ~/.soundcloud-mcp/tokens.json.
Claude Desktop
Open Settings > Developer > Edit Config and add:
{
"mcpServers": {
"soundcloud": {
"command": "node",
"args": ["/absolute/path/to/soundcloud-mcp/build/index.js"],
"env": {
"SOUNDCLOUD_CLIENT_ID": "your-client-id",
"SOUNDCLOUD_CLIENT_SECRET": "your-client-secret"
}
}
}
}Fully quit and reopen Claude Desktop. Other stdio clients use the same command
and environment variables. Build before connecting; clients run JavaScript, not
TypeScript. Paths must be absolute: clients do not expand ~ or shell variables.
If a GUI client cannot find Node, use its absolute path from which node.
The config file is at:
macOS:
~/Library/Application Support/Claude/claude_desktop_config.jsonWindows:
%APPDATA%\Claude\claude_desktop_config.json
Local environment
pnpm start and pnpm run auth load .env through Node. Direct
node build/index.js calls need environment variables supplied by the client.
Variable | Purpose |
| Required app client ID |
| Required app secret |
| Defaults to |
| Defaults to |
| Set |
Related MCP server: Spotify MCP Server
Worker setup
Run
pnpm install. Set your worker name inwrangler.jsonc.Create a KV namespace:
pnpm exec wrangler kv namespace create soundcloud-mcp-OAUTH_KVPut the returned ID in
wrangler.jsoncunder theOAUTH_KVbinding. Keep themigrationsblock; on existing deployments it removes the oldSoundCloudMCPDurable Object.Set each secret with
pnpm exec wrangler secret put <NAME>:SOUNDCLOUD_CLIENT_IDSOUNDCLOUD_CLIENT_SECRETCOOKIE_ENCRYPTION_KEY: generate withopenssl rand -hex 32ALLOWED_USERS: comma-separated profile URL slugs (thenameinsoundcloud.com/name) or numeric user IDs. Display names do not match.ENABLE_WRITE_TOOLS: set totrueto offer the Social and Playlists tools. Unset, the worker only reads.
Register
https://<your-worker>.workers.dev/callbackon your SoundCloud app. It must match exactly.Run
pnpm worker:deploy, then connect your MCP client tohttps://<your-worker>.workers.dev/mcpand complete browser OAuth.
For local development, copy .dev.vars.example to .dev.vars, fill it in, and
run pnpm worker:dev at http://localhost:8789. Register its /callback URL
when testing local OAuth.
CI deploys pushes to main when the repository variable DEPLOY_ENABLED is
true and secret CLOUDFLARE_API_TOKEN is set. If the repository variable
ENABLE_WRITE_TOOLS is set, CI copies it into the worker secret of the same name
before deploying. Forks must also set their account ID in
.github/workflows/ci.yml. Reconnect clients after deploying new tools; clients
cache the tool list.
Set ALLOWED_USERS unless you intend to offer public access. Empty or unset
allows any SoundCloud account to use your API quota. Access is checked at the
OAuth callback and tool registration, and the worker deletes stored tokens for
accounts removed from the list. Public hosting also needs a review of
SoundCloud's terms and shared rate limits; see
#1. SoundCloud's terms
restrict acting on users' behalf, so write tools stay off unless you set
ENABLE_WRITE_TOOLS.
The worker serves an install page at /, a privacy page at /privacy, an icon
at /icon.svg, and OAuth at /authorize, /callback, /token, and
/register. It stores each user's SoundCloud tokens, encrypted, in KV until
they call sign_out or 30 days pass. Update src/worker/privacy.ts if you
change what the worker stores.
Tools
Both servers share these tools. Only the local server has connect_soundcloud
and auth_status. On the hosted server, sign_out revokes the app's access at
SoundCloud and deletes your stored tokens for every connected client.
Group | Tools |
Auth |
|
Search |
|
Discovery |
|
Audience |
|
Playback and browsing |
|
Library (login) |
|
Social (login) |
|
Playlists (login) |
|
IDs accept numbers or URNs such as
soundcloud:tracks:123; prefer URNs.get_user_tracksandget_my_tracksacceptsort="asc"orsort="desc".The likes and reposts list tools accept
kind="tracks"(default) orkind="playlists". The likes tools also acceptkind="stations".get_feedacceptskind="all"to include playlist activity.get_stationtakes a station URN from a track's or user'sstation_urn.like_playlistandunlike_playlistalso accept station URNs.Pass
next_hreftonext_pagefor cursor pagination. Use SoundCloud API URLs only; authenticated requests include your token.Playlist track changes replace the full tracklist. Adding or removing a track fails when SoundCloud hides some of the playlist's tracks, since the rewrite would delete them. Comments have no delete tool or public API endpoint; treat them as permanent.
Stream URLs expire, and blocked tracks have no stream. Full tracks stream over HLS; the only MP3 is a short preview.
Results list each track, user and playlist compactly: ids and URNs, title or name, uploader, duration, links, counts, access and dates. Playlists in a list show
track_countwithout their tracks; read one withget_playlistfor its tracklist. Permalinks droputm_*tracking parameters. Passverbose: trueto get every field SoundCloud sends, such as descriptions. Resources return full objects.
Tools provide behavior annotations, structured results, and resource links.
Resources include soundcloud://me/{profile,playlists,likes} and templates for
soundcloud://{tracks,users,playlists}/{id}.
Development
Shared API and MCP code lives in src/{client,tools,types,server,icon}.ts.
src/index.ts and src/stdio/ handle local auth and transport;
src/worker.ts and src/worker/ handle Workers OAuth and HTTP.
pnpm check: lint, Markdown lint, both typechecks, and tests. Tests run on Node, plus a few in workerd against the bundled Worker.pnpm verify: build and check the live stdio server, including read tools, resources, and a temporary playlist create/like/read/delete cycle. Requires login and writes to the connected account.pnpm exec wrangler deploy --dry-run: bundle the worker without deploying. No test verifies a deployment.
See CLAUDE.md for safety and verification rules and
GitHub issues for open work.
Use the soundcloud-api-sync skill before adding endpoints or checking upstream
changes. It records the synced-through date; issue #2 holds the coverage gaps.
The standalone audit is:
node .claude/skills/soundcloud-api-sync/audit.mjs --since 2026-10-28The official spec is authoritative. Track release notes and spec edits.
Contributors
Available Tools
53 toolsadd_commentAdd commentA
Post a comment with an optional timestamp. Comments must be enabled; the API has no undo.
Inputs: body (required), trackId (required), verbose, timestamp.
add_tracks_to_playlistAdd tracks to playlistC
Append tracks to an existing playlist.
Inputs: trackIds (required), playlistId (required), verbose.
auth_statusAuth statusARead-only
Check whether a SoundCloud user is logged in.
Inputs: no named parameters.
connect_soundcloudConnect SoundCloudA
Log in through your browser and save the token for future sessions.
Inputs: no named parameters.
create_playlistCreate playlistA
Create a playlist with optional tracks. Private by default.
Inputs: title (required), sharing, verbose, trackIds, +1 more.
delete_playlistDelete playlistBDestructiveIdempotent
Delete a playlist permanently.
Inputs: playlistId (required).
follow_userFollow userCIdempotent
Follow a user.
Inputs: userId (required).
get_commentsGet track commentsBRead-only
Get comments on a track, with their timestamps into the audio.
Inputs: trackId (required), limit, verbose. Returns: next_href, collection
get_feedGet my feedARead-only
List recent activity from people the connected user follows: tracks by default, or all for playlists too.
Inputs: kind, limit, verbose. Returns: next_href, collection
get_my_followersGet my followersBRead-only
List the users who follow the connected user.
Inputs: limit, verbose. Returns: next_href, collection
get_my_followingsGet who I followCRead-only
List the users the connected user follows.
Inputs: limit, verbose. Returns: next_href, collection
get_my_likesGet my likesBRead-only
List tracks, playlists, or stations the connected user has liked.
Inputs: kind, limit, verbose. Returns: next_href, collection
get_my_playlistsGet my playlistsBRead-only
List the connected user's playlists.
Inputs: limit, verbose. Returns: next_href, collection
get_my_repostsGet my repostsBRead-only
List tracks or playlists the connected user has reposted.
Inputs: kind, limit, verbose. Returns: next_href, collection
get_my_tracksGet my uploadsBRead-only
List the connected user's uploads. Sort: asc for oldest first, desc for newest.
Inputs: sort, limit, verbose. Returns: next_href, collection
get_playlistGet playlistCRead-only
Get a playlist's details and its tracks.
Inputs: playlistId (required), verbose.
get_playlist_repostersGet playlist repostersCRead-only
List the users who reposted a playlist.
Inputs: playlistId (required), limit, verbose. Returns: next_href, collection
get_playlist_tracksGet playlist tracksCRead-only
List a page of playlist tracks.
Inputs: playlistId (required), limit, verbose. Returns: next_href, collection
get_profileGet my profileBRead-only
Get the connected user's SoundCloud profile.
Inputs: verbose.
get_recently_playedGet recently playedBRead-only
Tracks the connected user played recently, most recent first.
Inputs: limit, verbose. Returns: next_href, collection
get_stationGet stationARead-only
Get a station (system playlist) and its tracks. Tracks and users carry a station_urn; get_my_likes with kind=stations lists liked ones.
Inputs: stationUrn (required), verbose.
get_stream_urlGet stream URLARead-only
Get temporary audio URLs: HLS for full tracks, MP3 for previews. Blocked tracks have no stream.
Inputs: trackId (required).
get_trackGet trackCRead-only
Get details for one track.
Inputs: trackId (required), verbose.
get_track_likersGet track likersBRead-only
List the users who liked a track.
Inputs: trackId (required), limit, verbose. Returns: next_href, collection
get_track_repostersGet track repostersCRead-only
List the users who reposted a track.
Inputs: trackId (required), limit, verbose. Returns: next_href, collection
get_userGet userCRead-only
Get a user's public profile.
Inputs: userId (required), verbose.
get_user_followersGet an artist's followersCRead-only
List the users who follow a user.
Inputs: userId (required), limit, verbose. Returns: next_href, collection
get_user_followingsGet who an artist followsCRead-only
List the users a user follows.
Inputs: userId (required), limit, verbose. Returns: next_href, collection
get_user_likesGet an artist's likesCRead-only
List tracks, playlists, or stations a user has liked.
Inputs: userId (required), kind, limit, verbose. Returns: next_href, collection
get_user_playlistsGet an artist's playlistsCRead-only
List the playlists a user has published.
Inputs: userId (required), limit, verbose. Returns: next_href, collection
get_user_repostsGet an artist's repostsCRead-only
List tracks or playlists a user has reposted.
Inputs: userId (required), kind, limit, verbose. Returns: next_href, collection
get_user_tracksGet an artist's tracksARead-only
List a user's uploads. Find ids with search_users. Sort: asc for oldest first, desc for newest.
Inputs: userId (required), sort, limit, verbose. Returns: next_href, collection
get_user_web_profilesGet an artist's linksBRead-only
List the external links on a user's profile, such as a website or socials.
Inputs: userId (required), limit. Returns: items
is_followingCheck if I follow a userARead-only
Check whether the connected user follows a user. Unknown users count as not followed.
Inputs: userId (required). Returns: following
like_playlistLike playlistCIdempotent
Like a playlist or a station.
Inputs: playlistId (required).
like_trackLike trackDIdempotent
Like a track.
Inputs: trackId (required).
next_pageNext pageARead-only
Fetch next_href with a GET to the SoundCloud API (https://developers.soundcloud.com/docs/api/guide).
Inputs: nextHref (required), verbose.
remove_track_from_playlistRemove track from playlistCDestructiveIdempotent
Remove one track from a playlist.
Inputs: trackId (required), playlistId (required), verbose.
repost_playlistRepost playlistBIdempotent
Repost a playlist to the user's followers.
Inputs: playlistId (required).
repost_trackRepost trackCIdempotent
Repost a track to the user's followers.
Inputs: trackId (required).
resolve_urlResolve a SoundCloud URLARead-only
Resolve a soundcloud.com or on.soundcloud.com link to a track, user, playlist, or station. Use for pasted SoundCloud links; pass station URNs to get_station.
Inputs: url (required), verbose.
search_playlistsSearch playlistsCRead-only
Search SoundCloud playlists by keyword.
Inputs: query (required), limit, verbose. Returns: next_href, collection
search_tracksSearch tracksBRead-only
Search SoundCloud tracks by keyword, with optional genre/tag/BPM filters.
Inputs: query (required), tags, bpmTo, limit, +6 more. Returns: next_href, collection
search_usersSearch usersCRead-only
Search SoundCloud users/artists by keyword.
Inputs: query (required), limit, verbose. Returns: next_href, collection
sign_outSign outADestructiveIdempotent
Revoke this app's SoundCloud access and delete the stored token. Public search still works afterward.
Inputs: no named parameters.
unfollow_userUnfollow userCIdempotent
Unfollow a user.
Inputs: userId (required).
unlike_playlistUnlike playlistCIdempotent
Remove a like from a playlist or a station.
Inputs: playlistId (required).
unlike_trackUnlike trackCIdempotent
Remove a like from a track.
Inputs: trackId (required).
unrepost_playlistRemove playlist repostCIdempotent
Remove a repost of a playlist.
Inputs: playlistId (required).
unrepost_trackRemove repostCIdempotent
Remove a repost of a track.
Inputs: trackId (required).
update_playlistUpdate playlistADestructiveIdempotent
Edit a playlist's title, description, or sharing. trackIds replaces and orders the entire tracklist.
Inputs: playlistId (required), title, sharing, verbose, +2 more.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 53 tools
Tools are largely separable by a clear resource+actor pattern (get_my_likes vs get_user_likes, get_track_likers vs get_track_reposters), and descriptions add helpful boundaries. A few overlaps remain fuzzy, notably get_playlist (returns tracks) vs get_playlist_tracks, and the generic next_page which could apply to any listing tool.
The dominant convention is consistent snake_case verb_noun (search_tracks, like_playlist, get_user_followers), applied across virtually all tools. Minor deviations (is_following, auth_status, resolve_url, next_page) are readable predicates but break the strict verb_noun pattern.
53 tools is well above a comfortable surface for a single agent to select from reliably. Much of the bloat comes from parallel families (my_* mirroring user_*, separate like/unlike/repost/unrepost pairs for tracks and playlists) that could be collapsed with parameters.
Coverage is broad: search, detail fetches, likes/reposts/follows, playlist create/update/delete, comments, stations, streaming URLs, and auth lifecycle are all present. Gaps are minor: no comment editing or deletion, and no track upload/delete (largely an API limitation).
Maintenance
Related MCP Connectors
MCP server exposing the AceDataCloud Fish Audio API (text-to-speech with voice conditioning)
An MCP server that provides read access to your cloud storage providers, bank accounts and more.
An MCP server that provides tools to discover and retrieve podcast episodes transcripts.
MCP server for RiverScript, an AI transcription platform - fetches transcripts shared via a link.
Related MCP Servers
- AlicenseBqualityDmaintenanceAn MCP server that enables AI assistants to search, analyze, and retrieve information about audio samples from Freesound.org through their API.82MIT
- AlicenseAqualityBmaintenanceMCP server for the Spotify Web API — gives Claude and other AI assistants tools to search music, control playback, manage playlists, library, and podcasts.475MIT
- AlicenseNot gradedqualityDmaintenanceAn unofficial MCP server that provides access to Spotify's Web API through the Model Context Protocol, enabling AI assistants to search music, manage playlists, and control playback.29 npm9ISC
- AlicenseNot gradedqualityDmaintenanceAn MCP server that gives Claude access to your SoundCloud library, allowing you to manage playlists and tracks through natural language.3AGPL 3.0