Create a new Agent Builder. If any options are missing, the default will be applied:
forestServerUrl: 'https://api.forestadmin.com',
logger: (level, data) => console.error(level, data),
prefix: 'api/v1',
schemaPath: '.forestadmin-schema.json',
permissionsCacheDurationInSeconds: 15 * 60,
options
ProtectedcustomizationProtectedcustomizerProtectednocodeProtectedoptionsProtected ReadonlyprefixProtectedschemaOptionalstandaloneServe a BFF in-process, alongside the agent, at /bff — no second deployment, no second port.
The agent builds it on start(), stops it on stop(), and hands it a dispatcher that reaches its
own stack without a socket, so this works the same on every mount target.
Requires the @forestadmin/agent-bff package to be installed:
npm install @forestadmin/agent-bff
The secrets, the Forest urls and the logger are inherited from the agent. Everything left is
a feature the BFF switches on when configured: tokenEncryptionKey enables OAuth (and with it
the AI relay), allowedOrigins enables browser access, openapiEnabled serves the docs.
Optionaloptions: BffEmbedOptionsembedded BFF options
the agent instance for chaining
Create a new API chart
name of the chart
definition of the chart
Add a datasource
the datasource to add
Optionaloptions: DataSourceOptionsthe options
Run a workflow executor in-process, alongside the agent. The agent boots it on start(),
stops it on stop(), and proxies /_internal/executor/* to it — no separate deployment.
Requires the @forestadmin/workflow-executor package to be installed:
npm install @forestadmin/workflow-executor
The executor persists run state in a database: provide database, or set the DATABASE_URL
environment variable. Mutually exclusive with the workflowExecutorUrl option, which targets
a separately-deployed executor instead.
Optionaloptions: WorkflowExecutorEmbedOptionsembedded executor options
the agent instance for chaining
Allow to interact with a decorated collection
the name of the collection to manipulate
a function that provide a collection builder on the given collection name
Generate the schema (and typings, when typingsPath is set) and write them
to disk without starting the agent or sending the schema to Forest Admin servers.
Useful in a CI/CD pipeline to produce .forestadmin-schema.json at build time,
so it can be shipped with the deployed code instead of committed.
Note: when experimental no-code customizations are enabled, this still fetches their configuration from the Forest API so the generated schema includes them, which requires connectivity to Forest.
Note: when auditTrail is configured, its hooks are not installed here, so the audit
database is never connected to or migrated — only the collection structure is needed to
generate the schema.
Unlike start(), this always rebuilds the schema — even when isProduction is
true — and writes the typings whenever typingsPath is set, regardless of
isProduction.
Like the rest of the agent, this does not own the data source connection
lifecycle: a data source that opens a connection pool stays open after this
resolves. In a one-shot script, close your data source (or call
process.exit()) once it returns so the process can exit.
ProtectedgetDispatcher that runs agent-client requests against the agent's own /forest stack in-memory.
The handler is rebuilt on every (re)mount so a captured reference never goes stale.
ProtectedgetProtectedmountEnable MCP (Model Context Protocol) server support. This allows AI assistants to interact with your Forest Admin data.
Tool calls reach your data in-process (no socket), so they skip any host-app middleware you mounted in front of the agent (rate limiting, request logging, WAF). The agent's own JWT auth and permission checks still run on them, and the inbound MCP request itself is unaffected.
Optionaloptions: {agent.mountAiMcpServer();
// Example: read-only mode (only browse data, no create/update/delete/actions)
agent.mountAiMcpServer({ enabledTools: ['describeCollection', 'list', 'listRelated'] });
// Example: scope MCP routes under a prefix to avoid colliding with your app's own OAuth routes.
// OAuth discovery metadata stays at the origin root (prefix-suffixed), so root `.well-known`
// traffic must still reach the agent.
agent.mountAiMcpServer({ basePath: '/ai' });
// Example: shorten the OAuth token lifetimes. `accessTokenSeconds` cannot exceed the 1h Forest
// grants; `refreshTokenSeconds` bounds the time between two interactive logins, which is
// otherwise unbounded since Forest re-grants its refresh lifetime on every refresh.
agent.mountAiMcpServer({ tokenTtl: { accessTokenSeconds: 900, refreshTokenSeconds: 86400 } });
// Example: only accept approved OAuth client applications, matched by the domain of their
// registered redirect URIs (subdomains included). Other clients get invalid_client.
agent.mountAiMcpServer({ allowedOAuthClients: ['dust.tt'] });
// Example: action File fields work over MCP out of the box, with the files held in memory.
// Experimental. Point them at a real backend when one instance is not enough, or pass
// false to turn the feature off.
agent.mountAiMcpServer({ fileUploads: { storage } });
agent.mountAiMcpServer({ fileUploads: false });
Mount the agent on an express app.
instance of the express app or router.
Mount the agent on a fastify app
instance of the fastify app, or of a fastify context
Mount the agent on a koa app
instance of a koa app or a koa Router.
Mount the agent on a NestJS app
instance of a NestJS application
Expose the agent on a given port and host
Optionalport: numberport that should be used, defaults to 3351 or to the PORT environment variable.
O will be set a random available port and the port will be available in the standaloneServerPort property.
Optionalhost: stringhost that should be used, default to the unspecified IPv6 address (::) when IPv6 is available, or the unspecified IPv4 address (0.0.0.0) otherwise.
ProtectedremountRemove collections from the exported schema (they will still be usable within the agent).
the collections to remove
Restart the agent at runtime (remount routes).
ProtectedsendProtectedsetServe an embedded BFF at /bff. Pass null to stop answering there.
ProtectedsetRegister the MCP server at the root of the host application, or null to unregister it. The
matcher comes with the callback: there is no default pattern set, so nothing can claim host
urls by accident. Call this before mount() or remount().
Start the agent.
Stop the agent.
Update the typings files generated from your datasources
the path at which to write the new file
the max depth of relation typings
Allow to create a new Forest Admin agent from scratch. Builds the application by composing and configuring all the collection decorators.
Minimal code to add a datasource
Example