Boxline MCP server
Commit Oct 29, 2026Provides AI agents with isolated cloud machines equipped with browsers, shells, storage, and web searching capabilities.
Also known as Boxline-dev/mcp
- Stars
- 1
- Tools
- —
- Downloads, 30 days
- —
- Latest version
- —
- Last commit
- Oct 29, 2026
- License
- MIT
What is Boxline MCP?
Boxline provides AI agents with isolated cloud machines equipped with browsers, shells, storage, and web searching capabilities.
Summary generated from the project's README
About Boxline MCP server
Providing AI agents with isolated cloud infrastructure is what Boxline MCP enables for developers using clients like Claude Desktop, Cursor, or VS Code. It grants agents access to remote machines equipped with a real browser, a shell, and a disk. This allows an agent to perform complex tasks such as navigating websites, executing bash commands, and managing files within a secure, sandboxed environment.
Users can set up the server locally using npx or host it over HTTP for remote connections. Integration requires a Boxline API key and Node 20 or newer. The system uses a session-based model where tools like session_create and session_resume manage the lifecycle of the cloud machine. To maintain security, the server includes a credential management system that allows agents to log into websites using browser_login without ever seeing the actual password values in the chat or logs.
What you can do with it
- 1Automated web interactionAn agent can navigate websites, click buttons, and type text using plain English instructions.
- 2Secure website authenticationYou can allow an agent to sign into accounts using saved credentials without exposing sensitive passwords to the model.
- 3Remote command executionDevelopers can give agents a bash shell to run commands on an isolated cloud machine.
- 4Web data extractionAn agent can crawl entire websites or extract structured JSON data from multiple web pages.
Written from the project's README. Every use case is checked against a quote from it.
Configuration
BOXLINE_API_KEYMCP_ALLOWED_HOSTS
| Name | Description | |
|---|---|---|
| BOXLINE_API_KEY | — | |
| MCP_ALLOWED_HOSTS | — |
Automated checks
Ran Nov 15, 2026Full report →Not verified yet. A server needs a score of 80, no serious finding, and enough data for us to check. How checks work · What to fix for more points
- Source repository linked and reachableboxline-dev/mcp is public and reachablegithub.com/boxline-dev/mcp ↗Pass
- Package names this repository as its sourceNot checked
- Build provenance (Sigstore attestation)Not checked
- Open source license (OSI)MITspdx.org/licenses/MIT.html ↗Pass
- Commit or release in the last yearLast commit or release 2026-10-29github.com/boxline-dev/mcp ↗Pass
- OpenSSF ScorecardNot checked
- Package name not close to a popular packageNot checked
- No critical advisory in the package or its dependenciesNot checked
- No hidden instructions to the model0 tool descriptions and the README read; no override phrases, credential paths or hidden charactersPass
- Destructive tools are labelledNot checked
- Remote endpoint answers the MCP handshakeNot checked
README
View on GitHubBoxline MCP server
Give your AI agents the infrastructure they need: browsers, shells, storage and isolated machines.
This server gives any MCP client (Claude, Cursor, VS Code and others) an isolated cloud machine with a real browser, a shell and a disk, through Boxline. The agent can open pages, click and type, read a page as Markdown, run commands, read and write files, fetch pages and search the web.
Set it up
You need a Boxline API key (console → API keys) and Node 20 or newer.
Claude Desktop, Cursor and other clients that take a JSON config:
{
"mcpServers": {
"boxline": {
"command": "npx",
"args": ["-y", "@boxline/mcp"],
"env": { "BOXLINE_API_KEY": "bxl_your_key" }
}
}
}
Claude Code:
claude mcp add boxline --env BOXLINE_API_KEY=bxl_your_key -- npx -y @boxline/mcp
BOXLINE_API_URL points it at another API (default https://api.boxline.dev).
Tools
The server keeps nothing between calls: session_create returns a sessionId, and every tool that works in a session
takes it as a required sessionId (session_list finds an id again; a tool that acts resumes a stopped session first, as it
was; browser_read and browser_screenshot say to call session_resume instead, because a resume starts a machine and billing;
files_list and files_read read a stopped session's saved files without resuming it). session_create, session_list, credentials_list and the web_* tools need no session.
A session is a browser, a shell or both: session_create takes browser and shell (both true unless you say otherwise).
browser: false with a shell is a shell-only session, with no live view: the browser_* tools answer browser_disabled.
Every tool says what it does to the world in its MCP annotations (a title, and read-only, destructive and open-world hints), so a client can decide what to ask you about. There are 26 tools:
| Group | Tools |
|---|---|
| Sessions | session_create (a browser, a shell or both; optionally from a saved browser profile, and with credentials exported into the shell), session_list (find a session again), session_stop (saves the session as it is and stops billing), session_resume (brings a stopped session back as it was), session_delete (deletes it and what it saved, for good) |
| Browser | browser_navigate, browser_act (one or more steps in plain English or as exact actions: hover, scroll, drag, right and double clicks…), browser_click (a selector or x/y), browser_type (text, or a saved credential), browser_press (keys: Enter, Control+A, ctrl+a Delete), browser_read (Markdown or text), browser_screenshot, browser_login (sign in with a saved password), browser_computer (screenshot-driven computer use) |
| Shell | shell_exec (bash in the session) |
| Files | files_list, files_read, files_write, files_delete (the session's workspace, its disk; files_delete also removes a folder with everything in it) |
| Web | web_fetch (a page through a real browser), web_search (with the top pages as Markdown), web_screenshot (a quick screenshot), web_extract (JSON from up to 10 pages, from a prompt or a JSON Schema), web_crawl_start and web_crawl_get (a whole site or section, robots.txt respected); none needs a session |
| Credentials | credentials_list (names, types, sites and a password's code source for the saved passwords and secrets, never their values) |
browser_act is the tool for everything the others do not cover. A plain-English step ("click the Sign in link") is carried
out by a model, like a step of an agent run: it is billed as one and needs a plan that includes plain-English steps. An exact
action ({"action": "hover", "selector": "text=Products"}) uses no model. Each step gets one line saying what happened; an
evaluate step also gives the value it returned ({"action": "evaluate", "expression": "document.title"}). There are no agent-run tools: an MCP client is
already an agent.
Signing in without showing the agent a password
Save a website password (or a secret) as a credential in the Boxline console, the CLI or an SDK.
The agent calls credentials_list to see what exists (names, types and the sites each may be typed on; never a value), then
types it with browser_type:
browser_type { "sessionId": "<id>", "credential": "SHOP", "field": "username", "selector": "#email" }
browser_type { "sessionId": "<id>", "credential": "SHOP", "field": "password", "selector": "#password" }
browser_type { "sessionId": "<id>", "credential": "SHOP", "field": "otp", "selector": "#code" } // the current 2FA code, if the password has a 2FA key
Or sign in in one call with browser_login { "sessionId": "<id>", "credential": "SHOP", "url": "https://shop.example.com/login" }: a short run in the
session types the credential on its sites only, and the agent sees neither the password nor any code. A password whose
codeSource (in credentials_list) is push or url waits for the code or sign-in link that your system sends, up to its
timeout (the agent should tell you a code is needed); you send it with the CLI (boxline credentials push-code SHOP) or
an SDK (credentials.pushCode), never through the chat.
The platform types the value into the field itself, only on the sites the credential was saved for, and never shows it to
the agent, the chat or the logs: wherever a result would show it (browser_read, the page's elements, a screenshot, an
error), the text is replaced by %SHOP.password% and the field is covered. This hides a value; it does not protect
it. It is a guard against showing a credential by accident, not a boundary: code that runs in the page or the session
(an evaluate action in browser_act, a command in shell_exec) can still read a field and print it, for example reversed or in base64. Use a
password only in sessions whose pages and scripts you trust, and save it with the narrowest sites. session_create can also start from a saved browser profile (cookies and logins from an
earlier sign-in; persistProfile saves new ones back) and export credentials into the session's shell as environment
variables, for those credentials_list marks exportable (scope shell or all, or shell: true); others are refused. With a
shell, the password a profile signs in with is exported too when it is exportable. No tool creates or changes a credential, so a password never passes
through the chat: add them yourself, outside the conversation.
Sessions are billed while they run: stop them with session_stop when the work is done, or let them stop at their time
limit. A stopped session is free and is kept for your plan's retention days (7 on Free, 30 on Hobby and Startup, 90 on
Scale): session_resume brings it back with its tabs and files, and session_delete removes it at once, with its
recording and logs. A tool that acts, given the id of a stopped session, resumes it first; browser_read and browser_screenshot say to call session_resume; files_list and files_read read the saved files as they are.
Self-hosting over HTTP
boxline-mcp --http serves the same tools over HTTP at POST /mcp, for clients that connect to a URL instead of starting a
process. It speaks the MCP revision 2026-07-28 and, without sessions, the 2025-era protocol older clients still use.
MCP_ALLOWED_HOSTS=mcp.example.com BOXLINE_API_URL=https://api.boxline.dev npx -y @boxline/mcp --http
- Sign-in: every request carries its own Boxline API key as
Authorization: Bearer <API key>, or the OAuth access token an MCP client got when a person clicked "Connect" (below). The server holds no key of its own, never logs a token, and calls the API with the token of the request it is serving. Before a request is served the token is checked against the API (oneGET /v1/auth/me, remembered for a minute by its hash): a token the API refuses (expired, revoked, unknown) is401, so a client signs in again or refreshes it instead of getting a tool error. Without a token the answer is401withWWW-Authenticate: Bearer. - OAuth sign-in (for ChatGPT, Claude and other clients that offer "Connect" instead of a key field) is for Boxline's hosted
server,
https://mcp.boxline.dev/mcp. Boxline's sign-in issues tokens for that address only. A server you host yourself takes API keys (Authorization: Bearer bxl_…). The hosted server setsMCP_RESOURCE(its public URL) andMCP_AUTH_SERVER(the issuer,https://api.boxline.dev), then publishes protected resource metadata (/.well-known/oauth-protected-resource, RFC 9728) and answers a missing or refused token with401and aWWW-Authenticate: Bearer resource_metadata="…"challenge, which is what those clients follow to sign the person in. An OAuth token (bxo_…) always gets thedirectorytools (no saved credentials); abxl_API key getsMCP_TOOLS. - Stateless: each request is served on its own, so any number of copies behind a load balancer can answer any request,
and a restart loses nothing. Nothing is remembered between calls: the
sessionIdthatsession_createreturns is the only handle (as above).GET /mcpandDELETE /mcpanswer405. - Put it behind HTTPS (a reverse proxy or load balancer).
GET /healthzanswers200 okfor health checks, on any host. - Environment:
| Variable | Default | |
|---|---|---|
MCP_PORT |
8081 |
Port to listen on (0 picks a free one). |
MCP_HOST |
0.0.0.0 |
Address to bind. |
BOXLINE_API_URL |
https://api.boxline.dev |
The Boxline API the server calls. |
MCP_ALLOWED_HOSTS |
none | Comma-separated host names the server answers to (mcp.example.com), against DNS rebinding. localhost, 127.0.0.1 and [::1] always pass; * turns the host and origin checks off. A request whose Host is not listed gets 403, and so does a browser Origin that is not one of them. |
MCP_RESOURCE, MCP_AUTH_SERVER |
none | Both or neither: turn on OAuth sign-in discovery (above; Boxline's hosted server only). |
MCP_OPENAI_CHALLENGE |
none | The token ChatGPT's domain verification expects at /.well-known/openai-apps-challenge. |
MCP_TOKEN_CACHE_SECONDS |
60 |
How long a token's check against the API is remembered (0: every request). |
MCP_TOOLS |
full |
directory leaves out browser_login, credentials_list and every credential parameter (credential and field on browser_type, credentials on session_create), and browser_act refuses an action that names a credential or logs in: for a server listed in a public connector directory. |
Request bodies are limited to 4 MiB (413), at most 32 requests run at once (MCP_MAX_IN_FLIGHT; more get 503), and at most 8 per bearer token (MCP_MAX_IN_FLIGHT_PER_TOKEN; more get 503, so one caller cannot hold every slot). Live view URLs are left out of tool results. Long tool calls keep their connection alive with SSE comment frames every 15 seconds.
Links
- Docs: docs.boxline.dev
- Node SDK: Boxline-dev/sdk-node · Python SDK: Boxline-dev/sdk-python
MIT licence.
This repository holds the Boxline MCP server (@boxline/mcp). It is copied from Boxline's main repository on every change. Issues and pull requests are welcome here; accepted changes are made there and arrive with the next copy.
Boxline MCP questions
What infrastructure does the Boxline MCP server provide?
It provides an isolated cloud machine with a real browser, a shell, and a disk.
How can I sign in to websites without exposing my passwords to the AI agent?
You can use the credentials system to save passwords in the Boxline console and then use the browser_login tool, which allows the platform to type the value without showing it to the agent or logs.
Are sessions billed while they are stopped?
No, sessions are billed while they run; you should use session_stop to save the session and stop billing.