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 | mcp |
Arguments
| Field | Type | Required | Default | Values | 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. |
tools/list declares a type and a description for each field and nothing further. A — means neither the door nor that operation constrains the field.
Call it
A tools/call carries every argument in one flat object — nothing binds to a path or a query string. Nothing above is required, so every declared argument is shown rather than a guess at which matter.
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 the operation's own defaults and enumerated values where it declares them, and a <placeholder> where neither source declares one. 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 |
|---|---|---|---|
post_v1_mcp_servers | POST /v1/mcp/servers | mcp | Gives the caller's org one more external MCP server, so its tools join the org's tool… |
The same capability over plain HTTP is in the mcp API reference, on https://api.hanzo.ai.
All 755 tools · The door · API reference
Generated from tools/list on https://api.hanzo.ai/v1/mcp — 833 tools captured 2026-08-01, of which 755 are documented here (the operator surface is not published) (this build read the vendored copy; the door was unreachable).
How is this guide?