WebDeploy MCP
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@WebDeploy MCPdeploy my static site from GitHub main branch"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
WebDeploy MCP
Self-hosted website deployment for people and AI clients. WebDeploy MCP combines a Passkey-protected web dashboard, an OAuth 2.1 MCP endpoint, and a release worker that deploys static sites, frontend builds, Node.js services, and Python web applications without Docker.
The project is server-, IP-, and domain-agnostic. All paths, ports, hostnames, retention limits, and public URLs are installation settings.
Release status: v0.1.0 is the first public release. Test on a non-production server before adopting it for critical workloads.
What it provides
Git, ZIP/TAR, and small inline-file deployments
Custom install, build, output, start, health-check, and runtime settings
Per-project Linux service users and isolated release directories
Atomic static-site symlinks and health-checked dynamic blue/green activation
PM2 process management, Nginx routing, and optional Certbot HTTPS
PostgreSQL-backed jobs, releases, audit events, OAuth state, and encrypted settings
Passkey-only sign-in with administrator approval for every new enrollment
OAuth Authorization Code + PKCE, dynamic client registration, token expiry and revocation
MCP tools for project, deployment, log, release, domain, restart, rollback, and deletion tasks
Dashboard-only environment values encrypted with AES-256-GCM
Interactive install, verified release downloads, backup, restore, update, and uninstall
Related MCP server: CreateOS MCP
Architecture
Browser / MCP client
|
HTTPS + OAuth
|
Nginx reverse proxy
|
Control plane (Fastify)
| | |
Dashboard MCP Passkey/OIDC
\ | /
PostgreSQL
|
privileged worker
/ | \
project UID PM2 Nginx config
|
versioned releases + current symlinkThe control plane is an unprivileged network service. The systemd worker performs the narrowly scoped privileged operations needed to create project users, switch releases, and validate Nginx. See Architecture and Security.
Requirements
Ubuntu 22.04 or 24.04, or Debian 12
x86_64 or arm64
Root access for installation
A DNS name for the Dashboard and MCP endpoint
TCP 80/443 reachable if the installer should request certificates
At least 2 GB RAM and 10 GB free disk for a small installation
The installer provisions Node.js 24, pnpm, PM2, Nginx, Certbot, PostgreSQL, Git, Python, and
mise. Docker and Caddy are neither required nor used.
One-click installation
The review-first method is recommended:
curl -fsSLO https://github.com/ghbhiee/webdeploy-mcp/releases/latest/download/install.sh
curl -fsSLO https://github.com/ghbhiee/webdeploy-mcp/releases/latest/download/SHA256SUMS
sha256sum -c --ignore-missing SHA256SUMS
less install.sh
sudo bash install.shOr run the bootstrap directly:
curl -fsSL https://raw.githubusercontent.com/ghbhiee/webdeploy-mcp/main/install.sh | sudo bashThe interactive installer asks for installation/data paths, Dashboard and MCP domains, internal
port, bootstrap administrator identity, Nginx, HTTPS, ACME email, and automatic updates. It stops
if the selected port or Nginx server_name is already in use.
For unattended installation:
sudo bash install.sh \
--non-interactive \
--dashboard-domain deploy.example.com \
--mcp-domain deploy.example.com \
--admin admin@example.com \
--acme-email admin@example.com \
--auto-updateSubstitute domains and identities with your own values. None are compiled into the project.
First sign-in and Passkey approval
Open the Dashboard URL and register a Passkey with the bootstrap identity.
The page shows a short request code. The Passkey cannot sign in yet.
On the server, review and approve it:
sudo webdeploy auth list-pending
sudo webdeploy auth approve-passkey <request-code>Reject an unexpected request with:
sudo webdeploy auth reject-passkey <request-code>The approved bootstrap identity becomes the first administrator. Later enrollments can also be approved in the Dashboard. Revoking a Passkey revokes its web sessions; disabling a user also invalidates that user's OAuth objects.
Dashboard workflow
Create a project, choose static, node, or python, then configure:
Git repository and branch/tag/commit
install and build commands
static output directory or dynamic start command
preferred internal port and health-check path
Node.js/Python versions, SPA fallback, release retention, and auto deploy
custom domain
plain or secret environment values
Use Deploy now for Git, or upload a ZIP/TAR archive. Deployment progress and redacted logs stream into the project page. Releases can be rolled back; dynamic services can be restarted. The previous release is not stopped until the candidate passes its health check and activates.
Environment values are write-only after submission. Even administrators and MCP clients receive only variable names, type, presence, and timestamps.
MCP clients
The public endpoint is:
https://your-mcp-domain.example/mcpCodex CLI
codex mcp add webdeploy --url https://your-mcp-domain.example/mcp
codex mcp login webdeployThe login command opens the OAuth flow, which requires an approved Passkey. These commands follow the current Codex MCP CLI interface; they are not ChatGPT web commands.
ChatGPT
ChatGPT connections are configured in the ChatGPT web UI, not with codex mcp add. In a workspace
where custom MCP apps are enabled:
Open Settings → Apps & Connectors → Advanced settings and enable developer mode.
Create a custom app/connector and enter the HTTPS MCP URL.
Start OAuth. WebDeploy redirects to its Passkey page.
Sign in with an approved Passkey and approve the requested scopes.
Menu wording and workspace eligibility can change; consult current OpenAI help if the options are not present. Additional clients are covered in MCP clients.
MCP tools
Tool | Purpose |
| Health and authenticated-user summary |
| Accessible projects |
| Project settings and environment metadata |
| Create a project and return its setup URL |
| Deploy configured Git source |
| Deploy a Git URL/ref |
| Deploy up to 100 small files (1 MiB total) |
| Deployment state |
| Redacted build/deploy logs |
| Release history |
| Queue an atomic rollback |
| Restart an active dynamic project |
| Passkey-protected Dashboard URL |
| Configure the primary hostname |
| Queue project removal |
MCP intentionally has no tool that accepts or returns environment values.
Administration
sudo webdeploy users list
sudo webdeploy users disable <user-id>
sudo webdeploy users set-admin <user-id>
sudo webdeploy users remove-admin <user-id>
sudo webdeploy passkeys list <user-id>
sudo webdeploy passkeys revoke <passkey-id>
sudo webdeploy projects list
sudo webdeploy projects restart <project-id>Administrators can see all projects, manage roles and Passkeys, approve enrollment, transfer ownership, and override/delete environment values without reading existing plaintext. Security and role changes are audit logged.
Operations
sudo webdeploy status
sudo webdeploy start
sudo webdeploy stop
sudo webdeploy restart
sudo webdeploy logs
sudo webdeploy doctor
sudo webdeploy backup /secure/path/webdeploy-backup.tar.gz
sudo webdeploy update
sudo webdeploy uninstallbackup contains the database, configuration, encryption key, and signing key. Store it as a
high-value secret. Restore is intentionally interactive:
sudo webdeploy restore /secure/path/webdeploy-backup.tar.gz --confirmTo remove services but preserve data, run sudo webdeploy uninstall. To permanently delete the
database, configuration, and deployment data:
sudo /etc/webdeploy/uninstall.sh --purge-dataNginx, HTTPS, and PM2
The installer writes a new, dedicated Nginx file only after checking for server_name conflicts,
runs nginx -t, and reloads only on success. It never edits an existing virtual host. With
--no-nginx, configure a reverse proxy to the selected loopback control-plane port and disable
buffering for /mcp.
Certbot is optional. If certificate issuance fails, installation remains usable locally and prints the exact retry command after DNS is fixed.
PM2 manages the control plane and dynamic project releases. The worker is a systemd service and reconciles missing active PM2 processes after reboot.
Manual development installation
corepack enable
corepack prepare pnpm@11.10.0 --activate
pnpm install --frozen-lockfile
pnpm build
cp .env.example .env
# Create the PostgreSQL database, master key, and OIDC JWKS, then edit .env.
pnpm migrate
pnpm --filter @webdeploy/control-plane dev
pnpm --filter @webdeploy/worker devFor a production server, use the installer so users, permissions, systemd, PM2, Nginx, secrets, and backup/update scripts are installed consistently.
Testing
pnpm lint
pnpm typecheck
pnpm build
pnpm test
TEST_DATABASE_URL=postgresql://... pnpm test
pnpm exec playwright install chromium
pnpm test:e2eGitHub Actions runs lint, type checks, builds, PostgreSQL integration tests, Passkey/OAuth/MCP browser tests, and shell syntax checks on Ubuntu.
Troubleshooting
Passkey says pending: run
sudo webdeploy auth list-pending, then approve its request code.OAuth callback fails: verify the Dashboard/MCP public URLs and reverse-proxy scheme/host.
Deployment cannot start: check
sudo webdeploy doctor, deployment logs, start command, and that the app listens on injectedHOST=127.0.0.1andPORT.Health check fails: the candidate is removed and the old release remains active. Correct the path or application and redeploy.
Nginx conflict: remove or rename the existing
server_name; the installer will not overwrite it.Certificate failure: confirm DNS and inbound 80/443, then run the printed
certbot --nginxcommand.Private Git: use an SSH URL and install a read-only deploy key for the project's isolated Linux user. Never put credentials in a Git URL.
See Deployment and operations for details.
Known limitations in v0.1.0
Linux deployment execution is supported only on the listed Ubuntu/Debian versions.
Private Git key enrollment is an administrator-run server step; the Dashboard does not upload private keys.
The generic webhook signs canonical compact JSON as documented in Webhooks; provider-specific webhook adapters are not included.
Certificate renewal is delegated to the distribution's Certbot systemd timer.
Multi-node control planes and remote workers are not supported.
Contributing and license
See CONTRIBUTING.md and SECURITY.md. Licensed under Apache-2.0.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/ghbhiee/webdeploy-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server