Skip to content

Commit 4fbf1b2

Browse files
Merge branch 'main' into fix/windows_stdio_subprocess
2 parents 0f5f3fd + a027d75 commit 4fbf1b2

File tree

35 files changed

+804
-1248
lines changed

35 files changed

+804
-1248
lines changed

README.md

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,7 @@ mcp = FastMCP("My App",
334334
)
335335
```
336336

337-
See [OAuthServerProvider](mcp/server/auth/provider.py) for more details.
337+
See [OAuthServerProvider](src/mcp/server/auth/provider.py) for more details.
338338

339339
## Running Your Server
340340

@@ -410,32 +410,45 @@ app = Starlette(
410410
app.router.routes.append(Host('mcp.acme.corp', app=mcp.sse_app()))
411411
```
412412

413-
For more information on mounting applications in Starlette, see the [Starlette documentation](https://www.starlette.io/routing/#submounting-routes).
414-
415-
#### Message Dispatch Options
416-
417-
By default, the SSE server uses an in-memory message dispatch system for incoming POST messages. For production deployments or distributed scenarios, you can use Redis or implement your own message dispatch system that conforms to the `MessageDispatch` protocol:
413+
When mounting multiple MCP servers under different paths, you can configure the mount path in several ways:
418414

419415
```python
420-
# Using the built-in Redis message dispatch
416+
from starlette.applications import Starlette
417+
from starlette.routing import Mount
421418
from mcp.server.fastmcp import FastMCP
422-
from mcp.server.message_queue import RedisMessageDispatch
423419

424-
# Create a Redis message dispatch
425-
redis_dispatch = RedisMessageDispatch(
426-
redis_url="redis://localhost:6379/0", prefix="mcp:pubsub:"
427-
)
420+
# Create multiple MCP servers
421+
github_mcp = FastMCP("GitHub API")
422+
browser_mcp = FastMCP("Browser")
423+
curl_mcp = FastMCP("Curl")
424+
search_mcp = FastMCP("Search")
428425

429-
# Pass the message dispatch instance to the server
430-
mcp = FastMCP("My App", message_queue=redis_dispatch)
431-
```
426+
# Method 1: Configure mount paths via settings (recommended for persistent configuration)
427+
github_mcp.settings.mount_path = "/github"
428+
browser_mcp.settings.mount_path = "/browser"
432429

433-
To use Redis, add the Redis dependency:
430+
# Method 2: Pass mount path directly to sse_app (preferred for ad-hoc mounting)
431+
# This approach doesn't modify the server's settings permanently
434432

435-
```bash
436-
uv add "mcp[redis]"
433+
# Create Starlette app with multiple mounted servers
434+
app = Starlette(
435+
routes=[
436+
# Using settings-based configuration
437+
Mount("/github", app=github_mcp.sse_app()),
438+
Mount("/browser", app=browser_mcp.sse_app()),
439+
# Using direct mount path parameter
440+
Mount("/curl", app=curl_mcp.sse_app("/curl")),
441+
Mount("/search", app=search_mcp.sse_app("/search")),
442+
]
443+
)
444+
445+
# Method 3: For direct execution, you can also pass the mount path to run()
446+
if __name__ == "__main__":
447+
search_mcp.run(transport="sse", mount_path="/search")
437448
```
438449

450+
For more information on mounting applications in Starlette, see the [Starlette documentation](https://www.starlette.io/routing/#submounting-routes).
451+
439452
## Examples
440453

441454
### Echo Server
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# Simple MCP Server with GitHub OAuth Authentication
2+
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.
4+
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)
6+
7+
## Overview
8+
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:
27+
28+
```bash
29+
export MCP_GITHUB_GITHUB_CLIENT_ID="your_client_id_here"
30+
export MCP_GITHUB_GITHUB_CLIENT_SECRET="your_client_secret_here"
31+
```
32+
33+
The server will not start without these environment variables properly set.
34+
35+
36+
## Running the Server
37+
38+
```bash
39+
# Set environment variables first (see above)
40+
41+
# Run the server
42+
uv run mcp-simple-auth
43+
```
44+
45+
The server will start on `http://localhost:8000`.
46+
47+
## Available Tool
48+
49+
### get_user_profile
50+
51+
The only tool in this simple example. Returns the authenticated user's GitHub profile information.
52+
53+
**Required scope**: `user`
54+
55+
**Returns**: GitHub user profile data including username, email, bio, etc.
56+
57+
58+
## Troubleshooting
59+
60+
If the server fails to start, check:
61+
1. Environment variables `MCP_GITHUB_GITHUB_CLIENT_ID` and `MCP_GITHUB_GITHUB_CLIENT_SECRET` are set
62+
2. The GitHub OAuth app callback URL matches `http://localhost:8000/github/callback`
63+
3. No other service is using port 8000
64+
65+
You can use [Inspector](https://github.com/modelcontextprotocol/inspector) to test Auth
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
"""Simple MCP server with GitHub OAuth authentication."""
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
"""Main entry point for simple MCP server with GitHub OAuth authentication."""
2+
3+
import sys
4+
5+
from mcp_simple_auth.server import main
6+
7+
sys.exit(main())

0 commit comments

Comments
 (0)