parseMCPServerConfigID extracts the MCP server config UUID from the "mcpServer" path parameter. refreshMCPUserToken attempts to refresh an expired OAuth2 token for the given MCP server config. Returns true when the token is valid (either still fresh or successfully refreshed), false when the token i
( ctx context.Context, cfg database.MCPServerConfig, tok database.MCPServerUserToken, userID uuid.UUID, )
| 1174 | // valid (either still fresh or successfully refreshed), false when |
| 1175 | // the token is expired and cannot be refreshed. |
| 1176 | func (api *API) refreshMCPUserToken( |
| 1177 | ctx context.Context, |
| 1178 | cfg database.MCPServerConfig, |
| 1179 | tok database.MCPServerUserToken, |
| 1180 | userID uuid.UUID, |
| 1181 | ) bool { |
| 1182 | if cfg.AuthType != "oauth2" { |
| 1183 | return true |
| 1184 | } |
| 1185 | if tok.RefreshToken == "" { |
| 1186 | // No refresh token — consider connected only if not |
| 1187 | // expired (or no expiry set). |
| 1188 | return !tok.Expiry.Valid || tok.Expiry.Time.After(time.Now()) |
| 1189 | } |
| 1190 | |
| 1191 | result, err := mcpclient.RefreshOAuth2Token(ctx, cfg, tok) |
| 1192 | if err != nil { |
| 1193 | api.Logger.Warn(ctx, "failed to refresh MCP oauth2 token", |
| 1194 | slog.F("server_slug", cfg.Slug), |
| 1195 | slog.Error(err), |
| 1196 | ) |
| 1197 | // Refresh failed — token is dead. |
| 1198 | return false |
| 1199 | } |
| 1200 | |
| 1201 | if result.Refreshed { |
| 1202 | var expiry sql.NullTime |
| 1203 | if !result.Expiry.IsZero() { |
| 1204 | expiry = sql.NullTime{Time: result.Expiry, Valid: true} |
| 1205 | } |
| 1206 | |
| 1207 | //nolint:gocritic // Need system-level write access to |
| 1208 | // persist the refreshed OAuth2 token. |
| 1209 | _, err = api.Database.UpsertMCPServerUserToken( |
| 1210 | dbauthz.AsSystemRestricted(ctx), |
| 1211 | database.UpsertMCPServerUserTokenParams{ |
| 1212 | MCPServerConfigID: tok.MCPServerConfigID, |
| 1213 | UserID: userID, |
| 1214 | AccessToken: result.AccessToken, |
| 1215 | AccessTokenKeyID: sql.NullString{}, |
| 1216 | RefreshToken: result.RefreshToken, |
| 1217 | RefreshTokenKeyID: sql.NullString{}, |
| 1218 | TokenType: result.TokenType, |
| 1219 | Expiry: expiry, |
| 1220 | }, |
| 1221 | ) |
| 1222 | if err != nil { |
| 1223 | api.Logger.Warn(ctx, "failed to persist refreshed MCP oauth2 token", |
| 1224 | slog.F("server_slug", cfg.Slug), |
| 1225 | slog.Error(err), |
| 1226 | ) |
| 1227 | } |
| 1228 | } |
| 1229 | |
| 1230 | return true |
| 1231 | } |
| 1232 | |
| 1233 | func parseMCPServerConfigID(rw http.ResponseWriter, r *http.Request) (uuid.UUID, bool) { |
no test coverage detected