Surf Connector

For Surf on Mac · Surf requires macOS 14 or later · Guide updated 15 October 2026

Give your assistant a browser to work in. A compatible local MCP client can read and act in its own Surf tabs while you continue browsing.

You need: Surf Pro on Mac, this free connector, and compatible assistant software with your own account. Provider charges are separate. Assistant tabs share your website sign-ins; requested content goes to your assistant’s provider. Private tabs stay excluded. Privacy details.

Surf Connector — protocol 8

SurfConnector.pkg · 226 KB · installer version 1.8 · universal (Apple silicon and Intel) · macOS 13 or later · signed with Developer ID and notarized by Apple

Download protocol 8 — SurfConnector.pkg SHA-256 9245fc1c077a066ab665d2f1f59a1223f37082135cc1aa68501f8bd087e694db
Connector identity, update checks and privacy

It checks whether a newer connector has been published, and here is exactly what that means. A few seconds after it starts, the connector fetches this one file — connector.json — and compares the build number in it against its own. That is the only network request it ever makes; everything else it does is on your own machine, over the loopback. It sends nothing: no build number, no identifier, no telemetry, no query string. It is the same plain GET your browser just made to read this page, and the comparison happens on your Mac, on what came back. If a newer build exists, it tells the assistant so the assistant can tell you — which is the whole point, because nothing else could.

To turn off the update check, set SURF_CONNECTOR_NO_UPDATE_CHECK=1 in your assistant’s MCP configuration. For Claude Code’s .mcp.json, the entry looks like this (ChatGPT desktop and Codex use TOML instead):

"surf": {
  "command": "/usr/local/lib/surf/surf-connector",
  "env": { "SURF_CONNECTOR_NO_UPDATE_CHECK": "1" }
}

Which connector have you actually got? A protocol number answers “can Surf and this connector talk”, and it moves only when that changes — so two completely different builds can both report protocol 8. Ask for the build instead, which is a hash of the program itself and cannot be wrong:

/usr/local/lib/surf/surf-connector --identity

The protocol number answers the other question. It is what decides whether Surf and this connector can talk to each other at all, so these three should agree — but two connectors can agree here and still be different programs, which is what the build above is for:

Why it is a separate download

Claude talks to other programs over a standard called MCP, which means starting a small program of its own. An app from the Mac App Store is not the right thing to be writing programs onto your disk for something else to run, so we ship this one separately, signed with Developer ID and notarized by Apple in its own installer. It is also why Surf asks you to point at it rather than guessing where it is: a guess that is wrong produces a setup that looks finished and quietly does nothing.

Install it

  1. Download SurfConnector.pkg — protocol 8, 226 KB — and open it. macOS checks Apple's notarization before it runs.
  2. Open Surf, then the … menu → Add-Ons.
  3. Press Choose the Connector… and pick the program the installer placed at
    /usr/local/lib/surf/surf-connector.
    The open panel starts there. If you put the program somewhere else — ~/.local/bin is the usual choice when you would rather not type an administrator password — press ⌘⇧G in the panel and type that path instead. Surf records whatever you pick; it never guesses.
  4. Follow the setup for whichever assistant you use — choose your assistant below.
  5. Quit that assistant completely and open it again. Sessions already running will not see Surf.

Already have it? Verify it before reinstalling. Surf 1.14 for Mac, build 138 and later, requests remembered read-only access to check the selected connector after you relaunch Surf. If you chose it in an earlier build, press Verify Installed Connector… in Settings › AI Assistants or Add-Ons › AI Assistants when prompted, and select the already installed surf-connector. This is a one-time permission step when access is missing, not another installation. Verification only reads the selected file, never writes it, does not request parent-folder permission and does not run the connector to inspect it.

Up to date — no update needed means the readable selected file matches the latest download or, when Surf cannot read that file, a currently connected session does. Surf identifies the evidence it used. Download Again is optional. Older sessions get a separate instruction to restart their Surf connection or start a new session; they do not hide another current session. An older session or saved history alone does not prove the installed file needs an update. When Surf cannot verify the file or a current connection, it says so. Failed or disabled update checks remain explicit.

