Composing Agents
You have tool specs from multiple sources — an OpenAPI spec for Zendesk, a natural-language-generated Datadog set — and you want to combine them into a single deployable agent. Thecompose step merges tool specs and generates everything needed to run.
Prerequisites
- One or more Tool Spec YAML files (generated by any Forge path)
- The Svantic CLI installed (
npm install -g @svantic/cli)
Standalone Mode: Full Project Generation
Generate a complete, self-contained agent project:support-bot/ directory with:
| File | Purpose |
|---|---|
server.ts | Express server with all capabilities attached and triggers wired |
.env.template | All required environment variables collected from every tool spec |
package.json | Dependencies (@svantic/sdk, express, etc.) with a start script |
tsconfig.json | TypeScript configuration |
Dockerfile | Multi-stage build for production deployment |
capabilities/ | One .ts file per domain (zendesk, slack, datadog) |
triggers/ | Trigger handlers (webhooks, schedules) if any tool spec defines them |
The generated server
attach() function registers all capabilities on the agent. MeshConnector dials the Svantic edge — one URL, no ingress needed. The agent runs in connected mode by default.
Run it
Embedded Mode: Capabilities Only
Omit--standalone to generate just the capability and trigger files, without the server scaffold:
./src/generated/ so you can import them into an existing agent:
Programmatic Usage
Collision Detection
When composing tools from multiple domains, Forge checks for duplicate tool names. If two specs define a tool with the same name, the CLI reports an error:Resolving collisions
Option 1: Auto-prefix by domainzendesk_create_ticket and jira_create_ticket.
Option 2: Rename specific tools
.tool-spec.yaml files and change the tool name directly, then re-run compose.
Adding a Description
Forge auto-generates an agent description from the combined tool set. Override it:The .env.template
Forge collects everyenv field from every tool spec’s auth section and every trigger’s configuration, then writes a single .env.template:
