* Construct the per-request E2AClient for an already-resolved principal. * * Why the agent-email default lives here and not in the SDK: the SDK is a thin * contract shared by CLI, browser, server, and Python users — auto-resolving an * agent on construction would be too magical for those callers
( opts: HttpServerOptions, bearer: string, principal: ResolvedPrincipal, )
| 269 | * user) to pass `email` explicitly. |
| 270 | */ |
| 271 | function buildClient( |
| 272 | opts: HttpServerOptions, |
| 273 | bearer: string, |
| 274 | principal: ResolvedPrincipal, |
| 275 | ): McpClient { |
| 276 | const { agentEmail, scope } = principal; |
| 277 | if (opts.clientFactory) { |
| 278 | // Preserve the no-arg-factory shape for callers (and tests) that don't |
| 279 | // care about the resolved email/scope. Pass them through only when set. |
| 280 | return agentEmail || scope |
| 281 | ? opts.clientFactory(bearer, { ...(agentEmail ? { agentEmail } : {}), ...(scope ? { scope } : {}) }) |
| 282 | : opts.clientFactory(bearer); |
| 283 | } |
| 284 | return new McpClient( |
| 285 | new E2AClient({ apiKey: bearer, baseUrl: opts.baseUrl }), |
| 286 | agentEmail ?? "", |
| 287 | // Fail CLOSED if scope is ever absent: "agent" is the least-privilege tier |
| 288 | // (account = full admin surface). principal.scope is always set today, so |
| 289 | // this only guards a future refactor — but a fail-open default here would |
| 290 | // silently expose the admin surface. |
| 291 | scope ?? "agent", |
| 292 | ); |
| 293 | } |
| 294 | |
| 295 | /** |
| 296 | * Resolve a bearer's scope + bound agent from whoami (GET /account), which the |
no outgoing calls
no test coverage detected