Remove automatic environment variable loading from auth providers#2752
Remove automatic environment variable loading from auth providers#2752
Conversation
|
Warning Rate limit exceeded@jlowin has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 15 minutes and 56 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📒 Files selected for processing (1)
WalkthroughThis PR removes automatic environment-variable loading from all auth providers and replaces pydantic BaseSettings-based ProviderSettings with explicit constructor parameters. It updates provider init signatures to require concrete values (removing NotSet sentinels), removes Settings classes and server_auth wiring from global Settings, changes FastMCP.init to default auth to None (no env-based auto-creation), and updates docs to show explicit os.environ reads and passing provider instances into FastMCP. Possibly related PRs
Pre-merge checks and finishing touches✅ Passed checks (5 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 6
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (8)
docs/integrations/aws-cognito.mdx (1)
261-277: Remove contradictory dead code from previous version.This code block demonstrates the old automatic environment variable loading pattern that this PR specifically removes. Line 265's comment "Authentication is automatically configured from environment" describes the previous behavior where
FastMCPcould auto-load credentials without an explicit auth provider.This contradicts the new explicit pattern shown in lines 241-260 and will confuse users about the correct approach. This entire code block should have been removed as part of the PR changes.
🔎 Proposed fix
Remove this entire code block:
-```python server.py -from fastmcp import FastMCP -from fastmcp.server.dependencies import get_access_token - -# Authentication is automatically configured from environment -mcp = FastMCP(name="AWS Cognito Secured App") - -@mcp.tool -async def get_access_token_claims() -> dict: - """Get the authenticated user's access token claims.""" - token = get_access_token() - return { - "sub": token.claims.get("sub"), - "username": token.claims.get("username"), - "cognito:groups": token.claims.get("cognito:groups", []), - } -```docs/integrations/oci.mdx (1)
251-285: Duplicate "Production Configuration" section with conflicting content.There's already a "Production Configuration" section starting at line 203. This duplicate section at line 251 contains:
- A duplicate header
- A code block that isn't properly closed before the next one starts (line 269 vs 270)
- Contradictory content—the second code block (lines 270-285) includes
mcp = FastMCP(name="OCI Secured App")with the comment "Authentication is automatically configured from environment", which contradicts the PR's objective of removing automatic env var loadingThis appears to be leftover content that should be removed.
🔎 Suggested fix: Remove the duplicate section
-## Production Configuration - -For production deployments, load sensitive credentials from environment variables: - -```python server.py -import os -from fastmcp import FastMCP -from fastmcp.server.auth.providers.oci import OCIProvider - -# Load secrets from environment variables -auth = OCIProvider( - config_url=os.environ.get("OCI_CONFIG_URL"), - client_id=os.environ.get("OCI_CLIENT_ID"), - client_secret=os.environ.get("OCI_CLIENT_SECRET"), - base_url=os.environ.get("BASE_URL", "https://your-server.com") -) - -mcp = FastMCP(name="OCI Secured App", auth=auth) - -```python server.py -from fastmcp import FastMCP -from fastmcp.server.dependencies import get_access_token - -# Authentication is automatically configured from environment -mcp = FastMCP(name="OCI Secured App") - -@mcp.tool -def whoami() -> str: - """The whoami function is to test MCP server without requiring token exchange. - This tool can be used to test successful authentication against OCI IAM. - It will return logged in user's subject (username from IAM domain).""" - token = get_access_token() - user = token.claims.get("sub") - return f"You are User: {user}" -```docs/integrations/supabase.mdx (1)
103-112: Duplicate and contradictory FastMCP initialization.Lines 103-108 correctly demonstrate the new explicit configuration pattern. However, lines 110-111 show a second
mcp = FastMCP(...)call with the comment "Authentication is automatically configured from environment" and noauthparameter—this contradicts the PR's objective.Additionally, the code block appears to be missing its closing fence.
🔎 Suggested fix: Remove the duplicate initialization
mcp = FastMCP(name="Supabase Secured App", auth=auth) - -# Authentication is automatically configured from environment -mcp = FastMCP(name="Supabase Protected Server") +```docs/integrations/descope.mdx (1)
66-69: Syntax error in code example.Line 67 is missing quotes around the URL:
config_url=https://.../.well-known/openid-configuration,This should be a string literal or environment variable reference.
🔎 Proposed fix
auth_provider = DescopeProvider( - config_url=https://.../.well-known/openid-configuration, # Your MCP Server .well-known URL + config_url="https://.../.well-known/openid-configuration", # Your MCP Server .well-known URL base_url=SERVER_URL, # Your server's public URL )docs/integrations/azure.mdx (1)
283-309: Duplicate "Production Configuration" heading.This file has two H2 sections with the identical title "Production Configuration" (lines 241 and 283), creating the same issues as noted in google.mdx:
- Duplicate heading hierarchy
- Confusing navigation
- Ambiguous anchor links
Apply the same consolidation approach as recommended for google.mdx to merge both production configuration concerns into a single, comprehensive section.
docs/integrations/auth0.mdx (1)
218-229: Remove contradictory leftover code.Lines 218-229 contain orphaned code that contradicts the PR's objective:
from fastmcp import FastMCP # Authentication is automatically configured from environment mcp = FastMCP(name="Auth0 Secured App")This example suggests automatic environment-based configuration, which is exactly what this PR removes. The comment "Authentication is automatically configured from environment" is now incorrect.
This appears to be leftover code from before the changes that should have been removed.
Proposed fix
mcp = FastMCP(name="Auth0 Secured App", auth=auth) - -```python server.py -from fastmcp import FastMCP - -# Authentication is automatically configured from environment -mcp = FastMCP(name="Auth0 Secured App") - -@mcp.tool -async def search_logs() -> list[str]: - """Search the service logs.""" - # Your tool implementation here - pass -``` + +@mcp.tool +async def protected_tool(query: str) -> str: + """A tool that requires Auth0 authentication to access.""" + # Your tool implementation here + return f"Processing authenticated request: {query}" +```docs/integrations/github.mdx (1)
178-201: Duplicate "Production Configuration" heading.Lines 138 and 178 both contain "Production Configuration" H2 headings. Consolidate these sections following the same pattern recommended for google.mdx and azure.mdx.
docs/integrations/discord.mdx (1)
204-213: Remove contradictory leftover code.Lines 204-213 contain orphaned code that contradicts the PR's objective:
from fastmcp import FastMCP mcp = FastMCP(name="Discord Secured App")This code shows initialization without an explicit
authparameter, contradicting the PR's shift away from automatic environment-based configuration. This is leftover code from before the changes that should be removed (same issue as in auth0.mdx).Proposed fix
mcp = FastMCP(name="Discord Secured App", auth=auth) - -```python server.py -from fastmcp import FastMCP - -mcp = FastMCP(name="Discord Secured App") - -@mcp.tool -async def protected_tool(query: str) -> str: - """A tool that requires Discord authentication to access.""" - return f"Processing authenticated request: {query}" -``` + +@mcp.tool +async def protected_tool(query: str) -> str: + """A tool that requires Discord authentication to access.""" + return f"Processing authenticated request: {query}" +```
🧹 Nitpick comments (4)
src/fastmcp/server/auth/providers/oci.py (1)
60-67: Minor inconsistency in docstring example compared to documentation.The docstring example uses
Noneas the fallback foroci_domain_id:oci_domain_id=iam_guid.split(".")[0] if iam_guid else None,However,
docs/python-sdk/fastmcp-server-auth-providers-oci.mdxline 73 uses an empty string"":oci_domain_id=OCI_IAM_GUID.split(".")[0] if OCI_IAM_GUID else "",Consider aligning these for consistency—
Noneis typically preferred over empty string when representing "no value."docs/integrations/descope.mdx (1)
108-111: Consider usingos.environ[]for required fields.Using
os.environ.get()returnsNonewhen the variable is missing, which will likely cause a runtime error later. For required configuration likeconfig_url, consider usingos.environ["DESCOPE_CONFIG_URL"]to fail fast with a clearKeyErrorif the variable is not set.🔎 Proposed fix
auth = DescopeProvider( - config_url=os.environ.get("DESCOPE_CONFIG_URL"), + config_url=os.environ["DESCOPE_CONFIG_URL"], base_url=os.environ.get("BASE_URL", "https://your-server.com") )docs/servers/auth/oauth-proxy.mdx (1)
573-577: Useos.environ[]for required fields for consistency.The upgrade guide at
docs/development/upgrade-guide.mdxlines 167-169 usesos.environ["..."]for required fields:client_id=os.environ["GITHUB_CLIENT_ID"], client_secret=os.environ["GITHUB_CLIENT_SECRET"],This example uses
os.environ.get()which returnsNonefor missing variables. For consistency and fail-fast behavior, useos.environ[]for required fields.🔎 Proposed fix
# Load secrets from environment variables auth = GitHubProvider( - client_id=os.environ.get("GITHUB_CLIENT_ID"), - client_secret=os.environ.get("GITHUB_CLIENT_SECRET"), + client_id=os.environ["GITHUB_CLIENT_ID"], + client_secret=os.environ["GITHUB_CLIENT_SECRET"], base_url=os.environ.get("BASE_URL", "https://your-production-server.com") )docs/servers/auth/token-verification.mdx (1)
306-328: Consider simplifying the scopes parsing logic.Line 320 contains a complex one-liner for parsing
required_scopes:required_scopes=os.environ.get("JWT_REQUIRED_SCOPES", "").split(",") if os.environ.get("JWT_REQUIRED_SCOPES") else NoneWhile functionally correct, this reads
JWT_REQUIRED_SCOPEStwice and may be unclear for documentation readers.Clearer alternative
+# Parse optional comma-separated scopes +scopes_env = os.environ.get("JWT_REQUIRED_SCOPES") +required_scopes = scopes_env.split(",") if scopes_env else None + # Load configuration from environment variables verifier = JWTVerifier( jwks_uri=os.environ.get("JWT_JWKS_URI"), issuer=os.environ.get("JWT_ISSUER"), audience=os.environ.get("JWT_AUDIENCE"), - required_scopes=os.environ.get("JWT_REQUIRED_SCOPES", "").split(",") if os.environ.get("JWT_REQUIRED_SCOPES") else None + required_scopes=required_scopes )This approach:
- Reads the environment variable once
- Makes the conditional logic clearer
- Adds a helpful comment
- Is more suitable for documentation examples
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (13)
tests/deprecated/test_settings.pyis excluded by none and included by nonetests/server/auth/providers/test_auth0.pyis excluded by none and included by nonetests/server/auth/providers/test_aws.pyis excluded by none and included by nonetests/server/auth/providers/test_azure.pyis excluded by none and included by nonetests/server/auth/providers/test_descope.pyis excluded by none and included by nonetests/server/auth/providers/test_discord.pyis excluded by none and included by nonetests/server/auth/providers/test_github.pyis excluded by none and included by nonetests/server/auth/providers/test_google.pyis excluded by none and included by nonetests/server/auth/providers/test_introspection.pyis excluded by none and included by nonetests/server/auth/providers/test_scalekit.pyis excluded by none and included by nonetests/server/auth/providers/test_supabase.pyis excluded by none and included by nonetests/server/auth/providers/test_workos.pyis excluded by none and included by nonetests/server/test_server.pyis excluded by none and included by none
📒 Files selected for processing (47)
docs/development/upgrade-guide.mdxdocs/development/v3-notes/auth-provider-env-vars.mdxdocs/integrations/auth0.mdxdocs/integrations/authkit.mdxdocs/integrations/aws-cognito.mdxdocs/integrations/azure.mdxdocs/integrations/descope.mdxdocs/integrations/discord.mdxdocs/integrations/github.mdxdocs/integrations/google.mdxdocs/integrations/oci.mdxdocs/integrations/scalekit.mdxdocs/integrations/supabase.mdxdocs/integrations/workos.mdxdocs/python-sdk/fastmcp-server-auth-providers-auth0.mdxdocs/python-sdk/fastmcp-server-auth-providers-aws.mdxdocs/python-sdk/fastmcp-server-auth-providers-azure.mdxdocs/python-sdk/fastmcp-server-auth-providers-descope.mdxdocs/python-sdk/fastmcp-server-auth-providers-discord.mdxdocs/python-sdk/fastmcp-server-auth-providers-github.mdxdocs/python-sdk/fastmcp-server-auth-providers-google.mdxdocs/python-sdk/fastmcp-server-auth-providers-introspection.mdxdocs/python-sdk/fastmcp-server-auth-providers-jwt.mdxdocs/python-sdk/fastmcp-server-auth-providers-oci.mdxdocs/python-sdk/fastmcp-server-auth-providers-scalekit.mdxdocs/python-sdk/fastmcp-server-auth-providers-supabase.mdxdocs/python-sdk/fastmcp-server-auth-providers-workos.mdxdocs/python-sdk/fastmcp-settings.mdxdocs/servers/auth/authentication.mdxdocs/servers/auth/oauth-proxy.mdxdocs/servers/auth/oidc-proxy.mdxdocs/servers/auth/token-verification.mdxsrc/fastmcp/server/auth/providers/auth0.pysrc/fastmcp/server/auth/providers/aws.pysrc/fastmcp/server/auth/providers/azure.pysrc/fastmcp/server/auth/providers/descope.pysrc/fastmcp/server/auth/providers/discord.pysrc/fastmcp/server/auth/providers/github.pysrc/fastmcp/server/auth/providers/google.pysrc/fastmcp/server/auth/providers/introspection.pysrc/fastmcp/server/auth/providers/jwt.pysrc/fastmcp/server/auth/providers/oci.pysrc/fastmcp/server/auth/providers/scalekit.pysrc/fastmcp/server/auth/providers/supabase.pysrc/fastmcp/server/auth/providers/workos.pysrc/fastmcp/server/server.pysrc/fastmcp/settings.py
💤 Files with no reviewable changes (13)
- docs/python-sdk/fastmcp-settings.mdx
- docs/python-sdk/fastmcp-server-auth-providers-aws.mdx
- docs/python-sdk/fastmcp-server-auth-providers-discord.mdx
- docs/python-sdk/fastmcp-server-auth-providers-github.mdx
- docs/python-sdk/fastmcp-server-auth-providers-descope.mdx
- docs/python-sdk/fastmcp-server-auth-providers-azure.mdx
- docs/python-sdk/fastmcp-server-auth-providers-supabase.mdx
- docs/python-sdk/fastmcp-server-auth-providers-scalekit.mdx
- docs/python-sdk/fastmcp-server-auth-providers-google.mdx
- docs/python-sdk/fastmcp-server-auth-providers-introspection.mdx
- docs/python-sdk/fastmcp-server-auth-providers-auth0.mdx
- docs/python-sdk/fastmcp-server-auth-providers-jwt.mdx
- docs/python-sdk/fastmcp-server-auth-providers-workos.mdx
🧰 Additional context used
📓 Path-based instructions (4)
docs/**/*.mdx
📄 CodeRabbit inference engine (docs/.cursor/rules/mintlify.mdc)
docs/**/*.mdx: Use clear, direct language appropriate for technical audiences
Write in second person ('you') for instructions and procedures in MDX documentation
Use active voice over passive voice in MDX technical documentation
Employ present tense for current states and future tense for outcomes in MDX documentation
Maintain consistent terminology throughout all MDX documentation
Keep sentences concise while providing necessary context in MDX documentation
Use parallel structure in lists, headings, and procedures in MDX documentation
Lead with the most important information using inverted pyramid structure in MDX documentation
Use progressive disclosure in MDX documentation: present basic concepts before advanced ones
Break complex procedures into numbered steps in MDX documentation
Include prerequisites and context before instructions in MDX documentation
Provide expected outcomes for each major step in MDX documentation
End sections with next steps or related information in MDX documentation
Use descriptive, keyword-rich headings for navigation and SEO in MDX documentation
Focus on user goals and outcomes rather than system features in MDX documentation
Anticipate common questions and address them proactively in MDX documentation
Include troubleshooting for likely failure points in MDX documentation
Provide multiple pathways (beginner vs advanced) but offer an opinionated path to avoid overwhelming users in MDX documentation
Always include complete, runnable code examples that users can copy and execute in MDX documentation
Show proper error handling and edge case management in MDX code examples
Use realistic data instead of placeholder values in MDX code examples
Include expected outputs and results for verification in MDX code examples
Test all code examples thoroughly before publishing in MDX documentation
Specify language and include filename when relevant in MDX code examples
Add explanatory comments for complex logic in MDX code examples
Document all API...
Files:
docs/integrations/discord.mdxdocs/servers/auth/token-verification.mdxdocs/integrations/scalekit.mdxdocs/servers/auth/oidc-proxy.mdxdocs/integrations/aws-cognito.mdxdocs/integrations/supabase.mdxdocs/development/v3-notes/auth-provider-env-vars.mdxdocs/servers/auth/oauth-proxy.mdxdocs/integrations/authkit.mdxdocs/integrations/workos.mdxdocs/integrations/google.mdxdocs/integrations/azure.mdxdocs/integrations/auth0.mdxdocs/integrations/descope.mdxdocs/development/upgrade-guide.mdxdocs/servers/auth/authentication.mdxdocs/integrations/github.mdxdocs/python-sdk/fastmcp-server-auth-providers-oci.mdxdocs/integrations/oci.mdx
docs/**/*.{md,mdx,json}
📄 CodeRabbit inference engine (AGENTS.md)
Documentation uses Mintlify framework. Files must be in docs.json to be included. Never modify docs/python-sdk/** (auto-generated)
Files:
docs/integrations/discord.mdxdocs/servers/auth/token-verification.mdxdocs/integrations/scalekit.mdxdocs/servers/auth/oidc-proxy.mdxdocs/integrations/aws-cognito.mdxdocs/integrations/supabase.mdxdocs/development/v3-notes/auth-provider-env-vars.mdxdocs/servers/auth/oauth-proxy.mdxdocs/integrations/authkit.mdxdocs/integrations/workos.mdxdocs/integrations/google.mdxdocs/integrations/azure.mdxdocs/integrations/auth0.mdxdocs/integrations/descope.mdxdocs/development/upgrade-guide.mdxdocs/servers/auth/authentication.mdxdocs/integrations/github.mdxdocs/python-sdk/fastmcp-server-auth-providers-oci.mdxdocs/integrations/oci.mdx
docs/**/*.{md,mdx}
📄 CodeRabbit inference engine (AGENTS.md)
docs/**/*.{md,mdx}: Code examples in documentation must explain before showing code and make blocks fully runnable (include imports)
Documentation structure: Headers form navigation guide with logical H2/H3 hierarchy. Content should be user-focused with sections motivating features (why) before mechanics (how). Use prose over code comments for important information
Never use 'This isn't...' or 'not just...' constructions in writing - state what something IS directly. Avoid defensive writing patterns
Files:
docs/integrations/discord.mdxdocs/servers/auth/token-verification.mdxdocs/integrations/scalekit.mdxdocs/servers/auth/oidc-proxy.mdxdocs/integrations/aws-cognito.mdxdocs/integrations/supabase.mdxdocs/development/v3-notes/auth-provider-env-vars.mdxdocs/servers/auth/oauth-proxy.mdxdocs/integrations/authkit.mdxdocs/integrations/workos.mdxdocs/integrations/google.mdxdocs/integrations/azure.mdxdocs/integrations/auth0.mdxdocs/integrations/descope.mdxdocs/development/upgrade-guide.mdxdocs/servers/auth/authentication.mdxdocs/integrations/github.mdxdocs/python-sdk/fastmcp-server-auth-providers-oci.mdxdocs/integrations/oci.mdx
src/fastmcp/**/*.py
📄 CodeRabbit inference engine (AGENTS.md)
src/fastmcp/**/*.py: Python ≥ 3.10 with full type annotations required
Prioritize readable, understandable code - clarity over cleverness. Avoid obfuscated or confusing patterns even if shorter
Follow existing patterns and maintain consistency in code implementation
Be intentional about re-exports - don't blindly re-export everything to parent namespaces. Core types defining a module's purpose should be exported. Specialized features can live in submodules. Only re-export to fastmcp.* for most fundamental types
Never use bare except - be specific with exception types
Files:
src/fastmcp/server/auth/providers/descope.pysrc/fastmcp/server/auth/providers/jwt.pysrc/fastmcp/server/auth/providers/discord.pysrc/fastmcp/server/auth/providers/auth0.pysrc/fastmcp/server/auth/providers/oci.pysrc/fastmcp/server/server.pysrc/fastmcp/server/auth/providers/github.pysrc/fastmcp/settings.pysrc/fastmcp/server/auth/providers/supabase.pysrc/fastmcp/server/auth/providers/azure.pysrc/fastmcp/server/auth/providers/scalekit.pysrc/fastmcp/server/auth/providers/google.pysrc/fastmcp/server/auth/providers/introspection.pysrc/fastmcp/server/auth/providers/workos.pysrc/fastmcp/server/auth/providers/aws.py
🧠 Learnings (4)
📚 Learning: 2025-12-25T15:53:07.646Z
Learnt from: CR
Repo: jlowin/fastmcp PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-25T15:53:07.646Z
Learning: Applies to tests/**/*.py : Pass FastMCP servers directly to clients for testing without network complexity; only use HTTP transport when explicitly testing network features
Applied to files:
docs/servers/auth/oidc-proxy.mdxdocs/servers/auth/oauth-proxy.mdx
📚 Learning: 2025-11-26T21:52:08.947Z
Learnt from: CR
Repo: jlowin/fastmcp PR: 0
File: docs/.cursor/rules/mintlify.mdc:0-0
Timestamp: 2025-11-26T21:52:08.947Z
Learning: Applies to docs/**/*.mdx : Provide authentication examples showing proper format in MDX API documentation
Applied to files:
docs/integrations/auth0.mdxdocs/servers/auth/authentication.mdx
📚 Learning: 2025-12-25T15:53:07.646Z
Learnt from: CR
Repo: jlowin/fastmcp PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-25T15:53:07.646Z
Learning: Applies to src/fastmcp/**/*.py : Python ≥ 3.10 with full type annotations required
Applied to files:
src/fastmcp/server/server.py
📚 Learning: 2025-12-01T15:48:05.095Z
Learnt from: jlowin
Repo: jlowin/fastmcp PR: 0
File: :0-0
Timestamp: 2025-12-01T15:48:05.095Z
Learning: PR #2505 in fastmcp adds NEW functionality to get_access_token(): it now first checks request.scope["user"] for the token (which never existed before), then falls back to _sdk_get_access_token() (the only thing the original code did). This is not a reversal of order but entirely new functionality to fix stale token issues.
Applied to files:
src/fastmcp/server/auth/providers/aws.py
🧬 Code graph analysis (13)
src/fastmcp/server/auth/providers/descope.py (2)
src/fastmcp/server/auth/auth.py (1)
TokenVerifier(220-243)src/fastmcp/utilities/auth.py (1)
parse_scopes(9-34)
src/fastmcp/server/auth/providers/jwt.py (1)
src/fastmcp/utilities/auth.py (1)
parse_scopes(9-34)
src/fastmcp/server/auth/providers/discord.py (2)
src/fastmcp/server/context.py (2)
client_id(358-364)debug(445-459)src/fastmcp/utilities/auth.py (1)
parse_scopes(9-34)
src/fastmcp/server/auth/providers/auth0.py (1)
src/fastmcp/utilities/auth.py (1)
parse_scopes(9-34)
src/fastmcp/server/auth/providers/oci.py (1)
src/fastmcp/utilities/auth.py (1)
parse_scopes(9-34)
src/fastmcp/server/server.py (1)
src/fastmcp/server/auth/auth.py (1)
AuthProvider(91-217)
src/fastmcp/server/auth/providers/github.py (2)
src/fastmcp/server/context.py (2)
client_id(358-364)debug(445-459)src/fastmcp/utilities/auth.py (1)
parse_scopes(9-34)
src/fastmcp/server/auth/providers/supabase.py (2)
src/fastmcp/utilities/auth.py (1)
parse_scopes(9-34)src/fastmcp/server/auth/providers/jwt.py (1)
JWTVerifier(139-461)
src/fastmcp/server/auth/providers/azure.py (3)
src/fastmcp/server/context.py (2)
client_id(358-364)info(461-475)src/fastmcp/utilities/auth.py (1)
parse_scopes(9-34)src/fastmcp/server/auth/providers/jwt.py (1)
JWTVerifier(139-461)
src/fastmcp/server/auth/providers/scalekit.py (3)
src/fastmcp/server/context.py (2)
client_id(358-364)warning(477-491)src/fastmcp/server/auth/auth.py (1)
TokenVerifier(220-243)src/fastmcp/utilities/auth.py (1)
parse_scopes(9-34)
src/fastmcp/server/auth/providers/introspection.py (2)
src/fastmcp/server/context.py (1)
client_id(358-364)src/fastmcp/utilities/auth.py (1)
parse_scopes(9-34)
src/fastmcp/server/auth/providers/workos.py (2)
src/fastmcp/utilities/auth.py (1)
parse_scopes(9-34)src/fastmcp/server/auth/providers/jwt.py (1)
JWTVerifier(139-461)
src/fastmcp/server/auth/providers/aws.py (1)
src/fastmcp/utilities/auth.py (1)
parse_scopes(9-34)
🪛 LanguageTool
docs/integrations/oci.mdx
[style] ~101-~101: You have already used this phrasing in nearby sentences. Consider replacing it to add variety to your writing.
Context: ...ity-federation) For token exchange, we need to configure Identity propagation trust. T...
(REP_NEED_TO_VB)
🪛 Ruff (0.14.10)
src/fastmcp/server/auth/providers/jwt.py
185-185: Avoid specifying long messages outside the exception class
(TRY003)
188-188: Avoid specifying long messages outside the exception class
(TRY003)
src/fastmcp/server/auth/providers/discord.py
230-230: Possible hardcoded password assigned to argument: "upstream_token_endpoint"
(S106)
src/fastmcp/server/auth/providers/github.py
223-223: Possible hardcoded password assigned to argument: "upstream_token_endpoint"
(S106)
src/fastmcp/server/auth/providers/scalekit.py
88-88: Avoid specifying long messages outside the exception class
(TRY003)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: Run tests with lowest-direct dependencies
- GitHub Check: Run tests: Python 3.10 on ubuntu-latest
- GitHub Check: Run tests: Python 3.13 on ubuntu-latest
- GitHub Check: Run tests: Python 3.10 on windows-latest
🔇 Additional comments (27)
src/fastmcp/server/auth/providers/introspection.py (1)
68-104: LGTM! Clean refactor to explicit constructor parameters.The initialization logic correctly:
- Requires explicit
introspection_url,client_id, andclient_secretparameters- Handles
SecretStrnormalization appropriately- Delegates scope parsing to
parse_scopesutility- Passes parsed values to the parent class
src/fastmcp/server/auth/providers/google.py (1)
186-278: LGTM! Well-structured refactor to explicit parameters.The GoogleProvider initialization:
- Correctly requires explicit
client_id,client_secret, andbase_url- Appropriately defaults
required_scopesto["openid"]for Google OIDC- Properly handles the
issuer_urlfallback tobase_url- Maintains Google-specific defaults for
extra_authorize_paramssrc/fastmcp/server/auth/providers/supabase.py (1)
70-113: LGTM! Clean implementation with appropriate defaults.The SupabaseProvider correctly:
- Requires explicit
project_urlandbase_urlparameters- Defaults
algorithmto"ES256"matching Supabase's recommendation- Normalizes URLs by stripping trailing slashes
- Passes parsed scopes to the JWTVerifier
src/fastmcp/server/auth/providers/auth0.py (1)
58-123: LGTM! Consistent implementation with other auth providers.The Auth0Provider follows the same pattern as other refactored providers:
- Explicit required parameters (
config_url,client_id,client_secret,audience,base_url)- Scope parsing with
["openid"]default- Direct parameter passing to the parent class
src/fastmcp/server/auth/providers/aws.py (1)
97-170: LGTM! Clean refactor with Cognito-specific handling.The AWSCognitoProvider correctly:
- Requires explicit
user_pool_id,client_id,client_secret, andbase_url- Constructs the OIDC discovery URL from
aws_regionanduser_pool_id- Uses the specialized
AWSCognitoTokenVerifierfor claim filteringsrc/fastmcp/server/auth/providers/jwt.py (1)
158-229: LGTM! Robust JWT verifier with proper validation.The JWTVerifier correctly:
- Validates that exactly one of
public_keyorjwks_uriis provided- Validates the algorithm against a comprehensive whitelist
- Parses scopes using the shared utility
- Defaults algorithm to
"RS256"when not specifiedThe static analysis hints about long exception messages (TRY003) can be safely ignored here—the messages provide clear context for debugging configuration errors.
src/fastmcp/server/auth/providers/discord.py (1)
172-246: LGTM! Clean refactor to explicit constructor parameters.The constructor correctly:
- Requires
client_id,client_secret, andbase_urlas mandatory parameters- Uses
parse_scopesto handle flexible scope input with sensible default["identify"]- Defaults
issuer_urltobase_urlwhen not provided- Passes all parameters directly to the parent
OAuthProxyThe Ruff S106 hint on line 230 is a false positive—
upstream_token_endpointis a URL constant, not a password.src/fastmcp/server/auth/providers/oci.py (1)
117-169: LGTM! Constructor properly simplified to explicit parameters.The implementation correctly:
- Requires
config_url,client_id,client_secret, andbase_url- Uses
parse_scopeswith appropriate default["openid"]for OIDC- Passes parameters directly to
OIDCProxyparentsrc/fastmcp/server/auth/providers/workos.py (2)
134-211: LGTM! WorkOSProvider correctly refactored to explicit parameters.The implementation:
- Properly normalizes
authkit_domainto ensure HTTPS and trailing slash removal- Uses
parse_scopeswith empty list default (appropriate for WorkOS which may not require scopes)- Correctly defaults
issuer_urltobase_url
250-288: LGTM! AuthKitProvider simplified appropriately.The constructor correctly:
- Accepts explicit
authkit_domainandbase_urlparameters- Uses
parse_scopeswithNonedefault (correct for optional scopes)- Creates JWTVerifier with parsed scopes when no custom verifier provided
src/fastmcp/server/auth/providers/azure.py (2)
90-107: LGTM! Azure provider correctly requires explicit scopes.Unlike other providers,
required_scopesis a required parameter here (no default). This is appropriate since Azure requires custom API scopes to be explicitly defined under "Expose an API" in the Azure Portal.
151-211: Implementation is correct and well-documented.The scope handling logic properly:
- Filters OIDC scopes from validation (Azure doesn't include them in
scpclaim)- Prefixes custom scopes with
identifier_urifor Azure- Advertises full scopes via
valid_scopeswhile only validating non-OIDC onesdocs/development/upgrade-guide.mdx (1)
153-177: LGTM! Clear migration documentation.The upgrade guide effectively:
- Shows before/after code examples for the breaking change
- Lists all affected providers comprehensively
- Notes the
FastMCPSettingssimplification- Uses proper code group formatting
src/fastmcp/settings.py (1)
8-11: LGTM! Clean removal of unused imports.The removal of
TYPE_CHECKINGandImportStringaligns with eliminating the authentication provider wiring from settings.docs/servers/auth/oidc-proxy.mdx (1)
236-265: LGTM! Clear production configuration guidance.This section demonstrates the correct pattern:
- Explicit environment variable loading
- Complete, runnable code example
- Appropriate security reminder about keeping secrets out of codebase
- Single, well-structured Production Configuration section
src/fastmcp/server/server.py (1)
202-202: LGTM! Clean removal of implicit environment-based auth.The change from
NotSet-based default to explicitNonemakes the auth parameter behavior transparent. Users must now explicitly pass anAuthProviderinstance, eliminating the previous implicit environment-variable loading.docs/integrations/authkit.mdx (1)
81-96: LGTM! Excellent production configuration example.This section clearly demonstrates the new explicit environment variable loading pattern. The code is complete, runnable, and uses
os.environ.get()consistently for all configuration values with appropriate defaults.docs/integrations/workos.mdx (1)
176-188: LGTM! Environment variable configuration is correct.The code example properly demonstrates explicit environment variable loading using
os.environ.get()with appropriate defaults. This aligns with the new pattern across all auth providers.docs/development/v3-notes/auth-provider-env-vars.mdx (1)
1-73: LGTM! Excellent upgrade documentation.This documentation clearly explains the breaking change, provides strong rationale, and offers straightforward migration guidance. The structure follows best practices with:
- Clear status and background
- Well-articulated reasons (maintenance burden, complexity, etc.)
- Concrete before/after examples
- Backwards compatibility considerations
- Complete list of removed features
The content is user-focused and anticipates developer questions effectively.
docs/servers/auth/authentication.mdx (1)
181-202: LGTM! Clear and concise configuration guidance.The restructured configuration section effectively communicates the new explicit approach. The documentation:
- Clearly explains programmatic instantiation
- Provides production-focused environment variable guidance
- Includes a complete, runnable code example
- Notes flexibility in environment variable naming
This aligns well with the PR objectives and MDX documentation guidelines.
src/fastmcp/server/auth/providers/descope.py (1)
63-145: LGTM! Clean removal of settings-based configuration.The updated
DescopeProviderconstructor successfully removes automatic environment variable loading while maintaining backwards compatibility:
- Clear required vs optional parameters
- Explicit parameter types and defaults
- Proper validation with actionable error messages
- Supports both new API (config_url) and old API (project_id + descope_base_url)
- Consistent use of
parse_scopeshelperThe initialization logic correctly handles both API paths and provides clear errors when configuration is invalid.
src/fastmcp/server/auth/providers/scalekit.py (1)
63-142: LGTM! Well-executed migration with good backwards compatibility.The updated
ScalekitProviderconstructor successfully removes automatic environment variable loading while maintaining backwards compatibility through deprecation warnings:
- Required parameters (environment_url, resource_id) are explicit
- Graceful handling of deprecated
mcp_urlparameter with migration guidance- Deprecation warning for unnecessary
client_idparameter- Consistent use of
parse_scopeshelper- Clear error messages for missing configuration
The implementation balances the cleanup goals with user-friendly migration support.
docs/integrations/scalekit.mdx (1)
96-109: Fix variable reference inconsistency in code example.Lines 103-105 reference
SCALEKIT_ENVIRONMENT_URL,SCALEKIT_RESOURCE_ID, andBASE_URLdirectly as if they were Python variables, but they should be environment variable lookups viaos.environ.get(). The code won't execute as-is because these variables are undefined.🔎 Proposed fix
# Load configuration from environment variables auth = ScalekitProvider( - environment_url=os.environ.get("SCALEKIT_ENVIRONMENT_URL"), - resource_id=os.environ.get("SCALEKIT_RESOURCE_ID"), + environment_url=os.environ["SCALEKIT_ENVIRONMENT_URL"], + resource_id=os.environ["SCALEKIT_RESOURCE_ID"], base_url=os.environ.get("BASE_URL", "https://your-server.com") )Note: Using
os.environ["KEY"](without.get()) for required variables will raise a clearKeyErrorif they're missing, while optional variables likeBASE_URLcan use.get()with a default.⛔ Skipped due to learnings
Learnt from: CR Repo: jlowin/fastmcp PR: 0 File: AGENTS.md:0-0 Timestamp: 2025-12-25T15:53:07.646Z Learning: Applies to tests/**/*.py : Pass FastMCP servers directly to clients for testing without network complexity; only use HTTP transport when explicitly testing network featuressrc/fastmcp/server/auth/providers/github.py (4)
1-20: Documentation clearly reflects the new explicit configuration approach.The updated docstring effectively demonstrates the shift from automatic environment variable loading to explicit parameter passing, which aligns perfectly with the PR objectives.
209-212: Scope parsing logic correctly handles defaults and user-provided values.The implementation properly defaults to
["user"]whenNoneis provided, while allowing users to specify an empty list or custom scopes. Theparse_scopescall provides normalization even for list inputs, which is a defensive pattern consistent with the broader provider refactor.
170-240: Constructor successfully migrates to explicit parameter-based configuration.The refactored
__init__method properly implements the explicit parameter approach:
- All required credentials are now explicit parameters with proper type annotations
- Default values are sensible and well-documented
- The fallback logic for
issuer_url(line 229) is clean and correct- Parameter pass-through to
OAuthProxyandGitHubTokenVerifieris properly wiredThe implementation follows Python ≥3.10 guidelines with union types and provides full type annotations as required.
223-223: Static analysis false positive - GitHub OAuth endpoint URL is safe.The Ruff warning about a hardcoded password is a false positive. Line 223 contains GitHub's public OAuth token endpoint URL (
https://github.com/login/oauth/access_token), not a secret. This is a well-known, documented endpoint required for the OAuth flow. The actual sensitive credential (client_secret) is correctly passed as a constructor parameter rather than being hardcoded.
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
docs/integrations/oci.mdx (1)
129-154: Add error handling for missing environment variables.The code uses
os.environ.get()which returnsNoneif variables are not set, but onlyOCI_IAM_GUIDis checked before use (line 152). Lines 153-154 passOCI_CLIENT_IDandOCI_CLIENT_SECRETdirectly toTokenExchangeSignerwithout validation, which could cause confusing runtime errors if these environment variables are missing.🔎 Proposed fix to validate required environment variables
# Load configuration from environment -OCI_IAM_GUID = os.environ.get("OCI_IAM_GUID") -OCI_CLIENT_ID = os.environ.get("OCI_CLIENT_ID") -OCI_CLIENT_SECRET = os.environ.get("OCI_CLIENT_SECRET") +OCI_IAM_GUID = os.environ["OCI_IAM_GUID"] +OCI_CLIENT_ID = os.environ["OCI_CLIENT_ID"] +OCI_CLIENT_SECRET = os.environ["OCI_CLIENT_SECRET"]Then update line 152:
signer = TokenExchangeSigner( jwt_or_func=token, - oci_domain_id=OCI_IAM_GUID.split(".")[0] if OCI_IAM_GUID else "", + oci_domain_id=OCI_IAM_GUID.split(".")[0], client_id=OCI_CLIENT_ID, client_secret=OCI_CLIENT_SECRET, )This will raise a clear
KeyErrorwith the missing variable name if any required environment variable is not set.
🧹 Nitpick comments (1)
docs/integrations/oci.mdx (1)
222-234: Use consistent pattern for required vs. optional environment variables.The code mixes
os.environ.get()(lines 222-224) andos.environ[](lines 228, 231-233) inconsistently. Using.get()suggests the values are optional, butconfig_url,client_id, andclient_secretare likely required byOCIProvider. Consider usingos.environ[]for required variables to provide clear error messages when they're missing, and reserve.get()with defaults only for truly optional parameters likebase_url(line 225).🔎 Proposed fix for consistency
# Production setup with encrypted persistent token storage auth_provider = OCIProvider( - config_url=os.environ.get("OCI_CONFIG_URL"), - client_id=os.environ.get("OCI_CLIENT_ID"), - client_secret=os.environ.get("OCI_CLIENT_SECRET"), + config_url=os.environ["OCI_CONFIG_URL"], + client_id=os.environ["OCI_CLIENT_ID"], + client_secret=os.environ["OCI_CLIENT_SECRET"], base_url=os.environ.get("BASE_URL", "https://your-production-domain.com"), # Production token managementThis makes the pattern consistent: required variables use
[](raising clear errors when missing), while optional variables use.get()with sensible defaults.
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (11)
docs/integrations/auth0.mdxdocs/integrations/aws-cognito.mdxdocs/integrations/azure.mdxdocs/integrations/discord.mdxdocs/integrations/github.mdxdocs/integrations/google.mdxdocs/integrations/oci.mdxdocs/integrations/workos.mdxdocs/python-sdk/fastmcp-server-auth-providers-oci.mdxsrc/fastmcp/server/server.pysrc/fastmcp/settings.py
💤 Files with no reviewable changes (6)
- docs/integrations/azure.mdx
- docs/integrations/discord.mdx
- docs/integrations/workos.mdx
- docs/integrations/github.mdx
- docs/integrations/aws-cognito.mdx
- docs/integrations/auth0.mdx
✅ Files skipped from review due to trivial changes (1)
- docs/integrations/google.mdx
🚧 Files skipped from review as they are similar to previous changes (2)
- src/fastmcp/server/server.py
- docs/python-sdk/fastmcp-server-auth-providers-oci.mdx
🧰 Additional context used
📓 Path-based instructions (4)
docs/**/*.mdx
📄 CodeRabbit inference engine (docs/.cursor/rules/mintlify.mdc)
docs/**/*.mdx: Use clear, direct language appropriate for technical audiences
Write in second person ('you') for instructions and procedures in MDX documentation
Use active voice over passive voice in MDX technical documentation
Employ present tense for current states and future tense for outcomes in MDX documentation
Maintain consistent terminology throughout all MDX documentation
Keep sentences concise while providing necessary context in MDX documentation
Use parallel structure in lists, headings, and procedures in MDX documentation
Lead with the most important information using inverted pyramid structure in MDX documentation
Use progressive disclosure in MDX documentation: present basic concepts before advanced ones
Break complex procedures into numbered steps in MDX documentation
Include prerequisites and context before instructions in MDX documentation
Provide expected outcomes for each major step in MDX documentation
End sections with next steps or related information in MDX documentation
Use descriptive, keyword-rich headings for navigation and SEO in MDX documentation
Focus on user goals and outcomes rather than system features in MDX documentation
Anticipate common questions and address them proactively in MDX documentation
Include troubleshooting for likely failure points in MDX documentation
Provide multiple pathways (beginner vs advanced) but offer an opinionated path to avoid overwhelming users in MDX documentation
Always include complete, runnable code examples that users can copy and execute in MDX documentation
Show proper error handling and edge case management in MDX code examples
Use realistic data instead of placeholder values in MDX code examples
Include expected outputs and results for verification in MDX code examples
Test all code examples thoroughly before publishing in MDX documentation
Specify language and include filename when relevant in MDX code examples
Add explanatory comments for complex logic in MDX code examples
Document all API...
Files:
docs/integrations/oci.mdx
docs/**/*.{md,mdx,json}
📄 CodeRabbit inference engine (AGENTS.md)
Documentation uses Mintlify framework. Files must be in docs.json to be included. Never modify docs/python-sdk/** (auto-generated)
Files:
docs/integrations/oci.mdx
docs/**/*.{md,mdx}
📄 CodeRabbit inference engine (AGENTS.md)
docs/**/*.{md,mdx}: Code examples in documentation must explain before showing code and make blocks fully runnable (include imports)
Documentation structure: Headers form navigation guide with logical H2/H3 hierarchy. Content should be user-focused with sections motivating features (why) before mechanics (how). Use prose over code comments for important information
Never use 'This isn't...' or 'not just...' constructions in writing - state what something IS directly. Avoid defensive writing patterns
Files:
docs/integrations/oci.mdx
src/fastmcp/**/*.py
📄 CodeRabbit inference engine (AGENTS.md)
src/fastmcp/**/*.py: Python ≥ 3.10 with full type annotations required
Prioritize readable, understandable code - clarity over cleverness. Avoid obfuscated or confusing patterns even if shorter
Follow existing patterns and maintain consistency in code implementation
Be intentional about re-exports - don't blindly re-export everything to parent namespaces. Core types defining a module's purpose should be exported. Specialized features can live in submodules. Only re-export to fastmcp.* for most fundamental types
Never use bare except - be specific with exception types
Files:
src/fastmcp/settings.py
🪛 LanguageTool
docs/integrations/oci.mdx
[style] ~101-~101: You have already used this phrasing in nearby sentences. Consider replacing it to add variety to your writing.
Context: ...ity-federation) For token exchange, we need to configure Identity propagation trust. T...
(REP_NEED_TO_VB)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: Run tests: Python 3.10 on windows-latest
- GitHub Check: Run tests with lowest-direct dependencies
- GitHub Check: Run tests: Python 3.10 on ubuntu-latest
- GitHub Check: Run tests: Python 3.13 on ubuntu-latest
🔇 Additional comments (5)
src/fastmcp/settings.py (2)
8-11: LGTM: Import cleanup aligns with auth provider removal.The removal of TYPE_CHECKING and ImportString-related imports is appropriate given that server_auth configuration and lazy type resolution have been eliminated. All remaining imports are actively used.
142-334: Removal ofserver_authconfiguration is complete and safe.The deletion of
server_authandserver_auth_classfrom the Settings class is clean. No code attempts to access these removed settings fields. The codebase correctly usesAuthProvideras an explicit constructor parameter instead (seeserver.pyline 203 andhttp.pylines 135, 267), aligning with the v3.0 breaking change where auth providers require explicit instantiation.docs/integrations/oci.mdx (3)
20-20: Clear production URL guidance.The updated prerequisite clearly distinguishes between development and production URLs with concrete examples.
91-91: Updated guidance aligns with explicit configuration.The note appropriately directs users to configure the OCIProvider explicitly in code, consistent with the removal of automatic environment variable loading.
101-114: Generic placeholders improve clarity.The CLI command now uses clear placeholder syntax (
<IAM_GUID>,<CLIENT_ID>) and includes explicit instructions to replace them, making the example more universally applicable.
Test Failure AnalysisSummary: The integration test Root Cause: The test is hitting the GitHub Copilot MCP API (
Suggested Solution: The existing rate limit handling in # In tests/integration_tests/conftest.py, line 60-66
if (
report.when in ("call", "teardown") # Add teardown phase
and report.failed
and not hasattr(report, "wasxfail")
and item.module.__name__ == "tests.integration_tests.test_github_mcp_remote"
and _is_rate_limit_error(call.excinfo, report)
):This will allow the hook to catch rate limit errors that only appear during async context manager cleanup, converting them to skipped tests instead of failures. Detailed AnalysisError from logs: The timeout occurs at:
The 429 error surfaces during teardown at:
The current hook implementation checks Related Files
🤖 Automated analysis by marvin |
Auth providers no longer automatically read configuration from environment variables via pydantic-settings. This removes ~50-100 lines of boilerplate per provider and simplifies both the code and documentation.
Users can still use environment variables—they just read them explicitly:
This is cleaner than magic prefix conventions like
FASTMCP_SERVER_AUTH_GITHUB_CLIENT_ID, and lets users choose their own env var names or use any configuration library they prefer.Also removes the
server_authsetting fromSettings(andFASTMCP_SERVER_AUTHenv var) since it relied on the automatic env var loading that's being removed.Breaking change for v3.0 - documented in upgrade guide.
Closes #2745