post_v1_mcp_servers
CreateServer gives the caller's org one more external MCP server, so its tools join the org's tool plane and the fleet's MCP door.
CreateServer gives the caller's org one more external MCP server, so its tools
join the org's tool plane and the fleet's MCP door. It is the ONE way an org
gains a server, whether it typed the URL in or enabled a catalog listing: both
write the SAME record, and source says which it was. A second registration
path would be a second place for a server to exist, and then a second place to
forget to check the credential.
The credential VALUE is sealed in KMS under a per-org ref; the row keeps only the URL, the header name to inject it into, and a has-secret flag — so a secret with no KMS configured is refused 503 rather than stored in the clear. The URL is SSRF-validated here and re-checked by the dialer at connect time, which is the DNS-rebinding defense.
Enabling a listing the org already enabled REVISES that server rather than adding a near-duplicate beside it, so a retried enable is the same one server. Answers 201 with the stored record.
| Tool | post_v1_mcp_servers |
| Door | https://api.hanzo.ai/v1/mcp |
| Method | tools/call (JSON-RPC 2.0) |
| Arguments | 5 |
| Operation | POST /v1/mcp/servers |
| Product | cloud |
Arguments
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
authHeader | string | — | — | AuthHeader is the request header the credential is injected into, e.g. "Authorization". Empty means the server needs no credential. |
listing | string | — | — | Listing enables a CATALOG entry instead — the id from GET /v1/tools/catalog. The endpoint is the listing's own streamable-http remote, so a listing that only ships a stdio package is refused: there is nothing to reach yet. |
name | string | — | — | Name labels the server for the org. Required with URL; with Listing it defaults to the listing's own title. |
secret | string | — | — | Secret is the credential VALUE. It is sealed into KMS under a per-org ref and never stored in SQLite, never listed, and never returned. |
url | string | — | — | URL is the server's JSON-RPC endpoint. It must be an http(s) URL naming a PUBLIC host: loopback, link-local, private and cloud-metadata addresses are refused here and again when the dialer connects. |
This tool's schema does not declare which fields are required, nor any default, nor any enumerated value set. The columns above are empty because the door publishes nothing there, not because the answer is "none" — where a field is constrained, the constraint is stated in that field's own description.
Call it
A tools/call carries every argument in one flat object — nothing binds to a path or a query string. Every declared argument is shown, because the door marks none of them required.
curl -X POST https://api.hanzo.ai/v1/mcp \
-H "Authorization: Bearer $HANZO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "post_v1_mcp_servers",
"arguments": {
"authHeader": "<authHeader>",
"listing": "<listing>",
"name": "<name>",
"secret": "<secret>",
"url": "<url>"
}
}
}'Values are placeholders derived from each field's declared type. tools/list needs no credential; tools/call does — called without one the door answers HTTP 200 with a JSON-RPC result whose isError is set and whose text says what was missing. How to get a key →
The operation behind it
| Operation | Route | Product | Summary |
|---|---|---|---|
cloud_post_v1_mcp_servers | POST /v1/mcp/servers | cloud | CreateServer gives the caller's org one more external MCP server, so its tools join the or |
The same capability over plain HTTP is in the cloud API reference, on https://api.hanzo.ai.
All 834 tools · The door · API reference
Generated from tools/list on https://api.hanzo.ai/v1/mcp — 834 tools captured 2026-08-01 (this build read the vendored copy; the door was unreachable).
How is this guide?