Skip to main content

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

1. Authentication (PREREQUISITE)

Must authenticate before running any other CLI command.

Option A: API Key (Fully Non-Interactive)

If the user already has an API key:
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:
lua auth configure --email [email protected]
This sends a 6-digit OTP to the email. Step 2 - Verify OTP (user provides the code they received):
lua auth configure --email [email protected] --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)

Run lua init only ONCE per project. After initialization, you have your agent and codebase - work on it from there.

Two Modes

New Agent (--agent-name)

Creates a brand new agent from scratch:
# 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:
lua init --agent-id agent_abc123

# Override existing project
lua init --agent-id agent_abc123 --force
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.

Non-Interactive Flags

FlagDescription
--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-examplesInclude example code
--forceOverride 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. Agent Configuration (LuaAgent)

The main configuration lives in src/index.ts:
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

PropertyRequiredDescription
nameYesAgent identifier
personaYesPersonality, behavior, capabilities, limitations
skillsYesArray of LuaSkill instances
webhooksNoHTTP endpoints for external events
jobsNoScheduled cron tasks
preProcessorsNoMessage filters before agent processes
postProcessorsNoResponse formatters after agent responds
mcpServersNoExternal MCP tool servers (also auto-created via lua integrations)

4. Building Components

Skills & Tools

A Skill is a collection of related tools:
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:
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:
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:
import { LuaJob } from 'lua-cli';

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

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

PreProcessors & PostProcessors

import { PreProcessor, PostProcessor } from 'lua-cli';

const profanityFilter = new PreProcessor({
  name: 'profanity-filter',
  description: 'Filter inappropriate content',
  
  execute: async (user, message, channel) => {
    // Return null to block, or modified message to continue
    return message;
  }
});

const addDisclaimer = new PostProcessor({
  name: 'add-disclaimer',
  description: 'Add legal disclaimer to responses',
  
  execute: async (user, message, response, channel) => {
    return response + '\n\n_This is not legal advice._';
  }
});

5. Testing Strategy

This is one of the most important sections. Understanding when to use lua test vs lua chat is critical.

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
# 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:
ModeDescription
sandboxFree, unbilled, can override local code without push/deploy
productionUses pushed and deployed versions
# 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

CommandWhat it doesAI involved?Speed
lua testRuns execute function directly in VMNoFast
lua chatFull agent request with AIYesSlower

Clearing Conversation History (lua chat clear)

Important for testing! The agent has memory/conversation history. When testing, you often want a fresh state. Use lua chat clear to reset the AI’s memory.
# Clear all conversation history
lua chat clear --force

# Clear specific user's history
lua chat clear --user [email protected] --force
lua chat clear --user +1234567890 --force
lua chat clear --user user_abc123 --force
When to use:
  • Before testing a new feature or flow
  • When the agent’s context is polluted from previous tests
  • When debugging unexpected behavior that might be context-related
# 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. Clear conversation history for fresh test
lua chat clear --force

# 6. Test with full agent (sandbox)
lua chat -e sandbox -m "Test message"

# 7. When ready: push and deploy

# 8. Verify in production
lua chat -e production -m "Test message"

6. Push vs Deploy

Understanding this distinction is critical. Many users confuse these commands.

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
# Push a specific skill with version
lua push skill --name mySkill --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
# Deploy specific version
lua deploy --skill-name mySkill --skill-version 1.0.5 --force

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

Key Difference

CommandWhat it does
lua pushUpload version to server (staging)
lua deployMake that version live for all users

7. Environment Variables

Sandbox vs Production

EnvironmentSource
SandboxLocal .env file or CLI env variables
ProductionStored on server (set via lua env production)

Commands

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

8. Debugging with lua logs

This is the core debugging command. All console.log, console.error, etc. output appears here.
Works for ALL request types: lua test, lua chat, production requests.
# View all logs
lua logs --type all --limit 50

# Filter by type
lua logs --type skill --name mySkill --limit 10
lua logs --type job --name healthCheck --json
lua logs --type webhook --limit 20

# Pagination
lua logs --type all --limit 20 --page 2

Log Types

TypeDescription
allAll logs
skillSkill/tool executions
jobJob executions
webhookWebhook executions
preprocessorPreProcessor executions
postprocessorPostProcessor executions
user_messageUser messages
agent_responseAgent responses

9. Sandbox Overrides

When using lua chat -e sandbox, the following can be overridden with local compiled code without needing to push/deploy:
ComponentHow it works
SkillsLocal compiled code pushed to Redis cache
PersonaLocal persona overrides deployed production persona
PreProcessorsLocal code pushed to Redis cache
PostProcessorsLocal code pushed to Redis cache
EnvironmentLocal .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 are sandbox globals

Warning Signs

IssueMeaning
Empty bundles (< 100 bytes)Something went wrong during bundling
”Could not resolve” errorsCheck imports/dependencies
”Transform failed”TypeScript syntax issues

Debug Mode

Run with --debug for verbose compilation output:
lua compile --debug

11. Platform APIs Available at Runtime

