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

# AI Agent Building Guide

> Complete reference for AI Agents and AI Coding IDEs (Cursor, Windsurf, GitHub Copilot) to build, test, and deploy agents on the Lua platform

## Purpose

This guide is specifically designed for **AI Agents** and **AI Coding IDEs** (Cursor, Windsurf, GitHub Copilot, etc.) to build agents on the Lua platform using non-interactive CLI commands.

All commands in this guide use flags and arguments that work without interactive prompts, enabling full automation.

## Prerequisites

* Node.js 18+ installed
* npm, yarn, or pnpm
* Lua CLI installed: `npm install -g lua-cli`
* Authentication configured (see below)

## High-Level Workflow

```
Authenticate → lua init → Write Code → lua test → iterate → lua chat sandbox → push → deploy
                              ↓
                    (Optional) lua integrations connect → Agent gets third-party tools instantly
```

After **`lua init`**, the CLI surfaces a suggested build loop: **compile → test → chat (sandbox) → push and deploy**. Treat that sequence as your default checklist before iterating on agent code.

***

## 1. Authentication (PREREQUISITE)

<Note>
  **Must authenticate before running any other CLI command.**
</Note>

### Option A: API Key (Fully Non-Interactive)

If the user already has an API key:

```bash theme={null}
lua auth configure --api-key <api-key>
```

This validates and saves the API key immediately.

### Option B: Email OTP (Semi Non-Interactive, 2 Steps)

If the user doesn't have an API key yet:

**Step 1** - Request OTP:

```bash theme={null}
lua auth configure --email user@example.com
```

This sends a 6-digit OTP to the email.

**Step 2** - Verify OTP (user provides the code they received):

```bash theme={null}
lua auth configure --email user@example.com --otp 123456
```

This verifies the OTP and generates + saves an API key.

### Workflow for AI Agents:

1. Ask user if they have an API key
2. If yes: `lua auth configure --api-key <key>`
3. If no:
   * Get user's email
   * Run `lua auth configure --email <email>`
   * Ask user for the OTP they received via email
   * Run `lua auth configure --email <email> --otp <code>`
4. Continue with `lua init` once authenticated

***

## 2. Initialization (`lua init`)

<Warning>
  **Run `lua init` only ONCE per project.** After initialization, you have your agent and codebase - work on it from there.
</Warning>

### Two Modes

#### New Agent (`--agent-name`)

Creates a brand new agent from scratch:

```bash theme={null}
# Create agent in existing organization
lua init --agent-name "My Agent" --org-id org_abc123

# Create agent + new organization
lua init --agent-name "My Agent" --org-name "My Company"

# With example code included
lua init --agent-name "My Agent" --org-id org_abc123 --with-examples
```

#### Existing Agent (`--agent-id`)

Links to an agent that already exists:

```bash theme={null}
lua init --agent-id agent_abc123

# Override existing project
lua init --agent-id agent_abc123 --force
```

<Note>
  **Important limitation**: Existing code/primitives on the server CANNOT be pulled down to local codebase. Bundling is one-way only (local → server). Use this mode to start fresh development on an existing agent.
</Note>

### Non-Interactive Flags

| Flag                  | Description               |
| --------------------- | ------------------------- |
| `--agent-id <id>`     | Use existing agent        |
| `--agent-name <name>` | Name for new agent        |
| `--org-id <id>`       | Existing organization ID  |
| `--org-name <name>`   | Create new organization   |
| `--with-examples`     | Include example code      |
| `--force`             | Override existing project |

### Project Structure Created

```
project/
├── lua.skill.yaml      # Config manifest (managed by CLI, don't edit manually)
├── package.json
├── tsconfig.json
├── .env                # Local environment variables
└── src/
    └── index.ts        # LuaAgent configuration
```

***

## 3. Debugging with `lua logs` (read this BEFORE you write tools)

<Note>
  **This section is promoted to the top because every AI builder needs the post-deploy loop in their head before they write a single tool.** All `console.log`, `console.error`, etc. output from your tool code shows up in `lua logs`. The CLI also prints a `✨ Tip:` line at the end of every push/deploy/chat/sync/compile/test pointing at the right `lua logs --type X --limit N` command for what you just ran. Follow it.
</Note>

The single canonical post-deploy loop is:

```
lua push --auto-deploy → lua chat -m "test" → lua logs --type X --limit 10
```

For the full canonical guide, see [Debugging your agent — the post-deploy loop](/cli/debugging).

### The "post-test-always-check" pattern

After every `lua chat -m "test"`, immediately run:

