Skip to content

CP MCP Server ​

URL: https://mcp.computeportal.io/mcp

The Compute Portal MCP server exposes all CP platform capabilities as tools that AI assistants (Claude, Cursor, Windsurf, and any MCP-compatible client) can call directly. This lets you manage GPU workloads, deploy services, run sandboxes, provision databases, inspect billing, and more through natural language — without leaving your AI assistant.


Protocol ​

The CP MCP server implements the Model Context Protocol (MCP) using the Streamable HTTP transport. A local stdio alternative is also available via cpctl mcp serve.

PropertyValue
ProtocolMCP (Model Context Protocol)
TransportStreamable HTTP (hosted) or stdio (local via cpctl mcp serve)
Endpointhttps://mcp.computeportal.io/mcp
SDK@modelcontextprotocol/sdk
AuthAuthorization: Bearer <token> (per-request) — accepts cp_live_*, cp_key_*, or OAuth JWT
Total tools23

Authentication ​

The hosted MCP server is a stateless per-request Bearer forwarder — it holds no credentials of its own. Every request must include an Authorization header with a token accepted by the CP API's auth stack:

Authorization: Bearer <token>

Three token formats are supported:

  • cp_live_<hex> — personal access token from cpctl login (OS keyring or dashboard).
  • cp_key_<hex> — scoped API key minted via the dashboard or cpctl apikey. May be --read-only (blocks mutating verbs at the API) and carries an optional limit_cents ceiling (schema wired; see Spend controls).
  • OAuth JWT issued by auth.computeportal.io — carries explicit scopes (service.read, service.update, service.destroy, …). cp-mcp enforces scope-to-tool mapping (MCP_SCOPE_ENFORCE=1) and checks the OAuth revocation endpoint on every call (OAUTH_REVOCATION_CHECK=1) before forwarding.

The MCP server extracts the Bearer token and forwards it to the CP API. The API's auth stack validates it and enforces per-user data scope. There is no shared service account; two users calling the same tool see only their own resources.

Get your token from dashboard.computeportal.io under Settings → API Tokens, or run cpctl login --token <token> and read it back from your OS keyring.

Missing or invalid tokens return a JSON-RPC error:

json
{
  "jsonrpc": "2.0",
  "error": {
    "code": -32001,
    "message": "Missing Authorization header. Set Authorization: Bearer cp_live_<token>",
    "data": { "http_status": 401 }
  },
  "id": 1
}

Health & version ​

Two unauthenticated endpoints are available for probes and discovery:

GET https://mcp.computeportal.io/health   → 200 {"ok":true}
GET https://mcp.computeportal.io/version  → 200 {"name":"cp-mcp","version":"0.4.4-authtoken"}

Safety rails for mutating tools ​

Twelve tools that mutate state or spend money accept two extra fields: dry_run and confirm_token.

  • dry_run: true — validates inputs and returns a Plan object with a confirm_token instead of executing. The token is single-use, expires in 2 minutes, and is bound to the exact tool + arguments.
  • confirm_token: "<token>" — supplied on the real call to execute.

Three tools are destructive and require this flow: cp_destroy, cp_sandbox_destroy, cp_domain_remove. Calling them without confirm_token returns an error that tells you to call with dry_run: true first.

Other mutating tools (cp_deploy, cp_scale, cp_gpu_reserve, cp_gpu_run, cp_env_set, cp_db_create, cp_sandbox_create, cp_sandbox_exec, cp_domain_add) accept dry_run as an opt-in cost preview — pass it when you want to see the plan without executing. Direct calls without dry_run still work.

Example — destructive flow (cp_destroy):

Call 1 — dry run:

json
{ "name": "cp_destroy", "arguments": { "name": "ml-inference", "dry_run": true } }

Response:

json
{
  "kind": "Plan",
  "tool": "cp_destroy",
  "args": { "name": "ml-inference" },
  "would_mutate": true,
  "destructive": true,
  "confirm_token": "86f2005ba70ec1ce951374e41ba9bb08",
  "expires_in_seconds": 120,
  "note": "Call the same tool again with confirm_token to execute. Token is single-use and expires in 2 minutes."
}

Call 2 — real destroy:

