docs · tools

The local MCP server

browser-memory reaches your agent as an MCP server. If that phrase means nothing to you, this page is the whole thing from the beginning — what the protocol is, what “local” really means, what starts what, and what crosses the line between your machine and the internet.

What MCP is

The Model Context Protocol is a standard way for an AI application to talk to an external program that can do things. That is genuinely all it is: an agreed-upon vocabulary for “here are the tools I have” and “please run this one with these arguments”.

It exists because of arithmetic. Before it, every AI app that wanted to read your files, query your database or drive your browser had to implement each of those integrations itself, and every integration had to be written again for each app — the classic M×N problem. MCP turns it into M+N: a capability is implemented once as a server, and any client that speaks the protocol can use it. It is the same trick as a printer driver, or as LSP for editors.

Three roles, and it helps to keep them straight:

RoleWho that is here
HostThe app you actually use — Claude Code, Cursor, VS Code with Copilot, Codex. It runs the model and owns the conversation
ClientThe bit of the host that speaks MCP. One client per connected server. You never interact with it directly
ServerThe program exposing the capability — in our case browser-memory, which exposes the tool memory and a browser

Note what the model does not do: it never speaks MCP itself. The host lists the server’s tools to the model as ordinary tool-calling options, the model picks one, and the host relays the call.

What “local” means

An MCP server can live in two places. Ours lives in the first, and the difference matters more than it sounds:

Local (stdio)Remote (HTTP)
Where it runsA process on your own computerSomeone’s server, reached over the network
Who starts itYour agent, as a child processIt is already running; the agent just connects
How they talkstdin and stdout of that process — the same pipes as | in a shellHTTP requests, usually with an auth token
PortsNone. Nothing listens, nothing is exposedA URL, reachable by whoever has it
ReachYour files, your browser, your logged-in sessionsOnly what that service can reach

So a local MCP server is not a service you sign up for and not a daemon you keep running. It is a command line sitting in a config file. When your agent starts, it runs that command; when your agent quits, the process dies with it. In between, the two exchange JSON-RPC messages over the pipe.

For browser-memory the local part is the whole point: the tools it runs act as you, on sites where you are already signed in. That only works on a machine that has your browser on it.

The config entry, line by line

Every host stores this differently, but underneath it is the same three facts: a name, a command, and its arguments.

the shape every host agrees on
{
  "mcpServers": {
    "browser-memory": {
      "command": "npx",
      "args": ["-y", "browser-memory"]
    }
  }
}

Hosts differ in the wrapper only: most use the mcpServers key, VS Code uses servers and wants an explicit "type": "stdio", Codex uses TOML, and Claude Code has a command for it. You do not have to memorise any of that — one command writes the right shape into every agent it finds:

install
npx -y browser-memory install

It is idempotent, so running it twice is safe: it never overwrites an entry that is already there. To target a single host, name it — claude, cursor, vscode or codex:

one host only
npx -y browser-memory install cursor

It needs Node.js 18+ and Google Chrome already installed. Chrome is not optional: the server drives a real browser.

You have to restart the app

A host negotiates its MCP servers when its process starts, so a server added mid-session does not exist yet — and opening a new chat inside a running app is not enough. Quit the app fully (or exit the terminal session) and start it again. This trips up everyone once.

What happens when your agent starts

The handshake, in order, so nothing is mysterious:

connectionhost ⇄ local server
1. The host reads its configfinds an entry named browser-memory with a command to run
2. It spawns the processnpx -y browser-memory, as a child of the app, wired to its stdin/stdout
3. Both sides say helloprotocol version and capabilities are agreed on
4. The host asks for the tool listeach tool comes back with a name, a description and a schema for its arguments
5. The model can now call themit picks one from the descriptions; the host relays the call and hands back the result

Notice that no browser has opened yet. Chrome is launched lazily, by whichever call actually needs it — a discover is only a search over the index, so it never puts a window on your screen.

What this server exposes

Two groups. The first is the memory itself, and it is the part your agent uses all day:

ToolWhat it does
discoverSearches memory for tools that fit a site. First step of every web task, before the browser is touched
runReplays a known tool by name and returns structured data
requestFreezes what the browser just did, after a new action worked
savePersists that trace as a new tool, primitive or composite
list_sitesEvery site with at least one tool in memory
forget_siteDrops a site’s tools from local memory

The second group is a browser: bm_navigate, bm_click, bm_type, bm_snapshot, bm_screenshot, bm_network, bm_console, bm_wait_for, bm_tabs and a few more. These are the slow path — the ones the agent uses while learning an action it has no tool for. Once that action is saved, it stops touching them and calls run instead.

That is the shape of the whole product in one sentence: the bm_* tools are how something gets figured out, and run is how it never has to be figured out again.

The browser it drives

The server uses its own dedicated Chrome, with its own profile, rather than taking over the window you have your email open in. What that means in practice:

More on how a tool uses that session, and what happens when it expires, under sessions.

The registry, and turning it off

On its own, the server would only know what your agent taught it. By default it also reads from the hosted registry api.browser-memory.com — so a site somebody already worked out is fast on your very first run. This read is anonymous: no account, no sign-up, no login prompt. If the registry refuses or is unreachable, you are told once and everything keeps working with your local tools.

Where things sit:

WhatWhere
Tools your agent learned~/.tool-memory, on your disk. The server pulls tools from the registry; it does not push yours to it
Ready-made toolsFetched from the registry as needed, then cached locally
Sessions and cookiesThe dedicated Chrome profile, on your disk
Usage eventsBest-effort and off with the registry: which tool ran, its version, whether it succeeded, and a typed failure reason. Not your params, not your results

To run fully local, with no registry and no events:

local only
npx browser-memory config server off

config server on puts it back, and config set-url points it at a registry you host yourself.

Disconnecting it

uninstall
npx -y browser-memory uninstall

…and restart the app, for the same reason as before: a server cannot unload itself from a live session. It only edits the host’s config — your learned tools in ~/.tool-memory and the Chrome profile are left alone, so reinstalling picks up where you left off.

When it does not show up

SymptomAlmost always
The agent says it has no such toolThe app was not fully restarted. A new chat in a running app does not renegotiate servers
The server fails to startNode is missing or older than 18 — check with node -v
Everything connects, nothing can browseGoogle Chrome is not installed. The server drives a real one and cannot run without it
A tool returns re-authWorking as intended: the session expired. Log in by hand in the window it left open and run it again
The install command found no hostAdd the entry by hand with the JSON above, at user level rather than per project

Next