|
| 1 | +# pyright: reportPrivateUsage=false, reportUnknownParameterType=false |
| 2 | +"""Convenience helper for spinning up a FastMCP Transparent OAuth proxy server.""" |
| 3 | + |
| 4 | +from __future__ import annotations |
| 5 | + |
| 6 | +from typing import TYPE_CHECKING, Literal |
| 7 | + |
| 8 | +from pydantic import AnyHttpUrl |
| 9 | + |
| 10 | +from mcp.server.auth.settings import AuthSettings, ClientRegistrationOptions |
| 11 | +from mcp.server.fastmcp import FastMCP |
| 12 | +from mcp.server.fastmcp.utilities.logging import configure_logging |
| 13 | + |
| 14 | +from ..providers.transparent_proxy import TransparentOAuthProxyProvider |
| 15 | + |
| 16 | +if TYPE_CHECKING: # pragma: no cover – typing-only imports |
| 17 | + from mcp.server.auth.providers.transparent_proxy import _Settings as ProxySettings |
| 18 | + |
| 19 | +__all__ = ["build_proxy_server"] |
| 20 | + |
| 21 | + |
| 22 | +# --------------------------------------------------------------------------- |
| 23 | +# Public API |
| 24 | +# --------------------------------------------------------------------------- |
| 25 | + |
| 26 | + |
| 27 | +def build_proxy_server( # noqa: D401,E501 |
| 28 | + *, |
| 29 | + host: str = "0.0.0.0", |
| 30 | + port: int = 8000, |
| 31 | + issuer_url: str | None = None, |
| 32 | + log_level: Literal["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"] = "DEBUG", |
| 33 | + settings: ProxySettings | None = None, |
| 34 | +) -> FastMCP: |
| 35 | + """Return a fully-configured FastMCP instance running the proxy. |
| 36 | +
|
| 37 | + Prefer passing a fully-validated *settings* object (instance of |
| 38 | + :class:`mcp.server.auth.providers.transparent_proxy._Settings`) which makes |
| 39 | + configuration explicit and type-checked. |
| 40 | + """ |
| 41 | + |
| 42 | + # Runtime import to avoid circular dependency at module import time. |
| 43 | + from ..providers.transparent_proxy import _Settings as ProxySettings |
| 44 | + |
| 45 | + if settings is None: |
| 46 | + settings = ProxySettings.load() |
| 47 | + |
| 48 | + configure_logging(level=log_level) # type: ignore[arg-type] |
| 49 | + |
| 50 | + provider = TransparentOAuthProxyProvider(settings=settings) # type: ignore[arg-type] |
| 51 | + |
| 52 | + mcp = FastMCP( |
| 53 | + name="Transparent OAuth Proxy", |
| 54 | + host=host, |
| 55 | + port=port, |
| 56 | + auth_server_provider=provider, |
| 57 | + auth=AuthSettings( |
| 58 | + issuer_url=AnyHttpUrl(issuer_url or f"http://localhost:{port}"), # type: ignore[arg-type] |
| 59 | + resource_server_url=AnyHttpUrl(f"http://localhost:{port}"), # type: ignore[arg-type] |
| 60 | + required_scopes=["openid"], |
| 61 | + client_registration_options=ClientRegistrationOptions(enabled=True), |
| 62 | + ), |
| 63 | + ) |
| 64 | + |
| 65 | + return mcp |
0 commit comments