These are available as globals in the VM sandbox (don’t import from lua-cli):
APIDescription
UserUser data management
DataCustom data collections
ProductsProduct catalog
BasketsShopping cart
OrdersOrder management
AIAI generation
LuaRequest context (Lua.request.channel, Lua.request.webhook)
JobsJob scheduling
TemplatesMessage templates
CDNFile upload/retrieval
env(key)Environment variable access
fetchHTTP requests
consoleLogging (appears in lua logs)

12. Third-Party Integrations (POWERFUL FEATURE)

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.

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:
lua integrations connect --integration linear --auth-method oauth --scopes all
And your agent instantly gets tools like linear_create_issue, linear_list_projects, linear_update_task, etc.

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. Event-Driven - Optionally subscribe to webhooks to react to events

Connecting an Integration

# View available integrations
lua integrations available

# Connect with OAuth (recommended)
lua integrations connect --integration linear --auth-method oauth --scopes all

# Connect with specific scopes
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>

Testing Integration Tools

After connecting, test immediately:
# Clear conversation for fresh context
lua chat clear --force

# Test the integration tools
lua chat -e sandbox -m "Create a Linear issue titled 'Test from Lua' in my default project"

lua chat -e sandbox -m "List my upcoming Google Calendar events"

lua chat -e sandbox -m "Send a message to the #general channel on Discord"

Available Integrations (250+)

Common integrations include:
CategoryExamples
Task ManagementLinear, Asana, Jira, Monday.com, ClickUp, Notion
CommunicationDiscord, Slack, Microsoft Teams, Telegram
CalendarGoogle Calendar, Outlook Calendar, Calendly
CRMHubSpot, Salesforce, Pipedrive, Zoho CRM
DevelopmentGitHub, GitLab, Bitbucket
StorageGoogle Drive, Dropbox, OneDrive, Box
SupportZendesk, Intercom, Freshdesk
EmailGmail, Outlook, SendGrid
Run lua integrations available to see all available integrations for your workspace.

Event-Driven Workflows with Webhooks

You can subscribe to events from connected integrations:
# List available webhook events for a connection
lua integrations webhooks create  # Interactive - shows available events

# Create a webhook subscription
lua integrations webhooks create \
  --connection <connection-id> \
  --object task_task \
  --event created \
  --webhook https://webhook.heylua.ai/myagent/linear-handler

# List webhook subscriptions
lua integrations webhooks list

# Delete a subscription
lua integrations webhooks delete --webhook-id <id>
Example workflow: When a Linear issue is created, trigger your LuaWebhook to notify a Discord channel.

Managing MCP Servers for Integrations

Each integration creates an MCP server. You can manage them:
# 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

# 1. Check available integrations
lua integrations available

# 2. Connect Linear
lua integrations connect --integration linear --auth-method oauth --scopes all
# (Complete OAuth in browser)

# 3. Verify connection
lua integrations list

# 4. Clear chat history for fresh test
lua chat clear --force

# 5. Test the integration
lua chat -e sandbox -m "List all Linear projects I have access to"

lua chat -e sandbox -m "Create a task in Linear: Review documentation updates"

# 6. (Optional) Set up webhook for events
lua integrations webhooks create \
  --connection <linear-connection-id> \
  --object task_task \
  --event created \
  --webhook https://webhook.heylua.ai/myagent/linear-handler

# 7. The agent now has full Linear capabilities!

Key Points for AI Agents

Important for AI coding assistants building Lua agents:
  1. Ask the user what third-party services they want to connect
  2. Run lua integrations available to see what’s available
  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

13. Complete Workflow Example

# 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 [email protected]
# (user receives OTP via email)
lua auth configure --email [email protected] --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. Clear conversation and test with full agent (sandbox)
lua chat clear --force
lua chat -e sandbox -m "Get order 123"
lua chat -e sandbox -m "Create a Linear issue for order 123 review"  # If Linear connected

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

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

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

# 11. Test production
lua chat -e production -m "Get order 123"

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

Quick Reference: Non-Interactive Commands

TaskCommand
Authenticate with API keylua auth configure --api-key <key>
Request email OTPlua auth configure --email <email>
Verify email OTPlua auth configure --email <email> --otp <code>
Initialize with existing agentlua init --agent-id <id>
Initialize with new agentlua init --agent-name <name> --org-id <id>
Test a toollua test skill --name <name> --input '<json>'
Test a webhooklua test webhook --name <name> --input '<json>'
Test a joblua test job --name <name>
Chat in sandboxlua chat -e sandbox -m "<message>"
Chat in productionlua chat -e production -m "<message>"
Clear conversation historylua chat clear --force
Clear user’s historylua chat clear --user <email|mobile|userId> --force
View available integrationslua integrations available
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 integrationslua integrations list
Update integration scopeslua integrations update --integration <type> --scopes all
Disconnect integrationlua integrations disconnect --connection-id <id>
List integration webhookslua integrations webhooks list
Create integration webhooklua integrations webhooks create --connection <id> --object <type> --event <event> --webhook <url>
Delete integration webhooklua integrations webhooks delete --webhook-id <id>
List integration MCP statuslua integrations mcp list
Push alllua push all --force
Push and deploylua push all --force --auto-deploy
Deploy specific versionlua deploy --skill-name <name> --skill-version <ver> --force
Set env variablelua env <sandbox|production> -k <key> -v <value>
View logslua logs --type <type> --name <name> --limit <n>