You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Per-server oauth flow and massive refactoring (#20)
Adds OAuth for external MCP services and cleans up the auth code.
After Google login, users see a page listing services that need OAuth
(Linear, GitHub, etc). They can connect now or skip and do it later at
/my/tokens. Tokens get refreshed 5 min before expiry so they don't break
mid-session when users are in Claude.
Refactored the monolithic auth/oauth code into separate packages - oauth
for provider setup, googleauth for Google-specific stuff, browserauth
for session types, auth for the service OAuth client. Handlers split up
too. Everything uses dependency injection now.
Copy file name to clipboardExpand all lines: CLAUDE.md
+22-9Lines changed: 22 additions & 9 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -56,6 +56,8 @@ mcp-front is a Go-based OAuth 2.1 proxy server for MCP (Model Context Protocol)
56
56
-**Define interfaces where they are used** - Not in the package that implements them
57
57
-**Avoid circular imports** - Use interface segregation in separate packages when needed
58
58
-**Dependency injection over getter methods** - Pass dependencies to constructors
59
+
-**Functional core, imperative shell** - Prefer pure functions for business logic, keep side effects (I/O, state mutations) at the boundaries. Makes code more testable and reasoning easier.
60
+
-**Upstream lifecycle control** - Manage goroutines, servers, and background processes from the application root. Library code should expose Start/Stop methods, not start things autonomously.
59
61
60
62
### 🎯 Core Development Principles (from Zig Zen)
61
63
@@ -115,7 +117,7 @@ LOG_FORMAT="text" # json or text
115
117
116
118
#### Updating OAuth scopes
117
119
118
-
1. Check `internal/oauth/auth.go` for current scopes
120
+
1. Check `internal/googleauth/google.go` for current scopes
119
121
2. Use standard OpenID Connect scopes (not Google-specific URLs)
120
122
3. Update tests to verify new scopes work
121
123
@@ -129,14 +131,24 @@ LOG_FORMAT="text" # json or text
129
131
130
132
```
131
133
internal/
132
-
├── config/ # Configuration parsing and validation
@@ -153,6 +165,7 @@ cmd/mcp-front/ # Main application entry point
153
165
3. Don't create new auth patterns - use existing OAuth or bearer token auth
154
166
4. Don't modify git configuration
155
167
5. Don't create README files proactively
168
+
6.**Variable shadowing package names** - `config.MCPClientConfig is not a type` means a variable named `config` is shadowing the package. Always check for variables that shadow imported package names
Copy file name to clipboardExpand all lines: README.md
+39-7Lines changed: 39 additions & 7 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -33,7 +33,7 @@ mcp-front is an authentication proxy that sits between Claude.ai and your MCP se
33
33
34
34
-**Single sign-on** via Google OAuth for all MCP tools
35
35
-**Domain validation** to restrict access to your organization
36
-
-**Per-user tokens** for services like Notion
36
+
-**Per-user authentication** for services like Notion and Stainless (via OAuth or manual tokens)
37
37
-**Session isolation** so multiple users can share infrastructure
38
38
39
39
## Why use mcp-front?
@@ -52,7 +52,7 @@ With mcp-front:
52
52
53
53
1. Claude.ai connects to `https://your-domain.com/<service>/sse`
54
54
2. mcp-front validates the user's OAuth token
55
-
3. If the server needs a user token, prompts via `/my/tokens`
55
+
3. If a service requires user authentication, `mcp-front` will guide the user through a one-time setup (via an OAuth consent screen or a manual token entry page).
56
56
4. Proxies requests to the configured MCP server
57
57
5. For stdio servers, each user gets an isolated process
58
58
@@ -150,16 +150,24 @@ docker run -d -p 8080:8080 \
150
150
151
151
mcp-front uses explicit JSON syntax `{"$env": "VAR_NAME"}` for environment variables throughout its configuration. This deliberate choice eliminates the ambiguity and risks inherent in shell-style variable substitution. When configs pass through multiple layers of tooling and scripts, traditional `$VAR` syntax can expand unexpectedly, causing security issues and debugging nightmares. The JSON format ensures your configuration remains exactly as written until mcp-front processes it, providing predictable behavior across all deployment environments. For per-user authentication, `{"$userToken": "{{token}}"}` follows the same principle, keeping user credentials cleanly separated from system configuration.
152
152
153
-
### Per-user tokens
153
+
##Service Authentication (Per-User Tokens)
154
154
155
-
Some MCP servers are better to use with each users having their own integration token (e.g., Notion). Configure with:
155
+
Some MCP servers, like Notion or Stainless, require each user to provide their own individual API key or grant access via OAuth. `mcp-front` automates this process.
156
156
157
+
When a service is configured with `requiresUserToken: true`, `mcp-front` will guide the user through a one-time setup for that service after their initial Google login. This is handled in one of two ways, depending on the service's configuration.
158
+
159
+
### Manual Token Entry
160
+
161
+
For services that require a manually generated API key, you can configure `mcp-front` to prompt the user for it on a secure web page.
162
+
163
+
**Configuration:**
157
164
```json
158
165
{
159
166
"notion": {
160
167
"transportType": "stdio",
161
168
"requiresUserToken": true,
162
-
"tokenSetup": {
169
+
"userAuthentication": {
170
+
"type": "manual",
163
171
"displayName": "Notion Integration Token",
164
172
"instructions": "Create an integration and copy the token",
@@ -174,9 +182,33 @@ Some MCP servers are better to use with each users having their own integration
174
182
}
175
183
}
176
184
```
185
+
After authenticating, the user will be directed to the `/my/tokens` page to enter their token.
186
+
187
+
### Service OAuth Flow
177
188
178
-
After the initial OAuth authentication, when users try to use Claude.ai with the integration they will be prompted to
179
-
provide a token via the `/my/tokens` web UI.
189
+
For services that support OAuth, `mcp-front` can handle the entire flow automatically. After the user logs in with Google, they will be shown an interstitial page where they can connect to each service.
Save manual token. Form: `service={service_name}&token={user_token}`.
164
+
165
+
### `GET /oauth/callback/{service_name}`
166
+
167
+
OAuth callback. Set as redirect URI in service OAuth config.
168
+
141
169
## Authentication
142
170
143
171
### Bearer token
@@ -159,19 +187,4 @@ PKCE is required for all OAuth flows.
159
187
160
188
## Errors
161
189
162
-
All errors follow OAuth 2.1 format:
163
-
164
-
```json
165
-
{
166
-
"error": "invalid_request",
167
-
"error_description": "Missing required parameter"
168
-
}
169
-
```
170
-
171
-
Common errors:
172
-
173
-
-`invalid_request` - Bad parameters
174
-
-`invalid_client` - Unknown client
175
-
-`invalid_grant` - Bad auth code
176
-
-`unauthorized_client` - Client can't use grant type
177
-
-`server_error` - Internal error
190
+
OAuth 2.1 format with `error` and `error_description` fields. Common codes: `invalid_request` (bad parameters), `invalid_client` (unknown client), `invalid_grant` (bad auth code), `unauthorized_client` (client can't use grant type), `server_error` (internal error).
0 commit comments