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

# Tools

> Individual functions your agent can execute

## What is a Tool?

A **tool** is a single function that your AI agent can execute. Tools are the building blocks that give your agent real capabilities.

<Card title="Think of it as:" icon="wrench">
  A TypeScript function that does ONE specific thing - like "search products" or "check order status"
</Card>

<Note>
  Tools are bundled into skills, which are then added to your agent through the `LuaAgent` class. See [Agent Concept](/overview/agent) for the complete pattern.
</Note>

## Anatomy of a Tool

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

class SearchProductsTool implements LuaTool {
  // 1. Name - unique identifier
  name = "search_products";
  
  // 2. Description - what it does
  description = "Search for products in catalog";
  
  // 3. Input Schema - what it needs
  inputSchema = z.object({
    query: z.string().describe("Search query")
  });
  
  // 4. Execute - what it does
  async execute(input: { query: string }) {
    // Call your API or external service
    const response = await fetch(`https://your-api.com/search?q=${input.query}`);
    return await response.json();
  }
}
```

<CardGroup cols={2}>
  <Card title="Name" icon="tag">
    Unique identifier (snake\_case)
  </Card>

  <Card title="Description" icon="file-text">
    Clear explanation of purpose
  </Card>

  <Card title="Input Schema" icon="shield-check">
    Zod validation for inputs
  </Card>

  <Card title="Execute Function" icon="bolt">
    The actual logic
  </Card>
</CardGroup>

## Good vs Bad Tools

<Tabs>
  <Tab title="❌ Bad Tool">
    ```typescript theme={null}
    class BadTool implements LuaTool {
      name = "tool1";  // Unclear name
      description = "Does stuff";  // Vague description
      
      inputSchema = z.object({
        input: z.string()  // Unclear parameter
      });
      
      async execute(input) {
        // No error handling
        // No validation
        // Returns unclear data
        return "done";
      }
    }
    ```

    **Problems:**

    * Unclear name
    * Vague description
    * Generic input
    * No error handling
    * Unclear return value
  </Tab>

  <Tab title="✅ Good Tool">
    ```typescript theme={null}
    class SearchProductsTool implements LuaTool {
      name = "search_products";  // Clear, descriptive
      description = "Search product catalog by name, category, or keyword";  // Specific
      
      inputSchema = z.object({
        query: z.string().describe("Search query (e.g., 'laptop', 'running shoes')"),
        maxPrice: z.number().optional().describe("Maximum price filter")
      });
      
      async execute(input: { query: string; maxPrice?: number }) {
        try {
          // Call your API
          const response = await fetch(
            `https://your-api.com/search?q=${input.query}`
          );
          
          if (!response.ok) {
            throw new Error(`Search failed: ${response.statusText}`);
          }
          
          let products = await response.json();
          
          // Apply price filter if specified
          if (input.maxPrice) {
            products = products.filter(p => p.price <= input.maxPrice);
          }
          
          // Return structured data
          return {
            products: products.map(p => ({
              id: p.id,
              name: p.name,
              price: `$${p.price.toFixed(2)}`,
              category: p.category,
              inStock: p.inStock
            })),
            count: products.length,
            query: input.query
          };
          
        } catch (error) {
          throw new Error(`Failed to search products: ${error.message}`);
        }
      }
    }
    ```

    **Why it's good:**

    * Clear, descriptive name
    * Detailed description
    * Validated inputs
    * Error handling
    * Structured return value
    * Comments explain logic
  </Tab>
</Tabs>

## Tool Types

### 1. External API Tools

Connect to any external service:

```typescript theme={null}
class GetWeatherTool implements LuaTool {
  name = "get_weather";
  description = "Get current weather for a city";
  
  inputSchema = z.object({
    city: z.string()
  });
  
  async execute(input: { city: string }) {
    // Call external weather API
    const response = await fetch(
      `https://api.weather.com/v1/current?city=${input.city}`
    );
    return await response.json();
  }
}
```

### 2. Platform API Tools

Use Lua's built-in APIs:

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

class SearchProductsTool implements LuaTool {
  name = "search_products";
  description = "Search product catalog";
  
  inputSchema = z.object({
    query: z.string()
  });
  
  async execute(input: { query: string }) {
    // Use Platform API
    return await Products.search(input.query);
  }
}
```

