Skip to main content
Glama
rachadchazbek

Musicians MCP

Musicians MCP Server

Python MCP server for a classical musicians database stored in Supabase/PostgreSQL.

This project now supports both:

  • trusted database read/review tools, and

  • deterministic external-source enrichment/staging tools

for MusicBrainz and Wikidata.

The MCP client is the AI agent. This server does not call any LLM APIs internally.

Features

Core database tools

  • health_check()

  • search_musicians(query: str, limit: int = 10)

  • get_musician_profile(musician_id: str)

  • create_import_job(names: list[str], job_name: str | None = None)

  • get_review_queue(limit: int = 20)

  • approve_staged_musician(staged_profile_id: str)

External-source enrichment and staging tools

  • resolve_musician_identity(name: str, limit: int = 5)

  • fetch_wikidata_profile(qid: str)

  • fetch_musicbrainz_artist(mbid: str)

  • stage_musician_from_sources(...)

  • detect_staged_profile_conflicts(staged_profile_id: str)

  • process_import_job_next(import_job_id: str)

  • process_import_job_batch(import_job_id: str, max_names: int = 5)

Project Structure

.
├── .env.example
├── pyproject.toml
├── README.md
└── src
    └── musicians_mcp
        ├── __init__.py
        ├── db.py
        ├── external_sources.py
        └── server.py

Requirements

  • Python 3.11+

  • Supabase project URL

  • Supabase service role key

  • a valid MusicBrainz User-Agent string

  • a valid Wikimedia User-Agent string

Setup

python3 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
pip install -e .
cp .env.example .env

Update .env with:

SUPABASE_URL=https://your-project-ref.supabase.co
SUPABASE_SERVICE_ROLE_KEY=your-supabase-service-role-key
MUSICBRAINZ_USER_AGENT=ClassicalMusiciansMCP/0.1.0 (your-email-or-project-url)
WIKIMEDIA_USER_AGENT=ClassicalMusiciansMCP/0.1.0 (your-email-or-project-url)

User-Agent notes:

  • MusicBrainz expects a descriptive User-Agent.

  • Wikimedia also expects a descriptive User-Agent for automated access.

  • A good format is: ClassicalMusiciansMCP/0.1.0 (your-email-or-project-url)

Run the Server

source .venv/bin/activate
python -m musicians_mcp.server

Or with the installed script:

source .venv/bin/activate
musicians-mcp

Example MCP Client Config

{
  "mcpServers": {
    "musicians": {
      "command": "/absolute/path/to/Musicians MCP/.venv/bin/python",
      "args": ["-m", "musicians_mcp.server"],
      "cwd": "/absolute/path/to/Musicians MCP",
      "env": {
        "SUPABASE_URL": "https://your-project-ref.supabase.co",
        "SUPABASE_SERVICE_ROLE_KEY": "your-supabase-service-role-key",
        "MUSICBRAINZ_USER_AGENT": "ClassicalMusiciansMCP/0.1.0 (your-email-or-project-url)",
        "WIKIMEDIA_USER_AGENT": "ClassicalMusiciansMCP/0.1.0 (your-email-or-project-url)"
      },
      "disabled": false,
      "autoApprove": []
    }
  }
}

If your MCP client loads environment variables from the working directory, you can keep the values in .env instead.

Safety Rules

This server is intentionally conservative.

  • It does not write directly to musicians.

  • It does not auto-approve staged musicians.

  • It does not call approve_staged_musician during staging or batch processing.

  • It only stages facts that came from source-backed deterministic fetches.

  • It writes review signals and ambiguity details into staged rows/audit logs.

  • If identity resolution is ambiguous, it keeps the profile in review-oriented status instead of pretending the identity is verified.

Trusted promotion must still happen manually through:

  • approve_staged_musician(p_staged_profile_id uuid)

External Source Behavior

MusicBrainz

The server can:

  • search artists by name

  • fetch artist details by MBID

  • normalize aliases, artist type, country/area, life-span, disambiguation, and source URL

Wikidata

The server can:

  • search entities by name

  • fetch item details by QID

  • normalize labels, description, aliases, dates, citizenship, occupations, instruments, notable works, websites, and selected external identifiers

