Skip to main content
Cargo helps revenue teams automate their go-to-market motions with AI: enrich and score records, research accounts, run outbound, and keep the CRM clean. You build all of it as code. A Cargo workspace is a folder of TypeScript files — one define* call per resource. The CLI (cargo-ai) deploys that folder declaratively, so your connectors, data models, tools, agents, and plays are versioned, diffable, and reproducible.
npm install -g @cargo-ai/cli
cargo-ai login --token <your-api-token>
cargo-ai cdk init my-workspace
cd my-workspace && cargo-ai cdk deploy

A workspace at a glance

Each resource type has a home. The full starter template lays out the whole surface:
my-workspace/
├── package.json
├── cargo.state.json          # created on first deploy — commit it
├── connectors/
│   ├── hubspot.ts            # defineConnector
│   └── openai.ts
├── models/
│   └── contacts.ts           # defineModel — a table sourced from a connector
├── tools/
│   └── enrich.ts             # defineWorkflow + defineTool
├── agents/
│   ├── enricher.ts           # defineAgent (sub-agent)
│   └── sdr.ts                # defineAgent (main agent)
├── plays/
│   └── onboarding.ts         # definePlay — runs a workflow as rows change
├── mcp/
│   └── crm.ts                # defineMcpServer
├── context/                  # defineContext — GTM knowledge base
├── files/                    # defineFile
├── folders/                  # defineFolder
├── workers/                  # defineWorker (hosted edge handlers)
└── apps/                     # defineApp (hosted Vite SPAs)
You can understand most Cargo projects by reading that tree.

The files are the interface

Importing a .ts file is registration. There is no central manifest to keep in sync: each define* call registers a resource as a side effect, and you wire resources together by passing one resource’s handle into another.
tools/enrich.ts
import { defineTool, defineWorkflow } from "@cargo-ai/cdk";
import { z } from "zod";
import { enricher } from "../agents/enricher";

const enrichFlow = defineWorkflow(
  "enrich-contact",
  {
    input: z.object({ email: z.string() }),
    output: z.object({ company: z.string() }),
    uses: { enricher },
  },
  ({ input, uses }) => ({
    company: uses.enricher({ prompt: `Which company owns ${input.email}?` }),
  }),
);

export const enrich = defineTool("enrich", { workflow: enrichFlow });
Passing the enricher handle into uses is what creates the dependency edge — the dependency graph is just your variable graph. Cargo deploys the agent first and injects its real uuid into the tool.

Deploy declaratively

The CLI reconciles your code against the live workspace. plan is offline; deploy creates or updates only what changed and records the result in cargo.state.json.
cargo-ai cdk plan     # offline diff against cargo.state.json
cargo-ai cdk deploy   # create/update; write state
Re-deploying with no changes is a no-op. Change one resource and only it updates.

Quickstart

Install, authenticate, and deploy your first tool in a few minutes.

Project layout

The folder-per-resource convention, the loader, and state hygiene.

Connectors

defineConnector — link CRMs, warehouses, enrichment, and AI providers.

Workflows

defineWorkflow — the TypeScript DSL that backs tools and plays.

Agents

defineAgent — LLM workers with tools, models, and sub-agents.

CLI

Day-to-day operations: run tools, trigger plays, query data.

Prefer the visual builder?

Every resource can also be built in the Cargo web app, and code-first and UI-built resources run identically. The Models, Tools, Agents, and Plays sections each have a Using the UI page, and you can jump into the app any time at app.getcargo.io.