npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

lettactl

v0.5.13

Published

kubectl-style CLI for managing Letta AI agent fleets

Readme

LettaCTL

CI License: MIT TypeScript

Need help? Join the Letta Discord for support and discussions.

A kubectl-style CLI for managing stateful Letta AI agent fleets with declarative configuration. Think "Docker Compose" but for AI agents - define your entire agent setup in YAML and deploy with one command.

Two Ways to Use LettaCtl

| CLI Tool | Programmatic SDK | |--------------|---------------------| | Command-line interface | Library for applications | | Automated fleet management | Dynamic agent creation | | npm install -g lettactl | npm install lettactl | | Perfect for DevOps workflows | Perfect for SaaS platforms |

Prerequisites

  • Node.js 18+
  • A running Letta server instance

CLI Usage

For DevOps workflows

Installation

# Install globally from npm
npm install -g lettactl

# Set up your environment
export LETTA_API_URL=http://localhost:8283  # For self-hosting
export LETTA_API_KEY=your_api_key           # Only needed for Letta Cloud

Your First Fleet

Create a file called agents.yml

# Fleet configuration demonstrating lettactl's capabilities
# Two different agent types showing various features

shared_blocks:  # Memory blocks shared across agents
  - name: shared_guidelines
    description: "Shared operational guidelines for all agents"
    limit: 5000
    from_file: "memory-blocks/shared-guidelines.md"  # Load from file

agents:
  # 1. Simple agent with files only
  - name: document-assistant
    description: "AI assistant for document analysis and processing"
    llm_config:  # Required LLM settings
      model: "google_ai/gemini-2.5-pro"
      context_window: 32000
    system_prompt:
      value: "You are a document assistant. Help users analyze, summarize, and understand documents."
    folders:  # Files attached to agent
      - name: documents
        files:
          - "files/*"  # Auto-discover all files in files/
    embedding: "letta/letta-free"

  # 2. Cloud-powered agent using Supabase storage  
  - name: cloud-assistant
    description: "AI assistant powered by cloud storage"
    llm_config:
      model: "google_ai/gemini-2.5-pro" 
      context_window: 32000
    system_prompt:
      from_bucket:  # Load prompt from cloud storage
        provider: supabase
        bucket: test-bucket
        path: prompts/system-prompt.md
    shared_blocks:  # Use shared memory blocks
      - shared_guidelines
    memory_blocks:  # Agent-specific memory
      - name: cloud_knowledge
        description: "Knowledge base from cloud storage"
        limit: 8000
        from_bucket:  # Load content from cloud storage
          provider: supabase
          bucket: test-bucket
          path: knowledge/example.md
    embedding: "letta/letta-free"

Deploy the entire fleet:

lettactl apply -f agents.yml  # Deploy all agents and shared resources

That's it! Your entire fleet is now running with shared resources and cloud storage.

Commands

Deploy Configuration

lettactl apply -f agents.yml           # Deploy all agents
lettactl apply -f agents.yml --agent my-agent  # Deploy specific agent
lettactl apply -f agents.yml --dry-run # See what would change
lettactl apply -f agents.yml --root . # Specify root directory for file resolution
lettactl apply -f agents.yml -v       # Verbose output

# Template mode: apply config to existing agents matching a glob pattern
lettactl apply -f template.yaml --match "*-assistant"  # All agents ending in -assistant
lettactl apply -f template.yaml --match "user-*"       # All agents starting with user-
lettactl apply -f template.yaml --match "*" --dry-run  # Preview changes to all agents

Template Mode (--match): Apply a template configuration to multiple existing agents at once. Uses merge semantics - adds/updates tools, blocks, and prompts without removing existing resources. Perfect for propagating tool updates or shared config changes across agent fleets.

Create Agents

# Create basic agent
lettactl create agent my-agent --description "My helpful assistant"

# Create with full configuration
lettactl create agent advanced-agent \
  --description "Advanced AI assistant" \
  --model "google_ai/gemini-2.5-pro" \
  --system "You are an expert assistant." \
  --context-window 32000 \
  --embedding "letta/letta-free" \
  --tags "production,assistant"

Update Agents

