> ## 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.

# Defining Resources

> The define* builders for every Cargo resource — connectors, models, plays, tools, agents, MCP servers, folders, files, workers and apps — and how to wire them together with tokens.

Every Cargo resource has a `define*` builder. Each returns a **handle** whose
outputs are deferred **tokens**; you wire resources together by passing one
handle's token into another's spec.

## Connectors

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

// Config-based: pass credentials via secret().
export const hubspot = defineConnector("hubspot", {
  integration: "hubspot",
  config: { apiKey: secret("HUBSPOT_API_KEY") },
});

// OAuth / already-authenticated: adopt the existing connector by slug.
export const openai = defineConnector("open_ai", {
  integration: "openAi",
  adopt: true,
});
```

Creating a connector auto-creates a **dataset**; models source from it via
`connector.datasetUuid`.

## Models

```ts theme={null}
import { defineModel } from "@cargo-ai/cdk";

export const contacts = defineModel("contacts", {
  datasetUuid: hubspot.datasetUuid, // token
  extractSlug: "fetchRecords",
  config: { objectId: "contacts" },
  schedule: { type: "cron", cron: "0 * * * *" },
});
```

## Tools

A tool is backed by a workflow (`defineWorkflow`). The workflow body is parsed
and compiled — it is never executed at build time.

```ts theme={null}
import { defineTool, defineWorkflow } from "@cargo-ai/cdk";
import { z } from "zod";

const flow = defineWorkflow(
  "enrich-contact",
  { input: z.object({ email: z.string() }), output: z.object({ company: z.string() }) },
  ({ input, ai }) => ({ company: ai(`What company owns ${input.email}?`) }),
);

export const enrich = defineTool("enrich", {
  workflow: flow,
  emojiSlug: "mag",
  triggers: [{ cron: "0 9 * * 1", name: "Weekly" }],
});
```

## Agents

Agents reference an LLM connector, data models, tools, sub-agents and connector
actions — all by uuid token.

```ts theme={null}
import { defineAgent } from "@cargo-ai/cdk";

export const sdr = defineAgent("sdr", {
  color: "blue",
  connectorUuid: openai.uuid,
  languageModel: "gpt-4o",
  systemPrompt: "Qualify inbound leads.",
  capabilities: ["webSearch", "memory"],
  models: [{ uuid: contacts.uuid, readOnly: true }],
  tools: [{ uuid: enrich.uuid, waitUntilFinished: true }],
  subAgents: [{ uuid: enricher.uuid, isBulkAllowed: false }],
  connectorActions: [{ integration: "hunter", actionSlug: "emailFinder" }],
});
```

`tools`, `subAgents` and `connectorActions` all accept the same per-call
options: `name`, `description`, `isBulkAllowed`, and `waitUntilFinished`
(connector actions omit `waitUntilFinished`).

## Plays

A play runs over a data model and emits runs as its rows change. It can carry a
per-row `workflow`, deployed as its release.

```ts theme={null}
import { definePlay } from "@cargo-ai/cdk";

export const onboarding = definePlay("onboarding", {
  modelUuid: contacts.uuid,
  changeKinds: ["added", "updated"],
  runCreationRule: "always",
  schedule: { type: "realtime" },
});
```

## MCP servers

An MCP server bundles tools, agents and data-model resources behind one
endpoint — the same rich refs as an agent.

```ts theme={null}
import { defineMcpServer } from "@cargo-ai/cdk";

export const crm = defineMcpServer("crm", {
  tools: [{ uuid: enrich.uuid }],
  agents: [{ uuid: sdr.uuid }],
  models: [{ uuid: contacts.uuid, readOnly: true }],
});
```

## Folders & files

```ts theme={null}
import { defineFolder, defineFile } from "@cargo-ai/cdk";

// Folders are per-kind (a "model" folder and an "agent" folder are separate).
export const modelsFolder = defineFolder("crm", { kind: "model", name: "CRM" });

export const playbook = defineFile("playbook", {
  path: new URL("./playbook.md", import.meta.url).pathname,
});
```

## Workers & apps

`defineWorker`/`defineApp` deploy a **built** bundle directory. The CDK validates
the required files exist at define time.

```ts theme={null}
import { defineWorker, defineApp } from "@cargo-ai/cdk";

// worker bundle root needs: index.js + manifest.json + package.json + package-lock.json
export const webhook = defineWorker("webhook", {
  path: new URL("./webhook", import.meta.url).pathname,
});

// app bundle root needs: index.html + package.json + package-lock.json (a Vite app)
export const dashboard = defineApp("dashboard", {
  path: new URL("./dashboard", import.meta.url).pathname,
});
```

<Note>
  The hosting build runs `npm ci` then esbuild (workers) / `vite build` (apps) —
  it does not transpile TypeScript. A worker bundle must ship a built `index.js`.
</Note>

## Slug rules

Slugs are validated at define time to match what each endpoint enforces, so a
bad slug fails in `plan` rather than mid-deploy:

| Kind                 | Format                                         |
| -------------------- | ---------------------------------------------- |
| `connector`, `model` | `snake_case` (`my_source`)                     |
| `worker`, `app`      | kebab-case, starts with a letter (`my-worker`) |
| everything else      | lowercase letters, digits, `-`, `_`            |