```bash theme={null}
lua logs --type agent_error --limit 5
```

If the count is **zero**, the test passed cleanly. If **non-zero**, fix the error before running another test message — most pipeline errors (billing, validation, LLM provider failures) don't surface in the chat response itself.

The CLI helps by running a quiet `agent_error` probe automatically after every `lua chat` turn — when new errors fire, you'll see:

```
⚠️  2 new agent error(s) during this turn — run `lua logs --type agent_error --limit 2` to inspect.
```

Set `LUA_NO_HINTS=1` to silence all post-action hints.

### Post-deploy verification recipe

After deploying, always run this 3-line check:

```bash theme={null}
lua push all --force --auto-deploy
lua chat -m "verify deploy" -e production -t prod-verify --clear
lua logs --type agent_error --limit 5  # should be empty
```

If step 3 returns entries timestamped after your deploy, **don't walk away** — read them and decide whether to roll back.

<Warning>
  **Important:** `lua logs` returns **zero** results right after deploy until something executes. Generate traffic first, for example:

  ```bash theme={null}
  lua chat -e production -m "test"
  ```

  Then inspect:

  ```bash theme={null}
  lua logs --type skill --limit 10
  ```
</Warning>

### `lua logs` quick reference

```bash theme={null}
# View all logs
lua logs --type all --limit 50

# Filter by type (the CLI suggests the right --type after each command)
lua logs --type skill --name mySkill --limit 10
lua logs --type job --name healthCheck --json
lua logs --type webhook --limit 20
lua logs --type agent_error --limit 10  # post-chat canary
lua logs --type mcp --limit 20
lua logs --type rag --limit 10
lua logs --type runtime --limit 20

# Filter by user (for user-reported issues)
lua logs --type all --user-id user_abc123 --limit 50
```

### Filter types

| Type             | Description                                                              |
| ---------------- | ------------------------------------------------------------------------ |
| `all`            | All logs                                                                 |
| `skill`          | Skill/tool executions                                                    |
| `job`            | Job executions                                                           |
| `webhook`        | Webhook executions                                                       |
| `preprocessor`   | PreProcessor executions                                                  |
| `postprocessor`  | PostProcessor executions                                                 |
| `mcp`            | MCP tool executions                                                      |
| `runtime`        | Agent runtime / LLM SDK / framework-level logs (was previously `mastra`) |
| `rag`            | Knowledge-base / RAG retrieval logs                                      |
| `device`         | Device command executions                                                |
| `device-trigger` | Device trigger handler executions                                        |
| `user_message`   | User messages                                                            |
| `agent_response` | Agent responses                                                          |
| `agent_error`    | Pipeline errors — the signal to watch after a `lua chat` test            |
| `calls`          | Voice call records                                                       |

***

## 4. Agent Configuration (LuaAgent)

The main configuration lives in `src/index.ts`:

```typescript theme={null}
import { LuaAgent, LuaSkill } from 'lua-cli';

export const agent = new LuaAgent({
  name: 'my-agent',
  
  persona: `You are a helpful assistant.
  
Your role:
- Help users with their tasks
- Provide accurate information

Communication style:
- Friendly and professional
- Clear and concise`,

  skills: [mySkill],
  
  // Optional components:
  // webhooks: [myWebhook],
  // jobs: [myJob],
  // preProcessors: [myPreProcessor],
  // postProcessors: [myPostProcessor],
});
```

### Key Properties

| Property         | Required | Description                                                                                                         |
| ---------------- | -------- | ------------------------------------------------------------------------------------------------------------------- |
| `name`           | Yes      | Agent identifier                                                                                                    |
| `persona`        | Yes      | Personality, behavior, capabilities, limitations                                                                    |
| `model`          | No       | AI model to use — string like `'google/gemini-2.5-flash'` or a function `(request) => string` for dynamic selection |
| `skills`         | Yes      | Array of LuaSkill instances                                                                                         |
| `webhooks`       | No       | HTTP endpoints for external events                                                                                  |
| `jobs`           | No       | Scheduled cron tasks                                                                                                |
| `preProcessors`  | No       | Message filters before agent processes                                                                              |
| `postProcessors` | No       | Response formatters after agent responds                                                                            |
| `mcpServers`     | No       | External MCP tool servers (also auto-created via `lua integrations`)                                                |

***

## 5. Building Components

### Skills & Tools

A **Skill** is a collection of related tools:

