-
Notifications
You must be signed in to change notification settings - Fork 1.5k
feat: Made Changes to DescopeProvider to Support New Well Known URLs #2392
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
WalkthroughThe change introduces a MCP Server Well-Known URL workflow: Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
docs/integrations/descope.mdx (2)
60-74: Fix syntax error in code example.The
config_urlparameter on line 67 is missing quotes around the URL string, making this example non-executable. According to the coding guidelines, all code examples must be complete and runnable.Apply this diff:
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 )
78-78: Update comment to reference current parameters.The comment references
project_idanddescope_base_urlwhich are no longer parameters in the API. Update to reference the current parameters.Apply this diff:
-To test your server, you can use the `fastmcp` CLI to run it locally. Assuming you've saved the above code to `server.py` (after replacing the `project_id`, `base_url`, and `descope_base_url` with your actual values!), you can run the following command: +To test your server, you can use the `fastmcp` CLI to run it locally. Assuming you've saved the above code to `server.py` (after replacing the `config_url` and `base_url` with your actual values!), you can run the following command:
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
tests/server/auth/providers/test_descope.pyis excluded by none and included by none
📒 Files selected for processing (3)
docs/integrations/descope.mdx(6 hunks)docs/python-sdk/fastmcp-server-auth-providers-descope.mdx(2 hunks)src/fastmcp/server/auth/providers/descope.py(5 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
docs/**/*.mdx
📄 CodeRabbit inference engine (docs/.cursor/rules/mintlify.mdc)
docs/**/*.mdx: Use clear, direct language appropriate for technical audiences
Write instructions and procedures in second person ("you")
Use active voice over passive voice
Use present tense for current states and future tense for outcomes
Maintain consistent terminology across the documentation
Keep sentences concise while preserving necessary context
Use parallel structure in lists, headings, and procedures
Lead with the most important information (inverted pyramid)
Use progressive disclosure: basic concepts before advanced ones
Break complex procedures into numbered steps
Include prerequisites and context before instructions
Provide expected outcomes for each major step
End sections with next steps or related information
Use descriptive, keyword-rich headings for navigation and SEO
Focus on user goals and outcomes rather than system features
Anticipate common questions and address them proactively
Include troubleshooting for likely failure points
Offer multiple pathways when appropriate (beginner vs advanced) and provide an opinionated recommended path
Use for supplementary information that supports the main content
Use for expert advice, shortcuts, or best practices
Use for critical cautions, breaking changes, or destructive actions
Use for neutral background or contextual information
Use to confirm success or completion
Provide single code examples using fenced code blocks with language (and filename when relevant)
Use to present the same concept in multiple languages
For API docs, use to show requests
For API docs, use to show responses
Use and to document procedures and sequential instructions
Use and for platform-specific or alternative approaches
Use / for supplementary content that might interrupt flow
In API docs, use for parameters (path, body, query, header) with type and required/default as appropria...
Files:
docs/python-sdk/fastmcp-server-auth-providers-descope.mdxdocs/integrations/descope.mdx
🧠 Learnings (2)
📚 Learning: 2025-11-03T17:36:13.331Z
Learnt from: jlowin
Repo: jlowin/fastmcp PR: 2355
File: docs/clients/client.mdx:226-246
Timestamp: 2025-11-03T17:36:13.331Z
Learning: In FastMCP documentation, prefer showing the happy path in onboarding examples without over-explaining edge cases or adding defensive checks, as this reduces cognitive burden for new users learning the API.
Applied to files:
docs/python-sdk/fastmcp-server-auth-providers-descope.mdxdocs/integrations/descope.mdx
📚 Learning: 2025-10-27T14:38:52.643Z
Learnt from: CR
Repo: jlowin/fastmcp PR: 0
File: docs/.cursor/rules/mintlify.mdc:0-0
Timestamp: 2025-10-27T14:38:52.643Z
Learning: Applies to docs/**/*.mdx : Use <Update> to document versioned changes with labels, descriptions, and lists of changes
Applied to files:
docs/integrations/descope.mdx
🧬 Code graph analysis (1)
src/fastmcp/server/auth/providers/descope.py (2)
src/fastmcp/server/auth/auth.py (1)
TokenVerifier(170-193)src/fastmcp/server/auth/providers/jwt.py (1)
JWTVerifier(165-498)
🪛 LanguageTool
docs/python-sdk/fastmcp-server-auth-providers-descope.mdx
[uncategorized] ~58-~58: Loose punctuation mark.
Context: ...ata to clients. Args: - mcp_path: The path where the MCP endpoint is moun...
(UNLIKELY_OPENING_PUNCTUATION)
⏰ 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). (2)
- GitHub Check: Run tests: Python 3.10 on windows-latest
- GitHub Check: label-issue-or-pr
🔇 Additional comments (8)
docs/python-sdk/fastmcp-server-auth-providers-descope.mdx (1)
29-59: LGTM! Documentation updates align with code changes.The documentation has been properly updated to reflect the new Well-Known URL-based configuration approach. The instructions are clear, sequential, and follow the documentation guidelines with second-person voice and active language.
docs/integrations/descope.mdx (2)
21-44: LGTM! Clear onboarding instructions.The updated prerequisites and MCP Server setup steps are well-structured and follow the documentation guidelines. The use of
<Warning>callout for the DCR requirement is appropriate and helps users avoid common setup issues.
107-137: LGTM! Environment variable documentation is complete.The environment variable documentation properly uses
<ParamField>components and provides a complete.envexample. The structure follows the Mintlify documentation guidelines.src/fastmcp/server/auth/providers/descope.py (5)
10-10: LGTM! Necessary import added.The
urlparseimport is required for the new URL parsing logic and is correctly placed.
27-36: LGTM! Settings model updated for Well-Known URL approach.The change from
project_idtoconfig_urlis a breaking change but is intentional and properly documented. TheAnyHttpUrltype provides URL validation.
101-125: URL parsing logic appears sound but is tightly coupled to Descope's URL format.The implementation correctly:
- Handles URLs with or without the
/.well-known/openid-configurationsuffix- Validates that "agentic" exists in the path
- Checks array bounds before accessing path components
- Provides clear error messages
The logic assumes a specific Descope URL structure (
/v1/apps/agentic/P.../M...), which is appropriate for a Descope-specific provider. However, if Descope changes their URL structure, this will break.Consider adding a test to verify this parsing logic works correctly with the expected URL format and fails gracefully with invalid formats. This would help catch breaking changes if Descope updates their URL structure.
128-142: LGTM! Derived values used consistently.The JWT verifier and RemoteAuthProvider initialization correctly use the derived
issuer_url,project_id, anddescope_base_urlvalues. The configuration aligns with Descope's OAuth requirements.
144-187: LGTM! Metadata forwarding preserved with new configuration.The
get_routesmethod correctly uses the deriveddescope_base_urlandproject_idattributes to forward Descope's OAuth metadata. The functionality is preserved while adapting to the new Well-Known URL configuration approach.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
docs/integrations/descope.mdx (1)
78-78: Update outdated parameter references in test section comment.The comment references
project_id,base_url, anddescope_base_url, but the updated code example only usesconfig_urlandbase_url. Remove references to deprecated parameters to avoid confusion.-To test your server, you can use the `fastmcp` CLI to run it locally. Assuming you've saved the above code to `server.py` (after replacing the `project_id`, `base_url`, and `descope_base_url` with your actual values!), you can run the following command: +To test your server, you can use the `fastmcp` CLI to run it locally. Assuming you've saved the above code to `server.py` (after replacing the environment variables with your actual values), you can run the following command:
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
tests/server/auth/providers/test_descope.pyis excluded by none and included by none
📒 Files selected for processing (1)
docs/integrations/descope.mdx(6 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
docs/**/*.mdx
📄 CodeRabbit inference engine (docs/.cursor/rules/mintlify.mdc)
docs/**/*.mdx: Use clear, direct language appropriate for technical audiences
Write instructions and procedures in second person ("you")
Use active voice over passive voice
Use present tense for current states and future tense for outcomes
Maintain consistent terminology across the documentation
Keep sentences concise while preserving necessary context
Use parallel structure in lists, headings, and procedures
Lead with the most important information (inverted pyramid)
Use progressive disclosure: basic concepts before advanced ones
Break complex procedures into numbered steps
Include prerequisites and context before instructions
Provide expected outcomes for each major step
End sections with next steps or related information
Use descriptive, keyword-rich headings for navigation and SEO
Focus on user goals and outcomes rather than system features
Anticipate common questions and address them proactively
Include troubleshooting for likely failure points
Offer multiple pathways when appropriate (beginner vs advanced) and provide an opinionated recommended path
Use for supplementary information that supports the main content
Use for expert advice, shortcuts, or best practices
Use for critical cautions, breaking changes, or destructive actions
Use for neutral background or contextual information
Use to confirm success or completion
Provide single code examples using fenced code blocks with language (and filename when relevant)
Use to present the same concept in multiple languages
For API docs, use to show requests
For API docs, use to show responses
Use and to document procedures and sequential instructions
Use and for platform-specific or alternative approaches
Use / for supplementary content that might interrupt flow
In API docs, use for parameters (path, body, query, header) with type and required/default as appropria...
Files:
docs/integrations/descope.mdx
🧠 Learnings (2)
📚 Learning: 2025-10-27T14:38:52.643Z
Learnt from: CR
Repo: jlowin/fastmcp PR: 0
File: docs/.cursor/rules/mintlify.mdc:0-0
Timestamp: 2025-10-27T14:38:52.643Z
Learning: Applies to docs/**/*.mdx : Use <Update> to document versioned changes with labels, descriptions, and lists of changes
Applied to files:
docs/integrations/descope.mdx
📚 Learning: 2025-11-03T17:36:13.331Z
Learnt from: jlowin
Repo: jlowin/fastmcp PR: 2355
File: docs/clients/client.mdx:226-246
Timestamp: 2025-11-03T17:36:13.331Z
Learning: In FastMCP documentation, prefer showing the happy path in onboarding examples without over-explaining edge cases or adding defensive checks, as this reduces cognitive burden for new users learning the API.
Applied to files:
docs/integrations/descope.mdx
⏰ 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). (1)
- GitHub Check: Run tests: Python 3.10 on windows-latest
🔇 Additional comments (1)
docs/integrations/descope.mdx (1)
9-11: LGTM!The VersionBadge import and version reference correctly communicate compatibility information to users. The documentation structure and updated Well-Known URL flow align well with the underlying provider changes.
|
Thanks @gaokevin1! Just want to note that this appears to be a breaking change, in case you want to handle that gracefully for Descope users. From a FastMCP perspective, the fact that it is a breaking change is ok because the /auth module is exempt from our breaking change policy, so that's fine with me, only mentioning in case. (We'll document it as a breaking change in the release notes) |
Hi @jlowin, I plan to gracefully handle the BC and also want to make sure this doesn't get merged until later this month. I will tag you when this is ready for merging, just wanted to prepare the PR and test before hand. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (1)
docs/integrations/descope.mdx (1)
67-67: Fix Python syntax error: missing quotes around URL string.The
config_urlparameter value must be a string literal enclosed in quotes. This is invalid Python and will cause a syntax error.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 )
🧹 Nitpick comments (3)
docs/integrations/descope.mdx (3)
1-15: Document this breaking change prominently in the introduction.Since this PR is marked as a breaking change, readers upgrading from previous versions need clear migration guidance. The current intro doesn't signal that the setup process or configuration has changed significantly from the prior approach (no mention of the old project_id/descope_base_url pattern being deprecated or replaced).
Add a breaking change notice near the top of the file, after the version badge:
<VersionBadge version="2.12.4" /> +<Warning> +**Breaking Change (v2.12.4):** The Descope integration now uses MCP Server Well-Known URLs instead of project IDs and base URLs. If you're upgrading from an earlier version, see [Migration Guide](#migration) below. +</Warning> This guide shows you how to secure your FastMCP server using [**Descope**](https://www.descope.com), a complete authentication and user management solution. This integration uses the [**Remote OAuth**](/servers/auth/remote-oauth) pattern, where Descope handles user login and your FastMCP server validates the tokens.Then add a migration section later in the doc explaining how to transition from the old configuration to the new one.
78-82: Clarify environment variable requirement in testing instructions.The code example sets
config_url=https://...directly, but the testing section should explicitly note that for the example to work,DESCOPE_CONFIG_URLandSERVER_URLenvironment variables must be loaded (e.g., viapython-dotenv), or that users should replace the placeholders with actual values.Update the testing guidance:
To test your server, you can use the `fastmcp` CLI to run it locally. Assuming you've saved the above code to `server.py` (after replacing the environment variables with your actual values!), you can run the following command: + +First, ensure your `.env` file is in the same directory and contains `DESCOPE_CONFIG_URL` and `SERVER_URL`. Then run:
64-69: Simplify code example comments to reduce cognitive load.The inline comments in the code example could be more concise. For the happy path (onboarding example), shorter comments reduce cognitive burden for new users. Based on learnings, FastMCP documentation prefers showing the happy path without over-explanation.
-# The DescopeProvider automatically discovers Descope endpoints -# and configures JWT token validation auth_provider = DescopeProvider( config_url="https://.../.well-known/openid-configuration", # Your MCP Server .well-known URL base_url=SERVER_URL, # Your server's public URL )
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
docs/integrations/descope.mdx(7 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
docs/**/*.mdx
📄 CodeRabbit inference engine (docs/.cursor/rules/mintlify.mdc)
docs/**/*.mdx: Use clear, direct language appropriate for technical audiences
Write instructions and procedures in second person ("you")
Use active voice over passive voice
Use present tense for current states and future tense for outcomes
Maintain consistent terminology across the documentation
Keep sentences concise while preserving necessary context
Use parallel structure in lists, headings, and procedures
Lead with the most important information (inverted pyramid)
Use progressive disclosure: basic concepts before advanced ones
Break complex procedures into numbered steps
Include prerequisites and context before instructions
Provide expected outcomes for each major step
End sections with next steps or related information
Use descriptive, keyword-rich headings for navigation and SEO
Focus on user goals and outcomes rather than system features
Anticipate common questions and address them proactively
Include troubleshooting for likely failure points
Offer multiple pathways when appropriate (beginner vs advanced) and provide an opinionated recommended path
Use for supplementary information that supports the main content
Use for expert advice, shortcuts, or best practices
Use for critical cautions, breaking changes, or destructive actions
Use for neutral background or contextual information
Use to confirm success or completion
Provide single code examples using fenced code blocks with language (and filename when relevant)
Use to present the same concept in multiple languages
For API docs, use to show requests
For API docs, use to show responses
Use and to document procedures and sequential instructions
Use and for platform-specific or alternative approaches
Use / for supplementary content that might interrupt flow
In API docs, use for parameters (path, body, query, header) with type and required/default as appropria...
Files:
docs/integrations/descope.mdx
🧠 Learnings (2)
📚 Learning: 2025-10-27T14:38:52.643Z
Learnt from: CR
Repo: jlowin/fastmcp PR: 0
File: docs/.cursor/rules/mintlify.mdc:0-0
Timestamp: 2025-10-27T14:38:52.643Z
Learning: Applies to docs/**/*.mdx : Use <Update> to document versioned changes with labels, descriptions, and lists of changes
Applied to files:
docs/integrations/descope.mdx
📚 Learning: 2025-11-03T17:36:13.331Z
Learnt from: jlowin
Repo: jlowin/fastmcp PR: 2355
File: docs/clients/client.mdx:226-246
Timestamp: 2025-11-03T17:36:13.331Z
Learning: In FastMCP documentation, prefer showing the happy path in onboarding examples without over-explaining edge cases or adding defensive checks, as this reduces cognitive burden for new users learning the API.
Applied to files:
docs/integrations/descope.mdx
⏰ 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). (1)
- GitHub Check: Run tests: Python 3.10 on windows-latest
|
Ok! I'm going to convert it to a draft PR to avoid confusion in that case, feel free to update when ready |
|
@jlowin can you please review this? I added BC for our Inbound Apps, so it's no longer a breaking change. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (3)
src/fastmcp/server/auth/providers/descope.py (3)
113-141: Consider validating the extracted project_id format and adding robustness.The URL parsing logic makes several assumptions about the config_url structure that could break if Descope changes their URL format:
- It assumes the path contains "agentic" followed by the project_id
- It doesn't validate that the extracted project_id matches expected format (e.g., starts with "P")
- If "agentic" appears multiple times in the path, it uses the first occurrence
Consider adding:
- Format validation for the extracted project_id
- More detailed error messages if parsing fails
- Optionally, a regex pattern to extract the project_id more reliably
Example validation:
# Extract project_id from path (format: /v1/apps/agentic/P.../M...) if "agentic" in path_parts: agentic_index = path_parts.index("agentic") if agentic_index + 1 < len(path_parts): self.project_id = path_parts[agentic_index + 1] + # Validate project_id format + if not self.project_id.startswith("P"): + raise ValueError( + f"Extracted project_id '{self.project_id}' does not match expected format (should start with 'P')" + ) else: raise ValueError( f"Could not extract project_id from config_url: {issuer_url}" )
130-136: Optional: Consider exception classes for error messages.Static analysis suggests moving long error messages to exception class attributes per TRY003. However, since these messages include dynamic content (URLs), the current inline approach is acceptable and more readable.
189-206: Consider adding a timeout to the httpx request and refining error handling.The metadata forwarding endpoint could be improved:
- Missing timeout: The httpx request has no timeout, which could cause the endpoint to hang if Descope is slow or unresponsive
- Broad exception handling:
except Exceptioncatches everything, potentially masking specific issues- Error details exposure: Including the exception message in the response could leak sensitive information
Apply this diff to add timeout and improve error handling:
try: async with httpx.AsyncClient() as client: response = await client.get( f"{self.descope_base_url}/v1/apps/{self.project_id}/.well-known/oauth-authorization-server", + timeout=10.0, ) response.raise_for_status() metadata = response.json() return JSONResponse(metadata) + except httpx.TimeoutException: + logger.error("Timeout fetching Descope metadata") + return JSONResponse( + { + "error": "server_error", + "error_description": "Timeout fetching authorization server metadata", + }, + status_code=504, + ) + except httpx.HTTPError as e: + logger.error(f"HTTP error fetching Descope metadata: {e}") + return JSONResponse( + { + "error": "server_error", + "error_description": "Failed to fetch authorization server metadata", + }, + status_code=502, + ) except Exception as e: + logger.error(f"Unexpected error fetching Descope metadata: {e}") return JSONResponse( { "error": "server_error", - "error_description": f"Failed to fetch Descope metadata: {e}", + "error_description": "Internal server error", }, status_code=500, )
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
tests/server/auth/providers/test_descope.pyis excluded by none and included by none
📒 Files selected for processing (1)
src/fastmcp/server/auth/providers/descope.py(5 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
src/fastmcp/server/auth/providers/descope.py (2)
src/fastmcp/server/auth/auth.py (1)
TokenVerifier(170-193)src/fastmcp/server/auth/providers/jwt.py (1)
JWTVerifier(165-498)
🪛 Ruff (0.14.5)
src/fastmcp/server/auth/providers/descope.py
130-132: Avoid specifying long messages outside the exception class
(TRY003)
134-136: Avoid specifying long messages outside the exception class
(TRY003)
153-155: 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). (1)
- GitHub Check: Run tests: Python 3.10 on windows-latest
🔇 Additional comments (6)
src/fastmcp/server/auth/providers/descope.py (6)
10-11: LGTM: Import addition is appropriate.The
urlparseimport is correctly used to extract components from the config_url.
34-37: LGTM: Settings fields support both new and legacy configuration paths.The optional fields allow either the new
config_urlapproach or the legacyproject_id+descope_base_urlapproach, with validation in the constructor ensuring at least one valid configuration is provided.
50-75: LGTM: Documentation clearly guides users to the new recommended approach.The updated instructions reference the MCP Servers page and provide the Well-Known URL format, making onboarding straightforward.
78-86: LGTM: Constructor signature supports both configuration approaches.The addition of
config_urland retention ofproject_id/descope_base_urlenables a graceful migration path for existing users.
157-164: LGTM: JWT verifier configuration correctly uses derived values.The verifier is properly configured with the issuer_url that's derived from either the config_url path or the legacy project_id/descope_base_url path.
166-171: LGTM: Authorization server configuration uses the derived issuer_url.The issuer_url is correctly passed to the RemoteAuthProvider parent class.
Description
Changed the DescopeProvider to take in our new MCP Server well knowns instead of a Project ID and Base URL.
Contributors Checklist
Review Checklist