Tencent/WeKnora · error
principal context is required to connect to OAuth MCP servic
Error message
principal context is required to connect to OAuth MCP service %s
What it means
For OAuth-enabled MCP services, GetOrCreateClient requires a valid principal in the request context (from types.PrincipalFromContext / MCPOAuthPrincipalFromContext) so each identity can use its own token. If the principal is missing or invalid (Principal.Valid() == false), it returns "principal context is required to connect to OAuth MCP service %s".
Source
Thrown at internal/mcp/manager.go:76
func (m *MCPManager) GetOrCreateClient(ctx context.Context, service *types.MCPService) (MCPClient, error) {
// Check if service is enabled
if !service.Enabled {
return nil, fmt.Errorf("MCP service %s is not enabled", service.Name)
}
// Stdio transport is disabled for security reasons
if service.TransportType == types.MCPTransportStdio {
return nil, fmt.Errorf("stdio transport is disabled for security reasons; please use SSE or HTTP Streamable transport instead")
}
var tenantID uint64
var principal types.Principal
if service.AuthConfig.IsOAuth() {
tenantID, _ = types.TenantIDFromContext(ctx)
principal, _ = types.PrincipalFromContext(ctx)
principal = types.MCPOAuthPrincipalFromContext(ctx)
if !principal.Valid() {
return nil, fmt.Errorf("principal context is required to connect to OAuth MCP service %s", service.Name)
}
}
key := cacheKey(service, principal)
// For SSE/HTTP Streamable, check if client already exists and reuse
m.clientsMu.RLock()
client, exists := m.clients[key]
m.clientsMu.RUnlock()
if exists && client.IsConnected() {
return client, nil
}
// Create new client
m.clientsMu.Lock()
defer m.clientsMu.Unlock()
// Double check after acquiring write lockView on GitHub (pinned to 988cbb0330)
Solutions
- Ensure the request context passes through the auth middleware that injects the principal before MCP calls
- Use types.WithPrincipal (or the equivalent context helper) to attach a valid types.Principal to the context
- If no user context exists (system job), connect as a designated service principal instead
Example fix
// before client, err := manager.GetOrCreateClient(context.Background(), oauthSvc) // after ctx := types.WithPrincipal(context.Background(), principal) // principal from auth/session client, err := manager.GetOrCreateClient(ctx, oauthSvc)
Defensive patterns
Strategy: validation
Validate before calling
principal, _ := types.PrincipalFromContext(ctx)
if !principal.Valid() {
return errors.New("request context lacks a valid principal; required for OAuth MCP services")
} Type guard
func hasPrincipal(ctx context.Context) bool {
p, _ := types.PrincipalFromContext(ctx)
return p.Valid()
} Try / catch
client, err := manager.GetOrCreateClient(ctx, svc)
if err != nil && strings.Contains(err.Error(), "principal context is required") {
return fmt.Errorf("attach authenticated principal to ctx before using OAuth service %q", svc.Name)
} Prevention
- Route all MCP calls through middleware that injects the principal
- For background jobs, mint a service principal and attach it to the context explicitly
- Check service.AuthConfig.IsOAuth() before choosing which context a call needs
When it happens
Trigger: Calling GetOrCreateClient (or GetMCPServiceTools/Resources) with a context lacking the principal when service.AuthConfig.IsOAuth() is true — e.g. background jobs, webhook handlers, or code paths that build a bare context.Background() without auth middleware.
Common situations: Calling MCP tools from a cron/worker goroutine where auth middleware never ran; forgetting to inject the principal after extracting a tenant ID; a test constructing ctx without the principal helper.
Related errors
- principal context is required to connect to an OAuth MCP ser
- OAuth repository is required for OAuth MCP services
- load MCP OAuth token: %w
- principal context is required to authorize OAuth MCP service
- MCP OAuth metadata URL failed SSRF validation: %w
AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02).
Data as JSON: /api/errors/cfaf527efb468da3.
Report an issue: GitHub.