mpi-duplicate-detection
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., "@mpi-duplicate-detectionCheck if these two patient records are duplicates: John A. Doe and Jon Doe"
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.
mpi-duplicate-detection
Duplicate patient-record detection for a Master Patient Index (MPI), with an MCP server. Synthetic data only. Not for production use. Not for real patient data.
Author: Christopher Scharenberg. Write-up with results and limits: docs/case_study.md. Field definitions: DATA_DICTIONARY.md.
What's here
File | Purpose |
| Scores a pair of records (0 to 1) with a verdict and reasons |
| Nickname and name-variant matching |
| Reproduces the union-find over-merging bug found during evaluation |
| Injects labeled duplicates and look-alikes into Synthea data, scores every pair, reports precision and recall |
| FastMCP server exposing |
| Local model calls |
| Calls |
| Read-only report of OpenEMR lab results that created placeholder patients |
| Raw output of the runs reported in the case study |
Related MCP server: Claims Quality MCP Server
Setup
pip install -r requirements.txt
python3 patient_match.py # smoke test with invented recordsGenerate synthetic data
Patients come from Synthea. Reported runs used commit d9d07a6eef91ee5144293b42ab64224d84d124f8:
./run_synthea -s 42 -cs 42 -p 500 -r 20260923 --exporter.fhir.export=true MassachusettsThis wrote 586 patient files (500 living, 86 deceased); the eval uses all of them. Put the FHIR output in fhir/. I have not verified that Synthea reproduces byte-identical files from the same seed, so regenerating gives a comparable set, not necessarily an identical one.
Run the evaluation
python3 make_synthetic_eval.py --fhir-dir fhir --seed 42 --n-each 25 --out eval_seed42
python3 make_synthetic_eval.py --fhir-dir fhir --seed 7 --n-each 25 --out eval_seed7Same seed and same fhir/ folder reproduce the same records. Outputs are printed and saved as CSVs (ignored by git).
Run the agent test
Needs Ollama running with a tool-calling model. Check the tag with ollama list.
OLLAMA_MODEL=nemotron-3.5-lightning python3 nemotron_agent_test.pyModel output varies between runs.
Run the MCP server
Needs Python 3.10 or newer (FastMCP requirement).
python3 mpi_dedup_server.py
python3 test_mcp_server.py # in-process check that the MCP tool matches a direct callSee the FastMCP documentation for connecting a client.
Unmatched-results report
python3 unmatched_results_report.py --demo # sample data, no databaseAgainst a sandbox database, copy .env.example to .env, fill it in, and run without --demo. The script only reads.
Known limits
Synthetic data only, hand-set thresholds, a small 56-patient base set, and injected errors chosen by the author. Full list in the case study.
Third-party sources and licenses
Nicknames:
names.csvcomes from the carltonnorthern/nicknames project. License text:LICENSE-nicknames-carltonnorthern.txt(Apache-2.0). Unmodified: its content matched the upstreamnames.csvwhen compared in September 2026 (line endings aside). See the case study for the maintainers' caution about coverage bias.Synthea: Apache-2.0 (from the
LICENSEfile of commitd9d07a6eef91ee5144293b42ab64224d84d124f8). Synthea output is generated locally and not committed.OpenEMR: GNU GPL v3 (per its
LICENSEfile), version 8.2.0 (perversion.php), local checkout at commit6125a2fd8089c8bcc3848071c1293c60e27a7585. No OpenEMR code is included; the unmatched-results report only queries its database.Libraries (licenses from installed package metadata): FastMCP Apache-2.0; jellyfish MIT (license classifier); ollama MIT; PyMySQL MIT.
Model:
nemotron-3.5-lightning:latest(32.9B parameters, Q4_K_M quantization), run locally through Ollama and licensed by NVIDIA under the NVIDIA Open Model License Agreement (last modified October 24, 2025). Model weights are not included in this repo.
License
MIT. See LICENSE. The nickname data keeps its own license, noted above.
This server cannot be deployed
Maintenance
Related MCP Connectors
Privacy-preserving synthetic health data generation. FHIR R4/R5 compliant.
Find duplicate records in 30 seconds. Zero-config entity resolution, 97.2% F1 out of the box.
Fuzzy entity resolution and dedupe for names, addresses, and company records. $0.02/call via x402.
Synthetic EHR: medications, labs, conditions, allergies, immunizations, FHIR R4. No API key.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceIdentifies high-risk patient cohorts and generates care gap closure plans using a synthetic OMOP-like dataset. It provides clinical decision support tools for homecare management through a DuckDB-backed FastMCP server.-
- FlicenseNot gradedqualityBmaintenanceEnables MCP-compatible AI clients to validate healthcare claims data quality by running completeness, integrity, and temporal checks on CSV files via five callable tools, including profiling and full scans.-
- AlicenseNot gradedqualityAmaintenanceEnables AI agents to verify medical-record claims against synthetic FHIR evidence using a deterministic, non-AI verifier. Provides MCP tools for evidence retrieval, claim verification, and benchmark evaluation without requiring real patient data.2Apache 2.0
- AlicenseNot gradedqualityBmaintenanceEnables clinical workflows including search and summarization of synthetic FHIR patient records, PubMed literature search, and HIPAA Safe Harbor de-identification of text, via any MCP client.MIT