# Update description and model
lettactl update agent my-agent \
  --description "Updated description" \
  --model "google_ai/gemini-2.5-flash"

# Update system prompt and tags
lettactl update agent my-agent \
  --system "You are a specialized assistant." \
  --tags "updated,specialized"

Export/Import Agents

# Export agent to file
lettactl export agent my-agent --output my-agent-backup.json

# Export with legacy format
lettactl export agent my-agent --legacy-format --output legacy-backup.json

# Import agent from file
lettactl import my-agent-backup.json

# Import with custom name and copy suffix
lettactl import my-agent-backup.json \
  --name restored-agent \
  --append-copy

Message Operations

# List agent conversation history
lettactl messages my-agent --limit 10

# Send a message to an agent
lettactl send my-agent "Hello, how are you?"

# Send with streaming response
lettactl send my-agent "Tell me about Tokyo" --stream

# Send asynchronous message
lettactl send my-agent "Plan a 7-day itinerary" --async

# Reset agent's conversation history
lettactl reset-messages my-agent --add-default

# Compact agent's message history (summarize)
lettactl compact-messages my-agent

# Cancel running message processes
lettactl cancel-messages my-agent --run-ids "run1,run2"

Bulk Delete Operations

# Preview agents to be deleted (safe mode)
lettactl delete-all agents --pattern "test.*"           # Shows what would be deleted
lettactl delete-all agents                              # Preview all agents

# Bulk delete with pattern matching
lettactl delete-all agents --pattern "test.*" --force   # Delete all test agents
lettactl delete-all agents --pattern "dev.*" --force    # Delete all dev agents
lettactl delete-all agents --pattern "(old|temp).*" --force  # Complex patterns

# Pattern matching by agent ID (useful for cleanup)
lettactl delete-all agents --pattern ".*abc123.*" --force    # Match partial IDs

# Nuclear option - delete everything (be careful!)
lettactl delete-all agents --force                      # Deletes ALL agents

# Case-insensitive matching
lettactl delete-all agents --pattern "PROD.*" --force   # Matches "prod-agent-1", etc.

What gets deleted:

  • Agent-specific memory blocks
  • Agent-specific folders (if not shared)
  • Associated conversation history

What gets preserved:

  • Shared blocks and folders used by other agents

Safety Features:

  • Always shows preview before deletion
  • Requires explicit --force confirmation
  • Preserves shared resources used by other agents
  • Pattern matching is case-insensitive
  • Supports complex regex patterns

View Resources

# List resources
lettactl get agents                    # List all agents
lettactl get blocks                    # List all memory blocks
lettactl get tools                     # List all tools
lettactl get folders                   # List all folders

# Wide output with extra columns (agent counts, sizes, models)
lettactl get agents -o wide
lettactl get blocks -o wide
lettactl get tools -o wide

# Scoped to specific agent
lettactl get blocks -a my-agent        # Blocks attached to my-agent
lettactl get tools -a my-agent         # Tools attached to my-agent
lettactl get folders -a my-agent       # Folders attached to my-agent

# Fleet analysis
lettactl get tools --shared            # Tools used by 2+ agents
lettactl get blocks --orphaned         # Blocks not attached to any agent
lettactl get folders --shared -o wide  # Shared folders with agent counts

# Detailed resource info
lettactl describe agent my-agent       # Agent details + blocks/tools/folders
lettactl describe block persona        # Block details + attached agents + value preview
lettactl describe tool my-tool         # Tool details + attached agents + source code
lettactl describe folder docs          # Folder details + files + attached agents

# JSON output for scripting
lettactl get agents -o json
lettactl describe tool my-tool -o json

# Conversation history
lettactl messages my-agent             # View conversation history

Validate Configuration

lettactl validate -f agents.yml       # Check config syntax

SDK Usage

For building applications with dynamic agent creation.

Installation

# Install locally for programmatic usage (choose your flavor)
npm install lettactl

# Or
yarn install lettactl 

# Or
pnpm install lettactl

Three Usage Patterns

1. Dynamic YAML Generation

Write YAML configuration as strings and deploy directly:

import { LettaCtl } from 'lettactl';

const lettactl = new LettaCtl({
  lettaApiUrl: 'http://localhost:8283'
});

