An agent needed an entry point to control the browser. I did not make that entry a publicly reachable control server. The structure separates an application-owned local pipe, a small discovery file and a stdio process connected to the external conversation.

Separate conversation transport from the app connection

The external conversation exchanges MCP messages with a Node stdio server. That server reads discovery information for the running browser and forwards requests to its local pipe. The existing browser remains the execution host; connecting a conversation creates neither a new browser nor another login profile.

The intermediary therefore needs no model dependency. The browser executes the conversation's chosen work through checked tools rather than creating its own judgment. The local path and OS user session must match, so this is not a remote browser reachable from anywhere on the internet.

Knowing the endpoint does not authorize control

The app creates a pipe name and random token for its instance. An envelope supplies that token, a request ID and a typed request. The server compares lengths before using timingSafeEqual. Merely reaching the pipe with an arbitrary string does not reach the execution function.

The actual token in the discovery file is a secret and belongs in neither logs nor public examples. Public documentation can explain generation, transfer and comparison without reproducing a value. Endpoint discovery and control credentials are different assets even for a local connection.

Treat the discovery file as input too

The intermediary requires an absolute discovery-file path and checks that it is a regular file, not a symbolic link, within its size bound. It validates protocol, endpoint shape and token format. Readability alone does not make an arbitrary address the genuine browser entry point.

The app writes a temporary discovery file and renames it into place. During shutdown it removes the current file only if its instance matches. A late-closing old process must not delete the newer process's discovery information. Even a small local file needs ownership tied to the execution instance.

Bound message size and connection lifetime

The pipe server closes an oversized input buffer and accepts one initial request per connection. The intermediary also bounds reply size and waiting time. These checks do not solve every resource-exhaustion problem, but they avoid treating the entry point as an unlimited message accumulator.

A timeout describes the connection, not proof that a browser action was never sent. Intermediary errors retain the request ID and disable automatic replay. Communication errors and work outcomes must remain separate, or a reliability mechanism can become a source of duplicate input.

The same-OS-user limitation remains

A token does not isolate every process running under the same user's permissions. Access to the discovery file, operating-system rights and actual file permissions still matter. Supplying a mode value cannot be described as verification of every Windows ACL.

The current entry exposes no public HTTP or CDP endpoint and no general credential-extraction tool. That does not establish security of the whole PC. An administrator needs to understand who can read discovery information and send requests, rather than relying on a broad claim that the connection is local.

Connection authentication does not complete the workflow

The integration test checks that an invalid token produces no execution callback. For this article I compared server, intermediary and test code. I copied no actual secret, opened no new public server and changed no login profile.

A valid connection still requires work-scope, tab, enabled-plugin and outcome checks downstream. Authentication at the transport entry is not workflow success. In a company-specific integration, small explicit responsibilities at each layer are easier to maintain than claiming that a connection choice solves every problem.