Musicians MCP
A Python MCP server for managing a classical musicians database in Supabase/PostgreSQL, enabling search, review, and enrichment of musician profiles from MusicBrainz and Wikidata.
README
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_musicianduring 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_namedisplay_namesort_namenationalityprimary_role
Returns:
idfull_namedisplay_namenationalityprimary_rolebirth_datedeath_dateconfidenceis_verified
get_musician_profile(musician_id)
Returns a single trusted musician plus related:
fact_claimsexternal_identifiers
create_import_job(names, job_name=None)
Creates an import job and returns:
job_idtotal_namesstatus
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:
sourceexternal_idnamedescription/disambiguationbirth_datedeath_datecountryrolesmatch_scoresource_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_idstatusconfidenceselected_sourceswarnings
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
Recommended Manual Test Flow
- Run
health_check - Run
resolve_musician_identity("Claude Debussy") - Run
fetch_wikidata_profileon the selected QID - Run
fetch_musicbrainz_artiston the selected MusicBrainz artist ID - Run
create_import_job(["Claude Debussy", "Maurice Ravel"]) - Run
process_import_job_next(job_id) - Run
get_review_queue() - Run
detect_staged_profile_conflicts(staged_profile_id) - Only then run
approve_staged_musicianmanually 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_jobsstaged_musician_profilesstaged_fact_claimsimport_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.
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.