M4
The M4 server enables AI assistants to query and analyze multimodal Electronic Health Record (EHR) datasets through natural language using the Model Context Protocol (MCP).
Dataset Management: List available clinical datasets (MIMIC-IV, MIMIC-IV-Note, eICU) with their status and backend configuration, switch between active datasets, and extend with custom PhysioNet datasets or institutional EHR schemas.
Tabular Data Analysis: Discover database schemas, inspect table structures with column details and sample data, and execute SQL SELECT queries on large clinical datasets containing hundreds of thousands of patients.
Clinical Notes Processing: Search notes by keyword with contextual snippets, retrieve full note text by ID (with optional truncation), list patient note metadata (IDs, types, lengths), filter by note type (discharge, radiology), and cross-reference with tabular data using shared patient identifiers.
Multi-Modal Support: Automatically adapts available tools based on the active dataset's modality (tabular vs. notes) and supports switching between datasets for complementary analyses.
Programmatic Access: Python API for complex, multi-step analyses that returns pandas DataFrames for statistical computations, visualization, and reproducible research notebooks.
Integration: Compatible with MCP clients (Claude Desktop, Cursor, LibreChat), supports both local (DuckDB) and cloud (BigQuery) backends, includes OAuth2 authentication for secure access, and provides contextual guidance through Claude Code skills.
Provides SQL query execution and schema exploration capabilities for clinical datasets stored in DuckDB, including MIMIC-IV and eICU tabular data with tools for database schema inspection, table information retrieval, and SELECT query execution.
Enables querying of large-scale clinical datasets hosted on Google Cloud BigQuery, supporting full MIMIC-IV and eICU datasets for cloud-based analysis of electronic health records.
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., "@M4show me the most common diagnoses in the mimic-iv dataset"
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.
M4: Infrastructure for AI-Assisted Clinical Research
M4 is infrastructure for AI-assisted clinical research. Initialize MIMIC-IV, eICU, or custom datasets as fast local databases (with optional BigQuery for cloud access). Your AI agents get specialized tools (MCP, Python API) and clinical knowledge (agent skills) to query and analyze them.
Usage example – M4 MCP | Usage example – Code Execution
M4 builds on the M3 project. Please cite their work when using M4!
Why M4?
Clinical research shouldn't require mastering database schemas. Whether you're screening a hypothesis, characterizing a cohort, or running a multi-step survival analysis—you should be able to describe what you want and get clinically meaningful results.
M4 makes this possible by giving AI agents deep clinical knowledge:
Understand clinical semantics. LLMs can write SQL, but have a harder time with (dataset-specific) clinical semantics. M4's comprehensive agent skills encode validated clinical concepts—so "find sepsis patients" produces clinically correct queries on any supported dataset.
Work across modalities. Clinical research with M4 spans structured data, clinical notes, and (soon) waveforms and imaging. M4 dynamically selects tools based on what each dataset contains—query labs in MIMIC-IV, search discharge summaries in MIMIC-IV-Note, all through the same interface.
Go beyond chat. Data exploration and simple research questions work great via MCP. But real research requires iteration: explore a cohort, compute statistics, visualize distributions, refine criteria. M4's Python API returns DataFrames that integrate with pandas, scipy, and matplotlib—turning your AI assistant into a research partner that can execute complete analysis workflows.
Cross-dataset research. You should be able to ask for multi-dataset queries or cross-dataset comparisons. M4 makes this easier than ever as the AI can switch between your initialized datasets on its own, allowing it to do cross-dataset tasks for you.
Interactive exploration. Some research tasks—like cohort definition—benefit from real-time visual feedback rather than iterative text queries. M4 Apps embed purpose-built UIs directly in your AI client, letting you drag sliders, toggle filters, and see instant results without leaving your workflow.
Related MCP server: OMOP MCP Server
Quickstart (3 steps)
1. Install uv
macOS/Linux:
curl -LsSf https://astral.sh/uv/install.sh | shWindows (PowerShell):
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"2. Initialize M4
mkdir my-research && cd my-research
uv init && uv add m4-infra
source .venv/bin/activate # Windows: .venv\Scripts\activate
m4 init mimic-iv-demoThis downloads the free MIMIC-IV demo dataset (~16MB) and sets up a local DuckDB database.
3. Connect your AI client
Claude Desktop:
m4 config claude --quickOther clients (Cursor, LibreChat, etc.):
m4 config --quickCopy the generated JSON into your client's MCP settings, restart, and start asking questions!
If you don't want to use uv, you can just run pip install m4-infra
If you want to use Docker, look at docs/DEVELOPMENT.md
Code Execution
For complex analysis that goes beyond simple queries, M4 provides a Python API that returns Python data types instead of formatted strings (e.g. pd.DataFrame for SQL queries). This transforms M4 from a query tool into a complete clinical data analysis environment.
from m4 import execute_query, get_schema
dataset = "mimic-iv"
# Get schema as a dict
schema = get_schema(dataset=dataset)
print(schema['tables']) # ['mimiciv_hosp.admissions', 'mimiciv_hosp.diagnoses_icd', ...]
# Query returns a pandas DataFrame
df = execute_query("""
SELECT icd_code, COUNT(*) as n
FROM mimiciv_hosp.diagnoses_icd
GROUP BY icd_code
ORDER BY n DESC
LIMIT 10
""", dataset=dataset)
# Use full pandas power: filter, join, compute statistics
df[df['n'] > 100].plot(kind='bar')The API uses the same tools as the MCP server, so behavior is consistent. But instead of parsing text, you get DataFrames you can immediately analyze, visualize, or feed into downstream pipelines.
When to use code execution:
Multi-step analyses where each query informs the next
Large result sets (thousands of rows) that shouldn't flood your context
Statistical computations, survival analysis, cohort characterization
Building reproducible analysis notebooks
See Code Execution Guide for the full API reference and this example session for a walkthrough.
Agent Skills
M4 ships with a set of skills that teach AI coding assistants clinical research patterns. Skills activate automatically when relevant—ask about "SOFA scores" or "sepsis cohorts" and Claude uses validated SQL from MIT-LCP repositories.
For the canonical list of bundled skills, see src/m4/skills/SKILLS_INDEX.md.
Clinical skills:
Severity Scores: SOFA, APACHE III, SAPS-II, OASIS, LODS, SIRS
Sepsis: Sepsis-3 cohort identification, suspected infection
Organ Failure: KDIGO AKI staging
Measurements: GCS calculation, baseline creatinine, vasopressor equivalents
Cohort Selection: First ICU stay identification
Research Methodology: Common research pitfalls and how to avoid them
System skills:
M4 Framework: Python API usage, research workflow, setup repair, vitrine display, skill creation guide
Data Structure: MIMIC-IV table relationships, MIMIC-eICU mapping
Supported tools: Claude Code, Cursor, Cline, Codex CLI, Gemini CLI, GitHub Copilot
m4 skills # Interactive tool and skill selection
m4 skills --tools claude,cursor # Install all skills for specific tools
m4 skills --tools claude --tier validated # Only validated skills
m4 skills --tools claude --category clinical # Only clinical skills
m4 skills --tools claude --skills sofa-score,m4-api # Specific skills by name
m4 skills --list # Show installed skills with metadataSee Skills Guide for the full list and how to create custom skills.
M4 Apps
M4 Apps bring interactivity to clinical research. Instead of text-only responses, apps render interactive UIs directly in your AI client—ideal for tasks that benefit from real-time visual feedback.
Cohort Builder: Define patient cohorts with live filtering. Adjust age ranges, add diagnosis codes, and toggle clinical criteria while watching counts update instantly.
User: Help me build a cohort of elderly diabetic patients
Claude: [Launches Cohort Builder UI with interactive filters]M4 Apps require a host that supports the MCP Apps protocol (like Claude Desktop). In other clients, you'll get text-based results instead.
See M4 Apps Guide for details on available apps and how they work.
Example Questions
Once connected, try asking:
Tabular data (mimic-iv, eicu):
"What tables are available in the database?"
"Show me the race distribution in hospital admissions"
"Find all ICU stays longer than 7 days"
"What are the most common lab tests?"
Derived concept tables (mimic-iv, after m4 init-derived):
"What are the average SOFA scores for patients with sepsis?"
"Show KDIGO AKI staging distribution across ICU stays"
"Find patients on norepinephrine with SOFA > 10"
"What is the 30-day mortality for patients with Charlson index > 5?"
Clinical notes (mimic-iv-note):
"Search for notes mentioning diabetes"
"List all notes for patient 10000032"
"Get the full discharge summary for this patient"
Supported Datasets
Dataset | Modality | Size | Access | Local | BigQuery | Derived Tables |
mimic-iv-demo | Tabular | 100 patients | Free | Yes | No | No |
mimic-iv | Tabular | 365k patients | Yes | Yes | Yes | |
mimic-iv-note | Notes | 331k notes | Yes | Yes | No | |
eicu | Tabular | 200k+ patients | Yes | Yes | No |
These datasets are supported out of the box. However, it is possible to add any other custom dataset by following these instructions.
Choose datasets explicitly at each call site and switch the saved backend anytime:
m4 backend bigquery # Switch to BigQuery (or duckdb)
m4 capabilities # Show available interfaces, datasets, tools, and policies
m4 doctor # Diagnose local, BigQuery, and MCP setup
m4 status --dataset mimic-iv # Show dataset and backend status
m4 status --all # List all available datasets
m4 status --dataset mimic-iv --derived # Show per-table derived materialization statusFor automation and external agents, M4 also provides non-interactive JSON commands that use request-scoped dataset and backend options:
m4 agent-env --dataset mimic-iv --backend duckdb --json
m4 capabilities --json
m4 doctor --json
m4 download mimic-iv --json
m4 list-datasets --json --no-interactive
m4 schema --dataset mimic-iv --backend duckdb --json --no-interactive
m4 describe-table mimiciv_hosp.patients --dataset mimic-iv --json --no-interactive
m4 query --dataset mimic-iv --sql "SELECT COUNT(*) AS n FROM mimiciv_hosp.patients" --json --no-interactive
m4 provenance export --jsonMachine-facing status and backend metadata hide local filesystem paths by
default. Use --paths or M4_PATH_DISCLOSURE=1 only when the caller is allowed
to see raw local paths.
Long-running dataset setup can emit newline-delimited JSON progress events:
m4 init mimic-iv --json --events ndjson --no-interactive --download \
--physionet-credentials-file /path/to/physionet-credentials.json
m4 init-derived mimic-iv --json --events ndjsonWhen --events ndjson is used, stdout is an NDJSON stream instead of a single
JSON object. The final result is emitted as operation_completed.result; setup
failures are emitted as operation_failed.error.
Derived concept tables (MIMIC-IV only):
m4 init-derived mimic-iv # Materialize derived tables (SOFA, sepsis3, KDIGO, etc.)
m4 init-derived mimic-iv --list # List available derived tables without materializingAfter running m4 init mimic-iv, you are prompted whether to materialize derived tables. You can also run m4 init-derived separately at any time. Derived tables are created in the mimiciv_derived schema (e.g., mimiciv_derived.sofa) and are immediately queryable. The SQL is vendored from the mimic-code repository -- production-tested and DuckDB-compatible. BigQuery users already have these tables available via physionet-data.mimiciv_derived and do not need to run init-derived.
Get PhysioNet credentials: Complete the credentialing process and sign the data use agreement for the dataset.
Download the data with M4:
cat > physionet-credentials.json <<'JSON' { "username": "YOUR_USERNAME", "password": "YOUR_PASSWORD" } JSON m4 init mimic-iv --download --physionet-credentials-file physionet-credentials.jsonDo not pass PhysioNet passwords as command-line flags. Use a scoped credentials file with restrictive permissions and delete it after setup.
M4 implements the same recursive, resumable pattern PhysioNet documents for
wget -r -N -c -npagainst/files/...dataset URLs, while preserving the expected raw layout underm4_data/raw_files/<dataset>/.You can still download manually if needed:
m4 download mimic-ivFor credentialed datasets,
m4 downloadvalidates the expected local layout and prints a dataset-specific resumablewgetcommand.# For MIMIC-IV wget -r -N -c -np --cut-dirs=3 -nH --user YOUR_USERNAME --ask-password \ https://physionet.org/files/mimiciv/3.1/ \ -P m4_data/raw_files/mimic-iv # For eICU wget -r -N -c -np --cut-dirs=3 -nH --user YOUR_USERNAME --ask-password \ https://physionet.org/files/eicu-crd/2.0/ \ -P m4_data/raw_files/eicuThe
--cut-dirs=3 -nHflags remove the PhysioNetfiles/<dataset>/<version>/prefix so CSV files land underm4_data/raw_files/<dataset>/with only dataset-internal folders preserved.Initialize after a manual download:
m4 init mimic-iv # or: m4 init eicu
This converts the CSV files to Parquet format and creates a local DuckDB database.
Available Tools
M4 exposes these tools to your AI client. Data tools are checked against the explicit dataset selected for that call.
Dataset Management:
Tool | Description |
| List available datasets and their status |
| Removed migration aid; pass |
Tabular Data Tools (mimic-iv, mimic-iv-demo, eicu):
Tool | Description |
| List all available tables |
| Get column details and sample data |
| Run SQL SELECT queries |
Clinical Notes Tools (mimic-iv-note):
Tool | Description |
| Full-text search with snippets |
| Retrieve a single note by ID |
| List notes for a patient (metadata only) |
More Documentation
Guide | Description |
Design philosophy, system overview, clinical semantics | |
Python API for programmatic access | |
Interactive UIs for clinical research tasks | |
Clinical and system skills for AI-assisted research | |
MCP tool documentation | |
Google Cloud for full datasets | |
Add your own PhysioNet datasets | |
Reviewer workflow for MIMIC-IV/eICU initialization and benchmark reruns | |
Contributing, testing, code style | |
Enterprise security setup |
Roadmap
M4 is infrastructure for AI-assisted clinical research. Current priorities:
Clinical Semantics
More concept mappings (comorbidity indices, medication classes)
Semantic search over clinical notes (beyond keyword matching)
More agent skills that provide meaningful clinical knowledge
New Modalities
Waveforms (ECG, arterial blood pressure)
Imaging (chest X-rays)
Clinical Research Agents
Skills and guardrails that enforce scientific integrity and best practices (documentation, etc.)
Query logging and session export
Result fingerprints for audit trails
Troubleshooting
"Parquet not found" error:
m4 init mimic-iv-demo --forceMCP client won't connect: Check client logs (Claude Desktop: Help → View Logs) and ensure the config JSON is valid.
m4 command opens GNU M4 instead of the CLI:
On macOS/Linux, m4 is a built-in system utility. Make sure your virtual environment is activated (source .venv/bin/activate) so that the correct m4 binary is found first. Alternatively, use uv run m4 [command] to run within the project environment without activating it.
Need to reconfigure:
m4 config claude --quick # Regenerate Claude Desktop config
m4 config --quick # Regenerate generic configCitation
M4 builds on the M3 project. Please cite:
@article{attrach2025conversational,
title={Conversational LLMs Simplify Secure Clinical Data Access, Understanding, and Analysis},
author={Attrach, Rafi Al and Moreira, Pedro and Fani, Rajna and Umeton, Renato and Celi, Leo Anthony},
journal={arXiv preprint arXiv:2507.01053},
year={2025}
}Available Tools
11 toolscapabilitiesA
Return the M4 capability manifest as JSON.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided; the description is the sole source. It does not disclose behavioral traits such as read-only nature, authentication requirements, or performance implications. Only states it returns JSON.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence that conveys the purpose efficiently without superfluous words. It is front-loaded and appropriate for the tool's simplicity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no parameters and the presence of an output schema (which likely details the manifest structure), the description is nearly complete. It does not explain what 'capability manifest' means, but the output schema may compensate.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
This tool has zero parameters, achieving the baseline score of 4. The description adds value by specifying the output is the capability manifest, but no further parameter information is needed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool returns the M4 capability manifest as JSON. It uses a specific verb ('Return') and resource ('capability manifest'). It distinguishes from sibling tools like query or note tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this tool versus others. The description does not mention prerequisites, typical use cases, or alternatives among siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cohort_builderA
Launch the interactive cohort builder.
Opens a visual interface for filtering patients by demographics and clinical criteria. See live patient counts as you adjust filters.
Requires: A host that supports MCP Apps (like Claude Desktop). For non-UI hosts, returns dataset information as text.
Returns: Dataset info and welcome message. UI hosts will render the interactive cohort builder interface.
| Name | Required | Description | Default |
|---|---|---|---|
| dataset | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries full burden. It explains the visual interface and text fallback but does not disclose whether the tool is read-only, destructive, or requires specific permissions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with clear sections, but could be more concise. It is front-loaded with the main purpose and includes necessary details without excessive verbosity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the interactive nature and lack of annotations, the description adequately covers behavior for different hosts and mentions return values. It is fairly complete for the tool's complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The single optional parameter 'dataset' has 0% schema description coverage and the description does not explain its purpose or expected values, leaving the agent uninformed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool launches an interactive cohort builder for filtering patients by demographics and clinical criteria. It distinguishes from siblings like query_cohort by emphasizing the visual interface.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly mentions requiring a host that supports MCP Apps (like Claude Desktop) and explains fallback behavior for non-UI hosts. It provides context on when to use the tool effectively.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
execute_queryA
🚀 Execute SQL queries to analyze data.
Recommended workflow:
Use get_database_schema() to list tables
Use get_table_info() to examine structure
Write your SQL query with exact names
Args: dataset: Dataset name, e.g. 'mimic-iv'. sql_query: Your SQL SELECT query (SELECT only).
Returns: Query results or helpful error messages.
| Name | Required | Description | Default |
|---|---|---|---|
| sql_query | Yes | ||
| dataset | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses essential behaviors: only SELECT queries are allowed, returns results or error messages. With no annotations, the description carries the burden; it does not cover rate limits or authorization but is sufficient for basic understanding.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Very concise, with a bulleted workflow and clear args list. Every sentence adds value; no redundancy. Front-loaded with emoji and purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Complete for the tool's purpose given sibling tools and output schema. Explains workflow with siblings and parameter semantics. Does not elaborate on dataset default behavior, but that is minor.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Despite 0% schema description coverage, the description provides examples for dataset and clarifies sql_query is a SELECT query. This adds meaning beyond the bare schema. Could be improved with SQL dialect details or constraints.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states it executes SQL queries for data analysis, and specifies SELECT-only. Differentiates from sibling tools like get_database_schema and get_table_info which are for schema exploration.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides a recommended workflow involving sibling tools, guiding the agent on correct usage sequence. Lacks explicit when-not-to-use statements but implies context through the workflow and SELECT-only constraint.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_database_schemaA
📚 Discover what data is available in the database.
When to use: Start here to understand what tables exist.
Args: dataset: Dataset name, e.g. 'mimic-iv'.
Returns: List of all available tables in the database with current backend info.
| Name | Required | Description | Default |
|---|---|---|---|
| dataset | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description bears full responsibility. It implies a read-only operation and lists return type, but it does not explicitly state that it has no side effects or mention error conditions. It is adequate but lacks explicit transparency about behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise, with a clear purpose statement, a usage hint, and structured Args/Returns sections. Every element serves a purpose with no wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity (single optional parameter and output schema available), the description covers its main function adequately. It could elaborate on 'backend info' but overall provides sufficient context for an agent to use it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 0% schema description coverage, the description adds value by naming the parameter 'dataset' and providing an example ('mimic-iv'), which clarifies its purpose beyond the type definition in the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it discovers available data and tables, which distinguishes it from sibling tools like get_table_info that focus on specific table details. The verb 'Discover' and resource 'database schema' are specific, but it lacks explicit differentiation from siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The 'When to use' section advises starting here to understand tables, providing clear context. However, it does not explicitly state when not to use or mention alternatives like get_table_info for deeper details.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_noteA
📄 Retrieve full text of a specific clinical note.
Warning: Clinical notes can be very long. Consider using search_notes() first to find relevant notes, or use max_length to truncate output.
Args: dataset: Dataset name, e.g. 'mimic-iv-note'. note_id: The note ID (e.g., from search_notes or list_patient_notes). max_length: Optional maximum characters to return (truncates if exceeded).
Returns: Full note text, or truncated version if max_length specified.
| Name | Required | Description | Default |
|---|---|---|---|
| note_id | Yes | ||
| max_length | No | ||
| dataset | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the burden. It discloses that notes can be very long and that max_length truncates output. However, it does not mention whether the operation is read-only (likely) or any other behavioral traits like rate limits or authentication needs. A 3 is appropriate as it covers the main behavior but lacks depth.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is structured with a warning, then args/returns sections. It is relatively concise but includes an emoji and some redundancy (e.g., 'consider using search_notes() first'). Every sentence adds value, but could be slightly streamlined.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given that an output schema exists (implied by 'Returns'), the description does not need to detail return values further. It covers the operation, parameters, and a helpful usage hint. The tool is simple, and the description is sufficient for an agent to use it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It explains each parameter: dataset as a dataset name like 'mimic-iv-note', note_id as from search_notes or list_patient_notes, and max_length as optional truncation. This adds significant meaning beyond the schema's property types.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description explicitly states it retrieves the full text of a specific clinical note, with a clear verb (Retrieve) and resource (clinical note). It distinguishes from sibling tools like search_notes and list_patient_notes by focusing on the retrieval of full text for a specific note ID.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides practical guidance: warns about long notes, suggests using search_notes first, and recommends using max_length to truncate. It does not explicitly state when not to use, but the guidance is clear and helpful.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_table_infoA
🔍 Explore a specific table's structure and see sample data.
When to use: After identifying relevant tables from get_database_schema().
Args: dataset: Dataset name, e.g. 'mimic-iv'. table_name: Exact table name (case-sensitive). show_sample: Whether to include sample rows (default: True).
Returns: Table structure with column names, types, and sample data.
| Name | Required | Description | Default |
|---|---|---|---|
| table_name | Yes | ||
| show_sample | No | ||
| dataset | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full burden. It explains the return value (table structure, column names, types, sample data) and implies read-only behavior. No side effects or constraints are mentioned, but it's adequate for this simple tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-organized with sections (purpose, when to use, args, returns). Each sentence serves a purpose, no fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity and the presence of an output schema, the description fully covers what an agent needs: purpose, parameters, and return format.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so description adds meaning: dataset example, table_name case-sensitive, show_sample default true. This compensates well for missing schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'Explore' and the resource 'a specific table's structure and see sample data', distinguishing it from siblings like get_database_schema (list tables) and execute_query (run SQL).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says 'When to use: After identifying relevant tables from get_database_schema()', providing clear context. It doesn't list alternatives but the usage guidance is direct and helpful.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_datasetsA
📋 List all available datasets and their status.
Returns: A formatted string listing available datasets, indicating selected status, and showing availability of local database and BigQuery support.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full burden but only describes the return format. It does not disclose side effects, permissions, or limitations (e.g., read-only nature, authentication requirements).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise at two sentences, front-loaded with the primary action, and includes detailed return information without unnecessary words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple list tool with no parameters and an output schema, the description is adequate but could be more complete by mentioning context like authentication or dataset selection implications.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has zero parameters and 100% coverage, so no parameter description is needed. The description adds no extra meaning but is consistent with the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'list' and the object 'all available datasets and their status,' making the tool's function unambiguous. It distinguishes itself from siblings like set_dataset and get_database_schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is provided on when to use this tool versus alternatives (e.g., set_dataset, get_database_schema). The description lacks any when-to-use or when-not-to-use instructions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_patient_notesA
📋 List available clinical notes for a patient.
Returns note metadata (IDs, types, lengths) without full text. Use get_note(note_id) to retrieve specific notes.
Cross-dataset tip: Get subject_id from MIMIC-IV queries, then use it here to find related clinical notes.
Args: dataset: Dataset name, e.g. 'mimic-iv-note'. subject_id: Patient identifier (same as in MIMIC-IV). note_type: Type of notes to list ('discharge', 'radiology', or 'all'). limit: Maximum notes to return (default: 20).
Returns: List of available notes with metadata for the patient.
| Name | Required | Description | Default |
|---|---|---|---|
| subject_id | Yes | ||
| note_type | No | all | |
| limit | No | ||
| dataset | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description carries full burden. States it returns metadata without full text, implying read-only operation. Lacks details on pagination, rate limits, or data freshness, but adequately characterizes the basic behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with emoji, bullet-like 'Args' section, and front-loaded main action. Every sentence adds value; no redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Complete for a listing tool: explains return (metadata list), cross-dataset integration, and parameters. Minor gaps: no error handling details or limits on dataset values, but output schema exists and tool is straightforward.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, but description fully compensates by explaining all four parameters with examples (note_type values), defaults (limit 20, dataset null), and cross-dataset tip for subject_id. Adds meaning far beyond the schema's type/required info.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clear verb+resource: 'List available clinical notes for a patient.' Distinguishes from siblings: explicitly contrasts with get_note (full text) and implies difference from search_notes. Includes cross-dataset tip for context.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
States when to use (to list notes before retrieving specific ones) and provides cross-dataset guidance. Does not explicitly exclude alternative tools like search_notes, but the purpose is clear enough to infer appropriate usage.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
query_cohortA
Query cohort counts based on filtering criteria.
Used by the cohort builder UI for live updates as users adjust filters. Can also be called directly to get cohort statistics.
Args: dataset: Dataset name, e.g. 'mimic-iv'. age_min: Minimum patient age (0-130, inclusive). age_max: Maximum patient age (0-130, inclusive). gender: Patient gender ('M' or 'F'). icd_codes: List of ICD diagnosis code prefixes to filter by. icd_match_all: If True, patient must have ALL ICD codes (AND); default is ANY (OR). has_icu_stay: If True, require ICU stay; if False, exclude ICU patients. in_hospital_mortality: If True, require in-hospital death; if False, exclude deaths.
Returns: JSON with patient_count, admission_count, demographics, and SQL.
| Name | Required | Description | Default |
|---|---|---|---|
| age_min | No | ||
| age_max | No | ||
| gender | No | ||
| icd_codes | No | ||
| icd_match_all | No | ||
| has_icu_stay | No | ||
| in_hospital_mortality | No | ||
| dataset | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It describes filtering logic (icd_match_all default), return fields, and the nature of the operation (query). It does not cover performance or side effects, but for a read-only query tool this is adequate.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Description is succinct with a clear intro, usage context, and well-structured Args/Returns sections. Every sentence adds value, no redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers purpose, parameters, and return structure comprehensively. Given the presence of an output schema, the description complements it well. Minor gap: no mention of prerequisites (e.g., need to select dataset first) but dataset is a parameter.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, but the description provides full details for all 8 parameters, including acceptable values (age range, gender, icd_codes list) and semantics (icd_match_all default). This adds significant value beyond the schema definition.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states the tool queries cohort counts with filtering criteria. It specifies two use cases (cohort builder UI and direct calls), distinguishing it from sibling tools like `cohort_builder` which likely handles building rather than querying.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly mentions usage in cohort builder UI and as a direct query tool, providing clear context. However, no exclusions or comparisons to siblings like `execute_query` or `get_table_info` are given, which could help agents decide when to use this specific tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_notesA
🔍 Search clinical notes by keyword.
Returns snippets around matches to prevent context overflow. Use get_note() to retrieve full text of specific notes.
Note types: 'discharge' (summaries), 'radiology' (reports), or 'all'
Args: dataset: Dataset name, e.g. 'mimic-iv-note'. query: Search term to find in notes. note_type: Type of notes to search ('discharge', 'radiology', or 'all'). limit: Maximum number of results per note type (default: 5). snippet_length: Characters of context around matches (default: 300).
Returns: Matching snippets with note IDs for follow-up retrieval.
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | ||
| note_type | No | all | |
| limit | No | ||
| snippet_length | No | ||
| dataset | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, but the description explains snippet return, context prevention, and note IDs for follow-up. It is read-only and non-destructive. Minor gaps: no mention of case sensitivity or exact matching.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Efficient use of bullet points and front-loaded purpose. Under 100 words, each sentence adds value. Could slightly reduce redundancy (e.g., 'around matches' already implied).
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given output schema exists, the description adequately covers search behavior, parameters, and return shape. Missing details like pagination or sorting, but sufficient for typical use.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, but the description's Args section explains each parameter with examples (e.g., 'mimic-iv-note'), defaults, and types. Adds significant meaning beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Search clinical notes by keyword' and specifies it returns snippets rather than full text, distinguishing it from siblings like get_note(). The purpose is specific and actionable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly advises using get_note() for full retrieval, preventing context overflow. Note types and snippet rationale guide appropriate usage. No ambiguity about when to invoke this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_datasetD
Deprecated: M4 no longer keeps a global active dataset.
| Name | Required | Description | Default |
|---|---|---|---|
| dataset_name | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided. The description only mentions deprecation but does not disclose what happens when the tool is invoked (e.g., returns error, does nothing). The output schema is present but not described.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence, which is concise. However, it lacks important details about behavior and parameters, making it incomplete rather than concise.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a deprecated tool with one parameter and an output schema, the description is insufficient. It does not clarify the tool's current behavior, return value, or parameter semantics, leaving the agent with critical gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%. The description does not explain the 'dataset_name' parameter, its format, or its significance, especially given the deprecated status.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states the tool is deprecated and M4 no longer keeps a global active dataset, implying the original purpose was to set a global dataset. However, it is vague about what the tool currently does (e.g., no-op, error).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description says 'Deprecated' indicating it should not be used, but it does not explicitly state when or when not to use it, nor does it suggest alternatives among sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
8 tool updates
v0.5.2- Changed
cohort_builder1 field changed- added
Input schema / properties / datasetAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null +}
- Changed
execute_query1 field changed- added
Input schema / properties / datasetAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null +}
- Changed
get_database_schema1 field changed- added
Input schema / properties / datasetAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null +}
- Changed
get_note1 field changed- added
Input schema / properties / datasetAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null +}
- Changed
get_table_info1 field changed- added
Input schema / properties / datasetAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null +}
- Changed
list_patient_notes1 field changed- added
Input schema / properties / datasetAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null +}
- Changed
query_cohort1 field changed- added
Input schema / properties / datasetAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null +}
- Changed
search_notes1 field changed- added
Input schema / properties / datasetAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null +}
1 tool update
v0.5.0- Added
capabilities
10 tool updates
v0.4.4- Added
cohort_builder - Added
execute_query - Added
get_database_schema - Added
get_note - Added
get_table_info - Added
list_datasets - Added
list_patient_notes - Added
query_cohort - Added
search_notes - Added
set_dataset
8 tool updates
v0.4.0- Removed
execute_query - Removed
get_database_schema - Removed
get_note - Removed
get_table_info - Removed
list_datasets - Removed
list_patient_notes - Removed
search_notes - Removed
set_dataset
8 tool updates
v1.0.0- First observed
execute_query - First observed
get_database_schema - First observed
get_note - First observed
get_table_info - First observed
list_datasets - First observed
list_patient_notes - First observed
search_notes - First observed
set_dataset
TDQS
Scored across 11 tools
Each tool has a clearly distinct purpose: database exploration (get_database_schema, get_table_info, execute_query), note handling (search_notes, list_patient_notes, get_note), cohort building (cohort_builder, query_cohort), and meta tasks (capabilities, list_datasets). The deprecated set_dataset is clearly marked, avoiding confusion.
Most tools follow a consistent verb_noun snake_case pattern (e.g., execute_query, get_note, list_datasets). However, 'capabilities' is a plain noun and 'cohort_builder' is noun_noun, breaking the pattern slightly.
11 tools is well-scoped for a medical data analysis server. Each tool covers a necessary operation without overlap or redundancy, and the count feels balanced for the domain.
The tool surface covers core workflows: database discovery, SQL querying, note retrieval and search, and cohort filtering. A minor gap is the lack of a direct patient demographics tool, but SQL queries can retrieve that information.
Maintenance
Related MCP Connectors
Ask data questions in natural language. Get SQL, insights, and charts from your databases.
Medical RAG: semantic search for clinical guidelines, drug interactions, diagnoses & EHR data.
Medical RAG: semantic search for clinical guidelines, drug interactions, diagnoses & EHR data.
Semantic search across 5 US government healthcare databases.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceEnables querying MIMIC-IV medical data using natural language through MCP clients, with support for local DuckDB and cloud BigQuery backends.77MIT
- AlicenseNot gradedqualityDmaintenanceEnables natural language exploration of OMOP CDM databases for concept discovery, patient count queries, and cohort SQL generation with support for multiple database backends.1MIT
- FlicenseNot gradedqualityBmaintenanceEnables natural language querying of healthcare claims data by exposing a SQLite database with read-only SQL tools, allowing users to ask questions in plain English and get answers backed by real database queries.-
- AlicenseNot gradedqualityBmaintenanceEnables natural-language querying of a mock legacy healthcare database and returns validated FHIR resources (Patient, Observation, Condition).MIT