musicbrainz-mcp
# musicbrainz-mcp
[](https://github.com/chrischall/musicbrainz-mcp/actions/workflows/ci.yml)
[](https://www.npmjs.com/package/musicbrainz-mcp)
[](LICENSE)
An MCP server for [MusicBrainz](https://musicbrainz.org), the open music encyclopedia. It gives Claude live access to MusicBrainz metadata — artists, releases, recordings, labels, works, and more — plus Cover Art Archive images, and (optionally) lets you submit your own tags, ratings, and collection edits.
> Developed and maintained by AI (Claude Code). Use at your own discretion.
## Tools
**Read (no credentials required):**
| Tool | What it does |
| --- | --- |
| `musicbrainz_search` | Search any entity type with a Lucene query; returns ranked matches + MBIDs |
| `musicbrainz_lookup` | Look up an entity by MBID, with `inc` subqueries for linked data |
| `musicbrainz_browse` | List all entities linked to another (e.g. every release by an artist) |
| `musicbrainz_cover_art` | Cover Art Archive image URLs for a release / release-group |
| `musicbrainz_resolve` | Turn a pasted musicbrainz.org URL into its entity |
| `musicbrainz_healthcheck` | Verify connectivity and whether OAuth writes are configured |
**Write (OAuth, confirmed before sending):**
| Tool | What it does |
| --- | --- |
| `musicbrainz_submit_tags` | Apply user tags to an entity on your account |
| `musicbrainz_submit_rating` | Set your 0–100 rating for an entity |
| `musicbrainz_modify_collection` | Add/remove entities in one of your collections |
Each write asks you to confirm before it makes any network call — see [Confirmations](#confirmations).
Every read above takes a `view`, except `musicbrainz_cover_art`. It defaults to
`compact`, which strips image and avatar URLs — a subtractive rule, so it cannot
drop a field nobody knew was there; `view: "full"` returns MusicBrainz's payload
untouched. `musicbrainz_cover_art` takes none on purpose: the image URLs *are*
its answer, and stripping them would not shrink the response, it would empty it.
## Install
This is a Node MCP server (stdio). Point your MCP host at it:
```json
{
"mcpServers": {
"musicbrainz": {
"command": "npx",
"args": ["-y", "musicbrainz-mcp"]
}
}
}
```
Reads work immediately. MusicBrainz asks clients to make **at most one request per second** — the server throttles itself to stay within that limit, so large browses are paced automatically.
## Enabling the write tools (optional)
1. Register an application at [musicbrainz.org/account/applications](https://musicbrainz.org/account/applications) (redirect URI `urn:ietf:wg:oauth:2.0:oob`).
2. Complete the OAuth flow with the `tag`, `rating`, and `collection` scopes to obtain a **refresh token**.
3. Provide these via your MCP host's env (or a local `.env`):
```
MUSICBRAINZ_OAUTH_CLIENT_ID=...
MUSICBRAINZ_OAUTH_CLIENT_SECRET=...
MUSICBRAINZ_OAUTH_REFRESH_TOKEN=...
```
## Confirmations
Every write asks you first. A client that can show a confirmation prompt (Claude Code) shows one, with the entity, tags / rating / collection change. A client that cannot (claude.ai, Claude Desktop) gets a two-step flow instead: the first call sends nothing and returns a `confirmation-required` preview — the exact XML for tags and ratings, the method and path for collections — plus a `confirmToken`; only a repeat of the same call with that token submits. A token acts once, and changing any argument between the two calls invalidates it.
| variable | default | |
|---|---|---|
| `MCP_CONFIRM_MODE` | `ask-user` | What a write does on a client that cannot show a confirmation prompt (claude.ai, Claude Desktop). `ask-user`: two steps — the first call does nothing and returns a preview plus a token, and the model must get your approval in chat before calling again with it. `auto`: the same two steps, but the model may use the token after reviewing the preview itself. `refuse`: writes are refused on such clients. A client that can show prompts (Claude Code) always gets the real prompt, unless `MCP_CONFIRM_ELICITATION=off`. An unrecognised value is treated as `refuse`. |
| `MCP_CONFIRM_ELICITATION` | `on` | `off` never shows a confirmation prompt, so every client gets the `MCP_CONFIRM_MODE` behaviour. Set it for a client that says it can show prompts but never does (the write hangs — opencode 2.0.x). Any other value is treated as `on`, with a warning on stderr. |
| `MCP_CONFIRM_TTL_SECONDS` | `600` | How long a token stays valid. |
| `MCP_CONFIRM_SECRET` | random per process | Signing key; set it only if tokens must survive a server restart. |
## Development
```bash
npm install
npm run build
npm test
```
See [CLAUDE.md](CLAUDE.md) for architecture and [docs/MUSICBRAINZ-API.md](docs/MUSICBRAINZ-API.md) for the pinned API shapes.
## License
MIT. Data from MusicBrainz, licensed under [CC0 / CC BY-NC-SA](https://musicbrainz.org/doc/About/Data_License).
TDQS
Scored across 9 tools
Each tool has a distinct purpose: lookup (single entity by MBID), browse (paged linked entities), search (Lucene ranking), resolve (URL parsing), cover_art, three OAuth writes, and healthcheck. There is mild overlap between lookup and resolve (resolve is essentially URL-extraction + lookup) and between browse and search, but descriptions clearly differentiate ranked-fuzzy vs complete-paged semantics.
All tools use a consistent musicbrainz_ prefix and snake_case, which is highly predictable. The verb portion mixes styles slightly (submit_tags, submit_rating, modify_collection vs noun-ish lookup, browse, search, resolve, healthcheck), but this is readable and largely intuitive.
Nine tools is well-scoped for a MusicBrainz client covering reads, search, resolution, cover art, and the three OAuth write paths. No tool feels redundant or gratuitous, and nothing is obviously missing from the count.
The surface covers the core read lifecycle (search, lookup, browse, resolve, cover art) plus the realistic write operations MusicBrainz allows via OAuth (tags, ratings, collections) and a healthcheck. Minor gaps remain (e.g. no explicit release-group or genre-centric browse helper), but agents can work around them with lookup/browse and inc.