Partner MCP Gateway

Administer your Knotie AI Pro partner account — customers, AI Gateway keys, VPS deployments, credit balance, agents, billing, and more — through any MCP-compatible AI client using your existing partner pkt_ API key.

135 tools, 15 scope domains Spec 2025-11-25 Streamable HTTP pkt_ Bearer auth

Not using an AI agent?

The same 135 tools are also exposed as a conventional REST API with an auto-generated OpenAPI 3.1 spec — same pkt_ keys, same scope model. Ideal for scripts, CI pipelines, and no-code tools. See the Partner REST API →

Server URL

MCP endpoint
POST https://mcp.knotie-ai.pro/api/partner-mcp

Single Streamable-HTTP endpoint — accepts POST (JSON-RPC), GET (server-initiated SSE), and DELETE (session termination). Protected Resource Metadata is served at /.well-known/oauth-protected-resource/api/partner-mcp.

Authentication

Use your partner pkt_ API key (create one in Partner → Settings → API Keys) in the standard Authorization: Bearer header.

HTTP headers
Authorization: Bearer pkt_<your-64-hex-secret>
Accept: application/json, text/event-stream
Content-Type: application/json
MCP-Protocol-Version: 2025-11-25

Keys can be scoped (read, read-write, or full access) per domain. See the scope picker on each key in the dashboard, or use the PATCH /api/partner/api-keys/:keyId/mcp-scopes endpoint.

Quick start — MCP client configs

Claude Desktop (remote connector)

~/Library/Application Support/Claude/claude_desktop_config.json
{
  "mcpServers": {
    "knotie-partner": {
      "url": "https://mcp.knotie-ai.pro/api/partner-mcp",
      "headers": {
        "Authorization": "Bearer pkt_YOUR_KEY"
      }
    }
  }
}

n8n MCP Client node

n8n node config
{
  "serverUrl": "https://mcp.knotie-ai.pro/api/partner-mcp",
  "transport": "http",
  "authentication": {
    "type": "bearer",
    "token": "pkt_YOUR_KEY"
  }
}

Cursor / Windsurf

.cursor/mcp.json
{
  "mcpServers": {
    "knotie": {
      "url": "https://mcp.knotie-ai.pro/api/partner-mcp",
      "headers": {
        "Authorization": "Bearer pkt_YOUR_KEY"
      }
    }
  }
}

curl — call a tool directly

bash
curl -X POST https://mcp.knotie-ai.pro/api/partner-mcp \
  -H 'Authorization: Bearer pkt_YOUR_KEY' \
  -H 'Accept: application/json, text/event-stream' \
  -H 'Content-Type: application/json' \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "meta_whoami",
      "arguments": {}
    }
  }'

Scope model

Every tool declares a required scope like customers:read or vps:write. An API key can hold any of:

  • * — full access (default for existing keys)
  • domain:* — read + write for a domain (e.g. vps:*)
  • domain:read / domain:write — specific actions

Meta tools (meta_whoami, meta_scopes, meta_health) require no scope and always work. Restricted keys only see allowed tools in tools/list; a disallowed tools/call returns HTTP 403.

Tool catalog (135 tools, 15 scope domains + unscoped meta)

customers15 tools
  • • customers_list
  • • customers_onboard
  • • customers_update
  • • customers_enable_portal
customer-api-keys4 tools
  • • customer_api_keys_list
  • • customer_api_keys_create
agents8 tools
  • • agents_list
  • • agents_create
  • • agents_map_customer
ai-gateway11 tools
  • • ai_gateway_keys_list
  • • ai_gateway_keys_create
  • • ai_gateway_keys_top_up
credits20 tools
  • • credits_balance
  • • credits_purchase
  • • customer_credits_top_up
  • • customer_credits_set_monthly
vps20 tools
  • • vps_plans_list
  • • vps_checkout
  • • vps_applications_list
  • • vps_packages_create
  • • vps_instance_reinstall
