Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,7 @@ Returns: { success: true, result: "Example Domain" }

Example: “Log me into my Hacker News account and update my profile to add a random emoji at the bottom.” The agent should discover `news.ycombinator.com`, open the App when needed, wait for authentication, then continue the profile edit without asking for credentials or a profile name in chat.

The secure App defaults `record_session` and `browser_telemetry.enabled` to `true`, recording replay video plus the operational telemetry categories (`control`, `connection`, `system`, and `captcha`) for managed-auth browser sessions. Callers can explicitly disable either setting. The programmatic `manage_auth_connections` create, update, and login actions pass browser telemetry through the API’s current nested `browser.telemetry` configuration while preserving defaults and inheritance when the MCP parameter is omitted.
The secure App defaults `record_session` and `browser_telemetry.enabled` to `true`, recording replay video plus the operational telemetry categories (`control`, `connection`, `system`, and `captcha`) for managed-auth browser sessions. Callers can explicitly disable either setting. Set `region` in `open_auth_login`, or `browser_region` in `manage_auth_connections`, to choose where a managed-auth browser runs. Create and update set the connection default; login and reauth overrides apply only to that flow. Omit the field on create to use `us-east`, or omit it on update and login to preserve or inherit the connection default. The programmatic `manage_auth_connections` create, update, and login actions pass browser telemetry through the API’s current nested `browser.telemetry` configuration while preserving defaults and inheritance when the MCP parameter is omitted.

### Set up browser profiles for authentication

Expand Down
2 changes: 1 addition & 1 deletion src/lib/mcp/apps/generated/managed-auth-app.ts

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions src/lib/mcp/apps/managed-auth-entry.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ function sanitizeBeginArguments(input: JsonObject): JsonObject {
"save_credentials",
"record_session",
"browser_telemetry",
"region",
"proxy_id",
"proxy_name",
];
Expand Down
1 change: 1 addition & 0 deletions src/lib/mcp/apps/managed-auth-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export type SafeConnection = {
| null;
flow_type: "LOGIN" | "REAUTH" | null;
flow_expires_at: string | null;
region?: "us-east" | "eu-west" | "ap-southeast";
error_code: string | null;
};

