diff --git a/README.md b/README.md
index 4a57895..e15b2c6 100644
--- a/README.md
+++ b/README.md
@@ -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
diff --git a/src/lib/mcp/apps/generated/managed-auth-app.ts b/src/lib/mcp/apps/generated/managed-auth-app.ts
index 8bd1861..cccabe8 100644
--- a/src/lib/mcp/apps/generated/managed-auth-app.ts
+++ b/src/lib/mcp/apps/generated/managed-auth-app.ts
@@ -1,2 +1,2 @@
// Generated by scripts/build-managed-auth-app.mjs. Do not edit.
-export const MANAGED_AUTH_APP_HTML = "\n\n
\n\n\nKernel Managed Authentication\n\n\n\n\n\n";
+export const MANAGED_AUTH_APP_HTML = "\n\n\n\n\nKernel Managed Authentication\n\n\n\n\n\n";
diff --git a/src/lib/mcp/apps/managed-auth-entry.tsx b/src/lib/mcp/apps/managed-auth-entry.tsx
index 414540d..49faa4b 100644
--- a/src/lib/mcp/apps/managed-auth-entry.tsx
+++ b/src/lib/mcp/apps/managed-auth-entry.tsx
@@ -40,6 +40,7 @@ function sanitizeBeginArguments(input: JsonObject): JsonObject {
"save_credentials",
"record_session",
"browser_telemetry",
+ "region",
"proxy_id",
"proxy_name",
];
diff --git a/src/lib/mcp/apps/managed-auth-types.ts b/src/lib/mcp/apps/managed-auth-types.ts
index 47a1070..cb3f142 100644
--- a/src/lib/mcp/apps/managed-auth-types.ts
+++ b/src/lib/mcp/apps/managed-auth-types.ts
@@ -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;
};
diff --git a/src/lib/mcp/tools/auth-connections.test.ts b/src/lib/mcp/tools/auth-connections.test.ts
index 58808d7..a1152c0 100644
--- a/src/lib/mcp/tools/auth-connections.test.ts
+++ b/src/lib/mcp/tools/auth-connections.test.ts
@@ -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();
@@ -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;
@@ -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 } },
@@ -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 } },
@@ -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;
@@ -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: {
@@ -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: {
diff --git a/src/lib/mcp/tools/auth-connections.ts b/src/lib/mcp/tools/auth-connections.ts
index 9230d7a..543c4ba 100644
--- a/src/lib/mcp/tools/auth-connections.ts
+++ b/src/lib/mcp/tools/auth-connections.ts
@@ -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(
@@ -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,
}),
diff --git a/src/lib/mcp/tools/auth-login-app.test.ts b/src/lib/mcp/tools/auth-login-app.test.ts
index 51ce4ac..5cb72d7 100644
--- a/src/lib/mcp/tools/auth-login-app.test.ts
+++ b/src/lib/mcp/tools/auth-login-app.test.ts
@@ -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 });
@@ -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(
diff --git a/src/lib/mcp/tools/auth-login-app.ts b/src/lib/mcp/tools/auth-login-app.ts
index 7d700ff..7e50c8c 100644
--- a/src/lib/mcp/tools/auth-login-app.ts
+++ b/src/lib/mcp/tools/auth-login-app.ts
@@ -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(),
});
@@ -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 }),
};
diff --git a/src/lib/mcp/tools/managed-auth-start.test.ts b/src/lib/mcp/tools/managed-auth-start.test.ts
index d7b5901..5ebe8b7 100644
--- a/src/lib/mcp/tools/managed-auth-start.test.ts
+++ b/src/lib/mcp/tools/managed-auth-start.test.ts
@@ -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,
@@ -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 & {
+ 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 });
diff --git a/src/lib/mcp/tools/managed-auth-state.ts b/src/lib/mcp/tools/managed-auth-state.ts
index 5ac500d..33bce07 100644
--- a/src/lib/mcp/tools/managed-auth-state.ts
+++ b/src/lib/mcp/tools/managed-auth-state.ts
@@ -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 & {
+ region?: ManagedAuthRegion;
+};
+
export interface SafeAuthConnection {
id: string;
domain: string;
@@ -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;
}
@@ -47,6 +54,7 @@ export interface AuthLoginInput {
save_credentials?: boolean;
record_session?: boolean;
browser_telemetry?: ManagedAuthBrowserTelemetry;
+ region?: ManagedAuthRegion;
proxy_id?: string;
proxy_name?: string;
}
@@ -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,
@@ -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)
@@ -466,6 +478,7 @@ export async function beginAuthLogin(
record_session: recordSession,
browser: {
telemetry: browserTelemetry,
+ ...(input.region && { region: input.region }),
...(proxy && { proxy }),
},
});
@@ -516,6 +529,7 @@ export async function beginAuthLogin(
record_session: recordSession,
browser: {
telemetry: browserTelemetry,
+ ...(input.region && { region: input.region }),
...(proxy && { proxy }),
},
});