const userId = 'acme-corp';

// Write YAML configuration as a string with dynamic values
const yamlConfig = `
shared_blocks:  # Memory blocks shared across agents
  - name: shared-guidelines
    description: "Shared operational guidelines for all agents"
    limit: 5000
    value: "Common guidelines for all user agents."

agents:
  - name: user-${userId}-assistant  # Dynamic user ID
    description: "AI assistant for user ${userId}"
    llm_config:  # Required LLM settings
      model: "google_ai/gemini-2.5-pro"
      context_window: 32000
    system_prompt:  # How the agent behaves
      value: "You are an assistant for user ${userId}."
    shared_blocks:  # Use shared memory blocks
      - shared-guidelines
    embedding: "letta/letta-free"
`;

// Deploy directly from YAML string (no file I/O needed)
await lettactl.deployFromYamlString(yamlConfig);

2. Existing YAML Deployment

Deploy existing YAML files programmatically:

// Deploy existing configs
await lettactl.deployFromYaml('./configs/production.yaml');

// With filtering
await lettactl.deployFromYaml('./configs/all-agents.yaml', {
  agentPattern: 'user-123',  // Only deploy matching agents
  dryRun: true               // Preview changes
});

3. Direct Deployment

Build and deploy fleet configurations directly in memory:

// Build a fleet with shared resources and multiple agent types
const fleet = lettactl.createFleetConfig()
  .addSharedBlock({  // Shared memory across agents
    name: 'shared-guidelines',
    description: 'Shared operational guidelines',
    limit: 5000,
    value: 'Common guidelines for all user agents.'
  })
  .addAgent({  // Simple document-focused agent
    name: 'user-123-document-assistant',
    description: 'Document assistant for user 123',
    llm_config: { model: 'google_ai/gemini-2.5-pro', context_window: 32000 },
    system_prompt: { value: 'You analyze documents for user 123.' },
    folders: [{ name: 'documents', files: ['files/*'] }]  // Auto-discover files
  })
  .addAgent({  // Cloud-powered agent with shared memory
    name: 'user-123-cloud-assistant', 
    description: 'Cloud assistant for user 123',
    llm_config: { model: 'google_ai/gemini-2.5-pro', context_window: 32000 },
    system_prompt: { value: 'You are a cloud-powered assistant for user 123.' },
    shared_blocks: ['shared-guidelines'],  // Use shared memory
    memory_blocks: [{
      name: 'user-knowledge',
      description: 'User-specific knowledge base',
      limit: 8000,
      value: 'User 123 knowledge and preferences.'
    }]
  })
  .build();

await lettactl.deployFleet(fleet);  // Deploy entire fleet

Multi-Tenant SaaS Example

Create agents dynamically for different users:

const lettactl = new LettaCtl();

// Single user onboarding
const userId = 'acme-corp';
const companyInfo = 'Acme Corp is a B2B software company specializing in CRM solutions.';

const fleet = lettactl.createFleetConfig()
  .addAgent({
    name: `${userId}-assistant`,
    description: `AI assistant for ${userId}`,
    llm_config: { model: 'google_ai/gemini-2.5-pro', context_window: 32000 },
    system_prompt: { 
      value: `You are an AI assistant for ${userId}. Help with tasks and answer questions.`,
      disable_base_prompt: false  // Optional: control base prompt combination
    },
    memory_blocks: [{
      name: 'company-info',
      description: 'User company information',
      limit: 8000,
      value: companyInfo
    }]
  })
  .build();

await lettactl.deployFleet(fleet);

// Batch user onboarding
const users = [
  { id: 'startup-1', info: 'Tech startup focused on AI tools' },
  { id: 'enterprise-2', info: 'Large enterprise with complex workflows' },
  { id: 'agency-3', info: 'Marketing agency serving B2B users' }
];

const batchFleet = lettactl.createFleetConfig();
for (const user of users) {
  batchFleet.addAgent({
    name: `${user.id}-assistant`,
    description: `AI assistant for ${user.id}`,
    llm_config: { model: 'google_ai/gemini-2.5-pro', context_window: 32000 },
    system_prompt: { value: `You are an AI assistant for ${user.id}.` },
    memory_blocks: [{ 
      name: 'company-info', 
      description: 'Company information', 
      limit: 8000, 
      value: user.info 
    }]
  });
}

