View source on GitHub
Why
The OpenHands web UI lets you add an MCP server, but it does not currently tell you whether the server actually connects. If the URL, token, or network path is wrong, the server’s tools simply never appear in a conversation — with no error shown in the UI. (Under the hood, when multiple MCP servers are configured, a server that fails to connect is logged as a warning in the runtime/agent-server logs and silently skipped.) The agent-server already ships an endpoint that solves this:POST /api/mcp/test connects to a single candidate server, lists its tools,
and optionally invokes one read-only tool to exercise credentials. This example
drives that endpoint from the Cloud API so you can verify a config end-to-end.
Requires an agent-server that includes
POST /api/mcp/test
(added in agent-server 1.29.0 / OpenHands 1.8.0). Older runtimes return
404 and the script tells you to upgrade the runtime image.How It Works
POST /api/mcp/test returns HTTP 200 in both success and failure — a failed
connection is the expected outcome of validating user input, not a server
error:
error_kind is one of timeout, connection, or unknown. Note that HTTP
status failures (e.g. a 401 from a bad token) currently come back as
unknown with the status in the error text, so read error — not just
error_kind — when triaging auth problems.
Auth
X-Session-API-Key); the
agent-server calls use the per-sandbox session_api_key returned with the
sandbox.
Install
Only depends onrequests:
Run It
Testing your saved settings (and picking from multiple servers)
--from-settings reads agent_settings.mcp_config from GET /api/v1/settings
(handling the stored auth / transport shape, including bearer tokens) and,
by default, tests every server you have configured.
When several servers are installed you can see the options and target a subset:
MCP config is a single shared map (
mcp_config.mcpServers) — it is not
split across LLM/settings profiles, so “multiple installed” means multiple
servers in that one map. Use --list to discover names, then --server to
pick. Point --settings-url at an org/self-hosted settings endpoint if your
config lives somewhere other than {base-url}/api/v1/settings.--config accepts an SDK-style file (the same mcpServers shape returned by
GET /api/v1/settings under agent_settings.mcp_config):
--keep (or --sandbox-id) to leave it running. The process
exits non-zero if any server fails, so it is CI-friendly.
Example Output
Running against three servers — the official MCP reference server (@modelcontextprotocol/server-everything,
stdio) plus two deliberate failures:
Notes & Limitations
- Credentials checked only on tool invocation. Some servers connect and
list tools fine with a bad token, and only fail when a tool runs. Pass
--tool-call <read-only-tool>to exercise those credentials; the outcome is reported undertool_resultand does not changeok. - Plaintext secrets. This example sends whatever token/headers you pass, in plaintext, to the sandbox you control. (The web UI’s “edit” flow round-trips encrypted stored secrets to the same endpoint; that cross-cipher path is a UI-internal detail and out of scope here.)
- Self-hosted / Enterprise. Point
--base-url(orOH_API_BASE) at your deployment. The flow is identical as long as the runtime image is new enough to exposePOST /api/mcp/test.

