Container services
Run a personal web application from a public container image on ClosedMCP. Use this for an existing HTTP application with its own editor or UI. Use Serverless MCPs when publishing MCP tools from source code. A container service does not automatically become an MCP tool or receive a user's connected-account tokens.
Create and open an app
In the console, open Container services, choose or create a project, enter a service name, image version and HTTP port, then review and create. ClosedMCP resolves the image to an immutable digest. The app receives a stable private HTTPS URL. Open app signs the owner in on a separate app domain; copying its URL does not grant someone else access.
The image must run as a non-root user (UID 1000 by default), listen on 0.0.0.0 at the configured port, and work with a read-only root filesystem. /tmp is temporary writable memory. The HTTP port can be 1024 through 65535. A readiness check requests / and expects HTTP 200–399. There is no public TCP, SSH, UDP, host networking or Docker socket.
Agent workflow
Start with closedmcp_services and check runtime_enabled. If false, explain that this installation cannot run containers yet. You may prepare or edit a configuration if the user wants, but do not request keys, promise startup, or keep polling for readiness. The platform operator must enable the runtime first. Plans and service status repeat this field. A true value means a runtime is configured; only the service's ready state confirms its current revision passed its runtime check.
Find a project using closedmcp_projects, or create one with closedmcp_create_project. The signed-in human must own it and have deployment permission. Plan before applying:
{
"project": "PROJECT_ID_FROM_THE_TOOL",
"name": "my-web-app",
"config": {
"image": "docker.io/traefik/whoami:v1.11.0",
"port": 8080,
"environment": { "WHOAMI_PORT_NUMBER": "8080" }
}
}Send that object to closedmcp_service_plan. Show the image, port, internet destinations, storage and restart impact to the user. Call closedmcp_service_apply with {"plan":"RETURNED_PLAN_ID"}. A plan lasts 15 minutes. Repeating apply with the same plan recovers the same operation; do not create a replacement service because a request timed out.
Call closedmcp_services with {"service":"RETURNED_SERVICE_ID"} to read state. ready means the current revision passed its runtime check. needs_setup requires the owner to approve keys. blocked, failed and waiting_capacity include a safe explanation. Poll status at a reasonable interval, such as five seconds, while an operation is pending. List services with {}; paginate with after set to the last returned ID.
Private key setup
Declare environment names, for example "keys":["GITHUB_TOKEN"], in the configuration. Call closedmcp_service_setup_link with the service ID and give its returned link to the user. The link opens the console and requires login as the original owner in the correct workspace. The owner reviews the exact image and enters the values there. Never ask for credentials in chat, put them in public environment settings, or pass them through an MCP tool.
The link is single use, lasts 30 minutes and is bound to the service revision. An expired or stale link cannot change keys: request a new one. Reads reveal only whether each key is saved. Values are encrypted at rest and delivered only to the approved revision as environment variables. The application can read those values. ClosedMCP does not make an untrusted image safe to receive a sensitive credential; the owner must choose an appropriate credential and image.
Every configuration edit requires fresh key approval if the service declares keys. A saved value can be retained by leaving its field blank. Removing a key from the configuration prevents delivery to later revisions. Updating keys restarts the app. Project transfers never transfer keys or browser access.
Edit a port or image
Open the service, change HTTP port or image, review, and apply. The URL remains the same. The app restarts and brief downtime is expected. Port configuration describes where the gateway connects; it does not reconfigure the application itself. If the application uses a setting such as PORT, change that public setting too.
Agents first read the current configuration and generation, then plan with the same project and name, the complete new configuration and expected_generation set to that generation. A concurrent edit rejects the stale plan. Read status again before preparing a new plan. Use the old immutable image digest in a new plan to roll back an image; data migrations are not automatically undone.
Internet access and storage
Internet access is off by default. Add exact public HTTPS hostnames to https_hosts, such as api.github.com. The app must honor HTTPS_PROXY; ClosedMCP supplies authenticated proxy settings. Direct networking and DNS are blocked. Redirects to another host need that host declared too. Git/SSH, arbitrary TCP and applications that bypass the proxy are unsupported. Native third-party credentials still have to be entered/configured for that application; a GitHub connection in ClosedMCP is not automatically an n8n credential.
Optional volume has path and size_gib (1–10). Persistent storage starts only on an installation whose operator has qualified capacity enforcement and exclusive single-writer mounts. The default local-path provisioner is rejected. Without qualified storage the service is visibly blocked; temporary storage is never substituted. Existing volume paths and sizes cannot be edited. Stateful applications such as n8n require a separate image and storage qualification before use.
Stop and delete
closedmcp_service_stop takes a service ID and revokes browser and proxy access immediately; existing streams are rechecked within five seconds. The process then shuts down. Editing and applying its configuration restarts it, with fresh key approval when applicable.
closedmcp_service_delete additionally requires confirm_name equal to the exact service name. It removes runtime access and key delivery. Persistent data is retained for operator recovery; self-service restore and purge are not implemented. A deleted name cannot be reused in the same project. Never report deployment or deletion complete until status confirms it.
Current limits
- One container and one HTTP port per service; one replica, no automatic scale-out.
- Public Docker Hub and GHCR images only, with an explicit version or digest. No private registry credentials.
- Ten active services per owner. Each reserves 512 MiB memory and has a one-CPU limit; startup can wait for worker capacity.
- Owner-only browser access, sessions up to one hour, uploads up to 8 MiB. HTTP streaming and WebSockets are supported; web/service workers are disabled to prevent a previous image intercepting later sign-in.
- No public webhooks, shared app access, custom commands, raw application logs, private network access or automatic downstream-account delegation in this version.
- Runtime availability is installation-specific. A saved plan does not prove that the installation has enabled or qualified deployment.
For AI agents: this page as markdown is at /docs/container-services.md, and the closedmcp_guide tool returns it with topic services.