Project service
Overview
A project service is one extra container that runs in your project next to the agent, a sidecar for a database, a cache or a tool server. Only your agent can reach it. A common use is an MCP tool server that you don't want on the internet. You manage it on the Services tab of a project, and it starts with the next deploy.
Image
Give a lowercase image reference with a tag or an @sha256 digest, for example ghcr.io/acme/tools:1.2.0. A pinned tag keeps redeploys predictable.
Registry credentials
A public image needs none. For a private registry, add a credential with the registry host, a username and a password or token. The password is stored encrypted and the dashboard never shows it again. A credential that a service uses can't be deleted until you detach it.
Ports
List 1 to 4 ports between 1024 and 55535. Your agent reaches each one through a private port, and nothing is open to the internet.
Health check
We wait for the check to pass before the service counts as started. An HTTP check wants a 2xx answer from a path, a TCP check wants the port to accept a connection. The port must be one of the ports you listed.
Environment and secrets
By default the service gets none of your project's values. You can pick environment keys and secret keys one by one, or choose all. All copies every environment value and secret, including ones you add later. Extra variables are visible to this service only; their names must not start with VT_ or VOICETHERE_.
Resources and pricing
CPU goes from 100 to 1000 millicores and memory from 128 to 1024 MiB. While the service runs it uses 45 credits per hour for each unit, where a unit is one vCPU or one GiB, whichever the service uses more of. The result is rounded up to whole credits per hour. A half vCPU with 512 MiB takes 23 credits per hour. You are billed per minute while the service runs, and each started minute counts in full, so a service that runs 61 seconds is billed 2 minutes (on demand: only while it is up). Running time is measured from samples about once a minute and billed per started minute in 15-minute periods; each period is settled as its own usage line. A run can be billed up to about a minute less than its wall time.
Credits and limits
A project service runs on the same credits as your sessions. On the Free plan the service stops when the credits run out. It starts again when credits are back: an always-on service comes back by itself, an on-demand service at the next call from a session.
On a paid plan with metered overage enabled, the service keeps running after the included credits and packs are used up and is billed as overage. It stops when the organization or project budget limit is reached. On a paid plan without overage, it stops when the credits run out, like on Free.
Usage is settled at the end of each 15-minute period, so a service can run up to about 15 minutes past the limit before it stops. The Services tab shows each service as running, stopped because of credits or the budget, or stopped because it was idle.
Run mode
On demand starts the service when your agent first calls it and stops it after it has been idle for the idle stop time (5 to 120 minutes). Always on keeps it running and is part of the paid plans. The start timeout (30 to 600 seconds) is how long we wait for the health check.
Token
Each service has a token your agent presents to it. Rotate it from the service card. The previous token stays valid for 15 minutes, so redeploy within that time to hand the new one to your agent and the service.
Troubleshooting
When saving fails, the message names the field in brackets. These are the codes behind it. After a save on a deployed project the dashboard shows Redeploy to apply; see Deployment history for how a deploy can fail.
| Code | What it means | What to do |
|---|---|---|
SERVICE_NAME_INVALID | The service name is not allowed. | Use lowercase letters, digits and hyphens, start with a letter and stay under 40 characters. Names such as runner, orchestrator or anything starting with vt- are reserved. |
SERVICE_IMAGE_INVALID | The image reference could not be read. | Use a lowercase reference such as ghcr.io/acme/tools:1.2.0. |
SERVICE_PORT_INVALID | A port name or number is not allowed, or two ports share one. | Use 1 to 4 unique ports between 1024 and 55535 with short names. |
SERVICE_HEALTH_INVALID | The health check does not match your ports. | Point the health check at one of the ports you listed. An HTTP check needs a path that starts with /. |
SERVICE_ENV_INVALID | An extra variable has a name or value that is not allowed. | Use A-Z, 0-9 and _ in names, and don't start them with VT_ or VOICETHERE_. |
SERVICE_RESOURCES_INVALID | CPU, memory, idle stop or start timeout is out of range. | CPU 100 to 1000 millicores, memory 128 to 1024 MiB, idle stop 5 to 120 minutes, start timeout 30 to 600 seconds. |
SERVICE_RUN_MODE_NOT_IN_PLAN | Always on is not part of the project's plan. | Use on demand, or move the project to a paid plan. |
SERVICE_LIMIT_REACHED | The project already runs as many services as its plan allows. | Delete a service you no longer use, or move to a plan with more. |
REGISTRY_CREDENTIAL_NOT_FOUND | The service names a registry credential that doesn't exist. | Pick one from the list or add it first. |
REGISTRY_CREDENTIAL_IN_USE | A service still uses the credential you tried to delete. | Switch the service to another credential or none, then delete it. |
SECRET_REFERENCE_MISSING | The service asks for an environment value or secret that the project doesn't have. | Add the value in Environment and secrets, or untick it in the service. |
SECRET_IN_USE | A service still receives the secret or value you tried to delete. | Remove it from the service first, then delete it. |