> ## Documentation Index
> Fetch the complete documentation index at: https://docs.getcargo.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Cargo CDK Overview

> Define your entire Cargo workspace in code — connectors, models, plays, tools, agents, MCP servers, files, workers and apps — and deploy it declaratively with cargo-ai cdk.

The **Cargo CDK** (`@cargo-ai/cdk`) lets you describe a whole Cargo workspace in
TypeScript and deploy it like infrastructure-as-code — the same model as Pulumi
or the AWS CDK, but for Cargo resources.

You write `define*` calls; the CDK figures out the dependency order, creates or
updates each resource, and records what it made in a committed `cargo.state.json`
so the next deploy only changes what changed.

<CardGroup cols={2}>
  <Card title="Define resources" icon="pen-to-square" href="/cdk/resources">
    Every Cargo resource has a `define*` builder. Wire them together by passing
    one resource's token into another.
  </Card>

  <Card title="Deploy" icon="rocket" href="/cdk/deploying">
    `plan`, `deploy`, `--prune`, `--refresh`, `import` and `destroy` — the full
    reconcile lifecycle.
  </Card>

  <Card title="State & drift" icon="database" href="/cdk/state-and-drift">
    How `cargo.state.json` works, the lock file, and detecting changes made
    outside the CDK.
  </Card>

  <Card title="CLI" icon="terminal" href="/cli/overview">
    The CDK ships as `cargo-ai cdk` in the Cargo CLI.
  </Card>
</CardGroup>

## Install

```bash theme={null}
npm install -g @cargo-ai/cli
cargo-ai login
```

## A first workspace

Create a directory and add a resource file. Importing a file **is** registration —
there's no manifest to maintain.

```ts my-workspace/contacts.ts theme={null}
import { defineConnector, defineModel, secret } from "@cargo-ai/cdk";

export const hubspot = defineConnector("hubspot", {
  integration: "hubspot",
  config: { apiKey: secret("HUBSPOT_API_KEY") },
});

// `hubspot.datasetUuid` is a token — the model depends on the connector, so the
// CDK creates the connector first and injects the real uuid.
export const contacts = defineModel("contacts", {
  datasetUuid: hubspot.datasetUuid,
  extractSlug: "fetchRecords",
});
```

```bash theme={null}
export HUBSPOT_API_KEY=...           # secret() reads this at deploy time
cargo-ai cdk plan --dir my-workspace   # offline diff, no API calls
cargo-ai cdk deploy --dir my-workspace # create everything, write cargo.state.json
```

<Tip>
  `plan` is fully offline — it compiles your code and diffs it against
  `cargo.state.json` without touching the API. Run it freely.
</Tip>

## How it works

* **Handles & tokens.** `define*` returns a handle whose outputs (`uuid`,
  `datasetUuid`, `url`, …) are deferred tokens. Passing a token into another
  resource is what creates a dependency edge — the dependency graph is just your
  variable graph.
* **State.** Every deploy writes `cargo.state.json` (commit it). It's the
  authoritative link from a code resource to the real uuid Cargo assigned it.
* **Idempotent.** Each resource is content-hashed; a re-deploy with no code
  changes is a no-op. Change one resource and only it updates.

<Warning>
  Use `secret()` — never `env()` — for credentials. `secret()` resolves at deploy
  time and is kept out of the content hash and out of state. `env()` bakes the
  value into the hash (so rotating it shows as drift) and is meant for non-secret
  config you want tracked.
</Warning>