With update checks enabled and a connector on record, Surf checks at launch, when you open AI Assistants in Settings or Add-Ons, after you choose a connector, and when you turn checks back on. Check Now also requests a fresh comparison. You can turn these requests off in Settings › AI Assistants. The comparison uses the static connector.json described above; your installed build stays on your Mac.

If your build differs from the latest download, install it over the top — your existing setup is kept. The change that matters most in protocol 8 is not something an older connector cannot do — it is something it describes wrongly. An older connector tells the assistant it can only see the tabs it opened, and leaves it to conclude that it is browsing in a sandbox of its own. It is not. Every tab it opens is an ordinary Surf tab using your ordinary cookies, so a site you are signed into is signed in for it, and a sign-in or a sign-out it performs is one your own browsing keeps afterwards. An assistant holding the older description will switch an account or sign out of one believing it is tidying up after itself; this one is told whose browser it is in, on every reply. Alongside it: it is now told when closing its own tab moved which tab you are looking at, rather than asking you about something you did not do; the key names it may send are the ones Surf actually accepts, and pressing a shifted key now types the shifted character; and a full-page capture reports the coordinates it was really taken in, which is the difference between a click that lands and one several hundred pixels adrift. Surf says so in Add-Ons when a connected session is running an older connector, and tells the session directly on every reply — the assistant is the one that needs to know, and it never looks at a panel. As above, quit the assistant and open it again afterwards, or it will keep using the copy it already started.

Set it up in your assistant

The connector is a local MCP server for compatible assistant clients, with the same refusals, the same switch and the same per-session tabs. Surf 1.14 for Mac provides a ChatGPT & Codex choice in Settings › AI Assistants, with connector-path, Codex-command and TOML copy buttons. On earlier versions, configure your assistant separately using the instructions below. You need Surf Pro, the connector installed and selected in Surf, and automation enabled in Settings › AI Assistants or … → Add-Ons (named Claude in earlier Surf versions).

Jump to your tool

The three facts every tool needs

Whatever the tool calls its config file, it is asking for the same three things.

  1. The program to run: /usr/local/lib/surf/surf-connector
    If you installed the connector somewhere else, use that path instead — this is only where the installer puts it. (Newer versions of Surf can copy it for you: … menu → Add-Ons → Copy Connector Path.)
  2. No arguments, and a local / stdio server — not a URL, not a remote server. The connector is a program the tool launches, not a website it calls.
  3. A generous request timeout: 60 seconds. This is the one that will bite you, and it is a setting rather than a bug — see below.

About that timeout. Some tools default a request to about five seconds. Real browsing does not fit in five seconds: Surf waits up to fifteen for a page to finish loading before it answers, and up to six just to work out whether Surf is running at all. A five-second client gives up while Surf is still working, and what you see is a tool reporting that the server timed out or crashed — which looks exactly like a broken connector, so it sends you off fixing the one thing that is fine. Set 60 seconds and forget it.

One more thing worth doing if your tool offers it: give the server a working directory pointing at the project you are on. Surf names each connected session after that folder and the tool — my-project · opencode — and that name is what labels its tabs in the tab strip. Without it, two sessions look identical.

ChatGPT desktop & Codex

In ChatGPT desktop, open Settings › MCP servers › Add server. Name it surf, choose STDIO, and enter the path of the connector you selected in Surf. The installer’s default is /usr/local/lib/surf/surf-connector; use your actual path if it differs. Save, select Restart, then use /mcp to check the connection.

If Codex CLI is installed, this command adds the same server:

codex mcp add surf -- /usr/local/lib/surf/surf-connector

Or add this table to ~/.codex/config.toml, preserving your other settings and editing an existing mcp_servers.surf table instead of duplicating it:

[mcp_servers.surf]
command = "/usr/local/lib/surf/surf-connector"
tool_timeout_sec = 60

To disable the connector’s update check, add env = { SURF_CONNECTOR_NO_UPDATE_CHECK = "1" } inside that table. ChatGPT desktop, Codex CLI and the IDE extension share this configuration on the same host. Restart the client and start a fresh session after changes.

ChatGPT web is different: it does not read your Mac’s local configuration. These steps do not connect Surf to a chat at chatgpt.com. See OpenAI’s MCP setup documentation.