json
{
  "name": "cp_destroy",
  "arguments": {
    "name": "ml-inference",
    "confirm_token": "86f2005ba70ec1ce951374e41ba9bb08"
  }
}


Wallet-signed x402 deploys (require_x402 + auth_token) ​

The MCP tool surface supports an agent-only payment path: pay for a deploy on-chain with USDC instead of a prepaid plan. Two parameters wire it up.

cp_deploy — require_x402 and x_payment ​

  • require_x402: true — ask cp-api for the x402 handshake. The API responds with a 402 that includes pricing and the authorization requirements. The agent signs an EIP-3009 USDC authorization with wallet_sign_x402 and retries cp_deploy with the signed value in x_payment.
  • x_payment: "<base64url>" — the signed payment header from wallet_sign_x402. Setting this triggers the retry leg; cp-api verifies, settles on-chain, and returns a Service plus a short-lived deployment_jwt.

When neither is set, cp_deploy runs under the caller's Bearer and settles against the prepaid plan quota as usual.

Management tools — auth_token ​

Services created via the wallet-signed x402 path are owned by a synthesized wallet user (not the operator's OAuth identity). Without threading the deploy's JWT back in, follow-up calls like cp_service_status or cp_destroy would 404 — the operator Bearer cannot see the service.

Six management tools accept an optional auth_token parameter that overrides the operator Bearer for that single call:

  • cp_service_status
  • cp_service_logs
  • cp_scale
  • cp_destroy
  • cp_env_set
  • (implicit on all tools that touch a specific service name)

Pass the deployment_jwt from the x402 handshake. It is deployment-scoped (claims aud: deployment:<uuid>, scope: service.read service.update service.destroy), HS256-signed, and short-lived.

End-to-end flow:

1. cp_deploy({ repo: "...", require_x402: true })
   → 402 X402Challenge with pricing + authorization requirements

2. wallet_sign_x402({ challenge: <above> })
   → { x_payment: "<base64url>" }

3. cp_deploy({ repo: "...", x_payment: "<base64url>" })
   → { service: {...}, deployment_jwt: "<jwt>" }

4. cp_service_status({ name: "<service>", auth_token: "<jwt>" })
   → { status: "running", ... }

5. cp_destroy({ name: "<service>", auth_token: "<jwt>", dry_run: true })
   cp_destroy({ name: "<service>", auth_token: "<jwt>", confirm_token: "..." })

See cp-wallet MCP for wallet_sign_x402 and the signing policy.


Integrations ​

Claude Desktop ​

Add to your Claude Desktop config file.

macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
Windows: %APPDATA%\Claude\claude_desktop_config.json

Option A — hosted MCP (recommended for most users):

json
{
  "mcpServers": {
    "computeportal": {
      "url": "https://mcp.computeportal.io/mcp",
      "headers": {
        "Authorization": "Bearer cp_live_your_token_here"
      }
    }
  }
}

Option B — local stdio via cpctl mcp serve (token never leaves your machine):

json
{
  "mcpServers": {
    "computeportal": {
      "command": "cpctl",
      "args": ["mcp", "serve"]
    }
  }
}

cpctl mcp serve reads the token saved by cpctl login (OS keyring preferred, 0600 file fallback) and execs the local MCP server. Install the server with npm i -g @computeportal/mcp-server or set CP_MCP_COMMAND to point at a local build.

Restart Claude Desktop after saving. A hammer icon in the chat input area confirms MCP tools are active.

Verify: Ask Claude "List my CP services" — it should call cp_service_list and return your running services.


Cursor ​

Open Cursor Settings → MCP and add:

json
{
  "computeportal": {
    "url": "https://mcp.computeportal.io/mcp",
    "headers": {
      "Authorization": "Bearer cp_live_your_token_here"
    }
  }
}

Older Cursor versions without native HTTP MCP support can use the stdio bridge:

json
{
  "computeportal": {
    "command": "cpctl",
    "args": ["mcp", "serve"]
  }
}

Windsurf ​

In ~/.windsurf/mcp.json:

json
{
  "servers": {
    "computeportal": {
      "url": "https://mcp.computeportal.io/mcp",
      "headers": {
        "Authorization": "Bearer cp_live_your_token_here"
      }
    }
  }
}

Direct HTTP (curl / custom clients) ​

For clients that speak Streamable HTTP natively:

URL:     https://mcp.computeportal.io/mcp
Headers: Authorization: Bearer cp_live_your_token_here
         Content-Type: application/json
         Accept: application/json, text/event-stream

MCP initialize handshake:

bash
curl -X POST https://mcp.computeportal.io/mcp \
  -H "Authorization: Bearer cp_live_your_token_here" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "initialize",
    "params": {
      "protocolVersion": "2024-11-05",
      "capabilities": {},
      "clientInfo": { "name": "my-client", "version": "1.0.0" }
    }
  }'