### 3. Hybrid Tools

Mix both approaches:

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

class SmartSearchTool implements LuaTool {
  async execute(input: { query: string }) {
    // 1. Search YOUR external API
    const yourProducts = await fetch('https://your-api.com/search');
    
    // 2. Search Platform vector search
    const docs = await Data.search('help_docs', input.query);
    
    // 3. Combine results
    return { yourProducts, docs };
  }
}
```

### 4. Conditional Tools

Tools that are only available under certain conditions:

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

class PremiumFeatureTool implements LuaTool {
  name = "premium_feature";
  description = "Advanced feature for premium users";
  
  inputSchema = z.object({ query: z.string() });
  
  // Only show to premium users
  condition = async () => {
    const user = await User.get();
    return user.data?.isPremium === true;
  };
  
  async execute(input) {
    // Only runs if condition returned true
    return { result: "premium data" };
  }
}
```

<Note>
  The `condition` function runs before the tool is offered to the AI. If it returns `false` or throws an error, the tool is hidden from the conversation.
</Note>

**Use cases for conditional tools:**

* Premium/paid features
* User verification status
* Feature flags & A/B testing
* Region-specific tools
* Time-based access

## Tool Best Practices

<AccordionGroup>
  <Accordion title="Use Descriptive Names">
    ```typescript theme={null}
    // ✅ Good
    name = "search_products"
    name = "create_order"
    name = "cancel_booking"

    // ❌ Bad
    name = "search"  // Too generic
    name = "tool1"   // Not descriptive
    name = "do_stuff"  // Unclear
    ```
  </Accordion>

  <Accordion title="Write Clear Descriptions">
    ```typescript theme={null}
    // ✅ Good
    description = "Search product catalog by name, category, or keyword"

    // ❌ Bad
    description = "Searches stuff"
    ```
  </Accordion>

  <Accordion title="Validate Inputs">
    ```typescript theme={null}
    inputSchema = z.object({
      email: z.string().email(),
      age: z.number().min(0).max(120),
      priority: z.enum(['low', 'medium', 'high'])
    });
    ```
  </Accordion>

  <Accordion title="Handle Errors">
    ```typescript theme={null}
    async execute(input) {
      try {
        const result = await api.call(input);
        return result;
      } catch (error) {
        throw new Error(`Operation failed: ${error.message}`);
      }
    }
    ```
  </Accordion>

  <Accordion title="Return Structured Data">
    ```typescript theme={null}
    // ✅ Good - Structured
    return {
      success: true,
      data: { id, name, price },
      message: "Product found"
    };

    // ❌ Bad - Unstructured string
    return "Product found: ID 123";
    ```
  </Accordion>
</AccordionGroup>

## Testing Tools

<Tabs>
  <Tab title="Test Individual Tool">
    ```bash theme={null}
    lua test
    ```

    * Select specific tool
    * Enter test inputs
    * Verify output
    * Debug tool logic
  </Tab>

  <Tab title="Test in Conversation">
    ```bash theme={null}
    lua chat
    ```

    * Test how AI selects tool
    * Verify tool execution
    * Check output formatting
    * Test error cases
  </Tab>
</Tabs>

## Managing Tools

<CardGroup cols={2}>
  <Card title="Create" icon="plus">
    Write tools in `src/tools/`
  </Card>

  <Card title="Bundle" icon="box">
    Add to skills in `src/index.ts`
  </Card>

  <Card title="Test" icon="flask">
    ```bash theme={null}
    lua test
    ```
  </Card>

  <Card title="Deploy" icon="rocket">
    ```bash theme={null}
    lua push
    lua deploy
    ```
  </Card>
</CardGroup>

## Next Steps

<CardGroup cols={2}>
  <Card title="Learn About Skills" icon="puzzle-piece" href="/overview/skill">
    How tools are bundled into skills
  </Card>

  <Card title="See Tool Examples" icon="layer-group" href="/examples/overview">
    30+ working tool examples
  </Card>

  <Card title="API Reference" icon="book" href="/api/luatool">
    Complete LuaTool interface documentation
  </Card>

  <Card title="Build Your First Tool" icon="hammer" href="/getting-started/first-skill">
    Step-by-step tutorial
  </Card>
</CardGroup>