Compatibility checked 8 September 2026: Codex CLI 0.153.4, using the signed connector available above and the Surf 1.14 release candidate, opened a background fixture, read it, filled a field, clicked, resized it to 375 × 812, captured the page and closed only its own tab. The user’s window was not resized. Tool discovery inside the ChatGPT desktop interface has not yet been independently verified. Keep Surf open with Pro and its automation switch enabled, then follow Check it worked to confirm your client connects.

Claude app

No terminal needed.

  1. In Surf: … → Add-Ons → Copy Setup for Claude App.
  2. In Claude: Settings › Developer › Edit Config.
  3. If the file is empty, paste what you copied in as the whole file. If it already has an mcpServers block, paste just the "surf" entry inside it.
  4. Quit Claude completely (⌘Q) and open it again. Closing the window is not enough — the config is read once, at launch.

What gets pasted looks like this:

{
  "mcpServers": {
    "surf": {
      "command": "/usr/local/lib/surf/surf-connector"
    }
  }
}

Claude Code

One terminal command, once, and Surf works in every folder.

  1. In Surf: … → Add-Ons → Copy Command.
  2. Paste it into Terminal and press Return:
    claude mcp add --scope user surf -- "/usr/local/lib/surf/surf-connector"
  3. Start a new claude session. Sessions already open will not see Surf.

To set up a single folder instead, use Set Up One Folder… in Add-Ons — Surf writes a .mcp.json there and merges into anything already in it.

OpenCode

Edit opencode.json (or opencode.jsonc) — the global one in your config directory, or one in the project. The key is mcp, and the entry type is local:

{
  "mcp": {
    "surf": {
      "type": "local",
      "command": ["/usr/local/lib/surf/surf-connector"],
      "enabled": true,
      "timeout": 60000
    }
  }
}

The timeout line is not optional in practice. OpenCode’s own schema says it defaults to 5000 ms, which is shorter than a page load. OpenCode also accepts "cwd", and setting it to your project folder is what makes Surf’s session label useful.

Then start a new OpenCode session.

Zed

Open your Zed settings.json and add the server under context_servers. Zed asks for command, args and env, and the connector needs no arguments and no environment:

{
  "context_servers": {
    "surf": {
      "command": "/usr/local/lib/surf/surf-connector",
      "args": [],
      "env": {}
    }
  }
}

Restart Zed afterwards.

Cursor

Cursor uses the same shape as the Claude app, in ~/.cursor/mcp.json for everything, or .cursor/mcp.json inside a project:

{
  "mcpServers": {
    "surf": {
      "command": "/usr/local/lib/surf/surf-connector",
      "args": []
    }
  }
}

Restart Cursor, and check the MCP list in its settings shows surf as connected.

VS Code (GitHub Copilot)

VS Code uses servers rather than mcpServers, in .vscode/mcp.json for one workspace, or the user-level mcp.json you reach with the MCP: Open User Configuration command:

{
  "servers": {
    "surf": {
      "type": "stdio",
      "command": "/usr/local/lib/surf/surf-connector"
    }
  }
}

Surf’s tools then appear in Copilot’s tool list in agent mode.

Anything else that speaks MCP

Use the syntax your client expects with the program path and local transport described above. JSON entries and TOML tables are not interchangeable; follow the instructions for your selected client. Common configuration locations are:

ToolWhereKey
ChatGPT desktop / Codex~/.codex/config.toml[mcp_servers.surf]
Claude appclaude_desktop_config.json (Settings › Developer › Edit Config)mcpServers
Claude Code~/.claude.json, or .mcp.json in a foldermcpServers
Cursor~/.cursor/mcp.json or .cursor/mcp.jsonmcpServers
Windsurf~/.codeium/windsurf/mcp_config.jsonmcpServers
VS Code.vscode/mcp.json, or the user mcp.jsonservers
ZedZed settings.jsoncontext_servers
OpenCodeopencode.json / opencode.jsoncmcp

These file locations belong to those tools, not to us, and they do move between versions. If one of them is wrong, that tool’s own MCP documentation wins — the three facts at the top are what stay true.