List tools:

bash
curl -X POST https://mcp.computeportal.io/mcp \
  -H "Authorization: Bearer cp_live_your_token_here" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/list"}'

Tools Reference ​

The CP MCP server exposes 23 tools grouped by domain. Tools marked mutating accept dry_run; tools marked destructive require the two-step dry_run → confirm_token flow.

Service Tools ​

cp_deploy (mutating) ​

Deploy a new service from a Docker image or a public GitHub repo. When repo is provided, CP clones and builds the image internally — no registry setup needed. Build operations time out after 10 minutes.

Inputs

ParameterTypeRequiredDescription
imagestringNo*Docker image URI (e.g. myorg/agent:latest)
repostringNo*Public GitHub repo URL — CP builds from the Dockerfile
namestringNoService name (defaults to derived from image or repo)
regionstringNoRegion ID (e.g. eu-west)
gpustringNoGPU type: gb10 | rtx5090
gpu_countintegerNoNumber of GPUs (min: 1)
envobjectNoEnvironment variables as key-value pairs
domainsarrayNoCustom hostnames to attach after deploy
dry_runbooleanNoReturn a Plan with confirm_token instead of deploying
confirm_tokenstringNoConfirm token from a prior dry_run call

* Exactly one of image or repo is required.

Example — deploy from GitHub repo

json
{
  "tool": "cp_deploy",
  "arguments": {
    "name": "my-app",
    "repo": "https://github.com/my-org/my-app"
  }
}

Returns

json
{
  "service_id": "my-app",
  "name": "my-app",
  "url": "https://my-app.cpctl.app",
  "status": "running"
}

cp_service_list ​

List all running services. Optionally filter by region.

Inputs

ParameterTypeRequiredDescription
regionstringNoFilter by region ID

cp_service_status ​

Get current status, replica count, and health metrics for a service.

Inputs

ParameterTypeRequiredDescription
namestringYesService name

cp_service_logs ​

Fetch the most recent log lines from a running service.

Inputs

ParameterTypeRequiredDescription
namestringYesService name
tailintegerNoNumber of log lines to return (1–5000, default: 100)

cp_scale (mutating) ​

Scale replica count or update CPU and memory limits for a service.

Inputs

ParameterTypeRequiredDescription
namestringYesService name
countintegerNoNumber of replicas (min: 0)
cpustringNoCPU limit in vCPUs (e.g. '2')
ramstringNoMemory limit (e.g. '4Gi')
dry_runbooleanNoReturn a Plan with confirm_token instead of scaling
confirm_tokenstringNoConfirm token from a prior dry_run call

At least one of count, cpu, or ram must be provided.


cp_destroy (destructive — requires dry_run → confirm_token) ​

Permanently destroy a service and release all associated resources. This action is irreversible.

Inputs

ParameterTypeRequiredDescription
namestringYesService name to destroy
dry_runbooleanOn first callMust be true to mint a confirm_token
confirm_tokenstringOn second callToken from the dry_run response

Returns { "destroyed": "ml-inference" }


cp_env_set (mutating) ​

Set one or more environment variables on a running service. Triggers a rolling restart to apply changes.

Inputs

ParameterTypeRequiredDescription
servicestringYesService name
varsobjectYesKey-value pairs to set
dry_runbooleanNoReturn a Plan with confirm_token instead of applying
confirm_tokenstringNoConfirm token from a prior dry_run call

Returns { "service": "ml-inference", "set": 2 }


GPU Tools ​

cp_gpu_list ​

List available GPU nodes with specs, live utilization, VRAM usage, and temperature.

Inputs

ParameterTypeRequiredDescription
regionstringNoFilter by region
typestringNoFilter by GPU type: gb10 | rtx5090

cp_gpu_reserve (mutating) ​

