[build-system] requires = ["hatchling"] build-backend = "hatchling.build" [project] name = "swiss-snb-mcp" version = "0.4.5" description = "MCP server for Swiss National Bank (SNB) data portal — exchange rates, balance sheet, and monetary statistics" readme = "README.md" license = { text = "MIT" } requires-python = ">=3.11" dependencies = [ "mcp[cli]>=2.0.0,<3", "httpx>=0.27.0", "pydantic>=2.0.0", ] [project.urls] Homepage = "https://github.com/malkreide/swiss-snb-mcp" Repository = "https://github.com/malkreide/swiss-snb-mcp" Changelog = "https://github.com/malkreide/swiss-snb-mcp/blob/main/CHANGELOG.md" [project.optional-dependencies] dev = [ "pytest>=8.0", "pytest-asyncio>=0.23", "respx>=0.21", # Exakt gepinnt, nicht `>=`: ruff ist ein Gate, kein Hilfsmittel. Eine # neuere Version meldet Abweichungen an Code, den niemand angefasst hat. # # Die Version steht an ZWEI Stellen: hier und als `rev:` in # .pre-commit-config.yaml. Die CI hat keinen eigenen Pin-Schritt mehr, sie # installiert ueber das `dev`-Extra mit. Beide Stellen im selben Commit # bumpen — `scripts/check_ruff_pin.py` wird rot, wenn eine zurueckbleibt. # # Beim Anheben: beide Versionen aendern, `ruff format` einmal ueber die # gelinteten Pfade laufen lassen und das Ergebnis mit committen. "ruff==0.16.4", # Fährt die Hooks aus .pre-commit-config.yaml, die den lint-Job der CI # spiegeln. Ruff selbst zieht pre-commit dabei in der dort gepinnten # Version — die Zeile darüber gilt nur für ein manuelles `ruff …`. "pre-commit>=3.5", ] [project.scripts] swiss-snb-mcp = "swiss_snb_mcp.server:main" [tool.hatch.build.targets.wheel] packages = ["src/swiss_snb_mcp"] [tool.hatch.build] sources = ["src"] [tool.pytest.ini_options] asyncio_mode = "auto" testpaths = ["tests"] markers = [ "live: hits data.snb.ch — slow, brittle, runs only with `pytest -m live`", ] [tool.ruff] # Target the interpreter versions the project supports. target-version = "py311" [tool.ruff.lint] # Explicit rule set so a `ruff` upgrade in CI can't silently change what is # enforced. A config `select` fully replaces ruff's built-in defaults, so the # enforced set is exactly what is listed here regardless of the ruff version: # E4/E7/E9 — pycodestyle errors (line length E501 is left to the formatter) # F — Pyflakes # I — import sorting (isort) # UP — pyupgrade (modern syntax, e.g. `X | None`, collections.abc) # B — flake8-bugbear # C4 — flake8-comprehensions # SIM — flake8-simplify # RUF — ruff-specific rules select = ["E4", "E7", "E9", "F", "I", "UP", "B", "C4", "SIM", "RUF"] # The user-facing strings are German and use intentional typography — em/en # dashes (—, –), arrows (→) and the like. The ambiguous-unicode rules would # flag those as look-alikes, so they are disabled for this codebase. ignore = ["RUF001", "RUF002", "RUF003"]