-
Notifications
You must be signed in to change notification settings - Fork 1.5k
OCI Provider with Docs #2373
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
OCI Provider with Docs #2373
Conversation
WalkthroughThis pull request adds OCI IAM OAuth integration to FastMCP. It introduces a new OCIProvider class that extends OIDCProxy to handle OIDC authentication with Oracle Cloud Infrastructure. The implementation includes OCIProviderSettings for configuration management, validation logic for required fields, and scope parsing. Accompanying documentation is provided with setup instructions, configuration examples, and a complete workflow example showing how to integrate the OCI provider with FastMCP servers and clients. Pre-merge checks and finishing touches✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
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: 14
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (4)
docs/integrations/ociaddapplication.pngis excluded by!**/*.pngand included bydocs/**docs/integrations/ocieditdomainsettings.pngis excluded by!**/*.pngand included bydocs/**docs/integrations/ocieditdomainsettingsbutton.pngis excluded by!**/*.pngand included bydocs/**docs/integrations/ocioauthconfiguration.pngis excluded by!**/*.pngand included bydocs/**
📒 Files selected for processing (2)
docs/integrations/oci.mdx(1 hunks)src/fastmcp/server/auth/providers/ociprovider.py(1 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/oci.mdx
🧬 Code graph analysis (1)
src/fastmcp/server/auth/providers/ociprovider.py (3)
src/fastmcp/server/auth/oidc_proxy.py (1)
OIDCProxy(172-384)src/fastmcp/utilities/auth.py (1)
parse_scopes(9-34)src/fastmcp/utilities/logging.py (1)
get_logger(14-26)
🪛 GitHub Actions: Run static analysis
src/fastmcp/server/auth/providers/ociprovider.py
[error] 1-1: ruff-check failed. 1 error found (fixed by hooks).
[error] 1-1: ruff-format reformatted 1 file.
🪛 Gitleaks (8.28.0)
docs/integrations/oci.mdx
[high] 249-249: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
🪛 LanguageTool
docs/integrations/oci.mdx
[style] ~69-~69: 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). (2)
- GitHub Check: Run tests: Python 3.10 on windows-latest
- GitHub Check: label-issue-or-pr
🔇 Additional comments (4)
src/fastmcp/server/auth/providers/ociprovider.py (3)
173-191: LGTM! Clear validation with helpful error messages.The validation logic properly checks all required fields and provides actionable error messages that guide users to set values via parameters or environment variables.
193-213: LGTM! Proper settings mapping and sensible defaults.The implementation correctly:
- Defaults
required_scopesto["openid"]when not provided- Extracts the secret value from
SecretStr- Passes all settings to the parent
OIDCProxyclass- Logs initialization for debugging
1-1: Formatting issues resolved.The ruff formatting fixes have been successfully applied. The file now passes formatting checks with no remaining issues.
docs/integrations/oci.mdx (1)
1-7: Overall documentation structure is well-organized and comprehensive.The documentation effectively:
- Uses clear sections with progressive disclosure (prerequisites → configuration → token exchange → running → production)
- Provides both basic and advanced examples
- Includes environment variable alternatives
- Uses appropriate Mintlify components (
<Note>,<Info>,<ParamField>, etc.)- Follows the inverted pyramid approach with most important info first
Once the technical corrections and accessibility improvements are applied, this will be excellent documentation.
Also applies to: 17-21, 117-147, 154-199, 201-253
| 4. Open Settings tab. | ||
| 5. Click on "Edit Domain Settings" button. | ||
|
|
||
|  |
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.
Add descriptive alt text for accessibility.
The image uses generic "alt text" placeholder instead of describing the image content, which fails accessibility requirements.
Based on coding guidelines: "Include descriptive alt text for all images and diagrams."
Apply this diff:
-
+📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
|  | |
|  |
🤖 Prompt for AI Agents
In docs/integrations/oci.mdx around line 30 the image uses a placeholder alt
attribute ("alt text"); replace it with a concise, descriptive alt string that
conveys the image content and purpose (e.g., describe the button and the UI
context such as "OCI console — Edit Domain Settings button") so the markdown
image tag reads with a meaningful alt value for accessibility and screen
readers.
|
|
||
| 6. Enable "Configure client access" checkbox as show in the screenshot. | ||
|
|
||
|  |
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.
Add descriptive alt text for accessibility.
Apply this diff:
-
+📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
|  | |
|  |
🤖 Prompt for AI Agents
In docs/integrations/oci.mdx around line 34, the image uses a non-descriptive
alt text ("alt text") which hurts accessibility; replace it with a concise,
descriptive alt string that explains the image contents (e.g., "OCI Console —
Edit Domain Settings screenshot showing Domain Name and Configuration options")
so screen readers convey the image purpose; update the markdown image tag to use
that descriptive alt text.
| 7. Select Launch workflow. | ||
| 8. In the Add application details page, Enter name and description as shown below. | ||
|
|
||
|  |
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.
Add descriptive alt text for accessibility.
Apply this diff:
-
+📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
|  | |
|  |
🤖 Prompt for AI Agents
In docs/integrations/oci.mdx around line 48, the image uses a non-descriptive
alt attribute ("alt text"); replace it with meaningful descriptive alt text that
conveys the image content and purpose (e.g., what UI or step is shown and any
key labels or actions visible) so screen readers can understand the image;
ensure the alt text is concise, specific to the screenshot (not the filename)
and describes the relevant information a reader needs from the image.
| 10. Click on "Edit OAuth configuration" button. | ||
| 11. Configure the application as OAuth client by selecting "Configure this application as a client now" radio button. | ||
| 12. Select "Authorization code" grant type. If you are planning to use the same OAuth client application for token exchange then select "Client credentials" grant type as well. In the sample, we will use the same client. | ||
| 13. For Authorization grant type, select redirect URL. This is, in most cases, will be MCP server URL followed by "/oauth/callback". |
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.
Inconsistent redirect path in documentation.
Line 54 states the redirect URL is /oauth/callback, but the code implementation uses /auth/callback as the default (line 236 confirms FASTMCP_SERVER_AUTH_OCI_REDIRECT_PATH defaults to /auth/callback).
Apply this diff:
-13. For Authorization grant type, select redirect URL. This is, in most cases, will be MCP server URL followed by "/oauth/callback".
+13. For Authorization grant type, select redirect URL. This is, in most cases, will be MCP server URL followed by "/auth/callback".📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| 13. For Authorization grant type, select redirect URL. This is, in most cases, will be MCP server URL followed by "/oauth/callback". | |
| 13. For Authorization grant type, select redirect URL. This is, in most cases, will be MCP server URL followed by "/auth/callback". |
🤖 Prompt for AI Agents
In docs/integrations/oci.mdx around line 54, the redirect URL is documented as
"/oauth/callback" but the code default and env var
(FASTMCP_SERVER_AUTH_OCI_REDIRECT_PATH) use "/auth/callback"; update the
documentation to use "/auth/callback" (or explicitly state that the redirect
path is configurable via FASTMCP_SERVER_AUTH_OCI_REDIRECT_PATH and defaults to
"/auth/callback") so the docs match the implementation.
| 12. Select "Authorization code" grant type. If you are planning to use the same OAuth client application for token exchange then select "Client credentials" grant type as well. In the sample, we will use the same client. | ||
| 13. For Authorization grant type, select redirect URL. This is, in most cases, will be MCP server URL followed by "/oauth/callback". | ||
|
|
||
|  |
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.
Add descriptive alt text for accessibility.
Apply this diff:
-
+📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
|  | |
|  |
🤖 Prompt for AI Agents
In docs/integrations/oci.mdx around line 56, the image tag uses non-descriptive
alt text ("alt text"); replace it with a concise, meaningful description of the
image content and purpose (e.g., "OCI OAuth configuration screen showing client
ID, client secret, and redirect URI fields" or similar) so it conveys the image
to screen-reader users; update only the alt attribute text to accurately reflect
the screenshot's contents and intent.
|
|
||
| # OCI IAM configuration and credentials | ||
| FASTMCP_SERVER_AUTH_OCI_CONFIG_URL=https://{IDCS_GUID}.identity.oraclecloud.com/.well-known/openid-configuration | ||
| FASTMCP_SERVER_AUTH_OCI_CLIENT_ID=tv2ObNgaZAWWhhycr7Bz1LU2mxlnsmsB |
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.
Remove potentially real client ID from documentation.
Line 249 contains what appears to be a real client ID (tv2ObNgaZAWWhhycr7Bz1LU2mxlnsmsB), which was also flagged by Gitleaks as a potential secret. Even if this is a fake example, it's identical to line 173 and should use a placeholder.
Based on static analysis hints.
Apply this diff:
-FASTMCP_SERVER_AUTH_OCI_CLIENT_ID=tv2ObNgaZAWWhhycr7Bz1LU2mxlnsmsB
+FASTMCP_SERVER_AUTH_OCI_CLIENT_ID=your_oci_client_id_here📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| FASTMCP_SERVER_AUTH_OCI_CLIENT_ID=tv2ObNgaZAWWhhycr7Bz1LU2mxlnsmsB | |
| FASTMCP_SERVER_AUTH_OCI_CLIENT_ID=your_oci_client_id_here |
🧰 Tools
🪛 Gitleaks (8.28.0)
[high] 249-249: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
🤖 Prompt for AI Agents
In docs/integrations/oci.mdx around line 249, replace the actual-looking client
ID value (tv2ObNgaZAWWhhycr7Bz1LU2mxlnsmsB) with a non-sensitive placeholder
(e.g. FASTMCP_SERVER_AUTH_OCI_CLIENT_ID=REPLACE_WITH_OCI_CLIENT_ID or
FASTMCP_SERVER_AUTH_OCI_CLIENT_ID=${OCI_CLIENT_ID}); also check and replace the
identical value at line 173 to avoid leaking secrets and re-run the secret
scanner to confirm removal.
| token = get_access_token() | ||
| user = token.claims.get("sub") | ||
| return f"You are User: {user}" |
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.
Add missing import to make example complete.
The whoami function uses get_access_token() but the import is not shown in this code block.
Apply this diff:
```python server.py
from fastmcp import FastMCP
+from fastmcp.server.dependencies import get_access_token
# Authentication is automatically configured from environment🤖 Prompt for AI Agents
In docs/integrations/oci.mdx around lines 267 to 269 the example calls
get_access_token() but does not show its import; add an import line for
get_access_token from fastmcp.server.dependencies alongside the existing FastMCP
import (i.e., insert "from fastmcp.server.dependencies import get_access_token"
near the top of the Python example imports) so the whoami example is complete
and runnable.
| """OCI OIDC provider for FastMCP. | ||
|
|
||
| The pull request for the provider is submitted to fastmcp. | ||
|
|
||
| This module provides OIDC Implementation to integrate MCP servers with OCI. | ||
| You only need OCI Identity Domain's discovery URL, client ID, client secret, and base URL. | ||
|
|
||
| Post Authentication, you get OCI IAM domain access token. That is not authorized to invoke OCI control plane. | ||
| You need to exchange the IAM domain access token for OCI UPST token to invoke OCI control plane APIs. | ||
| The sample code below has get_oci_signer function that returns OCI TokenExchangeSigner object. | ||
| You can use the signer object to create OCI service object. | ||
|
|
||
| Example: | ||
| ```python | ||
| from fastmcp import FastMCP | ||
| from fastmcp.server.auth.providers.ociprovider import OCIProvider | ||
|
|
||
| import oci | ||
| from oci.auth.signers import TokenExchangeSigner | ||
|
|
||
| # Simple OCI OIDC protection | ||
| auth = OCIProvider( | ||
| config_url="https://{IDCS_GUID}.identity.oraclecloud.com/.well-known/openid-configuration", | ||
| client_id="oci-iamdomain-app-client-id", | ||
| client_secret="idcscs1234-121s23*****", | ||
| base_url="http://localhost:8000", | ||
| ) | ||
|
|
||
| _global_token_cache = {} #In memory cache for OCI session token signer | ||
|
|
||
| def get_oci_signer() -> TokenExchangeSigner: | ||
|
|
||
| #Check if the signer exists for the token ID in memory cache | ||
| cached_signer = _global_token_cache.get(tokenID) | ||
| logger.debug(f"Global cached signer: {cached_signer}") | ||
| if cached_signer: | ||
| logger.debug(f"Using globally cached signer for token ID: {tokenID}") | ||
| return cached_signer | ||
|
|
||
| #If the signer is not yet created for the token then create new OCI signer object | ||
| logger.debug(f"Creating new signer for token ID: {tokenID}") | ||
| signer = TokenExchangeSigner( | ||
| jwt_or_func=token, | ||
| oci_domain_id=IAM_GUID, | ||
| client_id=IAM_TOKENEXCHANGE_CLIENT_ID, | ||
| client_secret=IAM_TOKENEXCHANGE_CLIENT_SECRET | ||
| ) | ||
| logger.debug(f"Signer {signer} created for token ID: {tokenID}") | ||
|
|
||
| #Cache the signer object in memory cache | ||
| _global_token_cache[tokenID] = signer | ||
| logger.debug(f"Signer cached for token ID: {tokenID}") | ||
|
|
||
| return signer | ||
|
|
||
| mcp = FastMCP("My Protected Server", auth=auth) | ||
| ``` | ||
| """ |
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.
Fix incomplete and non-functional example code in module docstring.
The example code in the module docstring has several issues that would prevent it from working:
- Line 3 contains PR metadata that should be removed
- Lines 29-54 reference undefined variables (
tokenID,token,IAM_GUID,IAM_TOKENEXCHANGE_CLIENT_ID,IAM_TOKENEXCHANGE_CLIENT_SECRET) - The example mixes setup code with runtime logic without clear boundaries
- Missing imports for
ociandTokenExchangeSigner
The example should either:
- Be complete with all necessary variable definitions and imports, OR
- Focus only on the
OCIProviderinitialization and refer users to the documentation for token exchange details
Consider moving the token exchange example to the documentation file where it can be properly explained with full context.
🧰 Tools
🪛 GitHub Actions: Run static analysis
[error] 1-1: ruff-check failed. 1 error found (fixed by hooks).
[error] 1-1: ruff-format reformatted 1 file.
🤖 Prompt for AI Agents
In src/fastmcp/server/auth/providers/ociprovider.py around lines 1 to 58, remove
the stray PR metadata on line 3, simplify the module docstring example to a
minimal, functional snippet that only demonstrates OCIProvider initialization
with required imports and clearly defined placeholders for config_url,
client_id, client_secret, and base_url; do not include the token-exchange
runtime logic in the docstring — instead either move the full
TokenExchangeSigner example to external docs or add a short note pointing to
documentation for token exchange details, and if you must keep a token-exchange
snippet in docs ensure all variables (tokenID, token, IAM_GUID,
IAM_TOKENEXCHANGE_CLIENT_ID, IAM_TOKENEXCHANGE_CLIENT_SECRET) are defined or
replaced with clearly marked placeholders and add missing imports (e.g., oci and
TokenExchangeSigner).
| from pydantic_settings import BaseSettings, SettingsConfigDict | ||
|
|
||
| from fastmcp.server.auth.oidc_proxy import OIDCProxy | ||
| from fastmcp.server.dependencies import get_access_token |
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.
Remove unused import.
get_access_token is imported but never used in this file.
Apply this diff:
from fastmcp.server.auth.oidc_proxy import OIDCProxy
-from fastmcp.server.dependencies import get_access_token
from fastmcp.settings import ENV_FILE📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| from fastmcp.server.dependencies import get_access_token | |
| from fastmcp.server.auth.oidc_proxy import OIDCProxy | |
| from fastmcp.settings import ENV_FILE |
🤖 Prompt for AI Agents
In src/fastmcp/server/auth/providers/ociprovider.py around line 65, the module
imports get_access_token from fastmcp.server.dependencies but doesn't use it;
remove the unused import line to clean up the file and avoid linter warnings,
then run tests or linting to ensure no other references to get_access_token
remain.
| allowed_client_redirect_uris: list[str] | NotSetT = NotSet, | ||
| client_storage: AsyncKeyValue | None = None, | ||
| jwt_signing_key: str | bytes | NotSetT = NotSet, | ||
| require_authorization_consent: bool = False, |
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.
Security concern: require_authorization_consent defaults to False.
Setting require_authorization_consent=False bypasses the consent screen and differs from the parent OIDCProxy default of True. This means users won't see a confirmation before being redirected to OCI IAM for authentication.
According to the parent class documentation: "SECURITY WARNING: Only disable for local development or testing environments."
Consider either:
- Changing the default to
Trueto match the parent class and maintain security best practices - If
Falseis intentional for OCI, add a clear comment explaining why and warning users about the security implications
- require_authorization_consent: bool = False,
+ require_authorization_consent: bool = True, # Set to False only for local dev/testing📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| require_authorization_consent: bool = False, | |
| require_authorization_consent: bool = True, # Set to False only for local dev/testing |
🤖 Prompt for AI Agents
In src/fastmcp/server/auth/providers/ociprovider.py around line 138, the
parameter require_authorization_consent is defaulting to False which weakens
security compared to the parent OIDCProxy default of True; either change the
default to True to match the parent and preserve the consent screen, or if False
is intentional add a clear inline comment explaining why it's disabled, include
a SECURITY WARNING that it should only be used for local/dev/testing, and
ideally guard the False default behind an explicit dev-only configuration flag
or environment check.
|
Duplicate |
Description
Contributors Checklist
Review Checklist