```typescript theme={null}
import { LuaSkill } from 'lua-cli';

const mySkill = new LuaSkill({
  name: 'my-skill',
  description: 'Brief description of the skill',
  context: `Detailed instructions for when to use these tools.
  
  - Use tool_a when user asks about X
  - Use tool_b when user wants to do Y`,
  tools: [new ToolA(), new ToolB()]
});
```

A **Tool** is a single function the AI can call:

```typescript theme={null}
import { LuaTool } from 'lua-cli';
import { z } from 'zod';

class GetWeatherTool implements LuaTool {
  name = 'get_weather';
  description = 'Get current weather for a city';
  
  inputSchema = z.object({
    city: z.string().describe('City name'),
    units: z.enum(['metric', 'imperial']).optional().default('metric')
  });

  async execute(input: z.infer<typeof this.inputSchema>) {
    const { city, units } = input;
    // Implementation here
    return { temperature: 22, condition: 'sunny', city };
  }
}
```

### Webhooks

HTTP endpoints for external events:

```typescript theme={null}
import { LuaWebhook } from 'lua-cli';
import { z } from 'zod';

const paymentWebhook = new LuaWebhook({
  name: 'payment-webhook',
  description: 'Handle Stripe payment events',
  
  bodySchema: z.object({
    type: z.string(),
    data: z.any()
  }),

  execute: async (event) => {
    const { body } = event;
    // Handle the webhook
    return { received: true };
  }
});
```

### Jobs

Scheduled cron tasks:

```typescript theme={null}
import { LuaJob } from 'lua-cli';

const dailyReport = new LuaJob({
  name: 'daily-report',
  description: 'Generate daily report',
  schedule: { type: 'cron', expression: '0 9 * * *' }, // 9 AM daily

  execute: async (job) => {
    // Generate report
    return { status: 'completed' };
  }
});
```

### PreProcessors & PostProcessors

```typescript theme={null}
import { PreProcessor, PostProcessor } from 'lua-cli';

const profanityFilter = new PreProcessor({
  name: 'profanity-filter',
  description: 'Filter inappropriate content',

  execute: async (user, messages, channel) => {
    // Return { action: 'block', response } to block, or { action: 'proceed' } to continue
    const text = messages.map(m => m.type === 'text' ? m.text : '').join(' ');
    if (containsProfanity(text)) {
      return { action: 'block', response: 'Message blocked due to inappropriate content.' };
    }
    return { action: 'proceed' };
  }
});

const addDisclaimer = new PostProcessor({
  name: 'add-disclaimer',
  description: 'Add legal disclaimer to responses',

  execute: async (user, message, response, channel) => {
    return { modifiedResponse: response + '\n\n_This is not legal advice._' };
  }
});
```

***

## 6. Testing Strategy

<Note>
  This is one of the most important sections. Understanding when to use `lua test` vs `lua chat` is critical.
</Note>

### `lua test` - Isolated Component Testing

**Purpose**: Unit test for individual blocks (tools, jobs, webhooks, processors)

**How it works**:

* Creates a local VM and executes code directly
* **No AI involved** - just runs the `execute` function
* Fast - no network latency, no AI processing time

**Use for**: Quick testing, quick debugging, building components in isolation

**Input format**: Must match the tool's `inputSchema` exactly

```bash theme={null}
# Test a tool
lua test skill --name get_weather --input '{"city": "London"}'

# Test a webhook
lua test webhook --name payment-webhook --input '{"query": {}, "headers": {}, "body": {"type": "payment.completed"}}'

# Test a job
lua test job --name daily-report

# Test a preprocessor
lua test preprocessor --name profanity-filter --input '{"message": "hello", "channel": "web"}'

# Test a postprocessor
lua test postprocessor --name add-disclaimer --input '{"message": "hi", "response": "hello", "channel": "web"}'
```

### `lua chat` - Live Agent Testing

**Purpose**: Real agent requests involving AI

**How it works**:

* HTTP requests for streaming/generating responses
* Full integration - multiple components may execute (skills, tools, pre/post-processors)

**Two modes**:

| Mode         | Description                                                 |
| ------------ | ----------------------------------------------------------- |
| `sandbox`    | Free, unbilled, can override local code without push/deploy |
| `production` | Uses pushed and deployed versions                           |

```bash theme={null}
# Test in sandbox (uses local code)
lua chat -e sandbox -m "What's the weather in London?"

# Test in production (uses deployed code)
lua chat -e production -m "What's the weather in London?"
```

### Key Difference

| Command    | What it does                         | AI involved? | Speed  |
| ---------- | ------------------------------------ | ------------ | ------ |
| `lua test` | Runs execute function directly in VM | No           | Fast   |
| `lua chat` | Full agent request with AI           | Yes          | Slower |

