mirror of
https://github.com/eliasstepanik/core.git
synced 2026-01-12 06:58:27 +00:00
163 lines
4.5 KiB
Markdown
163 lines
4.5 KiB
Markdown
# MCP Auth Proxy
|
|
|
|
A simplified, callback-based authentication and proxy library for Model Context Protocol (MCP) servers with OAuth support.
|
|
|
|
## Features
|
|
|
|
- **🔐 OAuth Authentication**: Handle OAuth flows for any MCP server
|
|
- **📦 In-Memory Processing**: No file storage - everything through callbacks
|
|
- **🔄 Generic Server Support**: Works with any MCP server URL
|
|
- **⚡ Transport Flexibility**: Supports both SSE and HTTP transports
|
|
- **🛡️ Callback-Based Storage**: You control how credentials are saved/loaded
|
|
- **🧹 Self-Contained**: No external dependencies on other packages
|
|
|
|
## Installation
|
|
|
|
```bash
|
|
npm install mcp-auth-proxy
|
|
```
|
|
|
|
## Quick Start
|
|
|
|
### 1. Authentication (Two-Step Process)
|
|
|
|
```typescript
|
|
import { createMCPAuthClient } from 'mcp-auth-proxy'
|
|
|
|
const authClient = createMCPAuthClient(
|
|
{
|
|
serverUrl: 'https://mcp.example.com/sse',
|
|
clientName: 'My App'
|
|
},
|
|
// Callback to save credentials to your database
|
|
async (credentials) => {
|
|
await db.saveCredentials({
|
|
serverUrl: credentials.serverUrl,
|
|
accessToken: credentials.tokens.access_token,
|
|
refreshToken: credentials.tokens.refresh_token,
|
|
expiresAt: credentials.expiresAt
|
|
})
|
|
}
|
|
)
|
|
|
|
// Step 1: Get authorization URL
|
|
const authFlow = await authClient.initiateAuth()
|
|
console.log('Redirect user to:', authFlow.authUrl)
|
|
// Save authFlow.state - you'll need it for step 2
|
|
|
|
// Step 2: Complete authentication (in your OAuth callback route)
|
|
const result = await authClient.completeAuth({
|
|
code: 'code_from_oauth_callback',
|
|
state: authFlow.state // Must match from step 1
|
|
})
|
|
```
|
|
|
|
### 2. Proxy
|
|
|
|
```typescript
|
|
import { createMCPProxy } from 'mcp-auth-proxy'
|
|
|
|
const mcpProxy = createMCPProxy(
|
|
{
|
|
serverUrl: 'https://mcp.example.com/sse'
|
|
},
|
|
// Callback to load credentials from your database
|
|
async (userApiKey, serverUrl) => {
|
|
const creds = await db.getCredentials(userApiKey, serverUrl)
|
|
return creds ? {
|
|
serverUrl: creds.serverUrl,
|
|
tokens: {
|
|
access_token: creds.accessToken,
|
|
refresh_token: creds.refreshToken,
|
|
token_type: 'Bearer',
|
|
expires_in: Math.floor((creds.expiresAt.getTime() - Date.now()) / 1000)
|
|
},
|
|
expiresAt: creds.expiresAt
|
|
} : null
|
|
}
|
|
)
|
|
|
|
// Use in your API route
|
|
export async function POST(request: Request) {
|
|
const userApiKey = getUserApiKey(request)
|
|
return await mcpProxy(request, userApiKey)
|
|
}
|
|
```
|
|
|
|
## API Reference
|
|
|
|
### `createMCPAuthClient(config, onCredentialSave)`
|
|
|
|
Creates an authentication client for OAuth flows.
|
|
|
|
**Parameters:**
|
|
- `config: MCPRemoteClientConfig` - Configuration for the MCP server
|
|
- `onCredentialSave: (credentials: StoredCredentials) => Promise<void>` - Callback to save credentials
|
|
|
|
**Returns:** `MCPAuthenticationClient`
|
|
|
|
### `createMCPProxy(config, onCredentialLoad)`
|
|
|
|
Creates a proxy function for forwarding requests to MCP servers.
|
|
|
|
**Parameters:**
|
|
- `config: ProxyConnectionConfig` - Configuration for the proxy
|
|
- `onCredentialLoad: (userApiKey: string, serverUrl: string) => Promise<ProxyCredentials | null>` - Callback to load credentials
|
|
|
|
**Returns:** `MCPProxyFunction`
|
|
|
|
## Configuration Options
|
|
|
|
### MCPRemoteClientConfig
|
|
|
|
```typescript
|
|
interface MCPRemoteClientConfig {
|
|
serverUrl: string // MCP server URL
|
|
clientName?: string // OAuth client name
|
|
callbackPort?: number // OAuth callback port
|
|
host?: string // Callback host (default: localhost)
|
|
transportStrategy?: TransportStrategy // 'sse-first' | 'http-first' | 'sse-only' | 'http-only'
|
|
headers?: Record<string, string> // Additional headers
|
|
}
|
|
```
|
|
|
|
### ProxyConnectionConfig
|
|
|
|
```typescript
|
|
interface ProxyConnectionConfig {
|
|
serverUrl: string // MCP server URL
|
|
transportStrategy?: TransportStrategy // Transport preference
|
|
timeout?: number // Request timeout (default: 30000ms)
|
|
headers?: Record<string, string> // Additional headers
|
|
}
|
|
```
|
|
|
|
## Error Handling
|
|
|
|
```typescript
|
|
import {
|
|
MCPAuthProxyError,
|
|
InvalidCredentialsError,
|
|
OAuthError,
|
|
TransportError
|
|
} from 'mcp-auth-proxy'
|
|
|
|
try {
|
|
await authClient.authenticate()
|
|
} catch (error) {
|
|
if (error instanceof OAuthError) {
|
|
console.log('OAuth flow failed:', error.message)
|
|
} else if (error instanceof TransportError) {
|
|
console.log('Connection failed:', error.message)
|
|
}
|
|
}
|
|
```
|
|
|
|
## Examples
|
|
|
|
- [Remix Integration](./REMIX_INTEGRATION.md) - Complete Remix.run integration guide
|
|
- [Simple Usage](./examples/simple-usage.ts) - Basic usage examples
|
|
|
|
## License
|
|
|
|
MIT |