Skip to content

Commit fffe5bb

Browse files
mjunaidcaclaude
andcommitted
feat(oauth): standardize scopes and add RFC 8414 metadata endpoint
- Remove custom taskflow:read/write scopes, use standard OIDC scopes only - Add /.well-known/oauth-authorization-server route for MCP client discovery - Add taskflow MCP server config to .mcp.json - Aligns with Better Auth which doesn't support custom scopes 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 5020e38 commit fffe5bb

3 files changed

Lines changed: 61 additions & 5 deletions

File tree

.mcp.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
{
22
"mcpServers": {
3+
"taskflow": {
4+
"type": "http",
5+
"url": "http://0.0.0.0:8001/mcp"
6+
},
37
"context7": {
48
"type": "stdio",
59
"command": "npx",

packages/mcp-server/src/taskflow_mcp/server.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -109,12 +109,11 @@ async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
109109
"token_endpoint": f"{config.sso_url}/api/auth/oauth2/token",
110110
"device_authorization_endpoint": f"{config.sso_url}/api/auth/device/code",
111111
"jwks_uri": f"{config.sso_url}/api/auth/jwks",
112+
# Only standard OIDC scopes - Better Auth doesn't support custom scopes
112113
"scopes_supported": [
113114
"openid",
114115
"profile",
115116
"email",
116-
"taskflow:read",
117-
"taskflow:write",
118117
],
119118
"response_types_supported": ["code"],
120119
"grant_types_supported": [
@@ -135,11 +134,11 @@ async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
135134
response = JSONResponse({
136135
"resource": f"http://{config.mcp_host}:{config.mcp_port}/mcp",
137136
"authorization_servers": [config.sso_url],
137+
# Only standard OIDC scopes
138138
"scopes_supported": [
139139
"openid",
140-
"profile",
141-
"taskflow:read",
142-
"taskflow:write",
140+
"profile",
141+
"email",
143142
],
144143
"bearer_methods_supported": ["header"],
145144
"resource_documentation": "https://github.com/mjunaidca/taskforce",
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/**
2+
* OAuth 2.0 Authorization Server Metadata (RFC 8414)
3+
*
4+
* This endpoint provides OAuth AS metadata for MCP clients (Claude Code, Gemini CLI, etc.)
5+
* that use RFC 8414 discovery instead of OIDC Discovery.
6+
*
7+
* MCP Auth flow:
8+
* 1. Client fetches /.well-known/oauth-protected-resource from MCP server
9+
* 2. Client gets authorization_servers list pointing to this SSO
10+
* 3. Client fetches this endpoint to get OAuth endpoints
11+
* 4. Client performs OAuth flow
12+
*/
13+
14+
import { NextResponse } from "next/server";
15+
16+
const BASE_URL = process.env.BETTER_AUTH_URL || "http://localhost:3001";
17+
18+
export async function GET() {
19+
// Return OAuth AS metadata (RFC 8414)
20+
// This mirrors the OIDC Discovery document but in OAuth AS format
21+
return NextResponse.json({
22+
// Required fields
23+
issuer: BASE_URL,
24+
authorization_endpoint: `${BASE_URL}/api/auth/oauth2/authorize`,
25+
token_endpoint: `${BASE_URL}/api/auth/oauth2/token`,
26+
27+
// Optional but recommended
28+
jwks_uri: `${BASE_URL}/api/auth/jwks`,
29+
registration_endpoint: `${BASE_URL}/api/auth/oauth2/register`,
30+
scopes_supported: ["openid", "profile", "email", "offline_access"],
31+
response_types_supported: ["code"],
32+
response_modes_supported: ["query"],
33+
grant_types_supported: [
34+
"authorization_code",
35+
"refresh_token",
36+
"urn:ietf:params:oauth:grant-type:device_code",
37+
],
38+
token_endpoint_auth_methods_supported: ["client_secret_basic", "client_secret_post", "none"],
39+
code_challenge_methods_supported: ["S256"],
40+
41+
// Device authorization (RFC 8628)
42+
device_authorization_endpoint: `${BASE_URL}/api/auth/device/code`,
43+
44+
// Userinfo endpoint
45+
userinfo_endpoint: `${BASE_URL}/api/auth/oauth2/userinfo`,
46+
47+
// Revocation endpoint (if supported)
48+
revocation_endpoint: `${BASE_URL}/api/auth/oauth2/revoke`,
49+
50+
// End session endpoint (OIDC logout)
51+
end_session_endpoint: `${BASE_URL}/api/auth/oauth2/endsession`,
52+
});
53+
}

0 commit comments

Comments
 (0)