Connect an MCP client to a blocklet by giving it the host URL plus /mcp.
<host> is the domain the blocklet is served at, the same one you would open in a browser. If you are unsure you have the right one, GET https://<host>/.well-known/mcp.json and check its url field: it echoes the endpoint the runtime believes it is serving.
claude mcp add --transport http arc https://<host>/mcpNo header and no client id are needed to connect. The endpoint accepts anonymous requests and answers the read tools; a credential is only required once you call a write tool.
For the exact commands for Claude Code and Codex CLI, see Connect your tool.
Confirm it without a client
The endpoint is plain HTTP, so curl is enough to check a host before you wire up an agent.
curl -s -X POST https://<host>/mcp \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'A blocklet that declares no content collections answers with eight tools:
afs_read afs_list afs_write afs_delete afs_search afs_exec afs_stat afs_explainA blocklet that declares content collections answers with those eight plus three more:
search_content list_content get_contentWhich set you get depends on the blocklet's own declaration, not on your credential. See Tools.
initialize is not required
The request above sends tools/list directly, with no preceding initialize, and returns 200.
The endpoint is stateless. It does not issue an mcp-session-id, so there is no session for a client to hold, lose, or resynchronise. A client can send a stale session id and the request still succeeds; a runtime restart does not invalidate anything on the client side.
This matters for long-lived agents: there is no reconnect handshake to implement.
What anonymous access gives you
The handshake, the three list methods, and the read tools. Write, delete, and exec return 401 with a challenge, and so does any method not on the list. The rule is fail-closed.
Whether an allowed read actually returns data is a separate question, decided by what the blocklet declared. Both rules are set out in Access tiers.
When you need to write
Calling a write tool without a credential returns the challenge that starts authorization:
curl -s -i -X POST https://<host>/mcp \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"afs_write","arguments":{"path":"/tmp/x","content":"x"}}}'HTTP/1.1 401 Unauthorized
www-authenticate: Bearer resource_metadata="https://<host>/.well-known/oauth-protected-resource"
{"error":"Unauthorized"}Follow that URL to continue. See Authorize a client.
Connecting a stdio-only client
Clients that speak MCP over stdio and cannot open an HTTP transport need a bridge. Use arc mcp, which bridges stdio to a running local daemon.
The bridge is a compatibility path for those clients. If your client supports streamable HTTP, connect to /mcp directly and skip it.
Local runtime
Against a local Node runtime, a request from the same machine is a verified socket peer and is granted operator access, so write tools answer without a credential. That is the loopback tier; it does not exist over the network and it is not how a deployed blocklet behaves. Use a remote host to exercise the anonymous and authenticated paths.