example-remote-server/external-oauth/README.md
2025-10-05 23:51:06 -04:00

109 lines
4.6 KiB
Markdown

# External OAuth - External OAuth Provider Pattern
Two standalone servers demonstrating how MCP resource servers integrate with external OAuth providers.
## Overview
Per the [MCP specification](https://modelcontextprotocol.io/specification/2025-06-18/basic/authorization), "the authorization server may be a separate entity." This mode demonstrates the OAuth-as-a-Service pattern.
**Pattern**: MCP resource server delegating all OAuth operations to a separate authorization server.
**Real-world use cases**: Applications using Auth0, Okta, Google OAuth, AWS Cognito, or similar providers for authentication.
## Architecture
```
┌─────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ │ OAuth │ │ Token │ │
│ MCP Client │────────>│ Auth Server │<────────│ MCP Server │
│ │ │ (port 3001) │validate │ (port 3232) │
│ │<────────│ │ │ │
│ │ token │ Issues tokens │ │ Serves MCP │
│ │ │ │ │ resources │
│ │────────────────────────────────────> │ │
│ │ MCP requests with token │ │
└─────────────┘ └─────────────────┘
```
**Servers**:
1. **Auth Server** - Demo OAuth provider (represents Auth0/Okta) - [Details](auth-server/README.md)
2. **MCP Server** - Resource server with token validation only - [Details](mcp-server/README.md)
The MCP server contains no OAuth authorization code - it only validates tokens via introspection.
## Quick Start
```bash
# From repo root:
# 1. Make sure Redis is running
docker compose up -d
# 2. Install dependencies (if not already done)
npm install
# 3. Start both servers
npm run dev:separate
# 4. Test with MCP Inspector
npx -y @modelcontextprotocol/inspector
# Connect to: http://localhost:3232/mcp
# OAuth will redirect to auth server at :3001
```
## Individual Server Commands
```bash
# From repo root:
npm run dev:auth-server # Start just auth server (:3001)
npm run dev:mcp-server # Start just MCP server (:3232)
# Or from individual directories:
cd auth-server && npm run dev
cd mcp-server && npm run dev
```
## Server Roles
**Auth Server** (port 3001): Demo OAuth provider implementing client registration, authorization, token issuance, and introspection. In production, replace with Auth0, Okta, or similar. [Implementation details](auth-server/README.md)
**MCP Server** (port 3232): Resource server that validates tokens via introspection and serves MCP resources. Production-ready - just configure `AUTH_SERVER_URL`. [Implementation details](mcp-server/README.md)
## Testing
```bash
# From repo root:
npm run test:separate # Run all tests (104 total)
npm run test:e2e:separate # Full e2e test
# Individual workspace tests:
npm test --workspace=external-oauth/auth-server # 37 tests
npm test --workspace=external-oauth/mcp-server # 67 tests
```
## Key Differences from Embedded OAuth
| Aspect | Embedded OAuth | External OAuth |
|--------|----------------|---------------|
| Servers | 1 server | 2 servers |
| OAuth endpoints | On MCP server | On auth server |
| Token validation | Direct (in-process) | Remote (introspection API) |
| Deployment | Simpler | Production-like |
| Code sharing | All in one place | Separated by concern |
## Production Adaptation
Replace `auth-server/` with a commercial OAuth provider (Auth0, Okta, AWS Cognito, Azure AD). The `mcp-server/` code integrates with any RFC 7662-compliant introspection endpoint.
## References
- [MCP Authorization Spec](https://modelcontextprotocol.io/specification/2025-06-18/basic/authorization)
- [RFC 7662: Token Introspection](https://datatracker.ietf.org/doc/html/rfc7662)
- [OAuth 2.0 Resource Servers](https://www.oauth.com/oauth2-servers/the-resource-server/)
- [docs/oauth-flow.md](../docs/oauth-flow.md) - Detailed flow analysis
## Next Steps
- See [auth-server/README.md](auth-server/README.md) for OAuth provider implementation
- See [mcp-server/README.md](mcp-server/README.md) for token validation implementation
- Compare with [embedded-oauth](../embedded-oauth/README.md) for self-hosted OAuth alternative