Agent infrastructure as code

Define AI agents as versioned configuration. Deploy idempotently. Diff against live state. Roll back to any prior version. No more snowflake agents.

View on GitHub How It Works
$npm install -g @forge-ai/cli
How It Works

Terraform-style plan/apply for AI agents

Declare your agent in a forge.yaml file. Forge handles the rest.

01

Define

Write a forge.yaml describing your agent's model, tools, memory, and MCP servers.

02

Validate

forge validate checks your config against the schema. Catches errors before deploy.

03

Plan

forge diff shows exactly what would change. Creates, updates, deletes — all visible.

04

Apply

forge deploy applies changes idempotently. Same config twice = no-op. State is tracked via SHA-256 hash.

Terminalshell
$ forge deploy --env production → Agent: support-triage | Environment: production | Model: anthropic/claude-sonnet-4-5 Resources to CREATE: + Create agent "support-triage" + Configure model anthropic/claude-sonnet-4-5 + Add MCP server "filesystem" + Add MCP server "brave-search" Plan: 4 to add, 0 to change, 0 to destroy. ✓ Successfully deployed "support-triage" to production State written to .forge/state.json Config hash: 84ef0d1ddb5f... $ forge deploy --env production → Agent: support-triage | Environment: production No changes. Infrastructure is up to date. Agent "support-triage" is up to date (hash: 84ef0d1d)
Configuration

One file describes your entire agent

Model, tools, memory, environments, and deploy hooks — all in one place, version-controlled.

forge.yamlyaml
version: "1" agent: name: support-triage description: "Classifies and routes support tickets" model: provider: anthropic name: claude-sonnet-4-5-20251001 temperature: 0.3 max_tokens: 2048 system_prompt: file: ./prompts/system.md tools: mcp_servers: - name: filesystem command: npx args: ["-y", "@mcp/server-filesystem"] - name: brave-search command: npx args: ["-y", "@mcp/server-brave-search"] env: BRAVE_API_KEY: "${BRAVE_API_KEY}" memory: type: vector provider: chroma collection: support-memory environments: dev: model: name: claude-haiku-4-5-20251001 staging: {} production: model: temperature: 0.1 hooks: pre_deploy: - run: "pnpm test"

Multi-Provider

Anthropic, OpenAI, Google Gemini, Ollama, Bedrock. Switch providers by changing one line.

🔌 MCP Servers

Declare MCP tool servers alongside your agent. Filesystem, search, databases — managed as config.

🌎 Environments

Dev, staging, production overrides in one file. Use Haiku for dev, Sonnet for prod. --env selects the target.

🔒 Idempotent Deploys

Every config is SHA-256 hashed. Deploy twice with the same config = no-op. State is tracked in .forge/state.json.

📚 Drift Detection

forge diff compares desired state to actual. See exactly what changed, field by field, before applying.

Deploy Hooks

Run tests before deploy, send notifications after. --allow-hooks required for security — commands are shown before execution.

Architecture

Monorepo package structure

Clean separation of concerns. Types in the SDK, logic in the CLI, providers in adapters.

@forge-ai/cli

CLI binary. Commands: deploy, diff, rollback, validate. Contains the Zod schema, diff engine, and state manager.

@forge-ai/sdk

TypeScript types and programmatic API. ForgeConfig, AgentState, PlanResult — all shared types live here.

@forge-ai/adapters

Provider integrations. Anthropic, OpenAI, Google, Ollama. Each validates models and translates config to SDK params.

@forge-ai/enterprise

BUSL-1.1 licensed. Audit trail, RBAC, gated env promotion, secrets injection from Vault/SSM.

Key Design Decisions
// Idempotency model Every config is SHA-256 hashed. deploy() compares the desired hash against .forge/state.json. If hashes match, it's a no-op. // Plan/Apply cycle (borrowed from Terraform) plan() computes a diff between desired and actual state. apply() executes the plan. --dry-run shows the plan without applying. // State is local .forge/state.json is not committed to git. Each deployment target maintains its own state. Written with 0o600 permissions. // Environment overrides Shallow merge on top of root config. dev/staging/production are just patches — simple mental model, no inheritance chains. // Zod for schema validation forge.yaml is validated at parse time. Agent names must match /^[a-z0-9-]+$/. Temperature is bounded 0-2. Providers are enum'd.
CLI Reference

Four commands. That's it.

Simple, predictable, scriptable.

Terminalshell
# Validate configuration against schema $ forge validate -c forge.yaml ✓ Configuration is valid. Agent: support-triage Model: anthropic/claude-sonnet-4-5-20251001 Environments: dev, staging, production # Preview what would change $ forge diff --env production ~ Change temperature: 0.3 → 0.1 - Remove MCP server "brave-search" + Add MCP server "postgres" # Apply changes (with confirmation) $ forge deploy --env production $ forge deploy --env production --auto-approve # for CI $ forge deploy --dry-run # plan only # Roll back to a previous state $ forge rollback --target 84ef0d1d
OSS vs Enterprise

Open core, enterprise governance

The OSS core handles everything individual developers and small teams need. Enterprise adds governance for production agent fleets.

Feature OSS (MIT) Enterprise (BUSL-1.1)
forge.yaml parsing + validation
deploy / diff / rollback
Multi-environment overrides
MCP server management
Multi-provider support
Immutable audit trail
RBAC on deployments
Gated environment promotion
Secrets manager (Vault, SSM)
SSO / SAML
SLA + support
Getting Started

Up and running in 60 seconds

Terminalshell
# Install $ npm install -g @forge-ai/cli # Create a minimal agent config $ cat forge.yaml version: "1" agent: name: my-first-agent model: provider: anthropic name: claude-sonnet-4-5-20251001 temperature: 0.7 max_tokens: 4096 system_prompt: inline: "You are a helpful assistant." memory: type: none # Validate, preview, deploy $ forge validate $ forge diff $ forge deploy --env dev