### Thread Isolation for Testing

<Note>
  **Recommended for AI agents running automated tests.** Use `--thread` to scope each chat session to an isolated conversation context. This prevents test state from leaking between runs — no need to call `lua chat clear` between tests.
</Note>

Each `--thread` creates a completely independent conversation context. This also means **multiple tests can run concurrently** (5-10 at a time) without interfering with each other.

```bash theme={null}
# Scope to an explicit thread ID
lua chat -e sandbox -m "Test scenario A" --thread scenario-a

# Auto-generate a UUID thread (printed at start so you can log/reuse it)
lua chat -e sandbox -m "Test scenario B" --thread

# Isolated test with automatic cleanup after response
lua chat -e sandbox -m "Test scenario C" -t scenario-c --clear

# Run 10 isolated tests sequentially, each with a clean context
for i in $(seq 1 10); do
  lua chat -e sandbox -m "test scenario $i" -t "test-$i" --clear
done
```

**`--thread` flags:**

| Flag                        | Description                                                                                                                    |
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| `-t, --thread [id]`         | Scope to a named thread. Omit the ID to auto-generate a UUID. Thread ID is printed at session start.                           |
| `--clear`, `--clear-thread` | Clear the thread's history when the session ends (interactive: on exit, non-interactive: after response). Requires `--thread`. |

### Concurrent Testing

Because each `--thread` is a fully isolated conversation, you can run multiple `lua chat` invocations in parallel without any state collision. This is especially useful for AI agents that need to validate multiple conversation scenarios at once:

```bash theme={null}
# Run 5 tests in parallel (background jobs)
lua chat -e sandbox -m "test flow A" -t test-a --clear &
lua chat -e sandbox -m "test flow B" -t test-b --clear &
lua chat -e sandbox -m "test flow C" -t test-c --clear &
lua chat -e sandbox -m "test flow D" -t test-d --clear &
lua chat -e sandbox -m "test flow E" -t test-e --clear &
wait  # wait for all to complete
```

### Clearing Conversation History (`lua chat clear`)

```bash theme={null}
# Clear all conversation history
lua chat clear --force

# Clear specific user's history
lua chat clear --user user@email.com --force
lua chat clear --user +1234567890 --force
lua chat clear --user user_abc123 --force

# Clear a specific thread's history
lua chat clear --thread my-test-scenario --force
```

**When to use `lua chat clear` vs `--thread`**:

| Approach                 | When to use                                                  |
| ------------------------ | ------------------------------------------------------------ |
| `lua chat clear --force` | Reset all history before a new development session           |
| `--thread <id>`          | Isolate individual test runs without touching other contexts |
| `--clear`                | Auto-clean up thread history at end of each automated test   |

### Recommended Development Workflow

```bash theme={null}
# 1. Write/modify component code

# 2. Quick isolated test
lua test skill --name my_tool --input '{"param": "value"}'

# 3. Check logs if issues
lua logs --type skill --name my_tool --limit 5

# 4. Iterate until component works

# 5. Test with full agent in an isolated thread (no need to clear history)
lua chat -e sandbox -m "Test message" -t dev-session

# 6. Run a suite of scenario tests concurrently
lua chat -e sandbox -m "scenario 1" -t s1 --clear &
lua chat -e sandbox -m "scenario 2" -t s2 --clear &
wait

# 7. When ready: push and deploy

# 8. Verify in production
lua chat -e production -m "Test message" -t prod-verify --clear
```

***

## 7. Push vs Deploy

<Warning>
  Understanding this distinction is critical. Many users confuse these commands.
</Warning>

### `lua push` - Upload Code to Server

* Compiles local code and uploads to Lua platform server/database
* Creates a **version** on the server
* Code now exists on server, not just locally
* **Does NOT make it live yet**

```bash theme={null}
# Push a specific skill with version
lua push skill --name mySkill --set-version 1.0.0 --force

# Push all components
lua push all --force

# Push and immediately deploy
lua push all --force --auto-deploy
```

### `lua deploy` - Activate a Version

* Makes a previously pushed version **live/active**
* Only 1 version can be active at a time per primitive
* This is what production uses

```bash theme={null}
# Deploy specific version
lua deploy skill --name mySkill --set-version 1.0.5 --force

# Deploy latest version
lua deploy skill --name mySkill --set-version latest --force
```

### Key Difference

| Command      | What it does                         |
| ------------ | ------------------------------------ |
| `lua push`   | Upload version to server (staging)   |
| `lua deploy` | Make that version live for all users |

