Skip to content

Commit ce007de

Browse files
authored
Remove github from auth examples (#1011)
1 parent ecc9165 commit ce007de

File tree

6 files changed

+376
-502
lines changed

6 files changed

+376
-502
lines changed

examples/servers/simple-auth/README.md

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,6 @@ This example demonstrates OAuth 2.0 authentication with the Model Context Protoc
44

55
---
66

7-
## Setup Requirements
8-
9-
**Create a GitHub OAuth App:**
10-
- Go to GitHub Settings > Developer settings > OAuth Apps > New OAuth App
11-
- **Authorization callback URL:** `http://localhost:9000/github/callback`
12-
- Note down your **Client ID** and **Client Secret**
13-
14-
**Set environment variables:**
15-
```bash
16-
export MCP_GITHUB_CLIENT_ID="your_client_id_here"
17-
export MCP_GITHUB_CLIENT_SECRET="your_client_secret_here"
18-
```
19-
20-
---
217

228
## Running the Servers
239

@@ -33,9 +19,8 @@ uv run mcp-simple-auth-as --port=9000
3319

3420
**What it provides:**
3521
- OAuth 2.0 flows (registration, authorization, token exchange)
36-
- GitHub OAuth integration for user authentication
22+
- Simple credential-based authentication (no external provider needed)
3723
- Token introspection endpoint for Resource Servers (`/introspect`)
38-
- User data proxy endpoint (`/github/user`)
3924

4025
---
4126

@@ -90,6 +75,7 @@ curl http://localhost:9000/.well-known/oauth-authorization-server
9075
}
9176
```
9277

78+
9379
## Legacy MCP Server as Authorization Server (Backwards Compatibility)
9480

9581
For backwards compatibility with older MCP implementations, a legacy server is provided that acts as an Authorization Server (following the old spec where MCP servers could optionally provide OAuth):

examples/servers/simple-auth/mcp_simple_auth/auth_server.py

Lines changed: 40 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@
77
NOTE: this is a simplified example for demonstration purposes.
88
This is not a production-ready implementation.
99
10-
Usage:
11-
python -m mcp_simple_auth.auth_server --port=9000
1210
"""
1311

1412
import asyncio
@@ -20,14 +18,14 @@
2018
from starlette.applications import Starlette
2119
from starlette.exceptions import HTTPException
2220
from starlette.requests import Request
23-
from starlette.responses import JSONResponse, RedirectResponse, Response
21+
from starlette.responses import JSONResponse, Response
2422
from starlette.routing import Route
2523
from uvicorn import Config, Server
2624

2725
from mcp.server.auth.routes import cors_middleware, create_auth_routes
2826
from mcp.server.auth.settings import AuthSettings, ClientRegistrationOptions
2927

30-
from .github_oauth_provider import GitHubOAuthProvider, GitHubOAuthSettings
28+
from .simple_auth_provider import SimpleAuthSettings, SimpleOAuthProvider
3129

3230
logger = logging.getLogger(__name__)
3331

@@ -39,60 +37,64 @@ class AuthServerSettings(BaseModel):
3937
host: str = "localhost"
4038
port: int = 9000
4139
server_url: AnyHttpUrl = AnyHttpUrl("http://localhost:9000")
42-
github_callback_path: str = "http://localhost:9000/github/callback"
40+
auth_callback_path: str = "http://localhost:9000/login/callback"
4341

4442

45-
class GitHubProxyAuthProvider(GitHubOAuthProvider):
43+
class SimpleAuthProvider(SimpleOAuthProvider):
4644
"""
47-
Authorization Server provider that proxies GitHub OAuth.
45+
Authorization Server provider with simple demo authentication.
4846
4947
This provider:
50-
1. Issues MCP tokens after GitHub authentication
48+
1. Issues MCP tokens after simple credential authentication
5149
2. Stores token state for introspection by Resource Servers
52-
3. Maps MCP tokens to GitHub tokens for API access
5350
"""
5451

55-
def __init__(self, github_settings: GitHubOAuthSettings, github_callback_path: str):
56-
super().__init__(github_settings, github_callback_path)
52+
def __init__(self, auth_settings: SimpleAuthSettings, auth_callback_path: str, server_url: str):
53+
super().__init__(auth_settings, auth_callback_path, server_url)
5754

5855

59-
def create_authorization_server(server_settings: AuthServerSettings, github_settings: GitHubOAuthSettings) -> Starlette:
56+
def create_authorization_server(server_settings: AuthServerSettings, auth_settings: SimpleAuthSettings) -> Starlette:
6057
"""Create the Authorization Server application."""
61-
oauth_provider = GitHubProxyAuthProvider(github_settings, server_settings.github_callback_path)
58+
oauth_provider = SimpleAuthProvider(
59+
auth_settings, server_settings.auth_callback_path, str(server_settings.server_url)
60+
)
6261

63-
auth_settings = AuthSettings(
62+
mcp_auth_settings = AuthSettings(
6463
issuer_url=server_settings.server_url,
6564
client_registration_options=ClientRegistrationOptions(
6665
enabled=True,
67-
valid_scopes=[github_settings.mcp_scope],
68-
default_scopes=[github_settings.mcp_scope],
66+
valid_scopes=[auth_settings.mcp_scope],
67+
default_scopes=[auth_settings.mcp_scope],
6968
),
70-
required_scopes=[github_settings.mcp_scope],
69+
required_scopes=[auth_settings.mcp_scope],
7170
resource_server_url=None,
7271
)
7372

7473
# Create OAuth routes
7574
routes = create_auth_routes(
7675
provider=oauth_provider,
77-
issuer_url=auth_settings.issuer_url,
78-
service_documentation_url=auth_settings.service_documentation_url,
79-
client_registration_options=auth_settings.client_registration_options,
80-
revocation_options=auth_settings.revocation_options,
76+
issuer_url=mcp_auth_settings.issuer_url,
77+
service_documentation_url=mcp_auth_settings.service_documentation_url,
78+
client_registration_options=mcp_auth_settings.client_registration_options,
79+
revocation_options=mcp_auth_settings.revocation_options,
8180
)
8281

83-
# Add GitHub callback route
84-
async def github_callback_handler(request: Request) -> Response:
85-
"""Handle GitHub OAuth callback."""
86-
code = request.query_params.get("code")
82+
# Add login page route (GET)
83+
async def login_page_handler(request: Request) -> Response:
84+
"""Show login form."""
8785
state = request.query_params.get("state")
86+
if not state:
87+
raise HTTPException(400, "Missing state parameter")
88+
return await oauth_provider.get_login_page(state)
8889

89-
if not code or not state:
90-
raise HTTPException(400, "Missing code or state parameter")
90+
routes.append(Route("/login", endpoint=login_page_handler, methods=["GET"]))
9191

92-
redirect_uri = await oauth_provider.handle_github_callback(code, state)
93-
return RedirectResponse(url=redirect_uri, status_code=302)
92+
# Add login callback route (POST)
93+
async def login_callback_handler(request: Request) -> Response:
94+
"""Handle simple authentication callback."""
95+
return await oauth_provider.handle_login_callback(request)
9496

95-
routes.append(Route("/github/callback", endpoint=github_callback_handler, methods=["GET"]))
97+
routes.append(Route("/login/callback", endpoint=login_callback_handler, methods=["POST"]))
9698

9799
# Add token introspection endpoint (RFC 7662) for Resource Servers
98100
async def introspect_handler(request: Request) -> Response:
@@ -112,7 +114,6 @@ async def introspect_handler(request: Request) -> Response:
112114
if not access_token:
113115
return JSONResponse({"active": False})
114116

115-
# Return token info for Resource Server
116117
return JSONResponse(
117118
{
118119
"active": True,
@@ -133,39 +134,12 @@ async def introspect_handler(request: Request) -> Response:
133134
)
134135
)
135136

136-
# Add GitHub user info endpoint (for Resource Server to fetch user data)
137-
async def github_user_handler(request: Request) -> Response:
138-
"""
139-
Proxy endpoint to get GitHub user info using stored GitHub tokens.
140-
141-
Resource Servers call this with MCP tokens to get GitHub user data
142-
without exposing GitHub tokens to clients.
143-
"""
144-
# Extract Bearer token
145-
auth_header = request.headers.get("authorization", "")
146-
if not auth_header.startswith("Bearer "):
147-
return JSONResponse({"error": "unauthorized"}, status_code=401)
148-
149-
mcp_token = auth_header[7:]
150-
151-
# Get GitHub user info using the provider method
152-
user_info = await oauth_provider.get_github_user_info(mcp_token)
153-
return JSONResponse(user_info)
154-
155-
routes.append(
156-
Route(
157-
"/github/user",
158-
endpoint=cors_middleware(github_user_handler, ["GET", "OPTIONS"]),
159-
methods=["GET", "OPTIONS"],
160-
)
161-
)
162-
163137
return Starlette(routes=routes)
164138

165139

166-
async def run_server(server_settings: AuthServerSettings, github_settings: GitHubOAuthSettings):
140+
async def run_server(server_settings: AuthServerSettings, auth_settings: SimpleAuthSettings):
167141
"""Run the Authorization Server."""
168-
auth_server = create_authorization_server(server_settings, github_settings)
142+
auth_server = create_authorization_server(server_settings, auth_settings)
169143

170144
config = Config(
171145
auth_server,
@@ -175,22 +149,7 @@ async def run_server(server_settings: AuthServerSettings, github_settings: GitHu
175149
)
176150
server = Server(config)
177151

178-
logger.info("=" * 80)
179-
logger.info("MCP AUTHORIZATION SERVER")
180-
logger.info("=" * 80)
181-
logger.info(f"Server URL: {server_settings.server_url}")
182-
logger.info("Endpoints:")
183-
logger.info(f" - OAuth Metadata: {server_settings.server_url}/.well-known/oauth-authorization-server")
184-
logger.info(f" - Client Registration: {server_settings.server_url}/register")
185-
logger.info(f" - Authorization: {server_settings.server_url}/authorize")
186-
logger.info(f" - Token Exchange: {server_settings.server_url}/token")
187-
logger.info(f" - Token Introspection: {server_settings.server_url}/introspect")
188-
logger.info(f" - GitHub Callback: {server_settings.server_url}/github/callback")
189-
logger.info(f" - GitHub User Proxy: {server_settings.server_url}/github/user")
190-
logger.info("")
191-
logger.info("Resource Servers should use /introspect to validate tokens")
192-
logger.info("Configure GitHub App callback URL: " + server_settings.github_callback_path)
193-
logger.info("=" * 80)
152+
logger.info(f"🚀 MCP Authorization Server running on {server_settings.server_url}")
194153

195154
await server.serve()
196155

@@ -203,18 +162,12 @@ def main(port: int) -> int:
203162
204163
This server handles OAuth flows and can be used by multiple Resource Servers.
205164
206-
Environment variables needed:
207-
- MCP_GITHUB_CLIENT_ID: GitHub OAuth Client ID
208-
- MCP_GITHUB_CLIENT_SECRET: GitHub OAuth Client Secret
165+
Uses simple hardcoded credentials for demo purposes.
209166
"""
210167
logging.basicConfig(level=logging.INFO)
211168

212-
# Load GitHub settings from environment variables
213-
github_settings = GitHubOAuthSettings()
214-
215-
# Validate required fields
216-
if not github_settings.github_client_id or not github_settings.github_client_secret:
217-
raise ValueError("GitHub credentials not provided")
169+
# Load simple auth settings
170+
auth_settings = SimpleAuthSettings()
218171

219172
# Create server settings
220173
host = "localhost"
@@ -223,10 +176,10 @@ def main(port: int) -> int:
223176
host=host,
224177
port=port,
225178
server_url=AnyHttpUrl(server_url),
226-
github_callback_path=f"{server_url}/github/callback",
179+
auth_callback_path=f"{server_url}/login",
227180
)
228181

229-
asyncio.run(run_server(server_settings, github_settings))
182+
asyncio.run(run_server(server_settings, auth_settings))
230183
return 0
231184

232185

0 commit comments

Comments
 (0)