Steel MCP Server

Connect Claude, Cursor, VS Code, Codex, or any MCP client to Steel cloud browsers with the hosted Steel MCP server. Read pages, or drive a browser session with tools such as snapshot, click, and fill.

The Steel MCP server gives any MCP client cloud browsers. An agent can read a page in one call, or start a session and click, type, and fill forms in a real browser. Steel hosts the server, so there is nothing to install or run.

Claude Code
1
claude mcp add --transport http steel https://mcp.steel.dev/mcp

The first time the client connects, it opens a Steel sign-in page. Sign in and pick the project the agent should work in. Then ask for something that needs a browser:

Prompt
1
Use Steel to open news.ycombinator.com and list the top five stories.

Connect a client

The server URL is https://mcp.steel.dev/mcp. Add it to your client as a remote MCP server:

1
claude mcp add --transport http steel https://mcp.steel.dev/mcp
ClientWhere the config goesHow to sign in
Claude CodeRun the command in a terminal.Run /mcp in Claude Code and sign in to steel.
Cursor~/.cursor/mcp.jsonFollow Cursor's sign-in prompt.
VS Code.vscode/mcp.json in your workspaceFollow VS Code's sign-in prompt.
Codex~/.codex/config.tomlRun codex mcp login steel.

In Claude on the web or the desktop app, open the Connectors settings, choose Add custom connector, and paste the server URL. Any other client that supports remote MCP servers over Streamable HTTP works the same way.

Sign in

Steel signs clients in with OAuth. Clients find the sign-in page on their own: the server answers a request without credentials with 401 and points to its OAuth metadata.

401 response
1
HTTP/1.1 401 Unauthorized
2
WWW-Authenticate: Bearer realm="steel", resource_metadata="https://mcp.steel.dev/.well-known/oauth-protected-resource/mcp", scope="mcp:browser"

On the consent page, pick the organization and one project. Sessions the agent creates run in that project.

  • The approval covers that one project. To switch projects, sign in again and pick another one.
  • The client refreshes its access on its own, so you sign in once.
  • If your organization requires two-step verification, set it up before you connect.
  • Sign-in needs a client that supports Client ID Metadata Documents, from the MCP authorization spec. If your client can't sign in, use an API key.

Use an API key

Send a Steel API key as a bearer token when your client can't sign in, or when the agent runs unattended, such as in CI. Steel accepts the key, so the client skips the sign-in.

1
claude mcp add --transport http steel https://mcp.steel.dev/mcp \
2
--header "Authorization: Bearer $STEEL_API_KEY"

Sessions then run in the key's project. The server also accepts the key in the steel-api-key header. Create a key in API Keys.

How the tools work

The server tells the agent how to use its tools when it connects. The agent takes one of two paths:

TaskTools
Read a pagescrape opens the URL in a fresh browser and returns Markdown. No session, and nothing is left running.
Log in, click, type, or fill formssession_create, then snapshot and actions on refs, then session_release.

session_create starts a browser. It returns the session id, a link to watch it live, the first tab, and the first next:

session_create
1
session_id: 5b2c7c1e-3f4a-4d0e-9a8b-2c6f1e0d9a47
2
Watch it live: https://app.steel.dev/sessions/5b2c7c1e-3f4a-4d0e-9a8b-2c6f1e0d9a47
3
It ends after 60 minutes, or after 10 minutes without commands.
4
next: op_a1b2c3d4e5 (pass it as after with your first change)
5
<untrusted-page-content>
6
tab t1: about:blank —
7
</untrusted-page-content>

snapshot returns the page as an accessibility tree. Each element the agent can act on has a ref, such as e2:

snapshot
1
next: op_k3m5p7r9t1 (pass it as after with your next change)
2
<untrusted-page-content>
3
tab t1: https://shop.example.com/ — Example Shop
4
- heading "Find a product" [level=1, ref=e1]
5
- searchbox "Search" [ref=e2]
6
- button "Search" [ref=e3]
7
</untrusted-page-content>

Tools that change the page take after, the next from the previous result. Here the agent types into the search box and presses Enter:

type
1
{
2
"session_id": "5b2c7c1e-3f4a-4d0e-9a8b-2c6f1e0d9a47",
3
"after": "op_k3m5p7r9t1",
4
"target": "e2",
5
"text": "mechanical keyboard",
6
"submit": true
7
}
  • Safe retries. A repeated call with the same after returns the stored result. It never runs twice.
  • Page changes. If the page changed since that next, the result says so. The agent takes a new snapshot before it uses old refs.
  • Untrusted text. Page text comes back inside <untrusted-page-content>. The server tells the agent never to follow instructions found there. Results are cut at 30,000 characters.
  • Dialogs. Steel never answers a dialog on its own. The result names the dialog, and the agent answers it with dialog.
  • Long calls. A call that is still running returns an execution id. The agent waits for it with status or stops it with cancel.

Tools

Every tool except scrape, session_create, and session_list takes a session_id. Element tools take a target: a ref such as e5, or a CSS selector.

Sessions and scraping

ToolArgumentsWhat it does
scrapeurl, use_proxyReads a page without a session and returns it as Markdown.
session_createSee Session optionsStarts a browser session.
session_listallLists running sessions created through MCP. Set all to add sessions created any other way.
session_releasesession_idEnds a session and stops its billing.

Reading the page