Request discipline

Both source clients:

  • always send configured User-Agent headers

  • apply conservative pacing

  • use retry logic for transient HTTP failures

  • log every external request

Tool Summary

health_check()

Verifies that the server can connect to Supabase.

search_musicians(query, limit=10)

Searches musicians by:

  • full_name

  • display_name

  • sort_name

  • nationality

  • primary_role

Returns:

  • id

  • full_name

  • display_name

  • nationality

  • primary_role

  • birth_date

  • death_date

  • confidence

  • is_verified

get_musician_profile(musician_id)

Returns a single trusted musician plus related:

  • fact_claims

  • external_identifiers

create_import_job(names, job_name=None)

Creates an import job and returns:

  • job_id

  • total_names

  • status

get_review_queue(limit=20)

Reads staged profiles from staged_musician_review_queue.

approve_staged_musician(staged_profile_id)

Manually approves a staged profile through the Postgres RPC.

resolve_musician_identity(name, limit=5)

Searches both Wikidata and MusicBrainz and returns ranked normalized candidates.

Each candidate includes:

  • source

  • external_id

  • name

  • description / disambiguation

  • birth_date

  • death_date

  • country

  • roles

  • match_score

  • source_url

This tool does not write to the database.

fetch_wikidata_profile(qid)

Fetches and normalizes one Wikidata item.

Returns:

  • structured profile data

  • raw key fields useful for debugging

This tool does not write to the database.

fetch_musicbrainz_artist(mbid)

Fetches and normalizes one MusicBrainz artist.

Returns:

  • structured profile data

  • raw key fields useful for debugging

This tool does not write to the database.

stage_musician_from_sources(...)

Resolves and stages a musician from deterministic external sources.

Behavior:

  • if explicit external IDs are provided, it fetches those exact profiles

  • otherwise it resolves likely candidates first

  • only strong matches may be selected automatically

  • ambiguous cases remain review-oriented

  • inserts one row into staged_musician_profiles

  • inserts source-backed rows into staged_fact_claims

  • writes audit entries into import_audit_logs

  • does not write to musicians

  • does not call approval automatically

Returns:

  • staged_profile_id

  • status

  • confidence

  • selected_sources

  • warnings

detect_staged_profile_conflicts(staged_profile_id)

Checks staged facts for conflicts such as:

  • different birth dates

  • different death dates

  • different nationality/citizenship values

  • inconsistent roles/occupations

Returns property-level conflict details.

process_import_job_next(import_job_id)

Processes exactly one pending name from an import job.

It:

  • stages a single profile

  • updates processed names safely

  • writes audit logs

  • never approves automatically

process_import_job_batch(import_job_id, max_names=5)

Processes up to max_names pending names.

Returns per-name:

  • staging results

  • errors

  • job status progression

  1. Run health_check

  2. Run resolve_musician_identity("Claude Debussy")

  3. Run fetch_wikidata_profile on the selected QID

  4. Run fetch_musicbrainz_artist on the selected MusicBrainz artist ID

  5. Run create_import_job(["Claude Debussy", "Maurice Ravel"])

  6. Run process_import_job_next(job_id)

  7. Run get_review_queue()

  8. Run detect_staged_profile_conflicts(staged_profile_id)

  9. Only then run approve_staged_musician manually if the staged record is acceptable

Local Verification Commands

After setup, these are the main commands to run locally:

source .venv/bin/activate
python -m pip install -e .
python -m compileall src
python -c "import sys; sys.path.insert(0, 'src'); import musicians_mcp.server; print('server import ok')"
python -m musicians_mcp.server

Notes on Schema Flexibility

This implementation is intentionally defensive around the import/staging tables because exact column layouts were not fully specified here.

In particular, db.py uses fallback payload shapes for:

  • musician_import_jobs

  • staged_musician_profiles

  • staged_fact_claims

  • import_audit_logs

That makes the first version more resilient, but if you share the exact table schemas next, I can tighten the insert/update logic to match them precisely and reduce fallback branching.

-
license - not tested
-
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/rachadchazbek/Musicians-MCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server