From bf3afa271848f59272d71eb1c8e7d2fcf4cde836 Mon Sep 17 00:00:00 2001 From: rgarcia <72655+rgarcia@users.noreply.github.com> Date: Wed, 2 Sep 2026 19:45:09 +0000 Subject: [PATCH 1/2] Accept browser session name wherever a session ID is taken Bump @onkernel/sdk to 0.98.0, which renames the browser sub-resource path parameter to id_or_name, and describe every session_id input on the browser tools and the debug prompt as ID or name. manage_browsers gains name and tags on create and update so a session can be given the name it is later addressed by. Adapt the replay stop call to the renamed SDK parameter. --- README.md | 4 +- bun.lock | 6 +- package.json | 2 +- src/lib/mcp/prompts.ts | 2 +- src/lib/mcp/tools/browser-curl.ts | 2 +- src/lib/mcp/tools/browsers.test.ts | 88 ++++++++++++++++++++++++++++ src/lib/mcp/tools/browsers.ts | 20 ++++++- src/lib/mcp/tools/computer-action.ts | 2 +- src/lib/mcp/tools/playwright.ts | 2 +- src/lib/mcp/tools/replays.ts | 4 +- src/lib/mcp/tools/shell.ts | 2 +- 11 files changed, 119 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 090e342c..96b08f43 100644 --- a/README.md +++ b/README.md @@ -304,7 +304,7 @@ Call `get_connection_context` before deciding whether to create or select a proj ### manage\_\* tools -- `manage_browsers` - Create, update, list, get, and delete browser sessions, and read archived telemetry for active or deleted sessions. Supports headless/stealth modes, profiles, proxies, viewports, extensions, and SSH tunneling. +- `manage_browsers` - Create, update, list, get, and delete browser sessions, and read archived telemetry for active or deleted sessions. Supports headless/stealth modes, profiles, proxies, viewports, extensions, names and tags, and SSH tunneling. Every tool that takes a `session_id` also accepts the session's name. - `manage_profiles` - Setup (with guided live browser session), search/list with pagination, get, and delete browser profiles for persisting cookies and logins. - `manage_projects` - Create, list, get, update, and delete organization projects. Inspect and update per-project resource limits. - `manage_api_keys` - Create, list, get, update, and delete org-wide or project-scoped API keys. Create returns the plaintext key once. @@ -332,7 +332,7 @@ Call `get_connection_context` before deciding whether to create or select a proj Project resources use the prefix `kernel://orgs/{organization_id}/projects/{project_id}`. -- `/browsers` and `/browsers/{session_id}` - List or access browser sessions +- `/browsers` and `/browsers/{session_id}` - List or access browser sessions (`{session_id}` may be a session ID or name) - `/browser-pools` and `/browser-pools/{id_or_name}` - List or access browser pools - `/profiles` and `/profiles/{profile_name}` - List or access browser profiles - `/apps` and `/apps/{app_name}` - List or access deployed apps diff --git a/bun.lock b/bun.lock index 57c052b8..6e978dc0 100644 --- a/bun.lock +++ b/bun.lock @@ -10,7 +10,7 @@ "@clerk/themes": "^2.4.19", "@modelcontextprotocol/sdk": "1.26.0", "@onkernel/managed-auth-react": "0.5.1", - "@onkernel/sdk": "^0.97.0", + "@onkernel/sdk": "^0.98.0", "@posthog/mcp": "0.10.1", "@types/jsonwebtoken": "^9.0.10", "@types/redis": "^4.0.11", @@ -21,7 +21,7 @@ "jszip": "^3.10.1", "lucide-react": "^0.534.0", "mcp-handler": "^1.1.0", - "next": "16.2.11", + "next": "^16.2.11", "next-themes": "^0.4.4", "playwright": "^1.49.1", "posthog-node": "^5.46.1", @@ -149,7 +149,7 @@ "@onkernel/managed-auth-react": ["@onkernel/managed-auth-react@0.5.1", "", { "dependencies": { "clsx": "^2.1.1" }, "peerDependencies": { "react": ">=18", "react-dom": ">=18" } }, "sha512-tRnx91QTqlop2otlXyOxmI+jHodAMCW0dytWyk4hvu26cjACqH0387S0nP4IfgBVkZW6rwdNoBYKOheQfIxMgA=="], - "@onkernel/sdk": ["@onkernel/sdk@0.97.0", "", {}, "sha512-Mi9//b9l81tl+eBPV3TpYwU9noriW7c0lFdJ8z5dj1SOQwdPB3nwdQDIfpewxzMeOBNng/qA2jkLkhopXWLbDw=="], + "@onkernel/sdk": ["@onkernel/sdk@0.98.0", "", {}, "sha512-FTvTDEPj3rS6INa+JTqso1XpnGkBKP3axvcAumX8dfd5nAI157mIlaZDWQ2k61MxwKpHDEvD5iNwD+sUk4OEcw=="], "@oven/bun-darwin-aarch64": ["@oven/bun-darwin-aarch64@1.3.3", "", { "os": "darwin", "cpu": "arm64" }, "sha512-eJopQrUk0WR7jViYDC29+Rp50xGvs4GtWOXBeqCoFMzutkkO3CZvHehA4JqnjfWMTSS8toqvRhCSOpOz62Wf9w=="], diff --git a/package.json b/package.json index a649ff76..9a78182b 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,7 @@ "@clerk/themes": "^2.4.19", "@modelcontextprotocol/sdk": "1.26.0", "@onkernel/managed-auth-react": "0.5.1", - "@onkernel/sdk": "^0.97.0", + "@onkernel/sdk": "^0.98.0", "@posthog/mcp": "0.10.1", "@types/jsonwebtoken": "^9.0.10", "@types/redis": "^4.0.11", diff --git a/src/lib/mcp/prompts.ts b/src/lib/mcp/prompts.ts index 513e9fe0..95de0aa9 100644 --- a/src/lib/mcp/prompts.ts +++ b/src/lib/mcp/prompts.ts @@ -98,7 +98,7 @@ Production-ready platform for deploying and hosting browser automation code. Han session_id: z .string() .describe( - "The browser session ID to debug (e.g., 'abc123example456xyz')", + "The browser session ID or name to debug (e.g., 'abc123example456xyz' or 'checkout-flow')", ), issue_description: z .string() diff --git a/src/lib/mcp/tools/browser-curl.ts b/src/lib/mcp/tools/browser-curl.ts index 61b2b3ef..6ceba04a 100644 --- a/src/lib/mcp/tools/browser-curl.ts +++ b/src/lib/mcp/tools/browser-curl.ts @@ -33,7 +33,7 @@ export function registerBrowserCurlTool(server: McpServer) { "Send an HTTP request through an existing Kernel browser session's Chrome network stack. Use when the request needs that browser session's cookies, proxy, network context, or origin behavior; do not use for general documentation lookup or web search.", { ...projectSelectionInputSchema(), - session_id: z.string().describe("Browser session ID."), + session_id: z.string().describe("Browser session ID or name."), url: z.string().url().describe("Target http or https URL."), method: z .enum(["GET", "HEAD", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"]) diff --git a/src/lib/mcp/tools/browsers.test.ts b/src/lib/mcp/tools/browsers.test.ts index 52008130..eea49088 100644 --- a/src/lib/mcp/tools/browsers.test.ts +++ b/src/lib/mcp/tools/browsers.test.ts @@ -393,6 +393,94 @@ describe("manage_browsers region", () => { }); }); +describe("manage_browsers id or name", () => { + test("passes name and tags through create and update", async () => { + const createCalls: unknown[] = []; + const updateCalls: unknown[] = []; + const kernelClient = { + browsers: { + create: async (params: unknown) => { + createCalls.push(params); + return { session_id: "brr_123", name: "checkout-flow" }; + }, + update: async (idOrName: string, params: unknown) => { + updateCalls.push([idOrName, params]); + return { session_id: "brr_123" }; + }, + }, + }; + const { client, close } = await connectTestMcp( + registerBrowserCapabilities, + kernelClient, + ); + + try { + await client.callTool({ + name: "manage_browsers", + arguments: { + action: "create", + name: "checkout-flow", + tags: { team: "payments" }, + }, + }); + expect(createCalls).toEqual([ + { name: "checkout-flow", tags: { team: "payments" } }, + ]); + + await client.callTool({ + name: "manage_browsers", + arguments: { + action: "update", + session_id: "checkout-flow", + name: "checkout-flow-2", + tags: {}, + }, + }); + expect(updateCalls).toEqual([ + ["checkout-flow", { name: "checkout-flow-2", tags: {} }], + ]); + } finally { + await close(); + } + }); + + test("forwards a session name unchanged to get and delete", async () => { + const seen: string[] = []; + const kernelClient = { + browsers: { + retrieve: async (idOrName: string) => { + seen.push(`get:${idOrName}`); + return { session_id: "brr_123", name: idOrName }; + }, + deleteByID: async (idOrName: string) => { + seen.push(`delete:${idOrName}`); + }, + }, + }; + const { client, close } = await connectTestMcp( + registerBrowserCapabilities, + kernelClient, + ); + + try { + const got = toolResultJSON( + await client.callTool({ + name: "manage_browsers", + arguments: { action: "get", session_id: "checkout-flow" }, + }), + ); + expect(got.session_id).toBe("brr_123"); + await client.callTool({ + name: "manage_browsers", + arguments: { action: "delete", session_id: "checkout-flow" }, + }); + expect(seen).toEqual(["get:checkout-flow", "delete:checkout-flow"]); + } finally { + await close(); + } + }); +}); + describe("browser resources", () => { test("uses injected dependencies", async () => { const kernelClient = { diff --git a/src/lib/mcp/tools/browsers.ts b/src/lib/mcp/tools/browsers.ts index 8236fe19..d93f0eb9 100644 --- a/src/lib/mcp/tools/browsers.ts +++ b/src/lib/mcp/tools/browsers.ts @@ -433,7 +433,7 @@ export function registerBrowserCapabilities( // manage_browsers -- Manage browser sessions and read archived telemetry server.tool( "manage_browsers", - 'Manage browser sessions and their archived telemetry. Use "list" to choose an existing session, "create" before browser control, "update" to change supported session settings, "get" for full details, "get_telemetry" to diagnose active or deleted sessions, and "delete" when finished. get_telemetry compacts events by default; set compact=false with explicit categories and a limit of at most 5 when raw headers, request data, response bodies, or other omitted fields are needed.', + 'Manage browser sessions and their archived telemetry. Use "list" to choose an existing session, "create" before browser control, "update" to change supported session settings, "get" for full details, "get_telemetry" to diagnose active or deleted sessions, and "delete" when finished. Sessions can be addressed by ID or by the name given at creation. get_telemetry compacts events by default; set compact=false with explicit categories and a limit of at most 5 when raw headers, request data, response bodies, or other omitted fields are needed.', { ...projectSelectionInputSchema(), action: z @@ -442,7 +442,19 @@ export function registerBrowserCapabilities( session_id: z .string() .describe( - "Browser session ID. Required for update, get, get_telemetry, and delete actions.", + "Browser session ID or name. Required for update, get, get_telemetry, and delete actions.", + ) + .optional(), + name: z + .string() + .describe( + "(create, update) Human-readable session name, unique among active sessions in the project. Once set, the session can be addressed by this name wherever a session_id is accepted. On update, an empty string clears the name.", + ) + .optional(), + tags: z + .record(z.string()) + .describe( + "(create, update) Key-value tags for grouping sessions. Up to 50 pairs. On update, an empty object clears all tags.", ) .optional(), start_url: z @@ -679,6 +691,8 @@ export function registerBrowserCapabilities( createParams.chrome_policy = params.chrome_policy; } if (params.proxy_id) createParams.proxy_id = params.proxy_id; + if (params.name !== undefined) createParams.name = params.name; + if (params.tags !== undefined) createParams.tags = params.tags; const browserConfig = buildBrowserCreateConfig(params); if (!browserConfig.ok) return errorResponse(browserConfig.error); Object.assign(createParams, browserConfig.value); @@ -723,6 +737,8 @@ export function registerBrowserCapabilities( } else if (params.proxy_id !== undefined) { updateParams.proxy_id = params.proxy_id; } + if (params.name !== undefined) updateParams.name = params.name; + if (params.tags !== undefined) updateParams.tags = params.tags; const browserConfig = buildBrowserUpdateConfig(params); if (!browserConfig.ok) return errorResponse(browserConfig.error); Object.assign(updateParams, browserConfig.value); diff --git a/src/lib/mcp/tools/computer-action.ts b/src/lib/mcp/tools/computer-action.ts index ff1f55fb..2536200d 100644 --- a/src/lib/mcp/tools/computer-action.ts +++ b/src/lib/mcp/tools/computer-action.ts @@ -257,7 +257,7 @@ export function registerComputerActionTool(server: McpServer) { "Execute computer actions on a browser session. Pass a single action for simple operations (e.g. one click or one screenshot), or pass multiple actions to batch them into a single request for lower latency (e.g. click, type, press_key in one call). Use sleep actions between steps when the page needs time to react (e.g. after a click that triggers navigation or animation). IMPORTANT: Always include a screenshot as the last action so you can see the result of your actions. Action types: click_mouse, move_mouse, type_text, press_key, scroll, drag_mouse, set_cursor, sleep, write_clipboard, read_clipboard, screenshot, get_mouse_position. screenshot, read_clipboard, and get_mouse_position return data, so they must be the last action if included.", { ...projectSelectionInputSchema(), - session_id: z.string().describe("Browser session ID."), + session_id: z.string().describe("Browser session ID or name."), actions: z .array(computerActionSchema) .min(1) diff --git a/src/lib/mcp/tools/playwright.ts b/src/lib/mcp/tools/playwright.ts index 3fd01205..1bf88ba7 100644 --- a/src/lib/mcp/tools/playwright.ts +++ b/src/lib/mcp/tools/playwright.ts @@ -36,7 +36,7 @@ export function registerPlaywrightTool( session_id: z .string() .min(1, "session_id is required") - .describe("Browser session ID to execute the code against."), + .describe("Browser session ID or name to execute the code against."), }, { title: "Execute Playwright code", diff --git a/src/lib/mcp/tools/replays.ts b/src/lib/mcp/tools/replays.ts index 3baeda6b..e7405fef 100644 --- a/src/lib/mcp/tools/replays.ts +++ b/src/lib/mcp/tools/replays.ts @@ -23,7 +23,7 @@ export function registerReplayTools(server: McpServer) { action: z .enum(["start", "stop", "list"]) .describe("Operation to perform."), - session_id: z.string().describe("Browser session ID."), + session_id: z.string().describe("Browser session ID or name."), replay_id: z.string().describe("(stop) Replay ID to stop.").optional(), framerate: z .number() @@ -84,7 +84,7 @@ export function registerReplayTools(server: McpServer) { if (!params.replay_id) return errorResponse("Error: replay_id is required for stop."); await client.browsers.replays.stop(params.replay_id, { - id: params.session_id, + id_or_name: params.session_id, }); return textResponse("Replay stopped successfully"); } diff --git a/src/lib/mcp/tools/shell.ts b/src/lib/mcp/tools/shell.ts index 71e8e05f..3e8256ac 100644 --- a/src/lib/mcp/tools/shell.ts +++ b/src/lib/mcp/tools/shell.ts @@ -30,7 +30,7 @@ export function registerShellTool( 'Execute a command synchronously inside a browser VM. Returns stdout, stderr, and exit code. The command field is the executable; use args for its arguments. Common uses: read files (command: "cat", args: ["/var/log/supervisord.log"]), list dirs (command: "ls", args: ["/var/log"]), check DNS (command: "cat", args: ["/etc/resolv.conf"]), test connectivity (command: "curl", args: ["-I", "https://example.com"]).', { ...projectSelectionInputSchema(), - session_id: z.string().describe("Browser session ID."), + session_id: z.string().describe("Browser session ID or name."), command: z .string() .describe("Executable to run (e.g., 'cat', 'ls', 'curl')."), From f8b43bf621cab2cfd8249cd93fba1d6bb359c18e Mon Sep 17 00:00:00 2001 From: rgarcia <72655+rgarcia@users.noreply.github.com> Date: Wed, 2 Sep 2026 22:42:58 +0000 Subject: [PATCH 2/2] Scope name support to live sessions and browser tools A name resolves only a live session on the API, so get_telemetry on a deleted session needs its ID; say so on the session_id input, the debug prompt, and the tool description. Scope the README claim to the browser tools and mark pool release as ID only. State the name charset, wire the list action's query and tags filters, and cover name clearing on update. --- README.md | 4 +-- src/lib/mcp/prompts.ts | 4 +-- src/lib/mcp/tools/browser-pools.ts | 4 ++- src/lib/mcp/tools/browsers.test.ts | 42 ++++++++++++++++++++++++++++++ src/lib/mcp/tools/browsers.ts | 16 +++++++++--- 5 files changed, 61 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 96b08f43..b9e7fa09 100644 --- a/README.md +++ b/README.md @@ -304,7 +304,7 @@ Call `get_connection_context` before deciding whether to create or select a proj ### manage\_\* tools -- `manage_browsers` - Create, update, list, get, and delete browser sessions, and read archived telemetry for active or deleted sessions. Supports headless/stealth modes, profiles, proxies, viewports, extensions, names and tags, and SSH tunneling. Every tool that takes a `session_id` also accepts the session's name. +- `manage_browsers` - Create, update, list, get, and delete browser sessions, and read archived telemetry for active or deleted sessions. Supports headless/stealth modes, profiles, proxies, viewports, extensions, names and tags, and SSH tunneling. The browser tools (`manage_browsers`, `computer_action`, `execute_playwright_code`, `execute_shell_command`, `browser_curl`, `manage_replays`) accept a live session's name in place of its `session_id`; deleted sessions, and `manage_browser_pools` release, take the ID only. - `manage_profiles` - Setup (with guided live browser session), search/list with pagination, get, and delete browser profiles for persisting cookies and logins. - `manage_projects` - Create, list, get, update, and delete organization projects. Inspect and update per-project resource limits. - `manage_api_keys` - Create, list, get, update, and delete org-wide or project-scoped API keys. Create returns the plaintext key once. @@ -332,7 +332,7 @@ Call `get_connection_context` before deciding whether to create or select a proj Project resources use the prefix `kernel://orgs/{organization_id}/projects/{project_id}`. -- `/browsers` and `/browsers/{session_id}` - List or access browser sessions (`{session_id}` may be a session ID or name) +- `/browsers` and `/browsers/{session_id}` - List or access browser sessions (`{session_id}` may be a live session's ID or name) - `/browser-pools` and `/browser-pools/{id_or_name}` - List or access browser pools - `/profiles` and `/profiles/{profile_name}` - List or access browser profiles - `/apps` and `/apps/{app_name}` - List or access deployed apps diff --git a/src/lib/mcp/prompts.ts b/src/lib/mcp/prompts.ts index 95de0aa9..3881490b 100644 --- a/src/lib/mcp/prompts.ts +++ b/src/lib/mcp/prompts.ts @@ -98,7 +98,7 @@ Production-ready platform for deploying and hosting browser automation code. Han session_id: z .string() .describe( - "The browser session ID or name to debug (e.g., 'abc123example456xyz' or 'checkout-flow')", + "The browser session ID or name to debug (e.g., 'abc123example456xyz' or 'checkout-flow'). A name resolves only a live session; if the session was deleted, pass its ID so telemetry can still be read.", ), issue_description: z .string() @@ -135,7 +135,7 @@ kernel browsers playwright --help ## Telemetry Events (structured signal — works even after the session is deleted) -When telemetry was captured, it's usually the fastest way to pinpoint a failure — read it before reaching for screenshots or logs. If the session has been deleted, it's the only signal still available: every CLI command in this guide needs a live session. +When telemetry was captured, it's usually the fastest way to pinpoint a failure — read it before reaching for screenshots or logs. If the session has been deleted, it's the only signal still available: every CLI command in this guide needs a live session. A deleted session must be addressed by its ID; its name no longer resolves. Start broad: call \`manage_browsers\` with action "get_telemetry", session_id "${session_id}", and no filters. That starts at session creation and returns the first page (up to 100 events); page with \`next_offset\` as \`offset\` while \`has_more\` is true, preserving \`categories\`, \`until\`, and \`order\`. An empty unfiltered read is definitive: nothing was archived. Narrow when the output is too large to scan or you already know where to look: \`categories\` to isolate a signal you've spotted, \`order\` "desc" when the end of the session matters most, \`since\`/\`until\` to bracket a known failing step. Correlate event timestamps with the failing automation step. diff --git a/src/lib/mcp/tools/browser-pools.ts b/src/lib/mcp/tools/browser-pools.ts index c06cb825..be732ecf 100644 --- a/src/lib/mcp/tools/browser-pools.ts +++ b/src/lib/mcp/tools/browser-pools.ts @@ -388,7 +388,9 @@ export function registerBrowserPoolCapabilities(server: McpServer) { .optional(), session_id: z .string() - .describe("(release) Session ID of browser to release.") + .describe( + "(release) Session ID of the browser to release. Must be the ID, not the session name.", + ) .optional(), reuse: z .boolean() diff --git a/src/lib/mcp/tools/browsers.test.ts b/src/lib/mcp/tools/browsers.test.ts index eea49088..400642e2 100644 --- a/src/lib/mcp/tools/browsers.test.ts +++ b/src/lib/mcp/tools/browsers.test.ts @@ -439,6 +439,48 @@ describe("manage_browsers id or name", () => { expect(updateCalls).toEqual([ ["checkout-flow", { name: "checkout-flow-2", tags: {} }], ]); + + await client.callTool({ + name: "manage_browsers", + arguments: { action: "update", session_id: "brr_123", name: "" }, + }); + expect(updateCalls[1]).toEqual(["brr_123", { name: "" }]); + } finally { + await close(); + } + }); + + test("passes query and tags filters to list", async () => { + const listCalls: unknown[] = []; + const kernelClient = { + browsers: { + list: async (params: unknown) => { + listCalls.push(params); + return { + getPaginatedItems: () => [], + has_more: false, + next_offset: null, + }; + }, + }, + }; + const { client, close } = await connectTestMcp( + registerBrowserCapabilities, + kernelClient, + ); + + try { + await client.callTool({ + name: "manage_browsers", + arguments: { + action: "list", + query: "checkout", + tags: { team: "payments" }, + }, + }); + expect(listCalls).toEqual([ + { query: "checkout", tags: { team: "payments" } }, + ]); } finally { await close(); } diff --git a/src/lib/mcp/tools/browsers.ts b/src/lib/mcp/tools/browsers.ts index d93f0eb9..51ddf4bc 100644 --- a/src/lib/mcp/tools/browsers.ts +++ b/src/lib/mcp/tools/browsers.ts @@ -433,7 +433,7 @@ export function registerBrowserCapabilities( // manage_browsers -- Manage browser sessions and read archived telemetry server.tool( "manage_browsers", - 'Manage browser sessions and their archived telemetry. Use "list" to choose an existing session, "create" before browser control, "update" to change supported session settings, "get" for full details, "get_telemetry" to diagnose active or deleted sessions, and "delete" when finished. Sessions can be addressed by ID or by the name given at creation. get_telemetry compacts events by default; set compact=false with explicit categories and a limit of at most 5 when raw headers, request data, response bodies, or other omitted fields are needed.', + 'Manage browser sessions and their archived telemetry. Use "list" to choose an existing session, "create" before browser control, "update" to change supported session settings, "get" for full details, "get_telemetry" to diagnose active or deleted sessions, and "delete" when finished. Live sessions can be addressed by ID or by the name given at creation or set on update; deleted sessions only by ID. get_telemetry compacts events by default; set compact=false with explicit categories and a limit of at most 5 when raw headers, request data, response bodies, or other omitted fields are needed.', { ...projectSelectionInputSchema(), action: z @@ -442,19 +442,25 @@ export function registerBrowserCapabilities( session_id: z .string() .describe( - "Browser session ID or name. Required for update, get, get_telemetry, and delete actions.", + "Browser session ID or name. Required for update, get, get_telemetry, and delete actions. A name resolves only a live session; for a deleted session (get_telemetry) pass its ID.", ) .optional(), name: z .string() .describe( - "(create, update) Human-readable session name, unique among active sessions in the project. Once set, the session can be addressed by this name wherever a session_id is accepted. On update, an empty string clears the name.", + "(create, update) Human-readable session name, unique among active sessions in the project. 1-255 chars of letters, digits, '.', '_' or '-', and not a cuid-like ID. While the session is live it can be passed as session_id to the browser tools (manage_browsers, computer_action, execute_playwright_code, execute_shell_command, browser_curl, manage_replays). On update, an empty string clears the name.", ) .optional(), tags: z .record(z.string()) .describe( - "(create, update) Key-value tags for grouping sessions. Up to 50 pairs. On update, an empty object clears all tags.", + "(create, update) Key-value tags for grouping sessions. Up to 50 pairs. On update, an empty object clears all tags. (list) Return only sessions carrying all of these tags.", + ) + .optional(), + query: z + .string() + .describe( + "(list) Text filter matched against session name, session ID, profile name or ID, proxy ID, or pool name.", ) .optional(), start_url: z @@ -768,6 +774,8 @@ export function registerBrowserCapabilities( const page = await client.browsers.list({ ...(params.status && { status: params.status }), ...(params.region && { region: params.region }), + ...(params.query && { query: params.query }), + ...(params.tags !== undefined && { tags: params.tags }), ...(params.limit !== undefined && { limit: params.limit }), ...(params.offset !== undefined && { offset: params.offset }), });