# feat\(server\): let users withhold browser access from agents · PR \#7083 · pingdotgg/t3code

[View on GitCafe](https://git.cafe/pingdotgg/t3code/pull/7083)

Repository: [pingdotgg/t3code](https://git.cafe/pingdotgg/t3code)

Visibility: public

State: merged

Source repository: pingdotgg/t3code

Source branch: browser-agent-access

Target branch: main

Head commit: 0d31f1163ef219ee4489380e5e63400c77a4ddac

[Discussion and reviews](https://git.cafe/pingdotgg/t3code/pull/7083)

[Commits](https://git.cafe/pingdotgg/t3code/pull/7083/commits?format=markdown)

[Files changed](https://git.cafe/pingdotgg/t3code/pull/7083/diffs?format=markdown)

## Description

---

> Stacked on #7082 — review that first; this PR's base is `browser-viewport-defaults`.

Adds **Settings → Integrations → Browser → Agent browser access**, on by default. Agents could always drive the preview browser with no way to say no.

## How the gate works

Turning it off withholds the MCP credential in `ProviderService.prepareMcpSession`. That's the only place a credential is minted, and `/mcp` accepts nothing else, so **one branch covers all five providers and any external MCP client** — every adapter already treats a missing session as "no MCP server".

The Codex developer instructions describing `preview_*` drop out along with the tools. That's derived from the session's actual MCP configuration via the existing `hasConfiguredMcpServer`, not a second read of the setting, so the prompt cannot describe tools the turn doesn't have.

That coupling matters more than it looks: the block explicitly steers the model away from Playwright and agent-browser. Leaving it in with the tools gone would talk the agent out of the only browser automation it has left. There's a test asserting the anti-steering line disappears with the tool names.

## Two decisions worth a look

**Denying on an unreadable settings file.** Reading settings introduced `ServerSettingsError` into `ProviderServiceError`, a union every caller handles. Rather than widen it, the error is contained at the boundary and treated as deny. An explicit "off" silently becoming "on" would violate the user's choice; the reverse costs an agent one toolset and is visible immediately.

**Scope is new sessions.** Credentials live up to 24h and can't be rotated into an already-spawned agent process, so a running agent keeps its tools. The UI states this rather than implying otherwise. Closing it would mean revoking live credentials on the settings change — `revokeAllActiveMcpCredentials` exists, but there's no settings-change subscriber on the server today, so it needs a small daemon. Happy to add it if wanted.

## Why this one stays enabled on web

Unlike the client-local defaults in #7082, this is a `ServerSetting`. The agent runs server-side and its preview calls route to whichever desktop client is attached, so the realistic case is: desktop app running with an agent working, you're on a phone or web tab, and you want to revoke access. That's exactly when you'd reach for it and least want it greyed out.

## Testing

Typecheck and lint clean; full suite passing, including new coverage for the prompt gating. Verified in a running dev instance: toggle defaults on, flips, persists to `settings.json`, survives reload.


<!-- Macroscope's pull request summary starts here -->
<!-- Macroscope will only edit the content between these invisible markers, and the markers themselves will not be visible in the GitHub rendered markdown. -->
<!-- If you delete either of the start / end markers from your PR's description, Macroscope will append its summary at the bottom of the description. -->
> [!NOTE]
> ### Add user-controlled toggle to withhold browser access from agents
> - Adds `enableAgentBrowserAccess` to `ServerSettings` (default `true`), with a toggle in the Integrations settings UI under the Browser section.
> - When disabled, `makeProviderService` revokes any active MCP credential, clears the MCP provider session, and returns `undefined` for new sessions instead of issuing credentials.
> - Browser tool instructions are omitted from agent prompts when MCP server tools are unavailable, via a new `browserToolsAvailable` parameter threaded through `buildCodexDeveloperInstructions`.
> - The setting is searchable, restorable to defaults, and patchable via the server settings API.
> - Behavioral Change: disabling the setting actively revokes existing credentials mid-session, not just on new sessions.
>
> <!-- Macroscope's review summary starts here -->
>
> <sup><a href="https://app.macroscope.com">Macroscope</a> summarized 0d31f11.</sup>
> <!-- Macroscope's review summary ends here -->
>
<!-- Macroscope's pull request summary ends here -->

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Changes MCP credential issuance and revocation at session prepare time and agent-facing Codex prompts; mistakes could leave stale tokens valid or mislead agents about available browser tools, though tests cover the gate and prompt omission.
> 
> **Overview**
> Introduces **agent browser access** as a server-authoritative setting (`enableAgentBrowserAccess`, default on). When off, `ProviderService.prepareMcpSession` skips issuing the `t3-code` MCP credential, revokes any existing token for that thread, and clears the in-memory MCP session so agents never get `preview_*` tools. Unreadable settings are treated as deny rather than widening `ProviderServiceError`.
> 
> Codex **developer instructions** are now built via functions that take `browserToolsAvailable`; the T3 preview browser block (including anti–Playwright steering) is omitted entirely when MCP is not configured on the session. `CodexSessionRuntime` passes `hasConfiguredMcpServer(appServerArgs)` into turn start so prompts match the tools on that turn.
> 
> **Settings → Integrations → Browser** adds a toggle (searchable, included in restore-defaults), with copy that already-running agents keep tools they were given. Contracts gain `enableAgentBrowserAccess` on server settings and patch types.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 0d31f1163ef219ee4489380e5e63400c77a4ddac. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