Reserve GPU capacity for a fixed duration. Returns a reservation ID and hourly rate.

Inputs

ParameterTypeRequiredDescription
typestringYesGPU type: gb10 | rtx5090
countintegerNoNumber of GPUs (min: 1, default: 1)
durationstringNoReservation duration (e.g. 4h, 24h, 7d, default: 1h)
regionstringNoRegion (defaults to account default)
dry_runbooleanNoReturn a Plan with confirm_token instead of reserving
confirm_tokenstringNoConfirm token from a prior dry_run call

cp_gpu_run (mutating) ​

Submit a one-shot GPU job. Billed from your monthly prepaid balance. Returns a job ID and initial status immediately.

Inputs

ParameterTypeRequiredDescription
imagestringYesDocker image to run
scriptstringNoCommand or script to execute inside the container
gpustringNoGPU type (default: gb10)
gpu_countintegerNoNumber of GPUs (min: 1, default: 1)
regionstringNoRegion ID
dry_runbooleanNoReturn a Plan with confirm_token instead of running
confirm_tokenstringNoConfirm token from a prior dry_run call

Node Tools ​

cp_node_list ​

List all bare-metal nodes with hardware specs (CPU cores, RAM, GPU type/count) and reservation status.

Inputs

ParameterTypeRequiredDescription
regionstringNoFilter by region
gpustringNoFilter by GPU type: gb10 | rtx5090

Billing Tools ​

cp_billing_balance ​

Return current account balance, credit, hourly burn rate, and alert threshold.

Inputs — None

Returns

json
{
  "balance": 142.50,
  "credit": 0,
  "burn_rate_hourly": 3.20,
  "alert_threshold": 20.00
}

cp_billing_usage ​

Return itemized billing usage for a given period, optionally filtered by service.

Inputs

ParameterTypeRequiredDescription
periodstringNotoday | month | YYYY-MM (default: today)
servicestringNoFilter by service name

cp_billing_resync ​

Resync compute plans and entitlements from the marketplace. Call this after a user purchases a plan on https://computeportal.io/pricing to make the plan visible to the agent and clear a NO_ACTIVE_PLAN (402) error.

Inputs — None

Returns

json
{
  "synced": 1,
  "before": { "vcpu": 24, "memory_gib": 96, "gpu_count": 1 },
  "after": { "vcpu": 28, "memory_gib": 128, "gpu_count": 1 },
  "plans": [{ "sku": "hm-4-32-1000", "status": "active" }]
}

Catalog & Region Tools ​

cp_catalog_list ​

List all Compute Portal plan SKUs and prices. Useful for recommending a plan to the operator before they purchase on the web.

Inputs — None

Returns

json
{
  "catalog": [
    {
      "id": "basic-1-2-50",
      "category": "basic",
      "vcpu": 1,
      "memory_gib": 2,
      "storage_gib": 50,
      "gpu": null,
      "gpu_memory_gib": null,
      "price_per_month": 11.64
    }
  ]
}

cp_region_list ​

List all Compute Portal regions with compliance certifications, GPU availability, and latency.

Inputs — None


Database Tools ​

cp_db_create (mutating) ​

Provision a managed database. Returns connection credentials.

Inputs

ParameterTypeRequiredDescription
typestringYesDatabase engine: postgres | redis | mysql | mongo
namestringNoDatabase name (defaults to {type}-db)
regionstringNoRegion (defaults to account default)
size_gbintegerNoStorage in GB (min: 1, default: 10)
dry_runbooleanNoReturn a Plan with confirm_token instead of provisioning
confirm_tokenstringNoConfirm token from a prior dry_run call

Sandbox Tools ​

Sandboxes are isolated GPU-attached microVMs for AI agent code execution. They expose SSH access and a command execution API.

cp_sandbox_create (mutating) ​

Spin up a GPU-attached sandbox microVM.

Inputs

ParameterTypeRequiredDescription
imagestringYesContainer image
gpustringNoGPU type (default: gb10)
gpu_countintegerNoNumber of GPUs (min: 1, default: 1)
regionstringNoRegion ID
timeoutstringNoSandbox lifetime (default: 1h, e.g. 2h, 30m)
dry_runbooleanNoReturn a Plan with confirm_token instead of creating
confirm_tokenstringNoConfirm token from a prior dry_run call

