Skip to content

Commit 5c2097a

Browse files
committed
Implement separate Authorization Server (AS) / Resource Server (RS)
1 parent d0443a1 commit 5c2097a

File tree

13 files changed

+1464
-370
lines changed

13 files changed

+1464
-370
lines changed

examples/clients/simple-auth-client/mcp_simple_auth_client/main.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -160,8 +160,7 @@ async def connect(self):
160160
print(f"🔗 Attempting to connect to {self.server_url}...")
161161

162162
try:
163-
# Set up callback server
164-
callback_server = CallbackServer(port=3000)
163+
callback_server = CallbackServer(port=3030)
165164
callback_server.start()
166165

167166
async def callback_handler() -> tuple[str, str | None]:
@@ -175,7 +174,7 @@ async def callback_handler() -> tuple[str, str | None]:
175174

176175
client_metadata_dict = {
177176
"client_name": "Simple Auth Client",
178-
"redirect_uris": ["http://localhost:3000/callback"],
177+
"redirect_uris": ["http://localhost:3030/callback"],
179178
"grant_types": ["authorization_code", "refresh_token"],
180179
"response_types": ["code"],
181180
"token_endpoint_auth_method": "client_secret_post",

examples/servers/simple-auth/README.md

Lines changed: 84 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,91 +1,121 @@
1-
# Simple MCP Server with GitHub OAuth Authentication
1+
# MCP OAuth Authentication Demo
22

3-
This is a simple example of an MCP server with GitHub OAuth authentication. It demonstrates the essential components needed for OAuth integration with just a single tool.
3+
This example demonstrates OAuth 2.0 authentication with the Model Context Protocol using **separate Authorization Server (AS) and Resource Server (RS)** to comply with the new RFC 9728 specification.
44

5-
This is just an example of a server that uses auth, an official GitHub mcp server is [here](https://github.com/github/github-mcp-server)
5+
---
66

7-
## Overview
7+
## Setup Requirements
88

9-
This simple demo to show to set up a server with:
10-
- GitHub OAuth2 authorization flow
11-
- Single tool: `get_user_profile` to retrieve GitHub user information
12-
13-
14-
## Prerequisites
15-
16-
1. Create a GitHub OAuth App:
17-
- Go to GitHub Settings > Developer settings > OAuth Apps > New OAuth App
18-
- Application name: Any name (e.g., "Simple MCP Auth Demo")
19-
- Homepage URL: `http://localhost:8000`
20-
- Authorization callback URL: `http://localhost:8000/github/callback`
21-
- Click "Register application"
22-
- Note down your Client ID and Client Secret
23-
24-
## Required Environment Variables
25-
26-
You MUST set these environment variables before running the server:
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**
2713

14+
**Set environment variables:**
2815
```bash
29-
export MCP_GITHUB_GITHUB_CLIENT_ID="your_client_id_here"
30-
export MCP_GITHUB_GITHUB_CLIENT_SECRET="your_client_secret_here"
16+
export MCP_GITHUB_CLIENT_ID="your_client_id_here"
17+
export MCP_GITHUB_CLIENT_SECRET="your_client_secret_here"
3118
```
3219

33-
The server will not start without these environment variables properly set.
20+
---
3421

22+
## Running the Servers
3523

36-
## Running the Server
24+
### Step 1: Start Authorization Server
3725

3826
```bash
39-
# Set environment variables first (see above)
27+
# Navigate to the simple-auth directory
28+
cd /Users/inna/code/mcp/python-sdk/examples/servers/simple-auth
4029

41-
# Run the server
42-
uv run mcp-simple-auth
30+
# Start Authorization Server on port 9000
31+
python -m mcp_simple_auth.auth_server --port=9000
4332
```
4433

45-
The server will start on `http://localhost:8000`.
34+
**What it provides:**
35+
- OAuth 2.0 flows (registration, authorization, token exchange)
36+
- GitHub OAuth integration for user authentication
37+
- Token introspection endpoint for Resource Servers (`/introspect`)
38+
- User data proxy endpoint (`/github/user`)
4639

47-
### Transport Options
40+
---
4841

49-
This server supports multiple transport protocols that can run on the same port:
42+
### Step 2: Start Resource Server (MCP Server)
5043

51-
#### SSE (Server-Sent Events) - Default
5244
```bash
53-
uv run mcp-simple-auth
54-
# or explicitly:
55-
uv run mcp-simple-auth --transport sse
45+
# In another terminal, navigate to the simple-auth directory
46+
cd /Users/inna/code/mcp/python-sdk/examples/servers/simple-auth
47+
48+
# Start Resource Server on port 8001, connected to Authorization Server
49+
python -m mcp_simple_auth.server --port=8001 --auth-server=http://localhost:9000 --transport=streamable-http
5650
```
5751

58-
SSE transport provides endpoint:
59-
- `/sse`
6052

61-
#### Streamable HTTP
53+
### Step 3: Test with Client
54+
6255
```bash
63-
uv run mcp-simple-auth --transport streamable-http
56+
# Start Resource Server with streamable HTTP
57+
python -m mcp_simple_auth.server --port=8001 --auth-server=http://localhost:9000 --transport=streamable-http
58+
59+
# Start client with streamable HTTP
60+
MCP_SERVER_PORT=8001 MCP_TRANSPORT_TYPE=streamable_http python -m mcp_simple_auth_client.main
6461
```
6562

66-
Streamable HTTP transport provides endpoint:
67-
- `/mcp`
6863

64+
## How It Works
6965

70-
This ensures backward compatibility without needing multiple server instances. When using SSE transport (`--transport sse`), only the `/sse` endpoint is available.
66+
### RFC 9728 Discovery
7167

72-
## Available Tool
68+
**Client → Resource Server:**
69+
```bash
70+
curl http://localhost:8001/.well-known/oauth-protected-resource
71+
```
72+
```json
73+
{
74+
"resource": "http://localhost:8001",
75+
"authorization_servers": ["http://localhost:9000"]
76+
}
77+
```
7378

74-
### get_user_profile
79+
**Client → Authorization Server:**
80+
```bash
81+
curl http://localhost:9000/.well-known/oauth-authorization-server
82+
```
83+
```json
84+
{
85+
"issuer": "http://localhost:9000",
86+
"authorization_endpoint": "http://localhost:9000/authorize",
87+
"token_endpoint": "http://localhost:9000/token"
88+
}
89+
```
7590

76-
The only tool in this simple example. Returns the authenticated user's GitHub profile information.
91+
## Manual Testing
7792

78-
**Required scope**: `user`
93+
### Test Discovery
94+
```bash
95+
# Test Resource Server discovery endpoint
96+
curl -v http://localhost:8001/.well-known/oauth-protected-resource
7997

80-
**Returns**: GitHub user profile data including username, email, bio, etc.
98+
# Test Authorization Server metadata
99+
curl -v http://localhost:9000/.well-known/oauth-authorization-server
100+
```
81101

102+
### Test Token Introspection
103+
```bash
104+
# After getting a token through OAuth flow:
105+
curl -X POST http://localhost:9000/introspect \
106+
-H "Content-Type: application/x-www-form-urlencoded" \
107+
-d "token=your_access_token"
108+
```
82109

83110
## Troubleshooting
84111

85-
If the server fails to start, check:
86-
1. Environment variables `MCP_GITHUB_GITHUB_CLIENT_ID` and `MCP_GITHUB_GITHUB_CLIENT_SECRET` are set
87-
2. The GitHub OAuth app callback URL matches `http://localhost:8000/github/callback`
88-
3. No other service is using port 8000
89-
4. The transport specified is valid (`sse` or `streamable-http`)
112+
| **Issue** | **Solution** |
113+
|-----------|-------------|
114+
| "Environment variables not set" | Set `MCP_GITHUB_CLIENT_ID` and `MCP_GITHUB_CLIENT_SECRET` |
115+
| "Port already in use" | Change port: `--port=8001` |
116+
| "GitHub callback failed" | Update GitHub app callback to `http://localhost:9000/github/callback` |
117+
| "Token introspection failed" | Start Authorization Server first |
118+
| "Client can't discover Authorization Server" | Check Resource Server is configured with `--auth-server` |
119+
| "ModuleNotFoundError: No module named 'mcp_simple_auth'" | Run commands from the `simple-auth` directory as shown above |
120+
| "Resource Server exits immediately" | **Fixed:** This issue was caused by FastMCP auth configuration. The current version should work correctly. |
90121

91-
You can use [Inspector](https://github.com/modelcontextprotocol/inspector) to test Auth

0 commit comments

Comments
 (0)