.codex-plugin — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited .codex-plugin (MCP Server) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
<div align="center"> <h1>@cyanheads/musicbrainz-mcp-server</h1> <p><b>Search artists, releases, recordings, works, and labels; traverse relationships; resolve ISRC/ISWC/barcode; fetch cover art via MCP. STDIO or Streamable HTTP.</b> <div>10 Tools • 1 Resource</div> </p> </div>
<div align="center">
</div>
<div align="center">
</div>
<div align="center">
</div>
<div align="center">
Public Hosted Server: https://musicbrainz.caseyjhand.com/mcp
</div>
Ten read-only tools mapping the three MusicBrainz access modes — search when you have text, lookup (get_* and lookup_identifier) when you hold an MBID or standard identifier, and browse when you need the complete linked set beyond the single page that lookup folds in:
| Tool | Description |
|---|---|
musicbrainz_search_entities | Full-text Lucene search across an entity type (artist, release-group, release, recording, work, label). Returns ranked matches with MBID and a 0–100 relevance score. The first step when starting from a name. |
musicbrainz_get_artist | Artist profile by MBID — type, country, life span, aliases, tags/genres, discography (release-groups), band-membership relationships, and external links. |
musicbrainz_get_release_group | Release-group ("the album" above specific pressings) by MBID — primary/secondary type, first-release date, artist credit, editions, and a cover-art availability flag. |
musicbrainz_get_release | One edition's full detail by MBID — tracklist (media → tracks → recordings), label + catalog number, barcode, packaging, and a cover-art stub. |
musicbrainz_get_recording | Recording (a specific performance/track) by MBID — length, artist credits, ISRCs, the releases it appears on, the work(s) it performs, and performance/production relationships. |
musicbrainz_get_work | Work (a composition, distinct from any recording) by MBID — type, languages, ISWCs, writer/composer relationships, and the recordings that perform it. |
musicbrainz_get_label | Label by MBID — type, country, life span, label code, area, aliases, tags, and external links. |
musicbrainz_lookup_identifier | Resolve a standard identifier without a name search — ISRC → recordings, ISWC → works, barcode → releases. Output is discriminated on the resolved entity type. |
musicbrainz_browse_entities | Paginate the complete set of entities linked to a parent MBID — every release on a label, every release-group by an artist, every recording of a work. The only complete-enumeration path. |
musicbrainz_get_cover_art | Cover Art Archive images for a release or release-group MBID — front/back flags, image types, full-resolution URLs, and 250/500/1200px thumbnails. No art returns an empty set, not an error. |
musicbrainz_search_entitiesResolve a name to an MBID with full-text Lucene search.
artist:radiohead AND country:GB)score per hit (100 = exact); results stay in MusicBrainz score-descending order, not re-rankedlimit (1–100) and offset; echoes the effective query and the true upstream totalmusicbrainz_get_artistThe 80% artist-detail call.
incurl-rels — chainable to wikidata-mcp-server and friends; this server does not chase them itselfinc_release_groups and inc_relationships toggle the expensive sub-resourcesmusicbrainz_browse_entities (target_type=release-group, artist link)musicbrainz_get_releaseOne edition's full detail, the level with an actual tracklist.
m:ss, stored as milliseconds upstream)musicbrainz_get_cover_art with the release MBID for the actual image URLsmusicbrainz_lookup_identifierThe deterministic path when you already hold a standard identifier — no name search.
id_type=isrc → recordings (a recording-level code, often shared by several recordings)id_type=iswc → works (a composition-level code)id_type=barcode → releases (UPC/EAN)kind field tells you which entity type came backmusicbrainz_browse_entitiesThe complete-enumeration path — a correctness tool, not just convenience.
offset; totalCount is the true upstream totalget_* tools embed at most one page (25), and a partial list read as complete is a silent correctness gaplink MBID matching a valid parent→child relationship for the target_typemusicbrainz_get_cover_artCover Art Archive images, kept separate from the release record.
| Type | Name | Description |
|---|---|---|
| Resource | musicbrainz://{entity_type}/{mbid} | A single MusicBrainz entity by type and MBID, with default linked sub-resources folded in. Mirrors the matching musicbrainz_get_* tool. entity_type ∈ artist, release-group, release, recording, work, label. |
All entity data is also reachable via the get_* tools, so tool-only clients (the majority) lose nothing. There is no resource list() — the corpus is millions of entities; discovery is via musicbrainz_search_entities, not resource enumeration.
Built on @cyanheads/mcp-ts-core:
none, jwt, oauthin-memory, filesystem, Supabase, Cloudflare KV/R2/D1MusicBrainz-specific:
musicbrainz.org/ws/2, JSON) plus the Cover Art Archiveinc set) — MBIDs are stable and entity data changes slowly, keeping most repeat lookups off the wireinc-driven lookups fold discography, relationships, tracklists, and external IDs into a single call rather than serial requestsAgent-friendly output:
get_* tools disclose when an embedded linked list is capped at one page and name musicbrainz_browse_entities as the complete-enumeration pathmusicbrainz_lookup_identifier returns a kind-tagged union (recordings | works | releases) so callers branch on data, not string parsingscore surfaced as-is (not a fabricated confidence metric), and missing upstream fields are preserved as absent rather than inventedmusicbrainz-mcp-server is keyless — no API key or account. MusicBrainz does require a descriptive User-Agent with a contact and rate-limits to ~1 request/second per IP; the server ships a default contact so it works out of the box, but operators running a shared or hosted instance should set MUSICBRAINZ_CONTACT to their own email or URL.
A public instance is available at https://musicbrainz.caseyjhand.com/mcp — no installation required. Point any MCP client at it via Streamable HTTP, with this client config:
{
"mcpServers": {
"musicbrainz-mcp-server": {
"type": "streamable-http",
"url": "https://musicbrainz.caseyjhand.com/mcp"
}
}
}Add the following to your MCP client configuration file.
{
"mcpServers": {
"musicbrainz-mcp-server": {
"type": "stdio",
"command": "bunx",
"args": ["@cyanheads/musicbrainz-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info",
"MUSICBRAINZ_CONTACT": "[email protected]"
}
}
}
}Or with npx (no Bun required):
{
"mcpServers": {
"musicbrainz-mcp-server": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@cyanheads/musicbrainz-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info",
"MUSICBRAINZ_CONTACT": "[email protected]"
}
}
}
}Or with Docker:
{
"mcpServers": {
"musicbrainz-mcp-server": {
"type": "stdio",
"command": "docker",
"args": [
"run", "-i", "--rm",
"-e", "MCP_TRANSPORT_TYPE=stdio",
"-e", "[email protected]",
"ghcr.io/cyanheads/musicbrainz-mcp-server:latest"
]
}
}
}For Streamable HTTP, set the transport and start the server:
MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 [email protected] bun run start:http
# Server listens at http://localhost:3010/mcpMUSICBRAINZ_CONTACT to your email or URL — recommended for any shared or hosted deployment.git clone https://github.com/cyanheads/musicbrainz-mcp-server.gitcd musicbrainz-mcp-serverbun installcp .env.example .env
# edit .env and set MUSICBRAINZ_CONTACT (optional but recommended)Configuration is validated at startup via Zod schemas in src/config/server-config.ts.
| Variable | Description | Default |
|---|---|---|
MUSICBRAINZ_CONTACT | Contact (email or URL) embedded in the mandatory descriptive User-Agent. Not start-blocking — a default is provided — but operators of a shared/hosted instance should set their own so MusicBrainz can reach them about traffic. | repo URL |
MUSICBRAINZ_BASE_URL | MusicBrainz Web Service v2 base URL. Override for a private mirror or beta.musicbrainz.org. | https://musicbrainz.org/ws/2 |
MUSICBRAINZ_RATE_LIMIT_RPS | Client-side request-per-second ceiling. ~1 is the documented limit; lower it for shared-hosting headroom. | 1 |
MUSICBRAINZ_CACHE_TTL | Response cache TTL in seconds. MBIDs are stable, so data changes slowly. 0 disables caching. | 86400 |
MUSICBRAINZ_TIMEOUT_MS | Per-request HTTP timeout in milliseconds. | 30000 |
MUSICBRAINZ_MAX_RETRIES | Retry attempts for transient upstream failures (503 / 5xx / HTML error page). | 3 |
COVER_ART_BASE_URL | Cover Art Archive base URL. | https://coverartarchive.org |
MCP_TRANSPORT_TYPE | Transport: stdio or http. | stdio |
MCP_HTTP_PORT | Port for the HTTP server. | 3010 |
MCP_AUTH_MODE | Auth mode: none, jwt, or oauth. | none |
MCP_LOG_LEVEL | Log level (RFC 5424). | info |
OTEL_ENABLED | Enable OpenTelemetry instrumentation. | false |
See .env.example for the full list of optional overrides.
MusicBrainz enforces a ~1 request/second average rate limit per IP across the whole hosted instance and blocks requests without a descriptive `User-Agent` that identifies the application and a contact. This server satisfies both: it sends musicbrainz-mcp-server/<version> (<contact>) as the User-Agent and serializes all upstream calls through a process-wide token-bucket limiter, with response caching to keep repeat lookups off the wire. On a shared or hosted instance every client shares the one limiter, so bulk enumeration via musicbrainz_browse_entities paces accordingly. Set MUSICBRAINZ_CONTACT to your own email or URL when you deploy.
MusicBrainz core entity data is released under CC0 (public-domain dedication) — see the MusicBrainz license. This server stays on that core metadata and does not fetch annotation text (which carries a different, non-CC0 license). Cover art is served by the Cover Art Archive, a joint project of MusicBrainz and the Internet Archive; image URLs are linked, never rehosted, and each image's copyright stays with its rights holders. Cite MusicBrainz and the Cover Art Archive in downstream use.
# One-time build
bun run rebuild
# Run the built server
bun run start:stdio
# or
bun run start:http bun run devcheck # Lint, format, typecheck, security, packaging
bun run test # Vitest test suite
bun run lint:mcp # Validate MCP definitions against the linter rulesdocker build -t musicbrainz-mcp-server .
docker run --rm -e [email protected] -p 3010:3010 musicbrainz-mcp-serverThe Dockerfile defaults to HTTP transport, stateless session mode, and logs to /var/log/musicbrainz-mcp-server. OpenTelemetry peer dependencies are installed by default — build with --build-arg OTEL_ENABLED=false to omit them.
| Directory | Purpose |
|---|---|
src/index.ts | createApp() entry point — registers tools and the resource, inits both services. |
src/config | Server-specific environment variable parsing and validation with Zod. |
src/services/musicbrainz | MusicBrainz WS/2 client — User-Agent, rate limiter, response cache, retry, and domain types. |
src/services/cover-art | Cover Art Archive client — maps 404 to an empty image set, follows the release-group redirect. |
src/mcp-server/tools | Tool definitions (*.tool.ts). Ten read-only tools across search, lookup, browse, and cover art. |
src/mcp-server/resources | Resource definitions. The musicbrainz://{entity_type}/{mbid} entity mirror. |
tests/ | Unit and integration tests mirroring src/. |
See CLAUDE.md/AGENTS.md for development guidelines and architectural rules. The short version:
try/catch in tool logicctx.log for request-scoped logging, ctx.state for tenant-scoped storagesrc/mcp-server/*/definitions/index.tsfetch() MusicBrainz directly, or you bypass the User-Agent, rate limiter, and cacheIssues and pull requests are welcome. Run checks and tests before submitting:
bun run devcheck
bun run testApache-2.0 — see LICENSE for details.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.