In the rapidly evolving world of AI Agents and LLM automation, the biggest bottleneck isn't the model's intelligence—it's the context. How do we give an AI safe, structured access to sensitive local data like Electronic Medical Records (EMR) without uploading everything to the cloud?
Today, we are diving into the Model Context Protocol (MCP), a game-changing standard introduced by Anthropic. We’ll build a medical assistant that can browse local patient histories, parse PDFs, and provide structured clinical insights directly within Claude Desktop. By leveraging the MCP SDK and Python, we are moving past simple RAG into true tool-use orchestration.
The Architecture: How MCP Bridges the Gap
The Model Context Protocol acts as a universal translator between an AI model (the client) and your local data sources (the server). Instead of the AI "guessing," it calls specific tools to fetch exactly what it needs.
graph TD
A[Claude Desktop Client] -- MCP Protocol --> B[Local MCP Server]
B -- Query --> C[(SQLite Index)]
B -- Read --> D[Local PDF Repository]
C -- Metadata --> B
D -- Content Extraction --> B
B -- Structured Context --> A
A -- Reasoning --> E[Medical Advice / Summary]
Prerequisites
To follow this tutorial, you'll need:
- Claude Desktop installed.
-
Python 3.10+ (we'll use the
mcpPython SDK). - A directory of sample PDF medical records.
- SQLite (built-in with Python) for indexing file metadata.
Step 1: Setting Up the MCP Server
First, let's initialize our environment. The MCP SDK allows us to define "tools" that Claude can invoke.
pip install mcp langchain-community pypdf pysqlite3
Now, let's create our server file, medical_mcp_server.py. We want Claude to be able to list patients and read specific clinical notes.
from mcp.server.fastmcp import FastMCP
import sqlite3
import os
from pypdf import PdfReader
# Initialize FastMCP Server
mcp = FastMCP("MedicalRecordExplorer")
DB_PATH = "patients.db"
@mcp.tool()
def search_patients(query: str) -> str:
"""Search for patients in the local SQLite database by name or ID."""
conn = sqlite3.connect(DB_PATH)
cursor = conn.cursor()
cursor.execute("SELECT id, name, dob FROM patients WHERE name LIKE ?", (f"%{query}%",))
results = cursor.fetchall()
conn.close()
return f"Found patients: {results}"
@mcp.tool()
def read_patient_record(file_path: str) -> str:
"""Read and extract text from a local PDF medical record."""
if not os.path.exists(file_path):
return "Error: File not found."
reader = PdfReader(file_path)
text = ""
for page in reader.pages:
text += page.extract_text()
return f"Content of {file_path}:\n\n{text[:2000]}..." # Returning first 2k chars for context
if __name__ == "__main__":
mcp.run()
Step 2: Creating the Local Index
For the Agent to know which files exist, we need a lightweight index. This keeps our Model Context Protocol server fast.
# simple_init_db.py
import sqlite3
def setup_db():
conn = sqlite3.connect("patients.db")
curr = conn.cursor()
curr.execute("CREATE TABLE IF NOT EXISTS patients (id INT, name TEXT, dob TEXT)")
curr.execute("INSERT INTO patients VALUES (1, 'John Doe', '1985-05-12')")
curr.execute("INSERT INTO patients VALUES (2, 'Jane Smith', '1992-08-24')")
conn.commit()
conn.close()
setup_db()
Step 3: Connecting to Claude Desktop
To make Claude aware of our new medical powers, we need to edit the claude_desktop_config.json file.
-
macOS:
~/Library/Application Support/Claude/claude_desktop_config.json -
Windows:
%APPDATA%\Claude\claude_desktop_config.json
Add your server configuration:
{
"mcpServers": {
"medical-assistant": {
"command": "python",
"args": ["/absolute/path/to/medical_mcp_server.py"]
}
}
}
Restart Claude Desktop, and you’ll see a 🔌 icon indicating the MCP Server is active!
The "Official" Way: Advanced Patterns
While this local setup is great for a POC, production-grade medical agents require robust HIPAA-compliant auditing, advanced vector search for RAG, and multi-agent orchestration.
For a deeper look into production-ready AI architectures and how to scale these protocols in a healthcare environment, I highly recommend checking out the technical deep dives at WellAlly Blog. They cover advanced topics like:
- Securing LLM tool-calling in regulated industries.
- Optimized PDF parsing for complex clinical tables.
- Building autonomous agents with LangGraph and MCP.
Step 4: Testing the Agent
Now, open Claude and try a natural language prompt:
"Hey Claude, search for a patient named John Doe and summarize his latest clinical note from the local PDF folder."
What happens behind the scenes?
- Claude recognizes the intent to "search."
-
Claude calls the
search_patientstool via MCP. - Claude receives the ID and file path.
-
Claude calls
read_patient_recordto pull the text. - Claude summarizes the findings for you locally.
This approach ensures your data stays on your machine, only providing the LLM with the specific text needed for the current turn of the conversation.
Conclusion: The Future is Modular
The Model Context Protocol is more than just a plugin system; it's a fundamental shift in how we build Medical AI Agents. By decoupling the data source from the reasoning engine, we gain privacy, flexibility, and speed.
Are you building with MCP? What local data sources are you connecting first? Let me know in the comments below! 👇
Happy coding!
Top comments (0)