Deploy from your AI tool

Add Dockhold to your coding tool once. Then say "put this online" and it does.

Your AI coding tool can deploy and manage your apps on Dockhold directly: list them, read status and logs, deploy a repo, restart an app, resize it, set variables. It works through MCP, the open protocol AI tools use to call other services, and it acts as you, on your own account only. The install is one step per tool, and you sign in once in your browser. No token is pasted anywhere.

Two different things, both called "MCP." This page is about connecting your AI tool to Dockhold. If instead you want to host your own MCP server on Dockhold, see Deploy an MCP server.

1. Add Dockhold to your tool

Every tool ends up running the same small command on your machine, npx -y dockhold mcp. Pick yours.

Claude Code

Two commands inside Claude Code. The plugin adds the tools and a deploy skill.

/plugin marketplace add dockhold/mcp
/plugin install dockhold@dockhold

Cursor

Add to Cursor

Or paste this into .cursor/mcp.json in your project (or ~/.cursor/mcp.json for every project):

{
  "mcpServers": {
    "dockhold": {
      "command": "npx",
      "args": ["-y", "dockhold", "mcp"],
      "env": { "DOCKHOLD_REF": "cursor" }
    }
  }
}

VS Code

One command in a terminal:

code --add-mcp '{"name":"dockhold","command":"npx","args":["-y","dockhold","mcp"],"env":{"DOCKHOLD_REF":"vscode"}}'

Codex, Gemini CLI, Windsurf, any MCP client

The same server, in whichever form your client takes. Codex and Gemini CLI have an add command:

# Codex
codex mcp add dockhold --env DOCKHOLD_REF=codex -- npx -y dockhold mcp

# Gemini CLI
gemini mcp add -e DOCKHOLD_REF=gemini dockhold npx -y dockhold mcp

Windsurf reads ~/.codeium/windsurf/mcp_config.json. Any other client that can start a command takes this block in its MCP settings. Change the DOCKHOLD_REF value to your client's name; it only tells us which tool you came from.

{
  "mcpServers": {
    "dockhold": {
      "command": "npx",
      "args": ["-y", "dockhold", "mcp"],
      "env": { "DOCKHOLD_REF": "windsurf" }
    }
  }
}

Tool gives up while the server starts? npx -y dockhold mcp downloads the package the first time it runs, and some clients stop waiting before that finishes. Install it once with npm i -g dockhold, then use dockhold as the command and ["mcp"] as the args.

2. Sign in once

From any terminal:

npx dockhold login

This opens your browser. Approve it, and your tool picks the sign-in up on its next call, with no restart. The sign-in is saved on your machine, not in any editor config, so there is nothing to leak when that config is synced or committed. The same sign-in serves the CLI, so npx dockhold deploy works too. If you ask your tool to do something before signing in, it tells you the exact command to run.

3. Say what you want

"Put this online" is enough. Your tool calls deploy_app, then polls get_app_status until the URL is up, and tells you. These are the tools it can use:

  • list_apps: your apps, with status and URLs.
  • get_app_status: one app's deploy status, URL, and last error.
  • get_app_logs: recent runtime logs, for debugging a deploy.
  • list_github_repos: the repos you've connected, so it can deploy a private one.
  • deploy_app: deploy a new app from a public or private GitHub repo.
  • redeploy_app: restart the version already running.
  • rebuild_app: build the app again from its latest commit or last upload, and deploy it when the build passes.
  • set_app_variable / unset_app_variable: set or remove a configuration variable.
  • get_resource_usage: your memory, database, and storage pools, and how much is free.
  • resize_app: give an app more memory when it runs out.
  • resize_database / resize_database_storage: grow a managed database's memory or disk.
  • set_app_storage / remove_app_storage: give an app storage that survives restarts (the app then reads the folder path from DATA_DIR), or erase it.
  • deploy_group: deploy several services that call each other, wired together.

A private repo is the same instruction: the tool calls list_github_repos first. Before it adds storage, ask it to read app storage; remove_app_storage asks you to confirm before it erases anything.

Secrets (an API key, a password) are not part of this sign-in. Set them under Secrets in the dashboard sidebar, where they are encrypted and never readable through any tool afterward. set_app_variable refuses anything that looks like a key or password and points you there.

What it can't do

Your tool only ever does what you could do in the dashboard, on your own apps, within your plan. It can't reach anyone else's apps, can't change billing or delete your account, and can't read a stored secret. The sign-in expires on its own after a while; when it does, the tool tells you to run npx dockhold login again. To cut it off sooner, revoke it under API tokens in the dashboard sidebar, and it stops working immediately.

The one rule that still matters

Whether you deploy by hand or through your AI tool, the app itself has to listen on 0.0.0.0:$PORT. That's the whole contract. Everything else Dockhold handles.

If your client needs a remote server

Some clients can't start a command and only connect to an MCP server over HTTP. For those, Dockhold's server is at https://api.dockhold.eu/mcp, and you authenticate with a dashboard API token instead of the browser sign-in. Create one under API tokens in the dashboard sidebar: pick read-only or read and deploy, and tick "Also allow writing secrets" only if the tool must store secrets, since that token can write to every app on your account. The token starts with dh_mcp_ and is shown once. Pass it as a bearer header:

{
  "mcpServers": {
    "dockhold": {
      "url": "https://api.dockhold.eu/mcp",
      "headers": { "Authorization": "Bearer dh_mcp_live_…" }
    }
  }
}

In Claude Code, the same thing as one command:

claude mcp add --transport http dockhold https://api.dockhold.eu/mcp --header "Authorization: Bearer dh_mcp_live_…"

Only a dashboard token can carry the secrets scope; the browser sign-in from step 2 never has it. With that scope the tool also gets set_app_secret, bind_app_secret, unset_app_secret, list_app_secrets and list_secrets. Values are write-only: no tool ever reads one back. Any value you hand your AI tool has already passed through that tool's own context, so point it at a local .env file rather than typing a real key into the chat, and rotate the key afterward if you did.

Suggested guides
↑↓ to move ↵ to open Esc to close From the Dockhold docs