After `lua push` **without** `--auto-deploy`, code is **staged, not live**. The CLI says so explicitly — for example:

```
✨ Staged but NOT live yet. To make it active: lua deploy skill
```

Use `lua push … --auto-deploy` or run `lua deploy` explicitly before validating in production.

***

## 8. Environment Variables

### Sandbox vs Production

| Environment | Source                                          |
| ----------- | ----------------------------------------------- |
| Sandbox     | Local `.env` file or CLI env variables          |
| Production  | Stored on server (set via `lua env production`) |

### Commands

```bash theme={null}
# List variables
lua env sandbox --list
lua env production --list

# Set variable
lua env sandbox -k API_KEY -v "sk-test-xxx"
lua env production -k API_KEY -v "sk-live-xxx"

# Delete variable
lua env production -k OLD_KEY --delete
```

Set environment variables **as needed** when code requires them.

***

## 9. Sandbox Overrides

When using `lua chat -e sandbox`, the following can be overridden with local compiled code **without needing to push/deploy**:

| Component      | How it works                                        |
| -------------- | --------------------------------------------------- |
| Skills         | Local compiled code pushed to Redis cache           |
| Persona        | Local persona overrides deployed production persona |
| PreProcessors  | Local code pushed to Redis cache                    |
| PostProcessors | Local code pushed to Redis cache                    |
| Environment    | Local `.env` file used                              |

This allows testing changes instantly without the push/deploy cycle.

***

## 10. Compilation Gotchas

The CLI uses **esbuild** to bundle each `execute` function:

### What Works

* Standard TypeScript code
* Imports from `package.json` dependencies
* Relative imports within your project

### What May Not Work

* Not all Node.js file structures are supported
* Each execute function's code is extracted and bundled separately
* `lua-cli` imports are stripped - APIs like `User`, `Products`, `Data`, `Agents` are sandbox globals

### Warning Signs

| Issue                        | Meaning                              |
| ---------------------------- | ------------------------------------ |
| Empty bundles (\< 100 bytes) | Something went wrong during bundling |
| "Could not resolve" errors   | Check imports/dependencies           |
| "Transform failed"           | TypeScript syntax issues             |

### Debug Mode

Run with `--debug` for verbose compilation output:

```bash theme={null}
lua compile --debug
```

***

## 11. Platform APIs Available at Runtime