await lettactl.deployFleet(batchFleet.build());

Configuration Reference

Essential Configuration

LLM Configuration (Required)

Every agent needs an LLM configuration as the first key:

agents:
  - name: my-agent
    llm_config:
      model: "google_ai/gemini-2.5-pro"     # Required: which model to use
      context_window: 32000                  # Required: context window size

System Prompts

Define how your agent behaves with system prompts. You have two options:

Option 1: Inline prompt

system_prompt:
  value: |
    You are a helpful AI assistant focused on...

Option 2: File-based prompt (recommended)

system_prompt:
  from_file: "prompts/my-agent-prompt.md"

The system automatically combines your prompt with base Letta instructions for optimal behavior.

Advanced Option: Disabling Base Prompt Combination

system_prompt:
  from_file: "prompts/my-custom-prompt.md"
  disable_base_prompt: true  # Use only your prompt, skip base Letta instructions

By default, lettactl prepends base Letta system instructions (memory management, tool usage patterns, etc.) to your custom prompt. Set disable_base_prompt: true to use only your prompt content - useful when you want complete control over the system prompt or are experimenting with custom agent behaviors.

Memory Blocks

Give your agents persistent memory with two content options:

Option 1: Inline content

memory_blocks:
  - name: user_preferences
    description: "What the user likes and dislikes"
    limit: 2000
    value: "User prefers short, direct answers."

Option 2: File-based content (recommended for large content)

memory_blocks:
  - name: company_knowledge
    description: "Company knowledge base"
    limit: 10000
    from_file: "memory-blocks/company-info.md"

File Attachments

Attach documents to your agents with powerful auto-discovery:

Option 1: Auto-discover all files (recommended for large document sets)

folders:
  - name: documents
    files:
      - "files/*"      # All files in files/ directory
      - "files/**/*"   # All files recursively (subdirectories too)

Option 2: Specific files and patterns

folders:
  - name: documents
    files:
      - "files/manual.pdf"
      - "files/guidelines.txt"
      - "files/specs/*.md"  # All markdown in specs/ subdirectory