phone-numbers8 tools
  • • phone_numbers_list
  • • phone_numbers_purchase
  • • phone_numbers_assign_agent
knowledge-bases3 tools
  • • knowledge_bases_list
  • • knowledge_bases_upload_url
billing12 tools
  • • invoices_list
  • • invoices_create
  • • billing_analytics
analytics6 tools
  • • analytics_summary
  • • customer_report_update
team7 tools
  • • team_members_invite
  • • customer_team_members_add
whitelabel6 tools
  • • whitelabel_settings_update
  • • branding_update
quota3 tools
  • • tool_quota_get
  • • tool_quota_update
embed3 tools
  • • embed_tokens_list
  • • embed_tokens_create
memory5 tools
  • • memory_list_minds
  • • memory_remember
  • • memory_recall
  • • memory_ask
meta3 tools
  • • meta_whoami
  • • meta_scopes
  • • meta_health

Call tools/list against the endpoint to enumerate the full catalog for your key (filtered by scope).

Protocol lifecycle

  1. 1.initialize — handshake + protocol version negotiation. Server responds with serverInfo and capabilities.
  2. 2.notifications/initialized — one-way client notification (server responds 202 Accepted).
  3. 3.tools/list — returns tools visible to this key.
  4. 4.tools/call — executes the tool and returns the result (JSON text).

Security model — what the gateway does NOT expose

The Partner MCP is built to be safe against a malfunctioning or compromised agent holding a valid pkt_ key. Auth-related operations are either absent from the tool registry or require the agent to go through an email round-trip to obtain any credential.

Absent by design

  • Partner login / register / OAuth
  • Partner password change or MFA management
  • Partner API-key issuance (a new pkt_ can only be minted in the dashboard)
  • Customer impersonation (removed — previously returned a one-click login URL)

Email-mitigated (safe to use)

These tools trigger credential changes but credentials are emailed to the intended recipient — never returned in the MCP response body:

  • customers_reset_password — new password emailed to the customer
  • customers_enable_portal — initial credentials emailed to the customer
  • team_members_invite — invitee must click an email link

Secret-emitting — exposed but clearly labeled ⚠️

A few tools legitimately need to return a secret once in the body (so partners can automate key rotation, VPS recovery, etc.). Every such tool is marked ⚠️ SENSITIVEin its description. Grant the corresponding domain scope only to keys that truly need it:

  • vps:read — covers vps_instance_credentials (returns root password)
  • vps:write — covers vps_instance_fix_credentials, vps_instance_regenerate_ssh_key
  • customer-api-keys:write — covers customer_api_keys_create/renew (returns ckt_)
  • ai-gateway:write — covers ai_gateway_keys_create/regenerate (returns LiteLLM key)
  • embed:write — covers embed_tokens_create

Every invocation — successful or not — is audited to partner_mcp_invocations with the key ID, IP, latency, and a hash of the arguments (not the raw values). Operators can alert on unusual patterns.

Troubleshooting

Every error includes a structured data.type. Most common failure modes and fixes:

SymptomFix
invalid_credentials immediately after creating a keyAlmost always an ENCRYPTION_KEY mismatch between the main-app deployment (which writes the encrypted key to DB) and the Connect-Hub deployment (which reads it). See the block below.
mcp_disabled_on_keyOpen the key in Settings → Partner API Keys → click the scope pill → enable MCP.
insufficient_scope on tools/callResponse body shows required_scope and granted_scopes. Adjust scopes on the key.
missing_credentials with Basic authPartner MCP accepts Authorization: Bearer pkt_... (or X-API-Key: pkt_...). Basic auth is for the legacy analytics MCP only.
406 unacceptableAdd Accept: application/json, text/event-stream — the spec requires both.
503 feature_disabledSet PARTNER_MCP_ENABLED=true on the Connect-Hub deployment.

Shared-secret mismatch — the #1 cause of invalid_credentials