Check it worked

  1. In Surf, open … → Add-Ons and turn the Claude switch on. It starts off, and from Surf 1.12 for Mac it stays where you leave it — Automation › Stop Automation turns it off again from anywhere. (In Surf 1.11 and earlier it was off at every launch.)
  2. Start your assistant fresh and ask it: “Use Surf, not Chrome, to open example.com and tell me the heading.”
  3. Watch Surf. A tab opens, a coloured edge appears around the page, and a marker in the toolbar says how many tabs that session has.

Say Surf by name. If a Chrome extension is installed as well, “use the browser” is ambiguous and your assistant will usually reach for Chrome.

The Add-Ons panel lists every connected session by name, with its tab and request counts, so you can see the connection from Surf’s side without asking the assistant anything.

When it doesn’t

What it can and cannot do

While you have the feature switched on, your connected assistant can read the address, visible text and elements of a page it is working with — including anything already typed into an ordinary form field on it — take a picture of it, and see the messages and network requests that page made. It can also click, type, scroll and drag, go back and forward, open and close its own tabs, and resize its working page. In Surf 1.14 for Mac, resizing a detached background tab changes only its viewport. Resizing a visible assistant-owned tab changes that tab’s window. Earlier Surf versions can resize the visible window during background work. It can cause a file to be saved to your Mac, the same way following a download link yourself would; each one is reported back by name and path. Surf hands anything over only when asked.

Surf refuses some things in its own code, whatever it is asked. Private tabs are never exposed. Password fields are never filled, and Surf refuses any field it recognises as a card, security code or one-time code. What you typed into one is never read either: it is left out of what the assistant is told, and Surf hides it for the moment a screenshot is taken, so it is not in the picture either. Recognising a card field depends on how the site marks it up, so treat it as a strong safeguard rather than a guarantee. A session can only touch tabs it opened, or a tab you have handed to it deliberately.

It browses as you, in your own browser. A tab a session opens is an ordinary Surf tab with your ordinary cookies — there is no separate, signed-out profile behind the feature. So a site you are signed into is a site the session is signed into: it can open your account there, read it, and act as you. That runs both ways — if a session signs in to a site, or signs out of one, that is what your own browsing finds the next time you go there. Tab ownership keeps a session out of your other tabs; it does not give it a browser of its own. Private tabs are the exception on both counts: they keep their own cookies in memory, and Surf never exposes them to a session at all.

You can see when it is happening. While a session is working, Surf draws a coloured edge around the page and shows a marker in the toolbar saying how many tabs that session has; clicking it takes you to the one being worked on. Each session gets its own colour, and the same colour marks its tabs in the tab strip. This matters because the assistant can work in a background tab — one you are not looking at — so the window itself has to tell you. Those signals need a window to appear in, though: Surf keeps running with its window closed so downloads finish, and nothing is drawn anywhere at that point. Automation › Stop Automation is in the menu bar the whole time, which is the switch to rely on.

What your assistant does with what it receives is between you and its provider — it will send that content on to be processed, and Surf can neither see nor limit that. A page's own text can also try to influence an assistant that is reading it. Surf is not immune to that, and no browser is. The feature does nothing until you switch it on for exactly these reasons, and Automation › Stop Automation is in the menu bar the whole time it is running so that turning it off never requires finding a settings pane.

Full detail is in the privacy policy, section 7.

Check what you downloaded

The installer is signed by MW Supply Limited and notarized by Apple, so macOS verifies it for you before it will open. The certificate reads Developer ID Installer: Matthew Wong (6RZ8YV42XZ) — that is us; Apple issues these in the account holder’s name. If you would rather check it yourself:

shasum -a 256 SurfConnector.pkg

9245fc1c077a066ab665d2f1f59a1223f37082135cc1aa68501f8bd087e694db

spctl --assess --type install -v SurfConnector.pkg should answer accepted · source=Notarized Developer ID.

Remove it

Remove the surf entry from each assistant you configured, then delete the connector from its installed location (/usr/local/lib/surf/ for the installer above). The installer adds nothing else and runs no scripts. While it is running the connector writes one small file inside Surf’s own storage — the port Surf should call it back on — and removes it again when it exits.

Independent of your assistant provider

Surf and the Surf Connector are made by MW Supply Limited. Claude is a product of Anthropic; ChatGPT and Codex are products of OpenAI. Neither company sponsors or endorses Surf. You use your own assistant software and account. Surf provides no AI account and does not receive your assistant account credentials.