( serverName: string, oauth: McpOAuthConfig, )
| 317 | /** Build an OAuthClientProvider from an McpOAuthConfig. Returns the provider |
| 318 | * plus a callback-port hint (for the interactive flow). */ |
| 319 | export function buildAuthProvider( |
| 320 | serverName: string, |
| 321 | oauth: McpOAuthConfig, |
| 322 | ): { provider: OAuthClientProvider; callbackPort?: number } { |
| 323 | // M2M: client_credentials grant (no browser). |
| 324 | if (typeof oauth === "object" && "grantType" in oauth && oauth.grantType === "client_credentials") { |
| 325 | return { |
| 326 | provider: new ClientCredentialsProvider({ |
| 327 | clientId: oauth.clientId, |
| 328 | clientSecret: oauth.clientSecret, |
| 329 | scope: oauth.scope, |
| 330 | clientName: "OrbCode CLI", |
| 331 | }), |
| 332 | } |
| 333 | } |
| 334 | |
| 335 | // M2M: private_key_jwt assertion (no browser). |
| 336 | if (typeof oauth === "object" && "grantType" in oauth && oauth.grantType === "private_key_jwt") { |
| 337 | return { |
| 338 | provider: new PrivateKeyJwtProvider({ |
| 339 | clientId: oauth.clientId, |
| 340 | privateKey: oauth.privateKey, |
| 341 | algorithm: oauth.algorithm, |
| 342 | scope: oauth.scope, |
| 343 | clientName: "OrbCode CLI", |
| 344 | }), |
| 345 | } |
| 346 | } |
| 347 | |
| 348 | // Interactive authorization-code flow (browser redirect). |
| 349 | const scope = typeof oauth === "object" ? oauth.scope : undefined |
| 350 | const port = ephemeralPort() |
| 351 | return { provider: new FileOAuthProvider(serverName, port, scope), callbackPort: port } |
| 352 | } |
| 353 | |
| 354 | /** True if the config requests OAuth (vs. static headers). */ |
| 355 | export function hasOAuth(config: { oauth?: McpOAuthConfig }): boolean { |
no test coverage detected