8
8
from ..types import Record
9
9
from ..models .oauth import AuthorizationServerMetadata
10
10
from ..models .auth_server import AuthServerConfig , AuthServerType
11
- from ..exceptions import MCPAuthConfigException
11
+ from ..exceptions import (
12
+ AuthServerExceptionCode ,
13
+ MCPAuthAuthServerException ,
14
+ MCPAuthConfigException ,
15
+ )
12
16
13
17
14
18
class ServerMetadataPaths (str , Enum ):
@@ -22,6 +26,11 @@ class ServerMetadataPaths(str, Enum):
22
26
23
27
24
28
def smart_join (* args : str ) -> str :
29
+ """
30
+ Joins multiple path components into a single path string, regardless of leading or trailing
31
+ slashes.
32
+ """
33
+
25
34
return Path ("/" .join (arg .strip ("/" ) for arg in args )).as_posix ()
26
35
27
36
@@ -42,6 +51,23 @@ async def fetch_server_config_by_well_known_url(
42
51
type : AuthServerType ,
43
52
transpile_data : Optional [Callable [[Record ], Record ]] = None ,
44
53
) -> AuthServerConfig :
54
+ """
55
+ Fetches the server configuration from the provided well-known URL and validates it against the
56
+ MCP specification.
57
+
58
+ If the server metadata does not conform to the expected schema, but you are sure that it is
59
+ compatible, you can provide a `transpile_data` function to transform the metadata into the
60
+ expected format.
61
+
62
+ :param well_known_url: The well-known URL to fetch the server configuration from.
63
+ :param type: The type of the authorization server (OAuth or OIDC).
64
+ :param transpile_data: Optional function to transform the fetched data into the expected
65
+ format.
66
+ :return AuthServerConfig: An instance of `AuthServerConfig` containing the server metadata.
67
+ :raises MCPAuthConfigException: If there is an error fetching the server metadata.
68
+ :raises MCPAuthAuthServerException: If the server metadata is invalid or malformed.
69
+ """
70
+
45
71
try :
46
72
async with aiohttp .ClientSession () as session :
47
73
async with session .get (well_known_url ) as response :
@@ -52,9 +78,8 @@ async def fetch_server_config_by_well_known_url(
52
78
metadata = AuthorizationServerMetadata (** transpiled_data ), type = type
53
79
)
54
80
except pydantic .ValidationError as e :
55
- raise MCPAuthConfigException (
56
- "invalid_server_metadata" ,
57
- f"Invalid server metadata from { well_known_url } : { str (e )} " ,
81
+ raise MCPAuthAuthServerException (
82
+ AuthServerExceptionCode .INVALID_SERVER_METADATA ,
58
83
cause = e ,
59
84
) from e
60
85
except Exception as e :
@@ -70,6 +95,47 @@ async def fetch_server_config(
70
95
type : AuthServerType ,
71
96
transpile_data : Optional [Callable [[Record ], Record ]] = None ,
72
97
) -> AuthServerConfig :
98
+ """
99
+ Fetches the server configuration according to the issuer and authorization server type.
100
+
101
+ This function automatically determines the well-known URL based on the server type, as OAuth
102
+ and OpenID Connect servers have different conventions for their metadata endpoints.
103
+
104
+ See Also:
105
+ - `fetchServerConfigByWellKnownUrl` for the underlying implementation.
106
+ - https://www.rfc-editor.org/rfc/rfc8414 for the OAuth 2.0 Authorization Server Metadata
107
+ specification.
108
+ - https://openid.net/specs/openid-connect-discovery-1_0.html for the OpenID Connect Discovery
109
+ specification.
110
+
111
+ Example:
112
+ ```python
113
+ from mcpauth.utils import fetch_server_config, AuthServerType
114
+
115
+ # Fetch OAuth server config. This will fetch the metadata from
116
+ # `https://auth.logto.io/.well-known/oauth-authorization-server/oauth`
117
+ oauth_config = await fetch_server_config(
118
+ issuer="https://auth.logto.io/oauth",
119
+ type=AuthServerType.OAUTH
120
+ )
121
+
122
+ # Fetch OIDC server config. This will fetch the metadata from
123
+ # `https://auth.logto.io/oidc/.well-known/openid-configuration`
124
+ oidc_config = await fetch_server_config(
125
+ issuer="https://auth.logto.io/oidc",
126
+ type=AuthServerType.OIDC
127
+ )
128
+ ```
129
+
130
+ :param issuer: The issuer URL of the authorization server.
131
+ :param type: The type of the authorization server (OAuth or OIDC).
132
+ :param transpile_data: Optional function to transform the fetched data into the expected
133
+ format.
134
+ :return AuthServerConfig: An instance of `AuthServerConfig` containing the server metadata.
135
+ :raises MCPAuthConfigException: If there is an error fetching the server metadata.
136
+ :raises MCPAuthAuthServerException: If the server metadata is invalid or malformed.
137
+ """
138
+
73
139
well_known_url = (
74
140
get_oauth_well_known_url (issuer )
75
141
if type == AuthServerType .OAUTH
0 commit comments