Skip to main content
An agent service runs your agent as its own process, independent of the app server. Use it when you need a separate process boundary, direct control-plane registration, remote MCP tools, or service-level telemetry. Use a normal in-app route for everything else. Veryfront Cloud can invoke a push runtime directly against an agent service, which is the main reason to deploy one even when the app and the agent share a host. Shared and managed dedicated servers use the framework-owned veryfront serve runtime instead. That runtime discovers all project agents and tools, then routes each signed control-plane request by agentId. Projects on a managed dedicated server do not require a service.ts entrypoint. Add one only when you intentionally run the standalone Agent Service process described in this guide.

Prerequisites

  • At least one agent in agents/ that the service should expose (see Agents).
  • A deployment target you can run a long-running Node process on.
  • For Veryfront Cloud registration: VERYFRONT_API_TOKEN, VERYFRONT_PROJECT_ID or VERYFRONT_PROJECT_SLUG, and a publicly reachable VERYFRONT_AGENT_SERVICE_URL. See Configuration for the full list.
  • Immutable deployment metadata for runtimeSource when the control plane invokes the service.

Create a service entrypoint

Create a process entrypoint that starts the default Veryfront Cloud agent service runtime:
The bootstrap discovers the same project primitives as the app runtime:
  • agents/
  • tools/
  • skills/
  • resources/
  • prompts/
  • workflows/
  • tasks/
When exactly one code or markdown agent is discovered, that agent becomes the default for direct /api/runs requests. Pass agentId when the service exposes multiple agents and direct requests need a predictable default.

Keep agent behavior in project files

Define the agent in agents/ and keep service startup separate from agent behavior:
Markdown agents use the file path as the agent id:
For non-standard project layouts, configure discovery paths in veryfront.config.ts under ai.<primitive>.discovery.paths.

Configure registration

Control-plane registration is convention-first. In auto mode, the service registers only when VERYFRONT_API_TOKEN and VERYFRONT_AGENT_SERVICE_URL are present. Registration also requires the immutable runtimeSource binding described below.
Use VERYFRONT_AGENT_SERVICE_REGISTRATION=enabled when startup must fail if the service cannot register. Use disabled when the service must run without control-plane registration. The service name resolves from VERYFRONT_AGENT_SERVICE_NAME, then the nearest package.json or deno.json name, then veryfront-agent-service. Pass serviceName only when code should override that convention.

Bind control-plane runs to the deployed source

A standalone agent service discovers one local project snapshot at startup. It cannot select another project branch or release for an individual request. Bind the service to deployment-owned immutable metadata when it accepts signed control-plane runtime invocations:
The service accepts a control-plane invocation only when its agentSource exactly matches runtimeSource. An unbound service returns CONTROL_PLANE_AGENT_SOURCE_UNBOUND. A different release or environment returns CONTROL_PLANE_AGENT_SOURCE_MISMATCH. Branch sources are mutable and return CONTROL_PLANE_AGENT_SOURCE_UNSUPPORTED. Do not resolve runtimeSource from the latest deployment at request time. Pass the environment and release identifiers that produced the running service artifact. Direct /api/runs requests do not select project source and do not require this binding.

Add remote MCP tools

Use mcpServers when the service needs remote tools. Use veryfrontApiMcpServer() and veryfrontStudioMcpServer() for Veryfront-owned control-plane MCP servers and normal MCP server config objects for third-party servers. This service startup config uses endpoint and headers. Per-agent config in agent({ mcpServers }) uses transport, auth, and toolPolicy.
If mcpServers is omitted, the Veryfront Cloud preset includes veryfrontApiMcpServer() by default. Pass mcpServers: [] to run without remote MCP tools.

Reach trusted deployment-local MCP servers

The default remote MCP source uses guarded outbound networking. Keep that default for third-party, request-derived, and tenant-configured endpoints. A separately deployed agent service may need to reach a trusted MCP server on a private cluster address. In that case, capture the host transport and the exact allowed endpoints once at startup. Use the host transport only for those immutable endpoints and preserve the guarded source for everything else:
The framework rejects invalid allowlist entries at startup and uses the host transport only for an exact normalized URL match. Unmatched, invalid, and resolver-based endpoints retain guarded outbound networking. http: is appropriate only for private deployment-local networking; use https: for public networks. Never put a callback endpoint or a per-request URL in the trusted endpoint list.

Refresh runtime state

Use resolveRuntimeState when a long-lived service run must refresh instructions, context, or available tools at a model step boundary.
Services that use Veryfront Cloud project steering can reuse fetchDefaultAgentServiceProjectSteering() for the initial fetch and createDefaultAgentServiceProjectSteeringRefresh() for step-boundary refresh.

Use lower-level helpers

Use startAgentService() for the standard service shape. Use lower-level helpers only when the service needs a custom server adapter, custom execution preparation, or custom infrastructure.

Migrate custom durable child event writers

This migration applies to custom hosted runtimes that call the lower-level durable child helpers. Framework-managed startAgentService() runtimes create and scope writer capabilities internally. Raw authToken, apiUrl, and runEventAppendToken fields no longer grant durable child event-writer authority. The parsed hosted request also excludes the writer credential. Keep the credential inside trusted ingress and replace the removed fields with an opaque HostedRunEventWriterCapability. Apply the change at every integration point your custom runtime implements: The generated veryfront/agent reference lists the complete properties for these contracts.
  1. After trusted ingress verifies an exact root-run append credential, create the root capability. Do not pass a general user API token.
  2. Pass that exact-parent capability to helpers that own child persistence and capability delegation. Do not pre-mint for these helpers.
  3. For lower-level helpers that receive an already-persisted durableChildRun, mint and pass an exact-child capability:
  4. Update detached starter callbacks to accept the isolated request:
A durable execution without authority bound to the expected run fails before provider dispatch. Token exchange failures are bounded, sanitized, and fail closed; callers must not retry by falling back to a user API token.

Verify it worked

Start the service entrypoint and call the run route directly. The default port is 3001; override with PORT if needed.
A working service streams AG-UI events back. If Veryfront Cloud registration is enabled, the service should also appear in the cloud dashboard’s agent service list after the first heartbeat (VERYFRONT_AGENT_SERVICE_HEARTBEAT_INTERVAL_MS).