Connecting an AI assistant over MCP
Guard.ch runs a hosted MCP server that gives an AI assistant a real browser in our cloud. This guide covers the app key, the client configuration, the tools your assistant gets and how the sessions behave.
MCP (Model Context Protocol) is how an assistant reaches tools it does not ship with. Point yours at Guard.ch and it can open pages, read them, click, type, fill forms, upload files, run JavaScript and take screenshots in an isolated cloud browser, from the exit location you choose.
Nothing runs on your machine: there is no local browser service to install, no driver to keep current and no model key to configure here. Guard.ch supplies the browser, the session lifecycle, the egress and a live view you can open and take over at any moment; the model stays with your client.
What you need
- Endpoint
- https://api.guard.ch/mcp
- Transport
- Streamable HTTP, stateless per request
- Authentication
- A Guard.ch app key in a request header
- Plan
- A plan with programmatic access; the 30-day trial carries it
- Browsers
- Any Chromium-family image your plan allows, Chrome by default
- Concurrency
- Up to three running sessions per person, drawn on by that person and their agents alike
Create an app key
Create and manage your API keys in the browser.lol dashboard. Sign in with the same account you use for Guard.ch.
- One key per client. A key per assistant, machine or pipeline keeps revocation surgical: pulling one stops that client and nothing else.
- Choose an expiry. Never, 30 days, 90 days or one year, set at creation. Anything running unattended is safer with a date on it.
- Copy it once. The key is shown a single time, at creation. A lost key is replaced, not recovered: revoke it and create another.
- Revocation is immediate. A revoked key stops working at once, including in the middle of a conversation.
Endpoint and authentication
There is one endpoint, and it speaks Model Context Protocol over streamable HTTP. Every request stands on its own, so a conversation survives a client restart mid-task.
https://api.guard.ch/mcpSend the key in one of these two headers. It never belongs in the URL, where it would leak into browser history, proxy logs and analytics:
Authorization: Bearer YOUR_API_KEYas a Bearer token, which is what every snippet below uses.x-api-key: YOUR_API_KEYin the vendor header, for a client that cannot set Authorization.
Add the server to your client
Pick your client, put the configuration in and swap YOUR_API_KEY for the key you just created. The same key works everywhere, so a second machine only needs this step.
Claude Code
Run it in your terminal.
claude mcp add --transport http guardch https://api.guard.ch/mcp \
--header "Authorization: Bearer YOUR_API_KEY"Claude Desktop
Goes into claude_desktop_config.json.
{
"mcpServers": {
"guardch": {
"command": "npx",
"args": [
"-y", "mcp-remote", "https://api.guard.ch/mcp",
"--header", "Authorization:Bearer YOUR_API_KEY"
]
}
}
}Cursor
Goes into ~/.cursor/mcp.json.
{
"mcpServers": {
"guardch": {
"url": "https://api.guard.ch/mcp",
"headers": { "Authorization": "Bearer YOUR_API_KEY" }
}
}
}VS Code
Run it in your terminal.
code --add-mcp '{"name":"guardch","type":"http","url":"https://api.guard.ch/mcp","headers":{"Authorization":"Bearer YOUR_API_KEY"}}'Codex CLI
Run it in your terminal, with the key in the GUARDCH_API_KEY environment variable.
codex mcp add guardch --url https://api.guard.ch/mcp \
--bearer-token-env-var GUARDCH_API_KEYGemini CLI
Run it in your terminal.
gemini mcp add --transport http guardch https://api.guard.ch/mcp \
--header "Authorization: Bearer YOUR_API_KEY"Windsurf
Goes into ~/.codeium/windsurf/mcp_config.json.
{
"mcpServers": {
"guardch": {
"serverUrl": "https://api.guard.ch/mcp",
"headers": { "Authorization": "Bearer YOUR_API_KEY" }
}
}
}Restart the client afterwards, so it picks the new server up. Nothing else is installed: the browser lives on our side.
Ask for something
Give your assistant a task that needs a browser. It opens the session itself:
Open example.com in a Guard.ch browser and tell me what the page says.A description of the page coming back means the connection works. A client that reports no tools has not reloaded its MCP configuration yet.
The tools your assistant gets
Thirty-five tools, all named browser_*, with structured results. An assistant can start straight at browser_navigate: Guard.ch opens a session for it and answers with an accessibility snapshot whose ref ids every later tool acts on, which is cheaper and far more precise than working from screenshots.
Sessions and lifecycle
Explicit control over the browser itself: which one, where it leaves the internet, how long it lives.
| Tool | Description |
|---|---|
browser_session_create | Start a session and get its handle: browser image, name, absolute timeout, exit country, residential or custom-proxy egress, screen size, an initial URL and a retry key. |
browser_session_get | Read one session's state: status, image, current URL, whether analysis is attached, when it expires, and its live view URL. |
browser_session_list | List every session on the account, newest first, with the concurrency quota and 30 days of usage. Each row says whether an agent or a person started it. |
browser_session_close | Stop a session and free its slot at once, instead of waiting for the idle timeout. |
browser_session_rename | Give a session a display name, so a person reading the session list can tell what it is for. |
browser_session_analysis | Switch the live analysis lane on or off for a session a person started in the app. |
browser_set_location | Change where a running session's traffic leaves the internet, without restarting it. |
Navigation
Moving around, and the tabs to move around in.
| Tool | Description |
|---|---|
browser_navigate | Open a URL and get the page back as an accessibility snapshot. This is the entry point: it opens a session when there is none. |
browser_go_back | Go back one entry in the tab's history. |
browser_go_forward | Go forward one entry. |
browser_reload | Reload the page, optionally bypassing the cache. |
browser_tabs | List, open, switch and close tabs; every page tool takes a tab id. |
Reading the page
What the assistant sees, from a cheap structural snapshot to the network the page opened.
| Tool | Description |
|---|---|
browser_snapshot | The accessibility snapshot of the page, with the ref ids the interaction tools act on. |
browser_find | Search the page for text or a regular expression and get the matching refs back. |
browser_screenshot | Capture the viewport, the full page or one element. |
browser_console_messages | Read the console output and page exceptions. |
browser_network_requests | List the requests the page made, filterable by method, status and host. |
browser_network_request | Open one request in full: headers, timing and body. |
browser_extract | Ask for data in plain language and get it back structured. This sends the page's visible text and accessibility tree to OpenRouter and uses one metered model call. |
Interaction
Everything a person would do with a mouse and a keyboard, plus the escape hatches.
| Tool | Description |
|---|---|
browser_click | Click an element by ref, with modifiers and double-click. |
browser_type | Type into a field and optionally submit. |
browser_fill_form | Fill several fields in one call. |
browser_select_option | Choose options in a select element. |
browser_hover | Hover an element, for menus that only open that way. |
browser_drag | Drag one element onto another. |
browser_press_key | Press a single key, such as Enter or Escape. |
browser_scroll | Scroll by pixels or bring an element into view. |
browser_wait_for | Wait for text, a URL, a load state, or for something to disappear. |
browser_handle_dialog | Answer the JavaScript dialog that is blocking the page after a tool reported dialog_open: accept, dismiss, or type into a prompt. |
browser_file_upload | Hand a file to a file input, with the name the page should see. |
browser_evaluate | Run JavaScript in the page and return its result. |
browser_resize | Change the viewport size. |
browser_mouse | Raw mouse moves, presses and wheel events, for canvases and maps. |
browser_act | Describe one step in plain language and let the browser choose the click or keystroke. This sends the page's accessibility tree to OpenRouter and uses one metered model call. |
Downloads
Files the page hands over.
| Tool | Description |
|---|---|
browser_downloads | List what this session downloaded, with an authenticated link per completed file. |
Choosing a browser and an exit location
image on create picks the browser: any Chromium-family image the account may run, and Chrome when you name none. Firefox and Tor are browsing-only and cannot be driven programmatically, so asking for one is refused with the list of ids you may use instead.
country sets where the session leaves the internet, as a country or a city (us, de, us-dal), and residential asks for a residential address rather than the ordinary tunnel; proxy takes egress you run yourself. browser_set_location changes it on a running session, which is what you want as soon as a page geofences or shows something different per country.
Watching a session, and taking it over
Every session comes with a live view URL, and the sessions your agents are running are listed on the Agents tab of your dashboard. Open one and you are in the same viewer a person uses: the page streams live, and you can end the session from there.
Take the mouse and keyboard whenever the assistant meets a login, a captcha or a decision you would rather make yourself, then let it carry on. It is one browser and you both reach it, so nothing has to start over.
Live analysis beside the page
On a Chromium browser, Guard.ch's analysis lane can run beside the page: requests, redirect chains, response headers, console output, security issues, downloads, forms, cookies and storage, the technologies and trackers it recognises, WHOIS, IP and certificate look-ups on demand, and a verdict per host that shows its sources.
browser_session_analysis switches that lane on and off for a session a person started in the app: switching it on makes their session watchable and files it as an investigation in their dashboard. A session the assistant created itself is not eligible and is refused in both directions (analysis_unavailable).
How the sessions behave
- Sessions create themselves. The first page tool opens one when the key has none running. With more than one running, a call without a session_id is refused rather than guessed at, so an implicit call can never land on the wrong browser.
- Idle sessions end themselves. A session ends a few minutes after the last tool call or CDP disconnect, and always at its absolute timeout (a minute to six hours, one hour by default). Closing it yourself frees the slot immediately.
- Retries are safe. An idempotency key on create replays the successful creation instead of opening a second browser, which is what you want behind a queue or a retrying job.
- People and agents share one account. Your assistant can list, drive and close the sessions you started in the app, and you can do the same with its own. Closing one of yours closes the window you are watching, which is a good reason to name sessions.
- Reach stops at your account. Every tool works on your own sessions only. No other member's sessions are visible or reachable through the server.
Limits and refusals
- Programmatic access is a plan feature. Without it every call answers with an upgrade notice instead of a tool result. Both paid plans include it, and so does the 30-day trial.
- Concurrency is the unit: up to three per person. Every person on the plan may have up to three sessions running at once, and the agents working with that person's key draw on the same three. Creating one while all three are busy is refused, not queued.
- Most tools are free. Only browser_act and browser_extract use one model call each and count against the account's daily AI budget. Residential egress is metered against the workspace's allowance for the billing cycle. Every other tool is free.
- Creation is rate-limited. Per-minute, per-hour and per-day creation limits protect the platform. Ordinary agent work never meets them; a runaway loop does.
- Nothing is stored. A closed session is gone with everything it saw. The session list keeps 30 days of entries (what ran, when and for how long), never the pages themselves.
Security
- An app key is a credential: keep it in your client's secret store or an environment variable, never in a shared config file or a link, and revoke it on the Apps tab the moment it slips out.
- The key travels in a request header. Keep it out of URLs, where it would land in browser history, proxy logs and analytics.
- Pages load in our infrastructure, never on the machine running the assistant and never in a browser profile of yours: every session is a throwaway container.
- browser_act sends the page's accessibility tree to OpenRouter, and browser_extract sends its visible text and accessibility tree. If a person signed in through the live view, this can include their own data. No other tool sends page content outside the cluster.
- An agent's session is as visible as a person's. It is listed in the dashboard, watchable live, and can be ended by hand at any moment.
- Everything runs over TLS, and the sessions are covered by the same DPA as the rest of the product.
Troubleshooting
Most of what goes wrong is one of these:
The client lists no tools. It has not reloaded its configuration. Restart it after adding the server, and check the URL is the /mcp endpoint above rather than the REST base.
Every call answers with an upgrade notice. The account behind the key has no plan with programmatic access. Start the trial, or ask a workspace manager for a seat.
A call is refused as an ambiguous session. Two or more sessions are running on that key, so Guard.ch will not guess which one you mean. List them and pass the session_id explicitly from then on.
Creating a session is refused. Either all three of the account's running sessions are in use, or the image asked for cannot be driven programmatically. The refusal says which, and names the ids you may use.
The key stopped working mid-conversation. It was revoked or reached its expiry date. Create a new one and update the client's configuration.
The same browsers without MCP
A client that does not speak MCP can create the same sessions over REST and attach Playwright or Puppeteer to the CDP endpoint each one returns. The API integration guide covers that path.
Next steps
Create a key under Apps, add the endpoint to your client and ask it to open a page. The Agents tab lists the sessions your assistants are running and lets you watch or end any of them; for a client this guide does not cover, contact us.