Everything an AI agent needs to provision and operate infrastructure on Lookerhost. Machine-readable copy at /docs/mcp.md.
LookerHost is a cloud hosting platform: Cloud VPS, Web Hosting with a control panel, an App Platform that builds and runs web apps straight from a Git repository, managed databases and managed WordPress.
LookerHost is not a Git hosting service. It is not GitHub, Gitea or Forgejo.
Your code stays where it is; LookerHost clones it, builds it and serves it. Never
add a Git remote pointing at lookerhost.com — there is nothing to push to.
Everything a customer can do in the dashboard is also available over a REST API, and that API is wrapped by an MCP server so an AI agent can provision and operate infrastructure directly, with no manual steps.
Sign in at lookerhost.com/dashboard → Settings → API keys → Create key. Pick a name and the scopes the integration needs.
The secret (lh_live_…) is shown once, at creation. If it is lost, revoke the
key and issue a new one — it cannot be recovered.
The account must be linked to a company. Operator (admin) accounts do not issue customer keys; they issue platform keys from Integrations, which span the whole platform instead of one customer.
Create a file named .mcp.json — with a leading dot — at the root of your
project:
{
"mcpServers": {
"lookerhost": {
"command": "npx",
"args": ["-y", "lookerhost-mcp-server@latest"],
"env": {
"LOOKERHOST_API_URL": "https://api.lookerhost.com",
"LOOKERHOST_API_KEY": "lh_live_..."
}
}
}
}
The most common failure by far: naming the file
mcp.jsoninstead of.mcp.json. No MCP client reads a file without the leading dot, so the agent starts with no LookerHost tools at all and reports that it has never heard of LookerHost. Check the filename first.
With the Claude Code CLI the same thing can be done in one command:
claude mcp add lookerhost --env LOOKERHOST_API_URL=https://api.lookerhost.com --env LOOKERHOST_API_KEY=lh_live_... -- npx -y lookerhost-mcp-server@latest
For Claude Desktop, the same mcpServers block goes into
claude_desktop_config.json.
OpenAI Codex (CLI and the ChatGPT desktop app) reads ~/.codex/config.toml:
[mcp_servers.lookerhost]
command = "npx"
args = ["-y", "lookerhost-mcp-server@latest"]
[mcp_servers.lookerhost.env]
LOOKERHOST_API_URL = "https://api.lookerhost.com"
LOOKERHOST_API_KEY = "lh_live_..."
pnpm users can replace npx -y with pnpm dlx in any of the blocks above
("command": "pnpm", "args": ["dlx", "lookerhost-mcp-server@latest"]), or
install it once with pnpm add -g lookerhost-mcp-server and use
"command": "lookerhost-mcp-server" with no args. Gemini CLI reads the same
mcpServers JSON from ~/.gemini/settings.json.
The npm package is
lookerhost-mcp-server.
Pinning @latest matters: npx will otherwise reuse whatever version it cached
earlier, which is why an agent may insist the server is out of date.
Restart the agent and ask it to list your services. It should call
lookerhost_list_services. If it answers that it has no such tool: the config
file name or location is wrong. If it answers invalid-token: the key is wrong,
revoked or expired.
The MCP server authenticates with the API key as a bearer token
(Authorization: Bearer lh_live_…). A key is bound to one customer account
and to a set of scopes, so the agent only ever sees and operates that account’s
services. Anything the key does not allow is rejected with insufficient-scope,
and the response names the missing scope under need.
| Scope | Grants |
|---|---|
vps:read |
Read anything in the account: services, detail, live metrics and disk usage, catalog and plans, activity, deploy history, backups, invoices, app logs. Every GET of the customer portal requires it — a key without vps:read cannot read at all |
vps:write |
Create VPS and Web Hosting; install SSH public keys into a VPS |
vps:power |
Start, stop, restart any service |
apps:write |
Deploy and redeploy apps, create databases and WordPress sites, manage repository deploy keys |
service:delete |
Permanently delete a service — irreversible |
agent:run |
Run a coding agent inside the account’s own VPS over SSH, approve or deny its actions, continue the conversation, abort. In auto mode the agent changes the server without review — the most powerful scope after service:delete; off by default when creating a key |
Forty-two tools, and the REST endpoint each one calls.
| Tool | Scope | Endpoint | What it does |
|---|---|---|---|
lookerhost_list_services |
vps:read |
GET /api/services |
Every service in the account: VPS, web hosting, apps, databases, WordPress |
lookerhost_get_service |
vps:read |
GET /api/services/:id |
Full detail of one service |
lookerhost_get_metrics |
vps:read |
GET /api/services/:id/metrics |
Live CPU, RAM, network and disk of a VPS (VPS only) |
lookerhost_list_plans |
vps:read |
GET /api/services/plans |
Catalog: VPS plans, OS images, database kinds, WordPress variants, plus the account’s quota and usage |
lookerhost_get_activity |
vps:read |
GET /api/services/activity |
Audit log, per service or account-wide |
lookerhost_get_deploy_history |
vps:read |
GET /api/services/:id/paas/deploy-history |
Deploys of an app, newest first, with build logs of failed attempts |
lookerhost_repo_access |
vps:read |
GET /api/services/:id/repository-access |
Which credential clones the app’s repo: public, github-app, deploy-key or none |
lookerhost_create_vps |
vps:write |
POST /api/services |
Create a VPS |
lookerhost_create_webhosting |
vps:write |
POST /api/services/webhosting |
Create Web Hosting (CloudPanel preinstalled) |
lookerhost_add_ssh_key |
vps:write |
POST /api/services/:id/vps/ssh-keys |
Install an SSH public key into a VPS |
lookerhost_list_ssh_keys |
vps:read |
GET /api/services/:id/vps/ssh-keys |
List a VPS user’s authorized keys |
lookerhost_generate_ssh_key |
vps:write |
POST /api/services/:id/vps/ssh-keys/generate |
Generate a key pair, install it and return the private key once |
lookerhost_remove_ssh_key |
vps:write |
DELETE /api/services/:id/vps/ssh-keys |
Remove a key (confirm: true) |
lookerhost_set_vps_password |
vps:write |
POST /api/services/:id/vps/password |
Set a user password, optionally allow SSH passwords (confirm: true) |
lookerhost_list_port_forwards |
vps:read |
GET /api/services/:id/portforwards |
List the public ports mapped to a VPS |
lookerhost_open_port |
vps:write |
POST /api/services/:id/portforwards |
Open a public port to a VPS port (confirm: true; pending approval unless trusted) |
lookerhost_close_port |
vps:write |
DELETE /api/services/:id/portforwards/:pfId |
Release a port-forward (confirm: true) |
lookerhost_deploy_app |
apps:write |
POST /api/services/apps |
Create and deploy an app from a Git repository |
lookerhost_redeploy_app |
apps:write |
POST /api/services/:id/paas/deploy |
Redeploy an existing app (or restart a catalog AI app). Returns deployId to poll |
lookerhost_get_deploy |
vps:read |
GET /api/services/:id/paas/deploys/:deployId |
How one deployment ended (latest accepted). On failure it carries errorCode, a one-line reason and the fix |
lookerhost_rollback_app |
apps:write |
POST /api/services/:id/paas/rollback |
Return to a previous version. Edge apps only (static sites and workers), restoring the stored artifact; container apps answer rollback-not-supported |
lookerhost_repo_deploy_key |
apps:write |
POST /api/services/:id/repository-access/deploy-key |
Generate a read-only deploy key for a private repo |
lookerhost_create_database |
apps:write |
POST /api/services/databases |
Managed PostgreSQL, MySQL, MongoDB or Redis |
lookerhost_create_redis |
apps:write |
POST /api/services/redis |
Dedicated Redis instance in Docker: own endpoint, ACL username/password and IP allow-list. Born CLOSED: no allowed IPs, no public endpoint |
lookerhost_get_redis |
vps:read |
GET /api/services/:id/redis |
Configuration, endpoint, allow-list and live container state. Never returns the password |
lookerhost_redis_connection |
apps:write |
GET /api/services/:id/redis/connection |
Username, password and full redis:// URI. Only way to recover the password after creation; every call is audited |
lookerhost_redis_allowed_ips |
apps:write |
PUT /api/services/:id/redis/allowed-ips |
Replace the list of IPs/CIDRs allowed to connect. Widening needs confirm: true; an empty list closes the endpoint |
lookerhost_update_redis |
apps:write |
PATCH /api/services/:id/redis |
Version, ACL username, memory cap, eviction policy or persistence. Recreates the container; data survives |
lookerhost_redis_password |
apps:write |
POST /api/services/:id/redis/password |
Rotate the ACL user’s password (confirm: true): cuts every connection using the old one |
lookerhost_create_wordpress |
apps:write |
POST /api/services/wordpress |
Managed WordPress site, database included |
lookerhost_create_aiapp |
apps:write |
POST /api/services/aiapps |
One-click AI app: n8n, Hermes Agent, OpenClaw or Steel Browser |
lookerhost_app_volumes |
apps:write (list: vps:read) |
GET/POST/DELETE /api/services/:id/paas/volumes |
List, add or remove a PaaS app’s persistent volumes — without one, every redeploy loses anything written to disk. Removing needs confirm: true |
lookerhost_agent_chat |
apps:write |
POST /api/services/:id/aiapp/api |
Chat with the account’s Hermes Agent through its OpenAI-compatible API, reached over LookerHost’s internal network (the agent’s API is never exposed to the internet directly). api_key is the app’s own API_SERVER_KEY |
lookerhost_aiapp_api |
apps:write (GET: vps:read) |
POST /api/services/:id/aiapp/api |
Allow-listed call to an AI app’s API — Hermes runs/jobs, Steel Browser sessions and scraping |
lookerhost_browser_session |
apps:write |
POST /api/services/:id/aiapp/api |
Create, list, get or release a session on the account’s Steel Browser app — returns a CDP endpoint for Playwright/Puppeteer |
lookerhost_browser_scrape |
apps:write |
POST /api/services/:id/aiapp/api |
Render and extract a web page (markdown, HTML or readability) with the account’s own Steel Browser, no session bookkeeping needed |
lookerhost_power_service |
vps:power |
POST /api/services/:id/power |
Start, stop or restart any service |
lookerhost_delete_service |
service:delete |
DELETE /api/services/:id |
Delete a service permanently — also requires confirm: true |
lookerhost_run_agent |
agent:run |
POST /api/agent/jobs |
Start an autonomous coding/ops agent inside one VPS from a natural-language task (like Claude Code logged into the server). approval_mode: write-approval (default), auto (needs confirm: true), manual |
lookerhost_agent_job |
agent:run |
GET /api/agent/jobs/:id |
Status, transcript tail, pending approvals and final result of a job |
lookerhost_list_agent_jobs |
agent:run |
GET /api/agent/jobs |
Jobs of the account, optionally per VPS |
lookerhost_agent_approve |
agent:run |
POST /api/agent/jobs/:id/approval |
Allow (confirm: true) or deny one command or file write the agent asked for |
lookerhost_agent_message |
agent:run |
POST /api/agent/jobs/:id/message |
Follow-up instruction or files for a finished job; the agent resumes with full context |
lookerhost_agent_abort |
agent:run |
POST /api/agent/jobs/:id/abort |
Stop a running job (confirm: true) |
Provisioning is asynchronous. Creating a VPS returns it with status
provisioning; poll lookerhost_get_service until it reads running, typically
one to three minutes. The first app of an account also provisions its Docker
host, so that first deploy is noticeably slower.
lookerhost_deploy_app takes a build pack:
nixpacks — auto-detects Astro, Next.js, React, Vue, Svelte, Node.js,
Python, Go, Rust and PHP. Use it for anything that runs a server; pass the port
it listens on.static — builds and serves static output such as Astro’s dist/ or a
Vite build.dockerfile — builds from the repository’s Dockerfile.dockercompose — builds from the repository’s compose file.opennextjs-cloudflare — a Next.js project using @opennextjs/cloudflare,
built in an isolated VM and served as a Cloudflare Worker instead of getting its
own VM.Nothing LookerHost-specific has to be committed to the repository.
Public repositories need only their URL. For a private repository, call
lookerhost_repo_deploy_key to get a read-only public key and add it on GitHub
under Settings → Deploy keys, leaving Allow write access unchecked. The
private half stays encrypted on the platform and is never shown.
lookerhost_repo_access reports which credential is in play — a build that fails
with repository-credential-missing means the repository is private and no
credential covers it.
The MCP server is a convenience wrapper; the same key works directly.
curl -s https://api.lookerhost.com/api/services \
-H "Authorization: Bearer lh_live_..."
curl -s https://api.lookerhost.com/api/services/apps \
-H "Authorization: Bearer lh_live_..." \
-H "Content-Type: application/json" \
-d '{"label":"my-site","repoUrl":"https://github.com/acme/my-site","branch":"main","buildPack":"static","static":true}'
Every failure returns JSON with an error code. The ones worth handling:
| Code | Meaning |
|---|---|
no-token |
No key was sent — check LOOKERHOST_API_KEY |
invalid-token |
Key is invalid, revoked or expired |
insufficient-scope |
The key lacks a scope; need names it. Re-issue with that scope |
no-customer |
The key’s user is not linked to a company |
account-not-active |
Account pending or suspended: read-only until staff activates it |
quota-exceeded |
Account hit its service quota |
no-docker-host |
No PaaS Docker host yet; deploying an app provisions one |
protected |
Adopted VM, protected from self-service deletion |
rate-limited |
Too many requests; wait a few minutes |
timeout |
The call timed out but the operation may still be running — check with lookerhost_get_service before retrying |
For agents that need to discover all of this on their own:
https://api.lookerhost.com/ — JSON index of the APIhttps://api.lookerhost.com/.well-known/mcp.json — the MCP catalog: tools,
scopes, endpoints, errors, ready-to-paste client confighttps://api.lookerhost.com/llms.txt — the same map in plain texthttps://lookerhost.com/llms.txt — product-level summary of the platformhttps://lookerhost.com/docs/mcp.md — this page as raw markdownThe manifest at /.well-known/mcp.json is the source of truth for the tool list.
Email support@lookerhost.com, or open an issue at github.com/Cloudcity-Colombia/lookerhost.