feat(mcp): OAuth so claude.ai and ChatGPT can connect as connectors
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 2m49s

MindSift becomes the OAuth authorization server for its own MCP
endpoint: discovery (RFC 9728/8414), dynamic client registration,
authorization code with PKCE (S256), rotating refresh tokens with reuse
detection. The consent page lives in the app at /oauth/authorize. A
grant is an api_keys entry (kind 'oauth'), so scopes, origin badges,
renaming and revoking work as for keys; tokens are valid for /mcp only.
Unused connections expire after OAUTH_IDLE_DAYS (default 90). Requires
BASE_URL; off in demo mode. Release 0.51.0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
sandrodachandClaude Opus 5.5 committed 2026-11-01 20:01:32 +01:00
1 parent 994f6dc554
commit 75aea4a7d4
31 files changed
+1581 -49

No files matched your search

+4
View File
@@ -35,6 +35,9 @@ type Config struct {
DemoResetMinutes int
// TrustedProxies: whose X-Forwarded-For/X-Real-IP is believed ("private", "all", "none" or CIDRs)
TrustedProxies string
// OAuthIdleDays: OAUTH_IDLE_DAYS, after this many unused days an OAuth connection (MCP) is
// removed (0 = never)
OAuthIdleDays int
// DisableLoginProtection: LOGIN_PROTECTION=false switches off locking logins after repeated
// failures (the zero value keeps it on)
DisableLoginProtection bool
@@ -259,6 +262,7 @@ func Load() *Config {
TrustedProxies: getEnv("TRUSTED_PROXIES", "private"),
RetentionAllowNever: envBoolPtr("RETENTION_ALLOW_NEVER"),
DisableLoginProtection: strings.ToLower(getEnv("LOGIN_PROTECTION", "true")) == "false",
OAuthIdleDays: envInt("OAUTH_IDLE_DAYS", 90, 0, 36500),
SMTPHost: smtpHost,
SMTPPort: smtpPort,
SMTPUser: smtpUser,