[{"data":1,"prerenderedAt":40},["ShallowReactive",2],{"$f1dj5j1urbtx2f":3},{"href":4,"title":5,"description":6,"kind":7,"mark":7,"planned":8,"contributors":9,"provenance":7,"html":10,"headings":11},"\u002Fdocs\u002Fmcp\u002Fconnect","Connect a client","A token with the scopes your agent needs, then Claude Code, Claude Desktop, any other MCP client, or curl.",null,false,[],"\u003Ch2 id=\"create-a-token\">Create a token\u003C\u002Fh2>\n\u003Cp>Every client connects with an API token (\u003Ca href=\"\u002Fdocs\u002Fapi\u002Fauthentication\">Authentication\u003C\u002Fa>). Give each client its own, so\nrevoking one leaves the others working.\u003C\u002Fp>\n\u003Col>\n\u003Cli>\n\u003Cp>In the portal, open \u003Cstrong>Settings → API tokens\u003C\u002Fstrong>.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\n\u003Cp>Under \u003Cstrong>New token\u003C\u002Fstrong>, name it for the client and the machine it runs on, such as \u003Ccode>Claude Code, laptop\u003C\u002Fcode>.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\n\u003Cp>Set a level for each resource the client's tools need:\u003C\u002Fp>\n\u003Cdiv class=\"prose__table\">\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Tools\u003C\u002Fth>\n\u003Cth>Resource\u003C\u002Fth>\n\u003Cth>Level\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>os.list_runs\u003C\u002Fcode>, \u003Ccode>os.get_run\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>runs\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>read\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>os.list_blockers\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>blockers\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>read\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>os.list_open_gates\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>\u003Ccode>gates\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd>read\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003C\u002Fdiv>\n\u003Cp>Leave everything else at \u003Cstrong>none\u003C\u002Fstrong>. Every tool reads, so no tool needs \u003Ccode>write\u003C\u002Fcode>, and \u003Ccode>gates:write\u003C\u002Fcode> would let the\ntoken decide gates over the API. You can only grant scopes you hold yourself.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\n\u003Cp>\u003Cstrong>Create\u003C\u002Fstrong>, and copy the token. It starts \u003Ccode>zhos_\u003C\u002Fcode>, and it is shown once.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cp>A token without a scope a tool needs can still connect: that tool's calls are refused, naming the scope. Add it\nlater with \u003Cstrong>Edit scopes\u003C\u002Fstrong> on the token. The secret does not change, so nothing in the client does.\u003C\u002Fp>\n\u003Ch2 id=\"connect-your-client\">Connect your client\u003C\u002Fh2>\n\u003Cp>The server is at \u003Ccode>https:\u002F\u002Fmcp.zerohuman.com\u002Fv1\u002Fmcp\u003C\u002Fcode>. It speaks Streamable HTTP, and reads the token from one\nheader:\u003C\u002Fp>\n\u003Cpre>\u003Ccode>Authorization: Bearer zhos_…\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch3 id=\"claude-code\">Claude Code\u003C\u002Fh3>\n\u003Cpre>\u003Ccode class=\"language-bash\">claude mcp add --transport http zerohuman https:\u002F\u002Fmcp.zerohuman.com\u002Fv1\u002Fmcp \\\n  --header &quot;Authorization: Bearer zhos_…&quot;\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>\u003Ccode>zerohuman\u003C\u002Fcode> is the name Claude Code knows the server by; choose any. The server is added for the current project\nonly. Add \u003Ccode>--scope user\u003C\u002Fcode> to have it in every project.\u003C\u002Fp>\n\u003Cp>To share the server with everyone working in a repository without sharing a token, add it to the project's\n\u003Ccode>.mcp.json\u003C\u002Fcode> with the token read from each person's environment:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-json\">{\n  &quot;mcpServers&quot;: {\n    &quot;zerohuman&quot;: {\n      &quot;type&quot;: &quot;http&quot;,\n      &quot;url&quot;: &quot;https:\u002F\u002Fmcp.zerohuman.com\u002Fv1\u002Fmcp&quot;,\n      &quot;headers&quot;: { &quot;Authorization&quot;: &quot;Bearer ${ZEROHUMAN_TOKEN}&quot; }\n    }\n  }\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Each person sets \u003Ccode>ZEROHUMAN_TOKEN\u003C\u002Fcode> to their own token before starting Claude Code.\u003C\u002Fp>\n\u003Ch3 id=\"claude-desktop\">Claude Desktop\u003C\u002Fh3>\n\u003Cp>Claude Desktop's own config file starts local programs, so a remote server that takes a header is reached through\na bridge: \u003Ccode>mcp-remote\u003C\u002Fcode>, an open-source bridge that runs on your computer and needs Node.js 18 or later. If Claude\noffers you request headers, a \u003Ca href=\"#claude-with-a-custom-connector\">custom connector\u003C\u002Fa> needs no bridge.\u003C\u002Fp>\n\u003Col>\n\u003Cli>\n\u003Cp>In Claude Desktop, open \u003Cstrong>Settings → Developer → Edit Config\u003C\u002Fstrong>.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\n\u003Cp>Add the server to \u003Ccode>mcpServers\u003C\u002Fcode>:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-json\">{\n  &quot;mcpServers&quot;: {\n    &quot;zerohuman&quot;: {\n      &quot;command&quot;: &quot;npx&quot;,\n      &quot;args&quot;: [\n        &quot;-y&quot;,\n        &quot;mcp-remote&quot;,\n        &quot;https:\u002F\u002Fmcp.zerohuman.com\u002Fv1\u002Fmcp&quot;,\n        &quot;--header&quot;,\n        &quot;Authorization:${AUTH_HEADER}&quot;\n      ],\n      &quot;env&quot;: { &quot;AUTH_HEADER&quot;: &quot;Bearer zhos_…&quot; }\n    }\n  }\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Keep the header written as it is here, with no space after the colon and the token in \u003Ccode>env\u003C\u002Fcode>: Claude Desktop on\nWindows breaks an argument that contains a space.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\n\u003Cp>Quit Claude Desktop completely, and open it again.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cp>The token stays on your computer, in that file.\u003C\u002Fp>\n\u003Ch3 id=\"claude-with-a-custom-connector\">Claude, with a custom connector\u003C\u002Fh3>\n\u003Cp>If the \u003Cstrong>Add custom connector\u003C\u002Fstrong> dialog in Claude shows \u003Cstrong>Request headers\u003C\u002Fstrong> (Anthropic offers it to some\norganisations while it is in beta), you can add the server as a custom connector instead, with no bridge. Enter the\nserver URL, choose \u003Cstrong>No sign-in\u003C\u002Fstrong>, and add the header \u003Ccode>authorization\u003C\u002Fcode> with the value \u003Ccode>Bearer zhos_…\u003C\u002Fcode>, including\n\u003Ccode>Bearer\u003C\u002Fcode> and the space.\u003C\u002Fp>\n\u003Cp>Claude stores the token and sends it from Anthropic's servers. A connector an Owner adds for a Team or Enterprise\norganisation is shared: everyone who uses it acts with that one token, so give it only what everyone may read.\u003C\u002Fp>\n\u003Cdiv class=\"prose__planned\">\n\u003Cp class=\"prose__flag\">Planned\u003C\u002Fp>\n\u003Cp>A custom connector will be able to sign in with Zero Human instead, with no token to paste. See\n\u003Ca href=\"\u002Fdocs\u002Fmcp\u002Fconnected-apps\">Connected apps\u003C\u002Fa>.\u003C\u002Fp>\n\u003C\u002Fdiv>\n\u003Ch3 id=\"any-other-mcp-client\">Any other MCP client\u003C\u002Fh3>\n\u003Cp>Give it:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>the URL, \u003Ccode>https:\u002F\u002Fmcp.zerohuman.com\u002Fv1\u002Fmcp\u003C\u002Fcode>;\u003C\u002Fli>\n\u003Cli>the transport: Streamable HTTP, which some clients call &quot;HTTP&quot; or \u003Ccode>streamable-http\u003C\u002Fcode>;\u003C\u002Fli>\n\u003Cli>the header \u003Ccode>Authorization: Bearer zhos_…\u003C\u002Fcode>.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>A client that only starts local programs can reach the server through \u003Ccode>mcp-remote\u003C\u002Fcode>, as Claude Desktop does above. A\nclient that can only sign in to remote servers, with no way to send a header, cannot connect yet.\u003C\u002Fp>\n\u003Ch3 id=\"curl\">curl\u003C\u002Fh3>\n\u003Cp>Every request is a \u003Ccode>POST\u003C\u002Fcode> of one JSON-RPC message, with the token and \u003Ccode>Content-Type: application\u002Fjson\u003C\u002Fcode>. There is no\nsession: each request stands alone, so you can call a tool without initialising first. The server answers in JSON,\nnever an event stream, so no \u003Ccode>Accept\u003C\u002Fcode> header is needed.\u003C\u002Fp>\n\u003Cp>Initialise:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-bash\">curl https:\u002F\u002Fmcp.zerohuman.com\u002Fv1\u002Fmcp \\\n  -H &quot;Authorization: Bearer $ZEROHUMAN_TOKEN&quot; \\\n  -H &quot;Content-Type: application\u002Fjson&quot; \\\n  -d '{&quot;jsonrpc&quot;:&quot;2.0&quot;,&quot;id&quot;:1,&quot;method&quot;:&quot;initialize&quot;,&quot;params&quot;:{&quot;protocolVersion&quot;:&quot;2025-06-18&quot;,&quot;capabilities&quot;:{},&quot;clientInfo&quot;:{&quot;name&quot;:&quot;curl&quot;,&quot;version&quot;:&quot;1&quot;}}}'\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cpre>\u003Ccode class=\"language-json\">{&quot;result&quot;:{&quot;protocolVersion&quot;:&quot;2025-06-18&quot;,&quot;capabilities&quot;:{&quot;tools&quot;:{}},&quot;serverInfo&quot;:{&quot;name&quot;:&quot;zerohuman-os&quot;,&quot;version&quot;:&quot;…&quot;}},&quot;jsonrpc&quot;:&quot;2.0&quot;,&quot;id&quot;:1}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>List the tools:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-bash\">curl https:\u002F\u002Fmcp.zerohuman.com\u002Fv1\u002Fmcp \\\n  -H &quot;Authorization: Bearer $ZEROHUMAN_TOKEN&quot; \\\n  -H &quot;Content-Type: application\u002Fjson&quot; \\\n  -d '{&quot;jsonrpc&quot;:&quot;2.0&quot;,&quot;id&quot;:2,&quot;method&quot;:&quot;tools\u002Flist&quot;}'\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Each tool comes with its name, a description ending in the scope it needs, and the JSON Schema of its arguments.\u003C\u002Fp>\n\u003Cp>Call one:\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-bash\">curl https:\u002F\u002Fmcp.zerohuman.com\u002Fv1\u002Fmcp \\\n  -H &quot;Authorization: Bearer $ZEROHUMAN_TOKEN&quot; \\\n  -H &quot;Content-Type: application\u002Fjson&quot; \\\n  -d '{&quot;jsonrpc&quot;:&quot;2.0&quot;,&quot;id&quot;:3,&quot;method&quot;:&quot;tools\u002Fcall&quot;,&quot;params&quot;:{&quot;name&quot;:&quot;os.list_runs&quot;,&quot;arguments&quot;:{&quot;status&quot;:&quot;failed&quot;,&quot;limit&quot;:5}}}'\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>The result holds one text item: the API's JSON answer, as a string. A refusal is a result too, with\n\u003Ccode>&quot;isError&quot;: true\u003C\u002Fcode> and the reason as its text (\u003Ca href=\"\u002Fdocs\u002Fmcp\u002Ferrors\">Errors\u003C\u002Fa>).\u003C\u002Fp>\n\u003Cp>If you send an \u003Ccode>MCP-Protocol-Version\u003C\u002Fcode> header, it has to name a version the server supports; leave it out and the\nserver assumes one.\u003C\u002Fp>\n\u003Ch2 id=\"check-it-works\">Check it works\u003C\u002Fh2>\n\u003Col>\n\u003Cli>\u003Cstrong>The server is up.\u003C\u002Fstrong> \u003Ccode>https:\u002F\u002Fmcp.zerohuman.com\u002Fv1\u002Fhealth\u003C\u002Fcode> answers \u003Ccode>{&quot;ok&quot;:true, …}\u003C\u002Fcode>, with no token.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>The client connected.\u003C\u002Fstrong> In Claude Code, \u003Ccode>claude mcp list\u003C\u002Fcode> shows the server connected, and \u003Ccode>\u002Fmcp\u003C\u002Fcode> lists its\ntools. In Claude Desktop, the server is listed under \u003Cstrong>Connectors\u003C\u002Fstrong> in a chat's \u003Cstrong>+\u003C\u002Fstrong> menu.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>The token works.\u003C\u002Fstrong> Only a tool call proves it: connecting and listing tools do not check the token. Ask your\nagent what is blocked in your enterprise, or call \u003Ccode>os.list_open_gates\u003C\u002Fcode> with curl. An answer, even an empty list,\nmeans the token and its scope are good.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>The portal agrees.\u003C\u002Fstrong> Reload \u003Cstrong>Settings → API tokens\u003C\u002Fstrong>: the token's \u003Cstrong>Last used\u003C\u002Fstrong> shows your call, where it\nsaid \u003Ccode>never\u003C\u002Fcode> before.\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cp>If a step fails, \u003Ca href=\"\u002Fdocs\u002Fmcp\u002Ferrors\">Errors\u003C\u002Fa> says what each refusal means.\u003C\u002Fp>\n\u003Ch2 id=\"disconnect\">Disconnect\u003C\u002Fh2>\n\u003Cul>\n\u003Cli>\u003Cstrong>Revoke the token\u003C\u002Fstrong> on \u003Cstrong>Settings → API tokens\u003C\u002Fstrong>. It stops at once: the client may still connect and list tools,\nbut every call is refused. The token stays listed, revoked.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Rotate the token\u003C\u002Fstrong> to replace a secret you think has leaked. The old one stops at once; put the new one in the\nclient's header.\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Remove the server from the client\u003C\u002Fstrong>: \u003Ccode>claude mcp remove zerohuman\u003C\u002Fcode> in Claude Code, or delete its entry from\nClaude Desktop's config file and restart Claude Desktop.\u003C\u002Fli>\n\u003C\u002Ful>\n",[12,16,19,23,26,29,32,34,37],{"id":13,"text":14,"level":15,"planned":8},"create-a-token","Create a token",2,{"id":17,"text":18,"level":15,"planned":8},"connect-your-client","Connect your client",{"id":20,"text":21,"level":22,"planned":8},"claude-code","Claude Code",3,{"id":24,"text":25,"level":22,"planned":8},"claude-desktop","Claude Desktop",{"id":27,"text":28,"level":22,"planned":8},"claude-with-a-custom-connector","Claude, with a custom connector",{"id":30,"text":31,"level":22,"planned":8},"any-other-mcp-client","Any other MCP client",{"id":33,"text":33,"level":22,"planned":8},"curl",{"id":35,"text":36,"level":15,"planned":8},"check-it-works","Check it works",{"id":38,"text":39,"level":15,"planned":8},"disconnect","Disconnect",1791124519651]