{"record":{"id":"c9bcbaa013c3fdea","repo":"Tencent/WeKnora","slug":"mcp-service-s-is-not-enabled","errorCode":null,"errorMessage":"MCP service %s is not enabled","messagePattern":"MCP service (.+?) is not enabled","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/mcp/manager.go","lineNumber":61,"sourceCode":"// keyed per principal (each identity connects with its own token); all other\n// services share a single connection per service ID.\nfunc cacheKey(service *types.MCPService, principal types.Principal) string {\n\tif service.AuthConfig.IsOAuth() {\n\t\treturn service.ID + \"\\x00\" + principal.Normalize().StorageID()\n\t}\n\treturn service.ID\n}\n\n// GetOrCreateClient gets an existing client or creates a new one\n// Caches and reuses existing connections for SSE/HTTP Streamable\n// Note: Stdio transport is disabled for security reasons\n//\n// For OAuth-enabled services the connection is keyed per principal (derived from\n// ctx) so each identity connects with its own token.\nfunc (m *MCPManager) GetOrCreateClient(ctx context.Context, service *types.MCPService) (MCPClient, error) {\n\t// Check if service is enabled\n\tif !service.Enabled {\n\t\treturn nil, fmt.Errorf(\"MCP service %s is not enabled\", service.Name)\n\t}\n\n\t// Stdio transport is disabled for security reasons\n\tif service.TransportType == types.MCPTransportStdio {\n\t\treturn nil, fmt.Errorf(\"stdio transport is disabled for security reasons; please use SSE or HTTP Streamable transport instead\")\n\t}\n\n\tvar tenantID uint64\n\tvar principal types.Principal\n\tif service.AuthConfig.IsOAuth() {\n\t\ttenantID, _ = types.TenantIDFromContext(ctx)\n\t\tprincipal, _ = types.PrincipalFromContext(ctx)\n\t\tprincipal = types.MCPOAuthPrincipalFromContext(ctx)\n\t\tif !principal.Valid() {\n\t\t\treturn nil, fmt.Errorf(\"principal context is required to connect to OAuth MCP service %s\", service.Name)\n\t\t}\n\t}\n\tkey := cacheKey(service, principal)","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/Tencent/WeKnora/blob/988cbb03305e055d8ebb7d46d9ac6cc0803cd074/internal/mcp/manager.go#L43-L79","documentation":"GetOrCreateClient rejects connections to MCP services whose Enabled flag is false, returning \"MCP service %s is not enabled\". This is a configuration gate: disabled services are intentionally blocked from creating clients. It fires before any transport or OAuth logic runs.","triggerScenarios":"Passing a *types.MCPService with Enabled=false to GetOrCreateClient, directly or indirectly via GetMCPToolsInfo, GetMCPServiceTools, GetMCPServiceResources, or getOrCreateMCPClientWithOAuthRetry.","commonSituations":"An admin toggled the service off in the UI/DB while workers still reference it; a service was seeded into config disabled by default; stale cached service record after enablement change wasn't reloaded.","solutions":["Enable the service: set service.Enabled=true in the admin UI or database and reload the service config","Skip disabled services in caller code before requesting tools/resources","Re-fetch the MCPService record to ensure you're not using a stale disabled copy"],"exampleFix":"// before\nclient, err := manager.GetOrCreateClient(ctx, svc)\n// after\nif !svc.Enabled {\n    return nil, fmt.Errorf(\"service %q is disabled; enable it before use\", svc.Name)\n}\nclient, err := manager.GetOrCreateClient(ctx, svc)","handlingStrategy":"validation","validationCode":"if svc == nil { return errors.New(\"nil MCP service\") }\nif !svc.Enabled { return fmt.Errorf(\"service %q is disabled\", svc.Name) }","typeGuard":"func serviceUsable(svc *types.MCPService) bool { return svc != nil && svc.Enabled }","tryCatchPattern":"client, err := manager.GetOrCreateClient(ctx, svc)\nif err != nil && strings.Contains(err.Error(), \"is not enabled\") {\n    return fmt.Errorf(\"enable MCP service %q in settings first\", svc.Name)\n}","preventionTips":["Filter service lists on Enabled before iterating and connecting","Invalidate cached MCPService records after admin toggles","Surface enabled/disabled state in UIs so operators know why calls fail"],"tags":["mcp","configuration","service-disabled"],"backgroundTag":"service-disabled","analyzedSha":"988cbb03305e055d8ebb7d46d9ac6cc0803cd074","analyzedAt":"2026-09-02T14:41:08.344Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}