[build-system] requires = ["hatchling"] build-backend = "hatchling.build" [project] name = "swiss-academic-libraries-mcp" version = "1.2.0" description = "MCP Server für Schweizer Wissenschaftsbibliotheken: swisscovery (SRU), e-rara/e-periodica/e-manuscripta (OAI-PMH) und Open-Access-Rechtsliteratur (sui generis, ex/ante, Repositorium.ch). Kein API-Key erforderlich." readme = "README.md" license = { file = "LICENSE" } requires-python = ">=3.11" keywords = [ "mcp", "switzerland", "libraries", "swisscovery", "slsp", "e-rara", "e-periodica", "e-manuscripta", "open-data", "open-access", "sru", "oai-pmh", "academic", "legal", "law", "sui-generis", "ex-ante", "repositorium", ] classifiers = [ "Development Status :: 4 - Beta", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", ] dependencies = [ # Upper bound added deliberately: `mcp` 2.0.0 removed `mcp.server.fastmcp` # outright (the API moved to `mcp.server.mcpserver`), so an unbounded # `>=1.28.1` breaks every fresh install — CI and `pip install` alike. # Migrating to the 2.x API is real work and a decision to take on purpose, # not one a resolver should make silently. "mcp[cli]>=2.0.0,<3", "httpx>=0.27.0", "pydantic>=2.0.0", "defusedxml>=0.7.1", ] [project.optional-dependencies] # Die einzige Stelle mit dem ruff-Pin im Python-Paket. Vorher stand er in # `[tool.hatch.envs.default]`, in der `uv pip install`-Zeile der CI und im # lint-Job — drei Stellen, von denen keine gemerkt haette, wenn eine abweicht. # `.pre-commit-config.yaml` traegt dieselbe Zahl noch einmal, weil pre-commit # pyproject.toml nicht lesen kann; `scripts/check_gate_consistency.py` haelt # die beiden zusammen und meldet einen zurueckgekehrten CI-Pin. dev = [ "pytest>=8.0.0", "pytest-asyncio>=0.23.0", "respx>=0.21.0", "ruff==0.16.7", ] [project.scripts] swiss-academic-libraries-mcp = "swiss_academic_libraries_mcp.server:main" [project.urls] Homepage = "https://github.com/malkreide/swiss-academic-libraries-mcp" Repository = "https://github.com/malkreide/swiss-academic-libraries-mcp" Issues = "https://github.com/malkreide/swiss-academic-libraries-mcp/issues" [tool.hatch.build.targets.wheel] packages = ["src/swiss_academic_libraries_mcp"] [tool.hatch.envs.default] # Zieht dieselben Abhaengigkeiten wie CI und lokal — inklusive des einen # ruff-Pins. Eine eigene Liste hier waere eine zweite Wahrheit. features = ["dev"] [tool.hatch.envs.default.scripts] test = "PYTHONPATH=src pytest tests/ -v" test-live = "PYTHONPATH=src pytest tests/ -v -m live" lint = "ruff check src/ tests/ scripts/" fmt = "ruff format src/ tests/ scripts/" [tool.pytest.ini_options] asyncio_mode = "auto" testpaths = ["tests"] markers = [ "live: marks tests as requiring live network access (deselect with '-m not live')", # Welche Quelle prueft dieser Live-Test? Jeder `live`-Test traegt genau eine # `quelle`-Marke, an der Funktion oder an ihrer Klasse. Bis zum 19.8.2026 riet # `scripts/check_gate_consistency.py` das aus Datei- und Testnamen; ein Test, # der falsch nach einer Quelle hiess, wurde still der falschen zugerechnet. # Zulaessige Werte stehen in GRUPPEN in jenem Skript und sind die Zeilen der # Quellen-Tabelle in `.github/workflows/live-tests.yml`. "quelle(name): welche Quelle ein Live-Test prueft (z. B. swisscovery, e-rara)", ] [tool.ruff] line-length = 110 target-version = "py311" [tool.ruff.lint] select = ["E", "F", "I", "N", "W", "UP"] ignore = ["E501"]