1import type { EnvironmentId, ProviderInstanceId, ThreadId } from "@t3tools/contracts";
2
3export interface McpProviderSessionConfig {
4 readonly environmentId: EnvironmentId;
5 readonly threadId: ThreadId;
6 readonly providerSessionId: string;
7 readonly providerInstanceId: ProviderInstanceId;
8 readonly endpoint: string;
9 readonly authorizationHeader: string;
10 /**
11 * Whether this credential includes the "preview" capability. Adapters read
12 * it to keep developer instructions truthful: when the user withholds agent
13 * browser access, the prompt must not advertise `preview_*` tools that every
14 * call would reject.
15 */
16 readonly browserToolsAvailable: boolean;
17 /** Capabilities the credential grants ("preview", "device"). */
18 readonly capabilities?: ReadonlySet<string>;
19 /**
20 * Set when the session may drive devices. Adapters spread this into the
21 * provider subprocess environment so the `agent-device` CLI is on PATH and
22 * already pointed at the server's daemon; the agent never handles a token.
23 */
24 readonly agentDeviceEnvironment?: Readonly<Record<string, string>>;
25}
26
27/** Provider env with the device variables applied over `base`, or `base` untouched. */
28export function withAgentDeviceEnvironment(
29 base: NodeJS.ProcessEnv,
30 config: Pick<McpProviderSessionConfig, "agentDeviceEnvironment"> | undefined,
31): NodeJS.ProcessEnv {
32 const extra = config?.agentDeviceEnvironment;
33 if (!extra) return base;
34 const separator = extra.PATH_SEPARATOR ?? ":";
35 const basePath = base.PATH ?? base.Path;
36 const { PATH: shimDir, PATH_SEPARATOR: _separator, ...rest } = extra;
37 return {
38 ...base,
39 ...rest,
40 ...(shimDir ? { PATH: basePath ? `${shimDir}${separator}${basePath}` : shimDir } : {}),
41 };
42}