[project] name = "sql-safe-mcp" version = "1.2.0" description = "Minimal, read-only, PII-safe MCP server for SQL databases." readme = "README.md" requires-python = ">=3.12,<3.15" license = { file = "LICENSE" } dependencies = [ "anyio>=4.8,<5", "cryptography>=46.0.7,<47", "mcp>=2,<3", "pydantic>=2.10,<3", "pymysql>=1.2.3", "pyodbc>=5.2,<6", "pyyaml>=6,<7", "sqlalchemy>=2.0,<3", "sqlglot>=30.18,<31", ] [project.scripts] sql-safe-mcp = "sql_safe_mcp.__main__:main" [dependency-groups] dev = [ "hypothesis>=6.168,<7", "mutmut>=3.8,<4 ; sys_platform != 'win32'", "prek>=0.2", "pytest>=8.3,<10", "pytest-cov>=6,<8", "ruff>=0.11", "ty>=0.0.1a20", ] [build-system] requires = ["hatchling"] build-backend = "hatchling.build" [tool.hatch.build.targets.wheel] packages = ["src/sql_safe_mcp"] [tool.hatch.build.targets.sdist] include = [ "/CHANGELOG.md", "/LICENSE", "/README.md", "/pyproject.toml", "/server.json", "/sql-safe-mcp.example.yaml", "/src", ] [tool.pytest.ini_options] addopts = "-ra --strict-markers" testpaths = ["tests"] pythonpath = ["tests/security", "tests/integration/sqlserver", "tests/integration/mysql"] markers = [ "integration: requires a live database", "deep: expensive security verification", ] [tool.mutmut] source_paths = ["src/sql_safe_mcp"] also_copy = ["server.json", "README.md"] only_mutate = ["*security/*.py", "*config.py"] mutate_only_covered_lines = true pytest_add_cli_args = ["-q", "-m", "not integration and not deep", "-p", "no:cacheprovider"] pytest_add_cli_args_test_selection = ["tests/unit", "tests/security", "tests/contract"] timeout_multiplier = 3.0 timeout_constant = 5.0 [tool.coverage.run] branch = true source = ["sql_safe_mcp"] [tool.ruff] line-length = 100 target-version = "py312" [tool.ruff.lint] select = ["E", "F", "I", "B", "UP", "SIM", "RUF"] [tool.ruff.format] quote-style = "double" [tool.ty.src] include = ["src", "tests"] [tool.ty.environment] extra-paths = ["tests/security", "tests/integration/sqlserver", "tests/integration/mysql"]