[build-system] requires = ["hatchling"] build-backend = "hatchling.build" [project] name = "swiss-courts-mcp" version = "0.5.0" description = "MCP Server for Swiss court decisions — Federal Supreme Court, Federal Administrative Court, Federal Criminal Court + 26 cantonal courts via entscheidsuche.ch" readme = "README.md" license = { file = "LICENSE" } requires-python = ">=3.11" authors = [{ name = "Hayal Oezkan" }] keywords = [ "mcp", "model-context-protocol", "swiss-open-data", "court-decisions", "entscheidsuche", "bundesgericht", "swiss-law", "rechtsprechung", "jurisprudence", "claude", "llm", ] classifiers = [ "Development Status :: 4 - Beta", "Intended Audience :: Developers", "Intended Audience :: Legal Industry", "Intended Audience :: Science/Research", "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Topic :: Scientific/Engineering :: Artificial Intelligence", "Topic :: Text Processing :: General", ] dependencies = [ # Jetzt auf der 2.x-API (`mcp.server.mcpserver`). Die Untergrenze ist hart: # 2.0.0 hat `mcp.server.fastmcp` ohne Kompatibilitaetsschicht entfernt, # dieser Code laeuft also gar nicht mehr auf 1.x — ein `>=1.x`-Bereich # wuerde einen Resolver eine Version waehlen lassen, die beim Import # scheitert. Der `<3`-Deckel bleibt: ein Major-Sprung ist eine bewusste # Entscheidung. Updates via Dependabot. # Der Pin bestimmt weiterhin die Protokoll-Revision (ARCH-012), aber 2.x # bedient zwei Aeren, und der Server benennt beide: der # Legacy-`initialize`-Handshake deckelt bei 2025-11-25 # (== HANDSHAKE_PROTOCOL_VERSION), die moderne Envelope-Aera erreicht # 2026-07-28 (== MODERN_PROTOCOL_VERSION). Beide Pins haben einen # Drift-Guard in `tests/test_protocol.py`; was die Modern-Aera am Draht # tut, misst `tests/test_modern_era.py` nach. "mcp[cli]>=2.0.0,<3", "httpx>=0.28.1", "pydantic>=2.13.4", "structlog>=25.5.0,<27", # Cross-plattform Cache-Verzeichnis für den Offline-Dump-Fallback (Phase 3). "platformdirs>=4.0.0", ] [project.optional-dependencies] # HTTP-/Cloud-Transport mit Bearer-Token-Auth (SEC-009). http = [ "pyjwt[crypto]>=2.13.0", "uvicorn>=0.48.0", ] dev = [ "pytest>=9.0.3", "pytest-asyncio>=1.4.0", "pytest-cov>=7.1.0", "respx>=0.23.1", # Harter Pin, kein Bereich: ruff ist ein Gate, kein Hilfsmittel. Ein # Upstream-Release aendert den Default-Regelsatz oder den Formatter und # meldet dann Abweichungen an Code, den niemand angefasst hat. Der Pin # steht NUR hier — die CI installiert ruff ueber genau diese Extra, damit # lokal und in der CI dieselbe Version laeuft. Zwei Pins, die # uebereinstimmen muessen, sind eine Drift-Quelle und keine Absicherung. # Updates via Dependabot. "ruff==0.16.5", "pyjwt[crypto]>=2.13.0", ] [project.scripts] swiss-courts-mcp = "swiss_courts_mcp.server:mcp.run" [project.urls] Homepage = "https://github.com/malkreide/swiss-courts-mcp" Repository = "https://github.com/malkreide/swiss-courts-mcp" Issues = "https://github.com/malkreide/swiss-courts-mcp/issues" "Data Source" = "https://entscheidsuche.ch" [tool.hatch.build.targets.wheel] packages = ["src/swiss_courts_mcp"] [tool.pytest.ini_options] asyncio_mode = "auto" testpaths = ["tests"] addopts = "-v --tb=short" markers = [ "live: live API tests (skipped in CI by default)", ] [tool.ruff] line-length = 100 target-version = "py311" [tool.ruff.lint] select = ["E", "F", "W", "I", "UP"] ignore = ["E501"]