Auto-Discovery Features:

  • files/* - Discovers ALL files in the files/ directory automatically
  • files/**/* - Recursively discovers files in subdirectories
  • tools/* - Auto-discovers all Python tools in tools/ directory
  • No need to manually list every file!

Intelligent Updates

lettactl only updates what actually changed and preserves conversation history:

  • Edit tool source code → Tools automatically re-registered
  • Change memory block files → Content updated seamlessly
  • Modify documents → Files re-uploaded to folders
  • Update config → Agent settings changed
  • No changes → Nothing happens (fast!)
# Edit anything
vim tools/my_tool.py
vim memory-blocks/user-data.md
vim agents.yml

# Deploy - only changed parts update
lettactl apply -f agents.yml
# Conversation history preserved

Complete Configuration Reference

Agent Schema

agents:
  - name: agent-name                    # Required: unique identifier
    description: "What this agent does" # Required: human description
    
    # LLM configuration (required, should be first)
    llm_config:
      model: "google_ai/gemini-2.5-pro" # Required
      context_window: 32000             # Required
    
    # System prompt (required)
    system_prompt:
      value: "Direct prompt text"       # Option 1: inline
      from_file: "prompts/agent.md"    # Option 2: from file
      disable_base_prompt: false       # Option 3: skip base Letta instructions (default: false)
    
    # Tools (optional)
    tools:
      - archival_memory_insert          # Built-in tools
      - archival_memory_search
      - tools/*                         # Auto-discover from tools/ folder
      - custom_tool_name                # Specific custom tools
    
    # Shared blocks (optional)
    shared_blocks:
      - shared_block_name
    
    # Agent-specific memory blocks (optional)
    memory_blocks:
      - name: block_name
        description: "What this block stores"
        limit: 5000                     # Character limit
        version: "optional-tag"         # Optional: your version tag
        value: "Direct content"         # Option 1: inline
        from_file: "blocks/file.md"    # Option 2: from file
    
    # File attachments (optional)
    folders:
      - name: folder_name
        files:
          - "files/*"                   # Auto-discover files
          - "files/specific-file.pdf"   # Specific files
    
    embedding: "letta/letta-free"       # Optional: embedding model

Shared Blocks Schema

shared_blocks:
  - name: block_name
    description: "Shared across agents"
    limit: 10000
    version: "optional-tag"             # Optional: your version tag
    value: "Content here"               # Option 1: inline
    from_file: "shared/file.md"        # Option 2: from file

File Organization

lettactl expects this folder structure:

your-project/
├── agents.yml              # Main configuration
├── config/                 # Base system configuration
│   └── base-letta-system.md
├── prompts/                 # System prompts
│   ├── agent1-prompt.md
│   └── agent2-prompt.md
├── memory-blocks/          # Memory block content
│   ├── shared/
│   ├── agent1/
│   └── agent2/
├── files/                  # Files to attach to agents
│   ├── document1.pdf
│   └── document2.md
└── tools/                  # Custom Python tools
    ├── tool1.py
    └── tool2.py

Advanced Features

Environment Management

# Self-hosting Letta
export LETTA_API_URL=http://localhost:8283
# API key is optional for self-hosting

# Letta Cloud  
export LETTA_API_URL=https://api.letta.com
export LETTA_API_KEY=your_cloud_key  # Required for cloud

Supabase Storage Integration

For cloud storage support, lettactl can read agent configuration files from Supabase buckets. More cloud storage options coming soon.

# Required environment variables
export SUPABASE_URL=https://your-project.supabase.co
export SUPABASE_ANON_KEY=sb_publishable_your_anon_key

Important: Use the ANON key, not the service role key

  • Go to Supabase Dashboard > Settings > API
  • Copy the "anon public" key (starts with sb_publishable_...)
  • Do NOT use the "service role" key for lettactl

Bucket Configuration:

Your Supabase bucket must be either:

  1. Public bucket (recommended for shared configurations)
  2. Private bucket with RLS policy allowing anon key access

Example with cloud storage:

agents:
  - name: cloud-agent
    system_prompt:
      from_bucket:
        provider: supabase
        bucket: my-configs
        path: prompts/agent-prompt.md
    memory_blocks:
      - name: knowledge_base
        from_bucket:
          provider: supabase
          bucket: my-configs  
          path: knowledge/company-info.md

Implementation Notes

Stateless Design

Like kubectl, lettactl is completely stateless:

  • No local configuration files or session data stored
  • Each command is independent and relies on remote APIs (Letta, Supabase)
  • All agent state is managed by the Letta server, not lettactl
  • Consistent behavior across different machines and environments

Debugging & Fleet Inspection

Comprehensive commands for understanding your agent fleet:

# Quick health check
lettactl get agents                    # Are agents running?
lettactl get agents -o wide            # Check models, block/tool counts

# Find resource usage across fleet
lettactl get tools --shared -o wide    # Which tools are reused?
lettactl get blocks --shared -o wide   # Which blocks are shared?
lettactl get folders --shared -o wide  # Which folders are shared?

# Find orphaned resources (cleanup candidates)
lettactl get blocks --orphaned         # Blocks attached to 0 agents
lettactl get tools --orphaned          # Tools attached to 0 agents
lettactl get folders --orphaned        # Folders attached to 0 agents

# Inspect specific agent's resources
lettactl get blocks -a my-agent        # What memory does this agent have?
lettactl get tools -a my-agent         # What can this agent do?
lettactl get folders -a my-agent       # What documents can it access?

# Deep inspection
lettactl describe agent my-agent       # Full agent config + resources
lettactl describe tool my-tool         # Source code + which agents use it
lettactl describe block persona        # Value preview + which agents use it
lettactl describe folder docs          # File list + which agents use it

# Export for analysis
lettactl get tools --shared -o json | jq '.[] | .name'
lettactl describe agent my-agent -o json > agent-snapshot.json

Troubleshooting

Use verbose mode when debugging:

lettactl apply -v -f agents.yml

Check connection:

lettactl get agents

Validate config:

lettactl validate -f agents.yml