Generic MCP client setup
This page covers connecting any MCP-compatible client to the ziptie.ai API. For popular clients, see the dedicated guides: Claude Desktop, Claude Code, Cursor, VS Code.
Prerequisites
- An MCP client that speaks Streamable HTTP and lets you set a request header.
Clients that only load local stdio servers need the
mcp-remotebridge shape shown below. - A ziptie.ai API token with at least
readscope. Create one under Project Settings > API & MCP access, or a workspace token from Workspace Settings > API & MCP access for one token that reaches every project. The workspace needs the paid API & MCP access add-on active first - without it the create button is disabled and existing tokens are rejected withAPI_ADDON_INACTIVE. See authentication.
Server details
| Property | Value |
|---|---|
| Transport | Streamable HTTP (JSON-RPC 2.0 over POST) |
| URL | https://api.ziptie.ai/mcp |
| Auth | Authorization: Bearer zt_live_<your-token> |
| Protocol version | 2025-06-18 |
| Entitlement | API & MCP access add-on must be active on the workspace; every method, initialize included, is rejected without it |
Configuration shapes
MCP clients vary in both the top-level wrapper key, whether they need
an explicit "type" field, and whether they accept remote HTTP servers
directly or require a local stdio bridge. The four shapes you will
encounter:
mcpServers + explicit type (Claude Code's .mcp.json):
{
"mcpServers": {
"ziptie": {
"type": "http",
"url": "https://api.ziptie.ai/mcp",
"headers": {
"Authorization": "Bearer zt_live_<your-token>"
}
}
}
}mcpServers, type inferred from URL (Cursor):
{
"mcpServers": {
"ziptie": {
"url": "https://api.ziptie.ai/mcp",
"headers": {
"Authorization": "Bearer zt_live_<your-token>"
}
}
}
}servers + explicit type (VS Code's mcp.json):
{
"servers": {
"ziptie": {
"type": "http",
"url": "https://api.ziptie.ai/mcp",
"headers": {
"Authorization": "Bearer zt_live_<your-token>"
}
}
}
}stdio-bridge wrapper (Claude Desktop and any client that does not accept remote HTTP servers directly):
{
"mcpServers": {
"ziptie": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://api.ziptie.ai/mcp",
"--header",
"Authorization: Bearer ${ZIPTIE_TOKEN}"
],
"env": {
"ZIPTIE_TOKEN": "zt_live_<your-token>"
}
}
}
}Use whichever shape the client's own docs prescribe; the per-client guides linked above show the exact filename and form for each.
Manual JSON-RPC test
Verify the server is reachable with a raw curl call:
curl -X POST https://api.ziptie.ai/mcp \
-H "Authorization: Bearer zt_live_<your-token>" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2025-06-18",
"clientInfo": {"name": "curl-test", "version": "0"}
}
}'A successful response:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"protocolVersion": "2025-06-18",
"serverInfo": {"name": "ziptie-public-api", "version": "1.0.0"},
"capabilities": {"tools": {}}
}
}If this call fails, the status will still be 200 - read error.data.code from
the body, not the HTTP status. -32001 means the token is missing, malformed,
expired, or revoked. -32004 API_ADDON_INACTIVE means the token itself is
valid but the workspace's API & MCP access add-on is off, usually because it lapsed
or the subscription was cancelled; existing tokens are not revoked when that
happens, they just stop being accepted. -32004 PAYMENT_REQUIRED means the
subscription is overdue.
{
"jsonrpc": "2.0",
"id": 1,
"error": {
"code": -32001,
"message": "API token has expired",
"data": {"code": "TOKEN_EXPIRED", "error": "API token has expired"}
}
}These three are decided in front of the router, but they are reported the same
way as any tool error: a JSON-RPC error member at HTTP 200. Nothing on this
endpoint answers with a 401, 402 or 403.
Listing tools
curl -X POST https://api.ziptie.ai/mcp \
-H "Authorization: Bearer zt_live_<your-token>" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/list",
"params": {}
}'Calling a tool
curl -X POST https://api.ziptie.ai/mcp \
-H "Authorization: Bearer zt_live_<your-token>" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "list_prompts",
"arguments": {
"project_id": "PROJECT_ID",
"limit": 5
}
}
}'The response result.content is an array of {"type": "text", "text": "..."} objects
where text is the JSON-serialized API response.
Retrying a write safely
MCP has no header channel for a tool call, so Idempotency-Key is passed as an
ordinary argument alongside the rest and the server forwards it as the HTTP
header. Seven tools accept it: create_prompt, create_prompts_bulk, create_tag,
create_url, update_prompt, update_tag, and update_url.
{
"jsonrpc": "2.0",
"id": 4,
"method": "tools/call",
"params": {
"name": "create_prompt",
"arguments": {
"project_id": "PROJECT_ID",
"text": "What is the best AI monitoring tool?",
"Idempotency-Key": "550e8400-e29b-41d4-a716-446655440000"
}
}
}This is the only safe way for an agent to retry a write that timed out. Reuse
the same key on every attempt: the response is cached for 24 hours, so a replay
returns the original result instead of creating a second prompt. Reusing a key
with different arguments returns -32009 with data.code
IDEMPOTENCY_KEY_REUSED, and the body comparison is byte-exact - resend the
remaining arguments in the same order, not just with the same values. The two
suggestion tools, create_accept and
create_dismiss, do not accept the argument - a repeat call there returns
-32009 ALREADY_RESOLVED, which on a retry means the first attempt
succeeded. See Idempotency.
Error handling
MCP errors follow JSON-RPC 2.0. The error.data field contains the underlying
API error envelope {"code": "...", "error": "..."}. A tool-level failure is
returned with HTTP 200 and the error inside the envelope, so status-code checks
alone will read it as success; branch on error.data.code. See
error codes for the full code list and MCP JSON-RPC
mappings, and the MCP overview for which failures bypass the
JSON-RPC envelope entirely.