fastmcp 2.13.0rc1__py3-none-any.whl → 2.13.0rc3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,96 @@
1
+ """Enhanced authentication middleware with better error messages.
2
+
3
+ This module provides enhanced versions of MCP SDK authentication middleware
4
+ that return more helpful error messages for developers troubleshooting
5
+ authentication issues.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ import json
11
+
12
+ from mcp.server.auth.middleware.bearer_auth import (
13
+ RequireAuthMiddleware as SDKRequireAuthMiddleware,
14
+ )
15
+ from starlette.types import Send
16
+
17
+ from fastmcp.utilities.logging import get_logger
18
+
19
+ logger = get_logger(__name__)
20
+
21
+
22
+ class RequireAuthMiddleware(SDKRequireAuthMiddleware):
23
+ """Enhanced authentication middleware with detailed error messages.
24
+
25
+ Extends the SDK's RequireAuthMiddleware to provide more actionable
26
+ error messages when authentication fails. This helps developers
27
+ understand what went wrong and how to fix it.
28
+ """
29
+
30
+ async def _send_auth_error(
31
+ self, send: Send, status_code: int, error: str, description: str
32
+ ) -> None:
33
+ """Send an authentication error response with enhanced error messages.
34
+
35
+ Overrides the SDK's _send_auth_error to provide more detailed
36
+ error descriptions that help developers troubleshoot authentication
37
+ issues.
38
+
39
+ Args:
40
+ send: ASGI send callable
41
+ status_code: HTTP status code (401 or 403)
42
+ error: OAuth error code
43
+ description: Base error description
44
+ """
45
+ # Enhance error descriptions based on error type
46
+ enhanced_description = description
47
+
48
+ if error == "invalid_token" and status_code == 401:
49
+ # This is the "Authentication required" error
50
+ enhanced_description = (
51
+ "Authentication failed. The provided bearer token is invalid, expired, or no longer recognized by the server. "
52
+ "To resolve: clear authentication tokens in your MCP client and reconnect. "
53
+ "Your client should automatically re-register and obtain new tokens."
54
+ )
55
+ elif error == "insufficient_scope":
56
+ # Scope error - already has good detail from SDK
57
+ pass
58
+
59
+ # Build WWW-Authenticate header value
60
+ www_auth_parts = [
61
+ f'error="{error}"',
62
+ f'error_description="{enhanced_description}"',
63
+ ]
64
+ if self.resource_metadata_url:
65
+ www_auth_parts.append(f'resource_metadata="{self.resource_metadata_url}"')
66
+
67
+ www_authenticate = f"Bearer {', '.join(www_auth_parts)}"
68
+
69
+ # Send response
70
+ body = {"error": error, "error_description": enhanced_description}
71
+ body_bytes = json.dumps(body).encode()
72
+
73
+ await send(
74
+ {
75
+ "type": "http.response.start",
76
+ "status": status_code,
77
+ "headers": [
78
+ (b"content-type", b"application/json"),
79
+ (b"content-length", str(len(body_bytes)).encode()),
80
+ (b"www-authenticate", www_authenticate.encode()),
81
+ ],
82
+ }
83
+ )
84
+
85
+ await send(
86
+ {
87
+ "type": "http.response.body",
88
+ "body": body_bytes,
89
+ }
90
+ )
91
+
92
+ logger.info(
93
+ "Auth error returned: %s (status=%d)",
94
+ error,
95
+ status_code,
96
+ )