cp_sandbox_exec (mutating) ​

Execute a command inside a running sandbox and return stdout, stderr, exit code, and duration.

Inputs

ParameterTypeRequiredDescription
idstringYesSandbox ID
commandarray of stringsYesCommand and arguments (e.g. ["python", "train.py", "--epochs", "10"])
dry_runbooleanNoReturn a Plan with confirm_token instead of executing
confirm_tokenstringNoConfirm token from a prior dry_run call

Returns

json
{
  "stdout": "Epoch 10/10 — loss: 0.042",
  "stderr": "",
  "exit_code": 0,
  "duration_ms": 18420
}

cp_sandbox_destroy (destructive — requires dry_run → confirm_token) ​

Destroy a sandbox and release its GPU resources. This action is irreversible.

Inputs

ParameterTypeRequiredDescription
idstringYesSandbox ID
dry_runbooleanOn first callMust be true to mint a confirm_token
confirm_tokenstringOn second callToken from the dry_run response

Returns { "destroyed": "sb_abc123" }


Domain Tools ​

cp_domain_add (mutating) ​

Attach a custom hostname to a CP service. Validates the DNS CNAME record and provisions TLS automatically. The CNAME must point to cpctl.app.

Inputs

ParameterTypeRequiredDescription
servicestringYesService name (e.g. my-app)
hostnamestringYesCustom hostname (e.g. dashboard.myapp.com)
skip_dnsbooleanNoSkip DNS CNAME validation (default: false)
dry_runbooleanNoReturn a Plan with confirm_token instead of attaching
confirm_tokenstringNoConfirm token from a prior dry_run call

Returns

json
{
  "hostname": "api.myapp.com",
  "status": "active",
  "service": "ml-inference",
  "created_at": "2026-08-29T10:52:36.153Z"
}

cp_domain_list ​

List all domains attached to a service — both the default {service}.cpctl.app and any custom hostnames.

Inputs

ParameterTypeRequiredDescription
servicestringYesService name

cp_domain_remove (destructive — requires dry_run → confirm_token) ​

Remove a custom hostname from a CP service. The default {service}.cpctl.app domain cannot be removed.

Inputs

ParameterTypeRequiredDescription
servicestringYesService name
hostnamestringYesCustom hostname to remove
dry_runbooleanOn first callMust be true to mint a confirm_token
confirm_tokenstringOn second callToken from the dry_run response

Returns { "removed": "api.myapp.com", "service": "ml-inference" }


Usage Patterns ​

The AI assistant maps natural language to tool calls. You do not need to know tool names — just describe what you want.

Service management

"Show me all my running services" → cp_service_list
"Deploy https://github.com/my-org/trainer with 2 RTX 5090s" → cp_deploy
"Scale ml-inference to 3 replicas with 8Gi RAM" → cp_scale
"Delete the ml-inference service" → cp_destroy (two-step: dry_run → confirm)

GPU workloads

"What RTX 5090 nodes are available?" → cp_gpu_list
"Reserve 4 RTX 5090s for 24 hours" → cp_gpu_reserve
"Run a one-shot training job with image myorg/trainer:latest" → cp_gpu_run

Sandboxes

"Create a GPU sandbox for 2 hours using image myorg/dev-env:latest" → cp_sandbox_create
"Run nvidia-smi in sandbox sb_abc123" → cp_sandbox_exec

Billing & catalog

"What's my current balance and hourly burn rate?" → cp_billing_balance
"I just purchased a plan on the web — pull it in" → cp_billing_resync
"What plans are available?" → cp_catalog_list

Domains

"Attach api.myapp.com to ml-inference — CNAME is already set" → cp_domain_add

Debugging

"Show me the last 200 lines of logs from ml-inference" → cp_service_logs
"My service is crashing — show me its status and recent error logs" → cp_service_status then cp_service_logs


Agent recipes ​

Recovering from NO_ACTIVE_PLAN (402) ​

If a mutation returns a 402 with the hint "Purchase a compute plan at https://computeportal.io/pricing":

  1. Call cp_catalog_list to pick the right SKU for the workload.
  2. Tell the operator to purchase it on the web (CLI/agent purchase is intentionally not supported).
  3. Once the operator confirms, call cp_billing_resync to pull the new plan into the account.
  4. Retry the original mutation.

