[build-system] requires = ["setuptools>=68"] build-backend = "setuptools.build_meta" [project] name = "keycloak-mcp" dynamic = ["version"] description = "MCP server for KeyCloak Admin REST API via Service Account" readme = "README.md" license = "MIT" requires-python = ">=3.10" authors = [ {name = "AIKAWA Shigechika"}, ] keywords = ["keycloak", "mcp", "model-context-protocol", "sso", "authentication"] classifiers = [ "Development Status :: 3 - Alpha", "Intended Audience :: System Administrators", "Operating System :: OS Independent", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Programming Language :: Python :: 3.14", "Topic :: System :: Systems Administration", ] dependencies = [ "mcp>=1.2,<2", "httpx", ] [project.scripts] keycloak-mcp = "keycloak_mcp.__main__:main" [project.urls] Homepage = "https://github.com/shigechika/keycloak-mcp" Repository = "https://github.com/shigechika/keycloak-mcp" Issues = "https://github.com/shigechika/keycloak-mcp/issues" [dependency-groups] dev = [ "pytest", "pytest-cov", # respx < 0.22.0 is incompatible with httpx 0.28.x: the mocked routes # (incl. the token endpoint in conftest) fail to match and every request # raises respx AllMockedAssertionError. 0.22.0 added httpx 0.28 support. "respx>=0.22.0", # Pinned, unlike the other dev tools here: uv.lock is not tracked in this # repository, so CI resolves ruff fresh on every run and a release that # widens a selected rule family or changes formatter output would turn the # lint gate red on a pull request that changed nothing. Dependabot bumps # this as a visible PR instead. "ruff==0.16.7", ] [tool.setuptools] packages = ["keycloak_mcp"] [tool.setuptools.dynamic] version = {attr = "keycloak_mcp.__version__"} [tool.ruff] target-version = "py310" line-length = 120 # The smoke-test engine is shared verbatim with other servers and is formatted # at a narrower width there. Reformatting it here would make every future sync # produce a spurious diff and invite the copies to drift apart, so it is # excluded from *formatting* only — `ruff check` does not consult this list, so # its lint rules still apply. format.exclude = ["scripts/smoke_harness.py"] [tool.ruff.lint] select = ["E", "F", "I", "W", "UP"] [tool.pytest.ini_options] testpaths = ["tests"]