Expand Down
14 changes: 12 additions & 2 deletions src/lib/mcp/tools/auth-connections.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ describe("manage_auth_connections programmatic surface", () => {
expect(schema?.credential_auto.description).toContain("create, update");
expect(schema?.health_checks).toBeDefined();
expect(schema?.auto_reauth).toBeDefined();
expect(schema?.browser_region.safeParse("eu-west").success).toBe(true);
expect(schema?.browser_region.safeParse("emea").success).toBe(false);
expect(schema?.browser_stealth).toBeDefined();
expect(schema?.query).toBeDefined();
expect(schema?.timeline_type).toBeDefined();
Expand Down Expand Up @@ -131,7 +133,7 @@ describe("manage_auth_connections programmatic surface", () => {
expect(selectedProject).toBeUndefined();
});

test("forwards replay and browser telemetry settings on create and login", async () => {
test("forwards browser settings on create and login", async () => {
const { handler } = captureHandler();
let createBody: unknown;
let loginBody: unknown;
Expand Down Expand Up @@ -176,6 +178,7 @@ describe("manage_auth_connections programmatic surface", () => {
domain: "example.com",
profile_name: "work",
record_session: true,
browser_region: "eu-west",
browser_telemetry: {
enabled: true,
browser: { network: { enabled: true } },
Expand All @@ -186,6 +189,7 @@ describe("manage_auth_connections programmatic surface", () => {
expect(createBody).toMatchObject({
record_session: true,
browser: {
region: "eu-west",
telemetry: {
enabled: true,
browser: { network: { enabled: true } },
Expand All @@ -198,13 +202,17 @@ describe("manage_auth_connections programmatic surface", () => {
action: "login",
id: "conn_1",
record_session: false,
browser_region: "ap-southeast",
browser_telemetry: { enabled: false },
},
extra,
);
expect(loginBody).toEqual({
record_session: false,
browser: { telemetry: { enabled: false } },
browser: {
region: "ap-southeast",
telemetry: { enabled: false },
},
});
} finally {
kernelClientMock.factory = () => unusedKernelClient;
Expand Down Expand Up @@ -238,6 +246,7 @@ describe("manage_auth_connections programmatic surface", () => {
auto_reauth: false,
save_credentials: false,
record_session: true,
browser_region: "eu-west",
browser_stealth: false,
proxy_mode: "direct",
browser_telemetry: {
Expand All @@ -263,6 +272,7 @@ describe("manage_auth_connections programmatic surface", () => {
save_credentials: false,
record_session: true,
browser: {
region: "eu-west",
stealth: false,
proxy: { mode: "direct" },
telemetry: {
Expand Down
12 changes: 11 additions & 1 deletion src/lib/mcp/tools/auth-connections.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,12 @@ export function registerAuthConnectionTools(server: McpServer) {
"(create, update) Set the connection default for browser telemetry. (login) Override it for this login only. Use { enabled: true } for the default operational categories (control, connection, system, captcha); browser category settings can opt into console, network, page, interaction, screenshot, or platform capture, tune control CDP exclusions, and configure OTLP export. Omitted preserves the API default or inherited value.",
)
.optional(),
browser_region: z
.enum(["us-east", "eu-west", "ap-southeast"])
.describe(
"(create, update) Set the region for future managed-auth browser sessions. (login) Override the region for this login only. Defaults to us-east on create; omitted on update or login preserves or inherits the connection setting.",
)
.optional(),
browser_stealth: z
.boolean()
.describe(
Expand Down Expand Up @@ -278,10 +284,14 @@ export function registerAuthConnectionTools(server: McpServer) {
: undefined;
const buildBrowser = () => {
const proxy = buildProxy();
return params.browser_stealth !== undefined ||
return params.browser_region !== undefined ||
params.browser_stealth !== undefined ||
params.browser_telemetry !== undefined ||
proxy
? {
...(params.browser_region !== undefined && {
region: params.browser_region,
}),
...(params.browser_stealth !== undefined && {
stealth: params.browser_stealth,
}),
Expand Down
5 changes: 5 additions & 0 deletions src/lib/mcp/tools/auth-login-app.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,10 @@ describe("managed-auth MCP App registration", () => {
expect(schema.safeParse({ ...base, proxy_id: "proxy_1" }).success).toBe(
true,
);
expect(schema.safeParse({ ...base, region: "eu-west" }).success).toBe(
true,
);
expect(schema.safeParse({ ...base, region: "emea" }).success).toBe(false);
const defaults = schema.parse(base);
expect(defaults.record_session).toBe(true);
expect(defaults.browser_telemetry).toEqual({ enabled: true });
Expand Down Expand Up @@ -521,6 +525,7 @@ describe("managed-auth MCP App registration", () => {
expect(MANAGED_AUTH_APP_HTML).toContain("profile_name");
expect(MANAGED_AUTH_APP_HTML).toContain("record_session");
expect(MANAGED_AUTH_APP_HTML).toContain("browser_telemetry");
expect(MANAGED_AUTH_APP_HTML).toContain("region");
expect(MANAGED_AUTH_APP_HTML).toContain("manage_auth_connections");
expect(MANAGED_AUTH_APP_HTML).not.toContain("flow_wait_started_at");
expect(MANAGED_AUTH_APP_HTML).toContain(
Expand Down
7 changes: 7 additions & 0 deletions src/lib/mcp/tools/auth-login-app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,12 @@ const authLoginInputSchema = () => ({
"Browser telemetry for this managed-auth flow and the connection default for new connections. Defaults to { enabled: true }, which captures the operational categories (control, connection, system, captcha).",
)
.default({ enabled: true }),
region: z
.enum(["us-east", "eu-west", "ap-southeast"])
.describe(
"Region for the managed-auth browser session. Sets the connection default for a new login or overrides it for this reauth.",
)
.optional(),
proxy_id: z.string().min(1).optional(),
proxy_name: z.string().min(1).optional(),
});
Expand Down Expand Up @@ -104,6 +110,7 @@ function inputFromParams(params: AuthLoginParams): AuthLoginInput {
}),
record_session: params.record_session ?? true,
browser_telemetry: params.browser_telemetry ?? { enabled: true },
...(params.region && { region: params.region }),
...(params.proxy_id && { proxy_id: params.proxy_id }),
...(params.proxy_name && { proxy_name: params.proxy_name }),
};
Expand Down
23 changes: 23 additions & 0 deletions src/lib/mcp/tools/managed-auth-start.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { describe, expect, test } from "bun:test";
import { beginAuthLogin } from "./managed-auth-state";
import type { ManagedAuth } from "@onkernel/sdk/resources/auth/connections";
import {
assertNoSecrets,
connection,
Expand Down Expand Up @@ -66,6 +67,28 @@ describe("managed-auth start/resume state machine", () => {
});
});

test("secure App login forwards the selected region", async () => {
const initial = connection({
browser: { region: "eu-west" } as NonNullable<ManagedAuth["browser"]> & {
region: "eu-west";
},
});
const { client, calls } = fakeClient({ initial });
const result = await beginAuthLogin(client, {
mode: "new_login",
domain: "example.com",
profile_name: "work",
region: "eu-west",
});
expect(calls.createParams).toMatchObject({
browser: { region: "eu-west" },
});
expect(calls.loginParams).toMatchObject({
browser: { region: "eu-west" },
});
expect(result.connection.region).toBe("eu-west");
});

test("secure App login preserves explicit recording opt-outs", async () => {
const initial = connection();
const { client, calls } = fakeClient({ initial });
Expand Down
14 changes: 14 additions & 0 deletions src/lib/mcp/tools/managed-auth-state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ import {
} from "@/lib/mcp/tools/managed-auth-checkpoint";
import type { ManagedAuthBrowserTelemetry } from "@/lib/mcp/tools/managed-auth-telemetry";

export type ManagedAuthRegion = "us-east" | "eu-west" | "ap-southeast";

type ManagedAuthBrowserWithRegion = NonNullable<ManagedAuth["browser"]> & {
region?: ManagedAuthRegion;
};

export interface SafeAuthConnection {
id: string;
domain: string;
Expand All @@ -33,6 +39,7 @@ export interface SafeAuthConnection {
flow_expires_at: string | null;
can_reauth: boolean | null;
can_reauth_reason: string | null;
region: ManagedAuthRegion;
error_code: string | null;
error_message: string | null;
}
Expand All @@ -47,6 +54,7 @@ export interface AuthLoginInput {
save_credentials?: boolean;
record_session?: boolean;
browser_telemetry?: ManagedAuthBrowserTelemetry;
region?: ManagedAuthRegion;
proxy_id?: string;
proxy_name?: string;
}
Expand Down Expand Up @@ -97,6 +105,9 @@ const TERMINAL_ERROR_MESSAGES: Partial<
export function toSafeAuthConnection(
connection: ManagedAuth,
): SafeAuthConnection {
const browser = connection.browser as
| ManagedAuthBrowserWithRegion
| undefined;
return {
id: connection.id,
domain: connection.domain,
Expand All @@ -108,6 +119,7 @@ export function toSafeAuthConnection(
flow_expires_at: connection.flow_expires_at ?? null,
can_reauth: connection.can_reauth ?? null,
can_reauth_reason: connection.can_reauth_reason ?? null,
region: browser?.region ?? "us-east",
error_code: connection.error_code ?? null,
error_message: connection.flow_status
? (TERMINAL_ERROR_MESSAGES[connection.flow_status] ?? null)
Expand Down Expand Up @@ -466,6 +478,7 @@ export async function beginAuthLogin(
record_session: recordSession,
browser: {
telemetry: browserTelemetry,
...(input.region && { region: input.region }),
...(proxy && { proxy }),
},
});
Expand Down Expand Up @@ -516,6 +529,7 @@ export async function beginAuthLogin(
record_session: recordSession,
browser: {
telemetry: browserTelemetry,
...(input.region && { region: input.region }),
...(proxy && { proxy }),
},
});
Expand Down
Loading