Destroying a service safely ​

1. cp_destroy({"name": "x", "dry_run": true}) → {confirm_token: "…"}
2. cp_destroy({"name": "x", "confirm_token": "…"}) → {"destroyed": "x"}

The confirm_token is bound to ("cp_destroy", {"name":"x"}) — altering the name invalidates it. Tokens expire after 2 minutes and are single-use.


Troubleshooting ​

"No tools available" in Claude Desktop ​

  1. Verify your config file is valid JSON (no trailing commas).
  2. Confirm your token starts with cp_live_.
  3. Fully quit and relaunch Claude Desktop (Cmd+Q on macOS, not just close the window).
  4. If using the stdio bridge, check that cpctl is on PATH and cpctl whoami succeeds.

"Missing Authorization header" (401) ​

The hosted MCP server requires a Bearer token on every request. For HTTP mode, confirm the headers.Authorization entry is present and the value starts with Bearer cp_live_. For stdio mode (cpctl mcp serve), run cpctl whoami to confirm you're logged in — the stdio server reads the keyring token.

"cp_destroy is destructive. Call with dry_run: true first" ​

Destructive tools require the two-step flow. Call once with dry_run: true, read the confirm_token out of the response, then call again with that token.

"Invalid, expired, or mismatched confirm_token" ​

Confirm tokens are single-use, expire after 2 minutes, and are bound to the exact tool + arguments. If you change the arguments between calls, mint a fresh token with another dry_run: true call.

DNS validation failure when adding a domain ​

The cp_domain_add tool validates that the hostname's CNAME resolves to cpctl.app. If validation fails:

  1. Confirm the DNS record is saved and set to DNS only (not proxied through Cloudflare).
  2. Wait for propagation — typically 1–5 minutes for Cloudflare, up to 48 hours for other registrars.
  3. Verify: dig CNAME dashboard.myapp.com — the answer should point to cpctl.app.
  4. Pass skip_dns: true to attach the domain immediately without DNS validation.

Deploy from repo is slow ​

Repo-based deploys involve cloning, building, and pushing a Docker image. This typically takes 1–5 minutes depending on repo size and Dockerfile complexity. The tool has a 10-minute timeout — if exceeded, check the CP dashboard for build status.


Security ​

  • The hosted MCP server is stateless — it does not store tokens, does not hold a service account, and forwards your Bearer header to the CP API on every request. Two users calling the same tool see only their own resources.
  • Tokens are scoped to your CP account. Never share your cp_live_* token.
  • For maximum isolation, use cpctl mcp serve to run the MCP server locally. Your token stays on your machine and never crosses the hosted endpoint.
  • All traffic is HTTPS. Plain HTTP is not supported.
  • Revoke tokens at any time from the CP Dashboard.

Quick Reference ​

Mutating tools accept dry_run; destructive tools require it.

ToolKindDescription
cp_deploymutatingDeploy from image or public GitHub repo
cp_service_listreadList all running services
cp_service_statusreadStatus, replicas, and health for a service
cp_service_logsreadFetch recent log lines
cp_scalemutatingScale replicas, CPU, or memory
cp_destroydestructivePermanently destroy a service
cp_env_setmutatingSet environment variables on a service
cp_gpu_listreadList GPU nodes with utilization and specs
cp_gpu_reservemutatingReserve GPU capacity for a fixed duration
cp_gpu_runmutatingSubmit a one-shot GPU job
cp_node_listreadList bare-metal nodes with hardware specs
cp_billing_balancereadCurrent balance, credit, and burn rate
cp_billing_usagereadItemized usage for a period
cp_billing_resyncreadPull web-purchased plans into the agent view
cp_region_listreadAvailable regions with GPU availability
cp_catalog_listreadList all plan SKUs and prices
cp_db_createmutatingProvision a managed database
cp_sandbox_createmutatingCreate a GPU-attached microVM sandbox
cp_sandbox_execmutatingExecute a command inside a sandbox
cp_sandbox_destroydestructiveDestroy a sandbox
cp_domain_addmutatingAttach a custom hostname to a service
cp_domain_listreadList domains on a service
cp_domain_removedestructiveRemove a custom hostname

GPU Compute Platform · Status