Skip to content

CLI Reference

The swarmlord CLI deploys agents from config files. Define your agent in swarmlord.jsonc, write instructions in SOUL.md, add skills and workspace files, then deploy with a single command.

Install

The CLI ships with the swarmlord npm package:

bash
npm install -g swarmlord
bash
npx swarmlord <command>
bash
bunx swarmlord <command>

Project Structure

my-agent/
├── swarmlord.jsonc          # Agent configuration
├── SOUL.md                # Always-loaded instructions
├── tools/                   # Custom tools (TypeScript or Python)
│   ├── check_domain.ts
│   ├── package.json         # Tool dependencies (npm)
│   └── requirements.txt     # Tool dependencies (pip)
├── skills/                  # On-demand knowledge
│   ├── troubleshooting/
│   │   └── SKILL.md
│   └── data-analysis/
│       ├── SKILL.md
│       └── tools/           # Skill-scoped custom tools
│           └── analyze.ts
├── files/                   # Pre-loaded workspace files
│   ├── data/
│   │   └── products.csv
│   └── templates/
│       └── report.html
└── .gitignore
Local pathDeployed toPurpose
SOUL.md/workspace/SOUL.mdAlways-loaded system instructions
skills/<name>/SKILL.md/workspace/.swarmlord/skills/<name>/SKILL.mdOn-demand knowledge via the skill tool
files/*/workspace/*Pre-loaded workspace files

Config Format

swarmlord.jsonc is the agent configuration file. JSONC (JSON with comments) is supported.

The $schema field provides autocomplete, validation, and inline documentation in your editor. It includes all available OpenRouter models, built-in tool IDs, trigger providers, and field descriptions.

Editor Setup

VSCode — add https://swarmlord.ai to Settings → JSON → Schema Download: Trusted Domains.

Cursor — enable Settings → JSON → Schema Download: Enable, then add https://swarmlord.ai to Trusted Domains.

Schema download is enabled by default in VSCode but may be disabled in Cursor.

jsonc
{
    "$schema": "https://swarmlord.ai/config.json",
    "name": "my-agent",
    "model": "google/gemini-3-flash-preview",

    // Tool access
    "tools": {
        "bash": true,
        "websearch": true,
        "browser": false,
    },

    // Permissions
    "permission": { "*": "allow" },
}

By default, agents are on-demand — deploy and use via the SDK. Add trigger or schedule to activate agents automatically:

jsonc
{
    // Slack integration (optional)
    "trigger": {
        "provider": "slack",
        "events": ["message", "app_mention"],
    },
    "outputs": [{ "provider": "slack", "action": "thread_reply" }],
    "promptTemplate": "A user said: {{text}}\n\nRespond helpfully.",
}

Fields

FieldTypeRequiredDescription
namestringYesAgent name. Lowercase alphanumeric with hyphens, 1-64 chars.
descriptionstringNoHuman-readable description.
modelstringNoModel identifier (e.g. google/gemini-3-flash-preview).
triggerobjectNoWebhook-based activation. Omit for on-demand (SDK-only) agents.
trigger.providerstringYesOne of: slack, twilio, github, linear.
trigger.eventsstring[]NoEvent types to listen for.
scheduleobjectNoCron-based activation. Omit for on-demand (SDK-only) agents.
schedule.cronstringYesCron expression (e.g. 0 9 * * 1-5).
schedule.promptstringYesPrompt sent each time the cron fires.
outputsarrayNoWhere results go. Only valid with trigger or schedule.
toolsobjectNoTool enable/disable map. Unmentioned tools keep defaults.
permissionobjectNoPermission rules. Keys are tool names or *. Values: allow, deny, ask.
promptTemplatestringNoTemplate for incoming events. Uses {{variable}} substitution from the trigger payload. If omitted, a provider-specific default is used.
agentobjectNoNamed agent entries for multi-agent setups. Keys are agent names, values configure model, skills, steps, etc. See Multi-Agent.
workflowobjectNoDurable workflow definition bound to the agent. See Workflows.
skillsstring[]NoExternal skill references (e.g. owner/repo/skill-name).
integrationsobjectNoScope-based integration tool access (e.g. { "slack": ["read", "write"] }).
expectedToolsstring[]NoTool IDs the agent must call at least once. Enables missed-tool detection.
onMissedExpectedToolstringNoAction when expected tools are missed: "warn" (default, log only) or "retry" (re-prompt once).

Validation Rules

  • name must match ^[a-z0-9]+(-[a-z0-9]+)*$
  • At most one of trigger or schedule may be set (neither = on-demand agent)
  • outputs is only valid when trigger or schedule is set
  • permission values must be "allow", "deny", or "ask"
  • {{secrets.*}} references are not allowed in promptTemplate
  • Bundle size must not exceed 50 MB

Schedule Example

jsonc
{
    "$schema": "https://swarmlord.ai/config.json",
    "name": "daily-digest",
    "model": "google/gemini-3-flash-preview",
    "schedule": {
        "cron": "0 9 * * 1-5",
        "prompt": "Check for new GitHub issues labeled 'bug' and summarize them.",
    },
    "tools": {
        "bash": true,
        "websearch": true,
        "browser": false,
    },
    "permission": { "*": "allow" },
}

Instructions (SOUL.md)

SOUL.md is always loaded into the agent's context at the start of every session. Use it for:

  • System prompt and persona
  • Behavioral guidelines
  • Domain knowledge that applies to every conversation
  • References to skills the agent should load for specific topics
markdown
# Support Bot

You are a support agent for Acme Corp.

## Guidelines

- Be concise and friendly
- Load the relevant skill before answering domain-specific questions
- Always check workspace files in /workspace/data/ for reference data
- If you can't resolve an issue, escalate with a clear summary

## Available Skills

- **troubleshooting** — use when diagnosing customer issues
- **data-analysis** — use when working with CSV/JSON data

Skills

Skills are on-demand knowledge documents. Unlike SOUL.md (always loaded), skills are only loaded when the agent calls the skill tool — keeping context lean until specialized knowledge is needed.

Creating a Skill

Each skill lives in skills/<name>/SKILL.md with required YAML frontmatter:

markdown
---
name: troubleshooting
description: Step-by-step playbook for diagnosing common customer issues
---

# Troubleshooting Playbook

## Network Issues

1. Ask for the customer's region
2. Check if the issue is region-specific
   ...

How Skills Work

  1. At deploy time, skill names and descriptions are stored as metadata.
  2. The skill tool appears in the agent's tool list with all available skill names.
  3. When the agent calls skill({ name: "troubleshooting" }), the full SKILL.md content is loaded from the sandbox.
  4. The agent now has that specialized knowledge in its context.

This means the agent sees a lightweight menu of skills (names + descriptions) but only pays the token cost of loading a skill when it's actually needed.

Validation

  • The name in the YAML frontmatter must match the directory name
  • description is required, max 1024 characters
  • The directory name must be lowercase alphanumeric with hyphens

Workspace Files

Everything in the files/ directory is pre-loaded into the agent's sandbox at /workspace/:

files/
├── data/
│   └── sales.csv         → /workspace/data/sales.csv
├── templates/
│   └── report.html       → /workspace/templates/report.html
└── config.json           → /workspace/config.json

Use workspace files for reference data, templates, code to review, or any files the agent needs to work with.

Persistent Storage

By default, each session gets a fresh sandbox — workspace files are re-seeded from the deploy bundle, and anything the agent created in a previous session is gone. Persistent storage lets an agent accumulate state across runs.

How It Works

Any files the agent writes to /workspace/persist/ are automatically:

  1. Backed up to cloud storage when the session completes
  2. Restored into the next session's sandbox after workspace seeding

The persistent directory is scoped to the deployed agent — all sessions for the same agent share the same persistent state. This works for on-demand agents (SDK), scheduled agents (cron), and trigger-based agents (webhooks).

Usage

No configuration needed. If the agent writes to /workspace/persist/, it persists. Reference it in your SOUL.md:

markdown
## Data Layout

- `/workspace/persist/screenshots/` — accumulated screenshots (persists across runs)
- `/workspace/persist/changelog.md` — append-only log (persists across runs)
- `/workspace/report.md` — generated each run (does not persist)

Seed Data

Place initial files in files/persist/ to pre-populate the persistent directory on first deploy:

files/
└── persist/
    └── changelog.md       → /workspace/persist/changelog.md

On the first run (no prior state saved), the deploy bundle's files/persist/ content is used as-is. On subsequent runs, the saved state overwrites it — the agent's runtime changes take precedence.

Limits and Behavior

  • 100 MB maximum — the persistent directory is compressed and stored as a tarball. If it exceeds 100 MB after compression, the backup fails and an error is logged (the session still completes normally).
  • Last-write-wins — if multiple sessions for the same agent run concurrently, the last one to complete overwrites the persistent state. For scheduled agents (one run per cron tick), this is not an issue.
  • swarmlord run excluded — ephemeral runs created by swarmlord run do not backup or restore persistent state. Use swarmlord deploy for persistence.
  • Cleanup — when you swarmlord destroy an agent, its persistent state is deleted along with the workspace bundle.

Commands

swarmlord init

Scaffold a new agent project.

bash
swarmlord init [directory] [options]
OptionDescription
-n, --name <name>Agent name (default: inferred from directory, or my-agent)
-t, --trigger <provider>Trigger provider: slack, github, linear
-s, --schedule <cron>Cron expression for scheduled agents
-p, --prompt <prompt>Schedule prompt (required with --schedule)
-m, --model <model>Model identifier (default: anthropic/claude-haiku-4.5)
-y, --yesSkip interactive prompts, use defaults

The directory argument doubles as the agent name (lowercase, hyphens). Pass -n to override.

bash
# On-demand agent (default)
swarmlord init my-agent

# Slack integration
swarmlord init my-bot -t slack

# Scheduled agent
swarmlord init daily-check -s "0 9 * * 1-5" -p "Check for new issues"

# Interactive mode
swarmlord init

swarmlord deploy

Register a persistent agent in the cloud. Deployed agents are addressable by name from the SDK, and can receive webhook triggers or run on a cron schedule.

bash
swarmlord deploy [name] [options]
OptionDescription
--strictRequire explicit secret grants — fail if any grants are missing

Bundles the current directory (config, instructions, skills, tools, files), uploads the bundle, and creates or updates the agent. Detects agent directories automatically:

  • If swarmlord.jsonc is in the current directory: deploys that single agent.
  • If subdirectories contain swarmlord.jsonc: deploys all of them.
  • Pass a name to deploy a specific subdirectory only.

Note: if the current directory itself contains swarmlord.jsonc, only that single agent is deployed — subdirectories are not scanned.

On success, prints the agent name and SDK usage hint (for on-demand agents), webhook URL (for triggers), or schedule ID (for cron agents). Writes state to .swarmlord.

swarmlord run

One-off test run — no deploy required. Bundles your local directory, creates an ephemeral cloud session, streams the agent's response to your terminal, downloads workspace artifacts, and cleans up the session.

bash
swarmlord run [options] "<prompt>"
OptionDescription
-o, --output <dir>Download workspace artifacts to this directory (default: output)
--no-downloadSkip downloading artifacts after the run

Prints the session ID when complete, which you can use with swarmlord download to re-download artifacts later.

This is independent of swarmlord deploy. The agent doesn't need to be deployed first — run uploads a temporary bundle, executes it, and tears everything down. Use it to iterate on instructions and skills before deploying.

bash
swarmlord run "List all files in your workspace"
swarmlord run "Analyze data/sales.csv" -o results
swarmlord run "Review sample-app.ts" --no-download

swarmlord trigger

Manually fire a deployed scheduled agent. Creates a session, waits for completion, streams the result, and optionally downloads workspace artifacts.

bash
swarmlord trigger [name] [options]
OptionDescription
-o, --output <dir>Download workspace artifacts to this directory (default: output)
--no-downloadSkip downloading artifacts after the run

If name is omitted, the first agent in the local .swarmlord state is used. Only works with scheduled agents — use swarmlord run for on-demand agents.

bash
swarmlord trigger                          # trigger default agent
swarmlord trigger daily-digest -o results  # trigger by name, custom output dir
swarmlord trigger my-agent --no-download   # trigger without downloading files

swarmlord download

Download workspace files from an existing session, including anything in persist/.

bash
swarmlord download <session-id> [options]
OptionDescription
-o, --output <dir>Output directory (default: output)

Use the session ID printed by swarmlord run or swarmlord trigger to re-download artifacts after the fact.

bash
swarmlord download a620c181-4c32-42db-ba4e-5cada550f68a
swarmlord download a620c181-4c32-42db-ba4e-5cada550f68a -o my-files

swarmlord auth

Manage authentication.

bash
swarmlord auth login    # Store API key and base URL
swarmlord auth logout   # Remove stored key
swarmlord auth status   # Show current auth (masked key + base URL)

Credentials are saved to ~/.config/swarmlord/auth.json. The CLI resolves keys in order: SWARMLORD_API_KEY env var → stored auth file. When SWARMLORD_API_KEY is set via env var, the CLI always uses the default API URL (https://api.swarmlord.ai) — the stored baseUrl from auth.json is not used.

TIP

The TypeScript SDK does not read auth.json — use the env var for SDK scripts.

swarmlord list

List all deployed agents, triggers, and schedules.

bash
swarmlord list    # or: swarmlord ls

swarmlord status

Show detailed status for a deployed agent.

bash
swarmlord status [name]

If name is omitted, the first agent in the local .swarmlord state is used.

swarmlord logs

Show recent sessions for a deployed agent. Matches sessions by agent name, trigger ID, or title containing the agent name.

bash
swarmlord logs [name] [options]
OptionDescription
-n, --limit <number>Number of sessions to show (default: 10)
-a, --allShow recent sessions without filtering to a specific agent
bash
swarmlord logs                     # sessions for the default agent
swarmlord logs daily-digest -n 20  # last 20 sessions for a specific agent
swarmlord logs --all               # all recent sessions (unfiltered)

swarmlord pause / swarmlord resume

Disable or re-enable a deployed agent's trigger or schedule. On-demand agents are always available and cannot be paused.

bash
swarmlord pause [name]
swarmlord resume [name]

swarmlord destroy

Delete a deployed agent and clean up cloud resources.

bash
swarmlord destroy [name] [-y]
OptionDescription
-y, --yesSkip confirmation prompt

Removes the agent configuration, workspace bundle, persistent storage, and local .swarmlord state entry.

Multi-Agent Repos

A single repo can contain multiple agents. Place each in its own subdirectory:

my-agents/
├── support-bot/
│   ├── swarmlord.jsonc
│   ├── SOUL.md
│   └── skills/
├── daily-digest/
│   ├── swarmlord.jsonc
│   └── SOUL.md
└── code-reviewer/
    ├── swarmlord.jsonc
    ├── SOUL.md
    └── skills/
bash
swarmlord deploy                # deploy all agents
swarmlord deploy support-bot    # deploy just one

Each agent gets its own entry in the .swarmlord state file.

Dev Loop

The recommended workflow:

  1. swarmlord init — scaffold once
  2. Edit SOUL.md, skills/, files/, tools/
  3. swarmlord test --all — run custom tools locally with test fixtures
  4. swarmlord validate — check config, typecheck tools, verify bundle size
  5. swarmlord run "test prompt" — one-off cloud session, streams output, downloads artifacts
  6. Iterate — repeat steps 2-5 until the agent behaves well
  7. swarmlord validate --remote — verify secrets and grants exist on the server
  8. swarmlord deploy — register the agent permanently (SDK access, webhooks, cron)
  9. swarmlord logs — monitor production sessions
  10. swarmlord trigger — manually fire a scheduled agent to test without waiting for the cron
  11. swarmlord test-integration <trigger-id> — simulate a webhook event and stream the full agent run
  12. swarmlord download <session-id> — re-download files from any session

run and deploy are independent. You can run as many times as you want without ever deploying, and you can deploy without running first.

swarmlord test

Run custom tools locally without deploying. Uses the existing self-test mode (SWARMLORD_TOOL_SELFTEST=1).

bash
swarmlord test [tool] [options]
OptionDescription
-i, --input <json>JSON input string
-f, --file <path>Read input from a JSON file
--listList all discoverable tools
--allRun all tools using .test.json fixtures
bash
swarmlord test --list                                          # list tools
swarmlord test check_domain -i '{"domain": "example.com"}'    # test with inline input
swarmlord test check_domain -f test-input.json                 # test with file input
swarmlord test check_domain                                    # uses check_domain.test.json if it exists
swarmlord test --all                                           # run all tools with fixtures

Create .test.json fixtures alongside your tools for repeatable testing:

tools/
├── check_domain.ts
├── check_domain.test.json    ← {"domain": "example.com"}
├── search_tlds.ts
└── search_tlds.test.json     ← {"name": "coolstartup"}

Tools that declare secrets will receive empty strings in self-test mode. Set secrets as env vars for realistic testing:

bash
SLACK_BOT_TOKEN=xoxb-test swarmlord test post_slack -i '{"channel": "#test", "text": "hello"}'

swarmlord test-integration

Simulate a webhook event against a deployed trigger and stream the full agent run to your terminal. The agent runs exactly as it would in production — same tools, same instructions, same sandbox — except the inbound event is simulated (no real Slack/Twilio message needed).

bash
swarmlord test-integration <trigger-id> [options]
OptionDescription
--fixture <name>Named test fixture from the plugin (e.g. app_mention)
--payload <json>Custom JSON event payload
--list-fixturesList available test fixtures for this trigger
bash
# List available fixtures for a Slack trigger
swarmlord test-integration abc123 --list-fixtures

# Run with a named fixture
swarmlord test-integration abc123 --fixture app_mention

# Run with a custom payload (simulates a specific Slack message)
swarmlord test-integration abc123 --payload '{
  "type": "event_callback",
  "event": {
    "type": "app_mention",
    "text": "<@U123> find domains for a coffee shop",
    "channel": "C1234",
    "user": "U5678",
    "ts": "1234567890.123"
  }
}'

The output streams in real time — you see text deltas and tool call activity (with spinners and timing) as the agent works. When the agent finishes, a summary shows which tools were called:

Agent run started — streaming output:

I'll find domains for a coffee shop concept.
  ✔ search_tlds (9.2s)
  ✔ check_domain (1.1s)

*Domain Picks: Coffee shop concept*
🏆 *My recommendations*
• `brewbar.com` — $9/yr · Clean, memorable...

─── Test Summary ───

  Session:    928e372b-174b-46c2-a4a3-1d4845351053
  Tools used: search_tlds, check_domain

This is the primary way to validate trigger-based agents during development. The trigger ID is printed when you deploy (swarmlord deploy) or can be found with swarmlord list.

swarmlord validate

Validate agent config, tools, and optionally check remote secrets and grants.

bash
swarmlord validate [name] [options]
OptionDescription
--remoteAlso check that declared secrets exist and grants are set

Validates swarmlord.jsonc, typechecks tools, and verifies skill frontmatter. In a multi-agent repo, pass a name to validate a specific agent. Exits with code 1 on failure.

swarmlord secret

Manage encrypted secrets for custom tools and output integrations.

bash
swarmlord secret put <name>       # Set a secret (reads from stdin or prompts)
swarmlord secret list              # List all secrets
swarmlord secret delete <name>     # Delete a secret
swarmlord secret grant <agent> <secrets...>   # Grant secrets to an agent
swarmlord secret revoke <agent> <secret>      # Revoke a secret from an agent
swarmlord secret grants [agent]    # List grants (optionally filtered by agent)

Secret names must match ^[A-Za-z_][A-Za-z0-9_]*$. See Custom Tools — Secrets for usage in tool code.