- Custom MCP — your server is reachable at a public URL. Probe it, then add it; HQ detects its auth and connects.
- Connector — your server lives inside a private network with no public ingress. A small connector agent on your side dials out over an mTLS tunnel, and HQ routes tool calls back through it.
https://api.hq.zone and a personal access token with the admin scope: Authorization: Bearer hq_pat_.... The servers you add are private (T3) catalog entries — visible only to your workspace.
Custom integration policy
Both paths are gated by a workspace-wide policy enforced before any outbound call. Read it withGET /v1/mcp/custom/policy and set it with PUT:
custom_mcp_enabled(required) — master switch; whenfalse, every add/probe is refused.allowed_domains— if non-empty, only these hosts may be connected (an allowlist).blocked_domains— hosts that are always refused.require_approval— whentrue, a newly added server is held for an admin to approve before agents can see it.
Add a public MCP server (custom)
1
Probe the URL (dry run)
POST /v1/mcp/custom/probe connects to the server, detects its authentication, and previews its tools — without writing anything. It’s checked against your policy first.auth is one of none, api_key, oauth, or oauth_unsupported. connectable is true when you can finish setup self-serve (open servers, API-key servers, and OAuth servers that advertise dynamic client registration with a public client). When it’s false, note explains why — typically an OAuth server that needs an operator to register a confidential client. A blocked/invalid URL or a failed discovery returns 400. See Probe a custom MCP.2
Add it
POST /v1/mcp/custom re-probes, enforces policy, and creates the private catalog entry.url (required), an optional display_name, and an optional max_calls_per_day cap. The next field tells you what’s left:connected— done; an open server is enabled immediately (or held for review if your policy requires approval).api_key— finish by storing a key with the Set MCP key flow on the returned slug (see the Integrations guide).oauth_start— finish the OAuth connect (see the OAuth guide).
400. See Add a custom MCP.3
Approve, if held for review
When your policy sets See Approve a custom MCP.
require_approval, a new server lands in review_required and stays hidden from agents until an admin approves it with POST /v1/mcp/custom/{slug}/approve. The same endpoint re-approves a server after its tool list changes (a tool-poisoning guard re-freezes it on schema drift).DELETE /v1/mcp/custom/{slug} — see Delete a custom MCP.
Connect a private-network server (connector)
When the server has no public URL, register a connector: HQ mints a one-time enrollment token, your connector agent dials out and establishes a mutually-authenticated (mTLS) tunnel, and HQ routes tool calls to the private server through it.1
Create the connector
POST /v1/mcp/connectors registers a pending connector and returns a one-time enrollment token plus the tunnel address your agent dials.2
Enroll the connector agent
On your network, run the HQ connector agent with the token. It generates a keypair and a certificate signing request and calls
POST /v1/mcp/connectors/enroll (public, authenticated by the one-time token — no session), receiving a CA-signed client certificate, the CA certificate, and the tunnel address. It then dials tunnel_addr over mTLS and stays connected.A missing, invalid, expired, or already-used token returns 403. This call is made by the connector software, not by you directly. See Enroll a connector.3
Register the private MCP behind it
Once the tunnel is up, expose the private MCP server reachable through it with
POST /v1/mcp/connectors/{id}/mcp. This creates the catalog entry and installs it (enabled) for your workspace.display_name is required; path is the MCP’s path on the connector’s local base (default /mcp); max_calls_per_day is an optional cap. A revoked connector returns 400; an unknown one returns 404. See Register a private MCP behind a connector.GET /v1/mcp/connectors — each reports id, name, status (pending, enrolled, revoked), last_seen_at, and created_at (List connectors).
Revoke one with DELETE /v1/mcp/connectors/{id} — it clears the certificate fingerprint and any pending token so no new tunnel sessions can be established, and live sessions drop on their next reconnect (returns 204). See Revoke a connector.