Before you start
Use Node 22.18 or later and a project from the quickstart. Install its locked dependencies withnpm ci. Keep agent/, src/ and the package files in the deployed application;
TypeScript source runs directly on Node.
Start a production process
- MCP server
- Messaging agent
The starter’s Start it with:Put a TLS reverse proxy or load balancer in front of the process. Preserve the MCP paths and
OAuth discovery routes, and allow streaming responses. Connect remote hosts to
npm run mcp binds to loopback for local development. Add this entry point to
listen on the container or server’s network interface:src/serve-mcp.ts
Terminal
https://your-domain.example/mcp; plugins use /mcp/plugin.Add the MCP authentication configuration before exposing
account data. A public listener is not an authentication boundary.curl http://127.0.0.1:8080/health returns ok. Then make a real tool request
or send a test message; a healthy listener alone does not prove the integration works.
Persist conversations
Messaging state includes history, pending messages, background tools, scheduled messages and the agent’s own records. The default database is in memory and is lost on restart.
With a custom
buildAgent, pass the database through host: options.host to createAgent,
as the starter does. Here is a Postgres host configuration fragment; pool is your application’s
node-postgres pool:
Postgres host configuration
await agent.resume() before accepting messages with a durable database. Cut-off turns run
again; a tool that was running is reported as interrupted rather than silently executed again.
Pass
context.idempotencyKey through to your backend’s idempotency mechanism for writes. Flow
supplies the same key for the same tool input in a retried turn; your backend enforces one write.Handle retries and restarts
Pass the provider’s message id asmessageId to agent.message(). A retried webhook with that id
is handled once. Ids are kept for seven days by default (keepMessageIdsDays). Flow Messaging’s
adapter supplies these ids for you.
Run one steady-state messaging instance per database, kept warm with CPU available for timers.
Conversation leases protect deployment overlap; a dead copy’s lease expires after 15 seconds.
They are not a substitute for verifying multi-instance steady-state operation.
Keep the process under a supervisor, retain logs and alert when its messaging stream stops.
On release, stop routing new work to the old process and allow active work to finish before
termination. agent.status() reports activity and idle time.
Production checklist
- Store secrets in your hosting platform’s secret store; never bake
.envinto an image. - Use live messaging senders for real customers, not shared trial numbers.
- Keep the local playground private; the entry points above do not serve it.
- Back up the database and test restoring it. Never share a SQLite file across machines.
- Exercise restart recovery, a retried webhook and a slow tool before sending customer traffic.
Inspect traces
Connect runtime events to your observability system.
Deploy on Flow instead
Let Flow supply the host and durable store.