These are available as **globals** in the VM sandbox (don't import from lua-cli):

| API            | Description                                                                                                                                     |
| -------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| `User`         | **Per-user persistent storage** — store onboarding state, preferences, workflow progress, or any custom data that persists across conversations |
| `Data`         | Custom data collections                                                                                                                         |
| `Products`     | Product catalog                                                                                                                                 |
| `Baskets`      | Shopping cart                                                                                                                                   |
| `Orders`       | Order management                                                                                                                                |
| `AI`           | AI generation                                                                                                                                   |
| `Lua`          | Request context (`Lua.request.channel`, `Lua.request.webhook`)                                                                                  |
| `Jobs`         | Job scheduling                                                                                                                                  |
| `Templates`    | Message templates                                                                                                                               |
| `CDN`          | File upload/retrieval                                                                                                                           |
| `BasketStatus` | Enum for basket statuses (`ACTIVE`, `CHECKED_OUT`, `ABANDONED`, `EXPIRED`)                                                                      |
| `OrderStatus`  | Enum for order statuses (`PENDING`, `CONFIRMED`, `FULFILLED`, `CANCELLED`)                                                                      |
| `env(key)`     | Environment variable access                                                                                                                     |
| `process.env`  | Environment variables as an object (alternative to `env()`)                                                                                     |
| `fetch`        | HTTP requests                                                                                                                                   |
| `console`      | Logging (appears in `lua logs`)                                                                                                                 |

### User: Per-User Persistent Storage

<Note>
  **Critical for AI agents building stateful workflows.** The `User` API is the primary way to maintain state across conversations. It is a **schemaless, persistent key-value store** scoped to each end-user — not just a profile reader.
</Note>

Any property you set on the user object **persists forever** (across conversations, sessions, days, months) until you explicitly change it. This makes it the go-to primitive for:

* **Onboarding flows** — track `user.onboardingStep`, `user.completedSteps`
* **Multi-step workflows** — accumulate data across tool calls with `user.collectedData`
* **Session state** — store `user.lastIntent`, `user.pendingAction`
* **User preferences** — persist `user.theme`, `user.language`, `user.notificationSettings`

```typescript theme={null}
// In any tool — read and write arbitrary user state
const user = await User.get();   // User is a sandbox global

// These properties persist FOREVER until you change them
user.onboardingStep = 'identity_verification';
user.collectedData = { name: 'Jane', company: 'Acme' };
user.completedSteps = ['welcome', 'personal_info'];
await user.save();

// Next conversation, next day, next month — it's still there
const user = await User.get();
console.log(user.onboardingStep); // 'identity_verification'
console.log(user.completedSteps); // ['welcome', 'personal_info']
```

**State machine pattern** — use `user.onboardingStep` (or any field) to track where the user is in a multi-step flow, then resume from that point in any future conversation:

```typescript theme={null}
const user = await User.get();
const step = user.onboardingStep || 'not_started';

if (step === 'not_started') {
  user.onboardingStep = 'collecting_info';
  await user.save();
  return { message: "Let's get started!" };
} else if (step === 'collecting_info') {
  user.companyName = input.companyName;
  user.onboardingStep = 'awaiting_verification';
  await user.save();
  return { message: 'Now let\'s verify your identity.' };
}
// ... continue for each step
```

See the full [User API reference](/api/user) for all methods (`update()`, `save()`, `send()`, `clear()`).

***

## 12. Third-Party Integrations (POWERFUL FEATURE)

<Note>
  **This is one of the most powerful features of the Lua platform.** With a single command, you can give your agent access to 250+ third-party services (Linear, Discord, Google Calendar, HubSpot, Slack, GitHub, and more) - **without writing any code**.
</Note>

### Why This Matters

Instead of:

* Writing API integration code
* Managing OAuth tokens and refresh logic
* Building tools for each third-party service
* Handling rate limits and error handling

You simply run:

```bash theme={null}
lua integrations connect --integration linear --auth-method oauth --scopes all --triggers task_task.created
```

And your agent **instantly** gets:

* Tools like `linear_create_issue`, `linear_list_projects`, `linear_update_task`, etc.
* **Triggers** that wake up your agent when events occur (e.g., when a new issue is created)

### How It Works

1. **Connect** - Authenticate with the third-party service via OAuth or API token
2. **Auto-MCP** - An MCP (Model Context Protocol) server is automatically created
3. **Instant Tools** - Your agent can immediately use tools from that integration
4. **Triggers** - Optionally enable triggers to wake up your agent on events

### Discovery Commands (For AI Agents)

Before connecting, use discovery commands to understand what's available:

```bash theme={null}
# List all available integrations
lua integrations available

# Get detailed info about an integration (scopes and triggers)
lua integrations info linear

# Get info as JSON (for parsing)
lua integrations info linear --json

# List available trigger events
lua integrations webhooks events --integration linear
lua integrations webhooks events --integration linear --json
```

**JSON output** is especially useful for AI coding assistants to programmatically discover:

* Available OAuth scopes with friendly descriptions
* Available trigger events with friendly descriptions
* Webhook types (native vs virtual)

### Connecting an Integration

```bash theme={null}
# View available integrations
lua integrations available

# Connect with OAuth and triggers (recommended)
lua integrations connect --integration linear --auth-method oauth --scopes all \
  --triggers task_task.created,task_task.updated

# Connect with all available triggers
lua integrations connect --integration linear --auth-method oauth --scopes all --triggers all

# Connect with specific scopes only (no triggers)
lua integrations connect --integration linear --auth-method oauth --scopes "task_task_read,task_task_write"

# Connect with API token
lua integrations connect --integration linear --auth-method token

# List connected integrations
lua integrations list

# Update scopes on existing connection
lua integrations update --integration linear --scopes all

# Disconnect
lua integrations disconnect --connection-id <id>
```

### Triggers: Event-Driven Agent Wake-Up

**Triggers** are one of the easiest ways to make your agent reactive. When enabled, your agent automatically wakes up when events occur in connected services.

```bash theme={null}
# Enable triggers during connection
lua integrations connect --integration linear --auth-method oauth --scopes all \
  --triggers task_task.created,task_task.updated

# Or add triggers after connection
lua integrations webhooks create --connection <id> --object task_task --event created

# List active triggers
lua integrations webhooks list

# Delete a trigger
lua integrations webhooks delete --webhook-id <id>
```

**What happens when a trigger fires:**

1. An event occurs in the connected service (e.g., a new Linear issue is created)
2. Unified.to sends a webhook to your agent
3. Your agent wakes up with the event data in `runtimeContext`
4. The agent can respond based on what happened

### Testing Integration Tools

After connecting, test immediately. Use `--thread` to keep each test isolated:

```bash theme={null}
# Test integration tools in isolated threads (can run concurrently)
lua chat -e sandbox -m "Create a Linear issue titled 'Test from Lua' in my default project" -t test-linear --clear

lua chat -e sandbox -m "List my upcoming Google Calendar events" -t test-gcal --clear

lua chat -e sandbox -m "Send a message to the #general channel on Discord" -t test-discord --clear
```

### Available Integrations (250+)

Common integrations include:

| Category            | Examples                                         |
| ------------------- | ------------------------------------------------ |
| **Task Management** | Linear, Asana, Jira, Monday.com, ClickUp, Notion |
| **Communication**   | Discord, Slack, Microsoft Teams, Telegram        |
| **Calendar**        | Google Calendar, Outlook Calendar, Calendly      |
| **CRM**             | HubSpot, Salesforce, Pipedrive, Zoho CRM         |
| **Development**     | GitHub, GitLab, Bitbucket                        |
| **Storage**         | Google Drive, Dropbox, OneDrive, Box             |
| **Support**         | Zendesk, Intercom, Freshdesk                     |
| **Email**           | Gmail, Outlook, SendGrid                         |

Run `lua integrations available` to see all available integrations for your workspace.

### Managing MCP Servers for Integrations

Each integration creates an MCP server. You can manage them:

```bash theme={null}
# List MCP servers and their status
lua integrations mcp list

# Deactivate (hide tools from agent)
lua integrations mcp deactivate --connection <id>

# Reactivate
lua integrations mcp activate --connection <id>
```

### Integration Workflow Example

```bash theme={null}
# 1. Discover available integrations and their capabilities
lua integrations available
lua integrations info linear --json

# 2. Connect Linear with triggers
lua integrations connect --integration linear --auth-method oauth --scopes all \
  --triggers task_task.created,task_task.updated
# (Complete OAuth in browser)

# 3. Verify connection and triggers
lua integrations list
lua integrations webhooks list

# 4. Test the integration in isolated threads
lua chat -e sandbox -m "List all Linear projects I have access to" -t test-list --clear
lua chat -e sandbox -m "Create a task in Linear: Review documentation updates" -t test-create --clear

# 5. The agent now has full Linear capabilities and reacts to events!
```

### Key Points for AI Agents

<Warning>
  **Important for AI coding assistants building Lua agents:**

  1. **Use discovery commands** to understand what's available:
     * `lua integrations available` - list integrations
     * `lua integrations info <type> --json` - get scopes and triggers
     * `lua integrations webhooks events --integration <type> --json` - get trigger events

  2. **Enable triggers** during connection for event-driven workflows:
     * `--triggers task_task.created,task_task.updated` - specific triggers
     * `--triggers all` - all available triggers

  3. **Connect integrations** before writing custom tool code - the integration might already provide what's needed

  4. **Test with `lua chat`** after connecting to verify tools are available

  5. **One connection per integration type** per agent - use `update` to change scopes
</Warning>

***

## 13. Complete Workflow Example

```bash theme={null}
# 0. Authenticate (one-time setup)
# Option A: With API key
lua auth configure --api-key <your-api-key>

# Option B: With email (2 steps)
lua auth configure --email user@example.com
# (user receives OTP via email)
lua auth configure --email user@example.com --otp 123456

# 1. Initialize project (one-time per agent)
lua init --agent-id agent_abc123

# 2. Set environment variables (as needed)
lua env sandbox -k OPENAI_KEY -v "sk-test-xxx"

# 3. (OPTIONAL BUT POWERFUL) Connect third-party integrations
lua integrations available                                          # See what's available
lua integrations connect --integration linear --auth-method oauth --scopes all
lua integrations connect --integration discord --auth-method oauth --scopes all
lua integrations list                                                # Verify connections

# 4. Write your code in src/

# 5. Test individual components
lua test skill --name get_order --input '{"orderId": "123"}'

# 6. Check logs if issues
lua logs --type skill --name get_order --limit 5

# 7. Test with full agent in isolated threads (sandbox)
lua chat -e sandbox -m "Get order 123" -t test-get-order --clear
lua chat -e sandbox -m "Create a Linear issue for order 123 review" -t test-linear --clear  # If Linear connected

# Or run both concurrently
lua chat -e sandbox -m "Get order 123" -t test-get-order --clear &
lua chat -e sandbox -m "Create a Linear issue" -t test-linear --clear &
wait

# 8. Push to server
lua push skill --name order-service --set-version 1.0.0 --force

# 9. Deploy to production
lua deploy skill --name order-service --set-version latest --force

# 10. Set production env vars
lua env production -k OPENAI_KEY -v "sk-live-xxx"

# 11. Test production in isolated thread
lua chat -e production -m "Get order 123" -t prod-verify --clear

# 12. Monitor logs
lua logs --type skill --name order-service --limit 10 --json
```

***

## Quick Reference: Non-Interactive Commands

| Task                            | Command                                                                                              |
| ------------------------------- | ---------------------------------------------------------------------------------------------------- |
| Authenticate with API key       | `lua auth configure --api-key <key>`                                                                 |
| Request email OTP               | `lua auth configure --email <email>`                                                                 |
| Verify email OTP                | `lua auth configure --email <email> --otp <code>`                                                    |
| Initialize with existing agent  | `lua init --agent-id <id>`                                                                           |
| Initialize with new agent       | `lua init --agent-name <name> --org-id <id>`                                                         |
| Test a tool                     | `lua test skill --name <name> --input '<json>'`                                                      |
| Test a webhook                  | `lua test webhook --name <name> --input '<json>'`                                                    |
| Test a job                      | `lua test job --name <name>`                                                                         |
| Chat in sandbox                 | `lua chat -e sandbox -m "<message>"`                                                                 |
| Chat in production              | `lua chat -e production -m "<message>"`                                                              |
| Chat in isolated thread         | `lua chat -e sandbox -m "<message>" -t <thread-id>`                                                  |
| Chat in auto-generated thread   | `lua chat -e sandbox -m "<message>" -t`                                                              |
| Isolated test with auto-cleanup | `lua chat -e sandbox -m "<message>" -t <id> --clear`                                                 |
| Clear all conversation history  | `lua chat clear --force`                                                                             |
| Clear user's history            | `lua chat clear --user <email\|mobile\|userId> --force`                                              |
| Clear specific thread history   | `lua chat clear --thread <thread-id> --force`                                                        |
| View available integrations     | `lua integrations available`                                                                         |
| Get integration info (JSON)     | `lua integrations info <type> --json`                                                                |
| List trigger events (JSON)      | `lua integrations webhooks events --integration <type> --json`                                       |
| Connect with triggers           | `lua integrations connect --integration <type> --auth-method oauth --scopes all --triggers <events>` |
| Connect integration (OAuth)     | `lua integrations connect --integration <type> --auth-method oauth --scopes all`                     |
| Connect integration (Token)     | `lua integrations connect --integration <type> --auth-method token`                                  |
| List connected integrations     | `lua integrations list`                                                                              |
| Update integration scopes       | `lua integrations update --integration <type> --scopes all`                                          |
| Disconnect integration          | `lua integrations disconnect --connection-id <id>`                                                   |
| List triggers                   | `lua integrations webhooks list`                                                                     |
| Create trigger                  | `lua integrations webhooks create --connection <id> --object <type> --event <event>`                 |
| Delete trigger                  | `lua integrations webhooks delete --webhook-id <id>`                                                 |
| List integration MCP status     | `lua integrations mcp list`                                                                          |
| Push all                        | `lua push all --force`                                                                               |
| Push and deploy                 | `lua push all --force --auto-deploy`                                                                 |
| Deploy specific version         | `lua deploy skill --name <name> --set-version <ver> --force`                                         |
| Set env variable                | `lua env <sandbox\|production> -k <key> -v <value>`                                                  |
| View logs                       | `lua logs --type <type> --name <name> --limit <n>`                                                   |

***

## Related Documentation

<CardGroup cols={2}>
  <Card title="Debugging Loop" icon="bug" href="/cli/debugging">
    Canonical post-deploy debug loop and the active `agent_error` probe
  </Card>

  <Card title="CLI Commands Reference" icon="terminal" href="/cli/overview">
    Complete CLI command documentation
  </Card>

  <Card title="Non-Interactive Mode" icon="robot" href="/cli/non-interactive-mode">
    All non-interactive flags and CI/CD examples
  </Card>

  <Card title="Integrations Command" icon="link" href="/cli/integrations-command">
    Connect 250+ third-party services
  </Card>

  <Card title="LuaAgent API" icon="code" href="/api/luaagent">
    Complete LuaAgent configuration reference
  </Card>

  <Card title="Platform APIs" icon="plug" href="/concepts/platform-apis">
    User, Data, Products, and other runtime APIs
  </Card>

  <Card title="MCP Servers" icon="server" href="/cli/mcp-command">
    Manage MCP servers for external tools
  </Card>
</CardGroup>
