[build-system]
requires = ["pdm-backend"]
build-backend = "pdm.backend"
[project]
name = "m4-mcp"
dynamic = ["version"]
description = "MIMIC-IV + MCP + Models: Local MIMIC-IV querying with LLMs via Model Context Protocol"
requires-python = ">=3.10"
authors = [
{ name = "Rafi Al Attrach", email = "rafiaa@mit.edu" },
{ name = "Pedro Moreira", email = "pedrojfm@mit.edu" },
{ name = "Rajna Fani", email = "rajnaf@mit.edu" },
]
maintainers = [
{ name = "Rafi Al Attrach", email = "rafiaa@mit.edu" },
{ name = "Pedro Moreira", email = "pedrojfm@mit.edu" },
{ name = "Rajna Fani", email = "rajnaf@mit.edu" },
]
readme = "README.md"
license = "MIT"
keywords = ["mimic-iv", "clinical-data", "mcp", "llm", "medical", "healthcare", "duckdb", "bigquery"]
classifiers = [
"Development Status :: 4 - Beta",
"Intended Audience :: Science/Research",
"Intended Audience :: Healthcare Industry",
"Topic :: Scientific/Engineering :: Medical Science Apps.",
"Topic :: Database :: Database Engines/Servers",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Operating System :: OS Independent",
]
dependencies = [
"typer>=0.9.0", # Typer as a core dependency for the CLI
"rich>=13.0.0", # For Typer's rich output
"requests>=2.30.0",
"beautifulsoup4>=4.12.0",
"polars[pyarrow]>=0.20.10",
"appdirs>=1.4.0",
"sqlalchemy>=2.0.0",
"pandas>=2.0.0",
"fastmcp>=0.1.0", # MCP server functionality
"google-cloud-bigquery>=3.0.0", # BigQuery support
"db-dtypes>=1.0.0", # BigQuery data types
"sqlparse>=0.4.0", # SQL parsing for security validation
"pyjwt[crypto]>=2.8.0", # JWT token handling with cryptography support
"cryptography>=41.0.0", # Cryptographic operations for JWT
"python-jose[cryptography]>=3.3.0", # Additional JWT support with crypto
"httpx>=0.24.0", # Modern HTTP client for OAuth2 token validation
"duckdb>=1.4.1",
]
[dependency-groups]
dev = [
"ruff>=0.4.0",
"pre-commit>=3.0.0",
"pytest>=8.0.0",
"pytest-asyncio>=0.24.0",
"pytest-mock>=3.10.0",
"aiohttp>=3.8.0", # For MCP client testing
]
[project.scripts]
m4 = "m4.cli:app"
m4-mcp = "m4.mcp_server:main" # Primary entry point for simplicity (enables `uvx m4-mcp`)
m4-mcp-server = "m4.mcp_server:main" # Kept for backwards compatibility
[project.urls]
Homepage = "https://github.com/rafiattrach/m4"
Repository = "https://github.com/rafiattrach/m4"
Documentation = "https://github.com/rafiattrach/m4#readme"
Issues = "https://github.com/rafiattrach/m4/issues"
Changelog = "https://github.com/rafiattrach/m4/releases"
[tool.pdm.version]
source = "file"
path = "src/m4/__init__.py"
[tool.ruff]
line-length = 88
target-version = "py310"
src = ["src"]
[tool.ruff.lint]
select = [
"E", # pycodestyle errors
"W", # pycodestyle warnings
"F", # Pyflakes
"I", # isort (import sorting)
"UP", # pyupgrade (modernize syntax)
"RUF",# Ruff-specific rules
]
ignore = [
"E501", # Line too long (let ruff-format handle line length)
]
[tool.ruff.format]
# Ruff's default formatter will be used.
[tool.ruff.lint.isort]
known-first-party = ["m4"]
[tool.pytest.ini_options]
asyncio_mode = "auto"
asyncio_default_fixture_loop_scope = "function"
# Filter out Jupyter deprecation warning
filterwarnings = [
"ignore::DeprecationWarning:jupyter_client.*",
]