feat(mcp): Add OAuth 2.0 authentication support for MCP servers#2842
Merged
amitksingh1490 merged 16 commits intomainfrom Apr 8, 2026
Merged
feat(mcp): Add OAuth 2.0 authentication support for MCP servers#2842amitksingh1490 merged 16 commits intomainfrom
amitksingh1490 merged 16 commits intomainfrom
Conversation
- Add McpOAuthConfig and McpOAuthSetting to configure OAuth per server - Implement mcp_auth, mcp_logout, mcp_auth_status API methods - Add McpCredentialStore for persistent token storage with 0o600 permissions - Implement McpTokenStorage adapter for rmcp's CredentialStore trait - Support auto-detection of OAuth via 401 responses, explicit config, or disabled - Add CLI commands: `mcp login <name>` and `mcp logout <name|all>` - Integrate rmcp's OAuth state machine with PKCE, dynamic registration, metadata discovery - Open browser automatically and run local callback server for authorization flow
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
- Add `allow_interactive` parameter to control OAuth flow behavior - Prevent browser popups during normal MCP connections - Add automatic MCP reload after auth/login/logout operations - Update refresh_cache to avoid eager connections during reload
Comment on lines
+84
to
+87
| use std::os::unix::fs::PermissionsExt; | ||
| let mut perms = std::fs::metadata(&path)?.permissions(); | ||
| perms.set_mode(0o600); | ||
| std::fs::set_permissions(&path, perms)?; |
Contributor
There was a problem hiding this comment.
Blocking I/O in async function: Uses synchronous std::fs operations (std::fs::metadata and std::fs::set_permissions) inside an async function, which will block the async runtime.
#[cfg(unix)]
{
use std::os::unix::fs::PermissionsExt;
use tokio::fs as async_fs;
let metadata = async_fs::metadata(&path).await?;
let mut perms = metadata.permissions();
perms.set_mode(0o600);
async_fs::set_permissions(&path, perms).await?;
}
Suggested change
| use std::os::unix::fs::PermissionsExt; | |
| let mut perms = std::fs::metadata(&path)?.permissions(); | |
| perms.set_mode(0o600); | |
| std::fs::set_permissions(&path, perms)?; | |
| #[cfg(unix)] | |
| { | |
| use std::os::unix::fs::PermissionsExt; | |
| use tokio::fs as async_fs; | |
| let metadata = async_fs::metadata(&path).await?; | |
| let mut perms = metadata.permissions(); | |
| perms.set_mode(0o600); | |
| async_fs::set_permissions(&path, perms).await?; | |
| } | |
Spotted by Graphite
Is this helpful? React 👍 or 👎 to let us know.
crates/forge_infra/src/mcp_client.rs
Outdated
Comment on lines
+608
to
+612
| let mut auth_manager = AuthorizationManager::new(server_url) | ||
| .await | ||
| .map_err(|e| anyhow::anyhow!("Failed to create OAuth manager: {}", e))?; | ||
|
|
||
| auth_manager.set_credential_store(credential_store); |
Contributor
There was a problem hiding this comment.
Dead code: Creates an AuthorizationManager with credential store but never uses it. The OAuth flow is immediately started with a fresh OAuthState on line 615, making this initialization wasteful and misleading.
// Remove these unused lines:
// let mut auth_manager = AuthorizationManager::new(server_url)
// .await
// .map_err(|e| anyhow::anyhow!("Failed to create OAuth manager: {}", e))?;
// auth_manager.set_credential_store(credential_store);Spotted by Graphite
Is this helpful? React 👍 or 👎 to let us know.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Add OAuth 2.0 authentication support for MCP (Model Context Protocol) servers, enabling secure delegated access through standardized OAuth flows including PKCE, dynamic client registration, and automatic metadata discovery.
Context
MCP servers often require authentication to access protected resources. This change adds full OAuth 2.0 support to Forge, allowing users to authenticate with MCP servers that require OAuth (e.g., Slack, GitHub, Google APIs). The implementation follows the OAuth 2.0 standard with PKCE for security, supports automatic discovery of authorization server metadata (RFC 8414), and includes dynamic client registration when servers don't require pre-registered clients.
Changes
OAuth Configuration: Added
McpOAuthConfigandMcpOAuthSettingtypes to configure OAuth per-server with support for:Credential Storage: Implemented
McpCredentialStorefor secure token persistence:McpTokenStorageadapter for rmcp'sCredentialStoretraitAPI Methods: Added three new API methods:
mcp_auth(server_url): Initiates OAuth flow with browser auto-open and local callback servermcp_logout(server_url): Removes stored credentials for a specific server or all serversmcp_auth_status(server_url): Checks authentication statusCLI Commands: Added new CLI commands:
forge mcp login <name>: Authenticate with a specific MCP serverforge mcp logout <name|all>: Logout from a specific server or all serversOAuth Flow Integration: Integrated rmcp's OAuth state machine:
Key Implementation Details
http://127.0.0.1:8765/mcp/callbackas the redirect URIUse Cases
Testing
Links
closes #2777