Partner keys are AES-256-GCM encrypted by the main app's ENCRYPTION_KEY at write time and decrypted by Connect Hub at authentication time. The delegated service JWT on each tool call is signed with the main app's JWT_SECRET. On Connect Hub, those two main-app secrets are read under distinct names — MAIN_APP_ENCRYPTION_KEY and MAIN_APP_JWT_SECRET — because Connect Hub has its own ENCRYPTION_KEY / JWT_SECRET for local purposes (OAuth, schemas route, security tokens).

bash — verify hashes on both runtimes
# Main app:
echo -n "$ENCRYPTION_KEY" | sha256sum
echo -n "$JWT_SECRET"     | sha256sum

# Connect Hub:
echo -n "$MAIN_APP_ENCRYPTION_KEY" | sha256sum
echo -n "$MAIN_APP_JWT_SECRET"     | sha256sum

# Corresponding pairs MUST match byte-for-byte.

On an encryption-key mismatch, Connect Hub emits an error-level log line naming the specific env var — grep for "MAIN_APP_ENCRYPTION_KEY on Connect Hub does not match".

Error semantics

HTTPJSON-RPCMeaning
401−32001Missing / invalid / revoked / expired / IP-blocked key. WWW-Authenticate header points to PRM.
403−32002Insufficient scope, partner unapproved, or subscription inactive.
406−32600Missing required Accept header.
429−32029Daily/monthly rate limit exceeded. Retry-After header set.
503−32006MCP gateway disabled on this instance.

How it works — zero duplicated business logic

Every MCP tool is a thin proxy. When your agent calls a tool, the Connect-Hub gateway:

  1. Validates your pkt_ key, checks scope, and records an audit row.
  2. Mints a 60-second HS256 JWT with your partnerId + email, signed with the same JWT_SECRET the main app already trusts.
  3. Calls the existing /api/partner/* route — the same one the dashboard uses — with that JWT in the Authorization header.
  4. Returns the response back to your agent, then discards the JWT.

Implication: analytics pings, Stripe billing, Contabo provisioning, webhook dispatches, SendGrid emails, credit accounting — every side-effect embedded in the main-app route handler fires exactly as if a human clicked the button. We did not re-implement any business logic on the MCP layer.

Full technical write-up: See the architecture reference.

Example — agent deploys a VPS stack for a customer

An AI agent can orchestrate the full turnkey flow a human partner does through the VPS dashboard — purchase a plan, pick apps from the catalog, deploy a combo, grant customer SSH access, all in one conversation.

  1. 1. Discover what's deployable
    tools/call → vps_applications_list  •  vps_plans_list
  2. 2. (Optional) Create a reusable package SKU
    vps_packages_create with { bundledAppIds: ["n8n","supabase","redis"], basePlanId, priceMonthlyUsd }
  3. 3. Purchase the VPS
    vps_checkout with { planId, region, displayName, customerId } → returns Stripe checkout URL (hand to customer) or auto-provisions if pre-paid credits cover it.
  4. 4. Deploy apps onto the fresh instance
    vps_instance_reinstall with { instanceId, applicationIds: ["n8n","supabase","redis"] } — wipes the image and composes the stack in one call.
  5. 5. Surface credentials to the customer
    vps_instance_credentials (emails root password + IP), then vps_customer_access_grant to wire up SSH host/port/user for the customer portal.
  6. 6. Assign / rename / change status later
    vps_instance_update handles rename, customer re-assignment, status (active / suspended / cancelled), and IP changes.

All six steps go through the same /api/partner/vps/* endpoints the dashboard uses — no parallel provisioning pipeline. Billing + Contabo + customer emails fire exactly as they would from a manual flow.

Example — list your customers

Request
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "customers_list",
    "arguments": { "page": 1, "limit": 20 }
  }
}
Response (tool content)
{
  "success": true,
  "data": [ /* ...customer rows... */ ],
  "pagination": {
    "currentPage": 1,
    "totalPages": 5,
    "totalCount": 92,
    "limit": 20,
    "hasNextPage": true,
    "hasPrevPage": false
  }
}

Related resources