ToolArgumentsWhat it does
snapshottab, interactive, compact, depthReturns the accessibility tree with refs. interactive keeps only elements you can act on.
findby, value, name, exact, tabFinds elements by role, text, label, placeholder, alt, title, testid, or css, and returns their refs.
getwhat, target, attribute, tabReads text, html, markdown, value, attr, title, url, count, box, or locator.
screenshottarget, full_page, tabCaptures the tab, the full page, or one element as an image.
waittarget, state, text, url, load, ms, download, timeout, tabWaits for an element state, text, a URL, a load state, a download, or a fixed time.

Acting on the page

These tools take after.

ToolArgumentsWhat it does
navigatetab, url or actionOpens a URL, or goes back, forward, or reload.
clicktarget, double, tabClicks an element. double double-clicks it.
hovertarget, tabMoves the mouse over an element, for menus and tooltips.
typetarget, text, clear, submit, tabTypes key by key. clear empties the field first. submit presses Enter after.
fillfields, tabSets up to 50 field values in order. Stops at the first field that fails.
press_keykey, target, tabPresses a key or chord, such as Enter, Escape, or Control+a.
select_optiontarget, values, tabSelects options in a select by value or label.
checktarget, checked, tabChecks a checkbox, radio, or switch. checked: false unchecks it.
dragsource, target, tabDrags source and drops it on target.
scrolldirection, amount, target, tabScrolls the page, or brings target into view.
evaltab, script, timeoutRuns JavaScript in the page and returns its value.

Tabs, dialogs, and long calls

ToolArgumentsWhat it does
tabaction, tab, urlLists, opens, or closes tabs. Opening and closing take after.
dialogdialog_id, action, textAccepts or dismisses an open dialog. text answers a prompt.
statusexecutionWaits for a running execution and returns its result.
cancelexecutionStops a running execution.

Session options

The agent sets these on session_create when your prompt asks for them:

session_create
1
{
2
"use_proxy": true,
3
"solve_captcha": true,
4
"profile_id": "0b7c1d2e-4f5a-4b6c-8d9e-0f1a2b3c4d5e",
5
"persist_profile": true,
6
"timeout_minutes": 30
7
}
OptionEffect
use_proxyRoutes traffic through a Steel residential proxy.
solve_captchaLets Steel solve CAPTCHAs.
profile_idStarts from a saved profile, by its UUID.
persist_profileSaves cookies and storage back to the profile when the session ends.
use_credentialsFills logins saved with the Credentials API on matching pages.
timeout_minutesThe session's hard time limit, from 1 to 1440. Defaults to 60, capped by your plan.

Limits and billing

MCP sessions and scrapes are regular Steel sessions and scrapes. Sessions bill browser hours, and each scrape bills as a Browser Tools call. See Pricing/Limits.

LimitValue
Session length60 minutes by default, capped by your plan. timeout_minutes changes it.
Idle sessionsA session ends after 10 minutes without a tool call on it. See Session lifecycle.
scrape20 pages a minute per organization.
session_createYour plan's session create rate.
Concurrent sessionsYour plan's concurrency limit.
Page text30,000 characters per result.

Ask the agent to release sessions when the task is done. session_list shows the ones still running:

session_list
1
5b2c7c1e-3f4a-4d0e-9a8b-2c6f1e0d9a47 created 2026-11-05T09:12:44.000Z by mcp

You can also release sessions from the Sessions page in the dashboard.

Turn a run into a script

Once the agent has found the right element, get with what: "locator" lists ways to find it again in a later session, best first:

get
1
{
2
"session_id": "5b2c7c1e-3f4a-4d0e-9a8b-2c6f1e0d9a47",
3
"what": "locator",
4
"target": "e12"
5
}
Locators
1
[
2
{
3
"target": { "role": "button", "name": "Accept", "exact": true },
4
"frame": { "css": "iframe[src^=\"https://consent.example.com/?\"]" }
5
}
6
]

Use a locator as the target and frame of a Commands API command. The same step then runs from your code, with no model in the loop:

curl
1
curl -X POST https://api.steel.dev/v1/sessions/$SESSION_ID/commands \
2
-H "steel-api-key: $STEEL_API_KEY" \
3
-H "Content-Type: application/json" \
4
-d '{
5
"commands": [
6
{
7
"command": "click",
8
"frame": { "css": "iframe[src^=\"https://consent.example.com/?\"]" },
9
"target": { "role": "button", "name": "Accept", "exact": true }
10
}
11
]
12
}'

Disconnect a client

Open Settings → Profile → Security in the dashboard. Disconnect the client under Connected apps.

  • OAuth clients lose access within 10 minutes of being disconnected.
  • API keys stop working when you delete them in API Keys.

Troubleshooting

Tool errors start with Failed: and a code. Most results also tell the agent what to do next.

CodeWhat to do
invalid_operation_tokenSteel no longer knows the after. Use the next from the latest result.
session_endedThe session is over. Start a new one with session_create.
session_not_foundCheck session_id, or start a session with session_create.
browser_restartedEvery tab and ref changed. Start again with tab and snapshot.
stale_refThe element left the page. Take a new snapshot.
missing_capabilityThe session's browser is too old for these tools. Start a new session.
delivery_failedSteel could not reach the browser. Call again with the same arguments. It will not run twice.
expired, queue_fullThe call did not start. Call again with the same arguments.

See the Commands API reference for every error code. Connection errors come back as HTTP status codes:

MessageFix
401 The access token is not valid for this MCP server.Sign in again from your client.
401 The project this sign-in was approved for no longer exists.Sign in again and pick another project.
401 with an API keyCheck the key in API Keys, or create a new one.
403 Account suspendedContact support@steel.dev.

FAQ

Next steps