Connect a client
A token with the scopes your agent needs, then Claude Code, Claude Desktop, any other MCP client, or curl.
Create a token
Every client connects with an API token (Authentication). Give each client its own, so revoking one leaves the others working.
-
In the portal, open Settings → API tokens.
-
Under New token, name it for the client and the machine it runs on, such as
Claude Code, laptop. -
Set a level for each resource the client's tools need:
Tools Resource Level os.list_runs,os.get_runrunsread os.list_blockersblockersread os.list_open_gatesgatesread Leave everything else at none. Every tool reads, so no tool needs
write, andgates:writewould let the token decide gates over the API. You can only grant scopes you hold yourself. -
Create, and copy the token. It starts
zhos_, and it is shown once.
A token without a scope a tool needs can still connect: that tool's calls are refused, naming the scope. Add it later with Edit scopes on the token. The secret does not change, so nothing in the client does.
Connect your client
The server is at https://mcp.zerohuman.com/v1/mcp. It speaks Streamable HTTP, and reads the token from one
header:
Authorization: Bearer zhos_…
Claude Code
claude mcp add --transport http zerohuman https://mcp.zerohuman.com/v1/mcp \
--header "Authorization: Bearer zhos_…"
zerohuman is the name Claude Code knows the server by; choose any. The server is added for the current project
only. Add --scope user to have it in every project.
To share the server with everyone working in a repository without sharing a token, add it to the project's
.mcp.json with the token read from each person's environment:
{
"mcpServers": {
"zerohuman": {
"type": "http",
"url": "https://mcp.zerohuman.com/v1/mcp",
"headers": { "Authorization": "Bearer ${ZEROHUMAN_TOKEN}" }
}
}
}
Each person sets ZEROHUMAN_TOKEN to their own token before starting Claude Code.
Claude Desktop
Claude Desktop's own config file starts local programs, so a remote server that takes a header is reached through
a bridge: mcp-remote, an open-source bridge that runs on your computer and needs Node.js 18 or later. If Claude
offers you request headers, a custom connector needs no bridge.
-
In Claude Desktop, open Settings → Developer → Edit Config.
-
Add the server to
mcpServers:{ "mcpServers": { "zerohuman": { "command": "npx", "args": [ "-y", "mcp-remote", "https://mcp.zerohuman.com/v1/mcp", "--header", "Authorization:${AUTH_HEADER}" ], "env": { "AUTH_HEADER": "Bearer zhos_…" } } } }Keep the header written as it is here, with no space after the colon and the token in
env: Claude Desktop on Windows breaks an argument that contains a space. -
Quit Claude Desktop completely, and open it again.
The token stays on your computer, in that file.
Claude, with a custom connector
If the Add custom connector dialog in Claude shows Request headers (Anthropic offers it to some
organisations while it is in beta), you can add the server as a custom connector instead, with no bridge. Enter the
server URL, choose No sign-in, and add the header authorization with the value Bearer zhos_…, including
Bearer and the space.
Claude stores the token and sends it from Anthropic's servers. A connector an Owner adds for a Team or Enterprise organisation is shared: everyone who uses it acts with that one token, so give it only what everyone may read.
Planned
A custom connector will be able to sign in with Zero Human instead, with no token to paste. See Connected apps.
Any other MCP client
Give it:
- the URL,
https://mcp.zerohuman.com/v1/mcp; - the transport: Streamable HTTP, which some clients call "HTTP" or
streamable-http; - the header
Authorization: Bearer zhos_….
A client that only starts local programs can reach the server through mcp-remote, as Claude Desktop does above. A
client that can only sign in to remote servers, with no way to send a header, cannot connect yet.
curl
Every request is a POST of one JSON-RPC message, with the token and Content-Type: application/json. There is no
session: each request stands alone, so you can call a tool without initialising first. The server answers in JSON,
never an event stream, so no Accept header is needed.
Initialise:
curl https://mcp.zerohuman.com/v1/mcp \
-H "Authorization: Bearer $ZEROHUMAN_TOKEN" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"curl","version":"1"}}}'
{"result":{"protocolVersion":"2025-06-18","capabilities":{"tools":{}},"serverInfo":{"name":"zerohuman-os","version":"…"}},"jsonrpc":"2.0","id":1}
List the tools:
curl https://mcp.zerohuman.com/v1/mcp \
-H "Authorization: Bearer $ZEROHUMAN_TOKEN" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/list"}'
Each tool comes with its name, a description ending in the scope it needs, and the JSON Schema of its arguments.
Call one:
curl https://mcp.zerohuman.com/v1/mcp \
-H "Authorization: Bearer $ZEROHUMAN_TOKEN" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"os.list_runs","arguments":{"status":"failed","limit":5}}}'
The result holds one text item: the API's JSON answer, as a string. A refusal is a result too, with
"isError": true and the reason as its text (Errors).
If you send an MCP-Protocol-Version header, it has to name a version the server supports; leave it out and the
server assumes one.
Check it works
- The server is up.
https://mcp.zerohuman.com/v1/healthanswers{"ok":true, …}, with no token. - The client connected. In Claude Code,
claude mcp listshows the server connected, and/mcplists its tools. In Claude Desktop, the server is listed under Connectors in a chat's + menu. - The token works. Only a tool call proves it: connecting and listing tools do not check the token. Ask your
agent what is blocked in your enterprise, or call
os.list_open_gateswith curl. An answer, even an empty list, means the token and its scope are good. - The portal agrees. Reload Settings → API tokens: the token's Last used shows your call, where it
said
neverbefore.
If a step fails, Errors says what each refusal means.
Disconnect
- Revoke the token on Settings → API tokens. It stops at once: the client may still connect and list tools, but every call is refused. The token stays listed, revoked.
- Rotate the token to replace a secret you think has leaked. The old one stops at once; put the new one in the client's header.
- Remove the server from the client:
claude mcp remove zerohumanin Claude Code, or delete its entry from Claude Desktop's config file and restart Claude Desktop.