Operations Guide

January 29, 2026 · View on GitHub

Deployment, monitoring, troubleshooting, and runbooks

Deployment

Prerequisites

  • Node.js 20.0.0 or higher
  • npm or yarn package manager
  • Optional: GitHub CLI (gh) for GitHub features
  • Optional: Ollama for local LLM inference

Installation Methods

NPM Global Install

npm install -g @blackms/aistack

NPM Local Install

npm install @blackms/aistack

From Source

git clone https://github.com/blackms/aistack.git
cd aistack
npm install
npm run build

Initialization

# Create new project
npx aistack init

# With custom path
npx aistack init --path ./my-project

This creates:

./
├── aistack.config.json    # Configuration
├── data/                  # Database directory
└── plugins/               # Plugin directory

Configuration

Minimal Configuration

{
  "version": "1.0.0",
  "providers": {
    "default": "anthropic",
    "anthropic": {
      "apiKey": "${ANTHROPIC_API_KEY}"
    }
  }
}

Full Configuration

{
  "version": "1.0.0",
  "memory": {
    "path": "./data/aistack.db",
    "defaultNamespace": "default",
    "vectorSearch": {
      "enabled": true,
      "provider": "openai",
      "model": "text-embedding-3-small"
    }
  },
  "providers": {
    "default": "anthropic",
    "anthropic": {
      "apiKey": "${ANTHROPIC_API_KEY}",
      "model": "claude-sonnet-4-20250514"
    },
    "openai": {
      "apiKey": "${OPENAI_API_KEY}",
      "model": "gpt-4o"
    },
    "ollama": {
      "baseUrl": "http://localhost:11434",
      "model": "llama3.2"
    }
  },
  "agents": {
    "maxConcurrent": 5,
    "defaultTimeout": 300
  },
  "github": {
    "enabled": true,
    "useGhCli": true
  },
  "plugins": {
    "enabled": true,
    "directory": "./plugins"
  },
  "mcp": {
    "transport": "stdio"
  },
  "hooks": {
    "sessionStart": true,
    "sessionEnd": true,
    "preTask": true,
    "postTask": true
  }
}

Claude Code Integration

Add AgentStack as an MCP server:

claude mcp add agentstack -- npx @blackms/aistack mcp start

Or manually edit Claude Code settings:

{
  "mcpServers": {
    "agentstack": {
      "command": "npx",
      "args": ["@blackms/aistack", "mcp", "start"]
    }
  }
}

Environment Variables

VariableDescriptionRequired
ANTHROPIC_API_KEYAnthropic API keyIf using Anthropic
OPENAI_API_KEYOpenAI API keyIf using OpenAI/embeddings
GITHUB_TOKENGitHub tokenIf not using gh CLI

CLI Providers

AgentStack supports CLI-based providers for agent execution:

ProviderCLI ToolInstallation
Claude Codeclaudenpm install -g @anthropic-ai/claude-code
Gemini CLIgeminipip install google-generativeai
CodexcodexInstall from Codex repository

Verify CLI provider availability:

# Check Claude Code
claude --version

# Check Gemini CLI
gemini --version

# Check Codex
codex --version

Monitoring

System Status

# CLI status check
npx aistack status

Output:

AgentStack Status
─────────────────
Agents: 3 active (1 idle, 2 running)
Memory: 150 entries in 2 namespaces
Tasks: 5 pending, 2 processing
Health: All systems operational

MCP Tool: system_status

Returns JSON with current metrics:

{
  "agents": {
    "active": 3,
    "byStatus": { "idle": 1, "running": 2 }
  },
  "memory": {
    "entries": 150,
    "namespaces": ["default", "architecture"]
  },
  "tasks": {
    "pending": 5,
    "processing": 2
  }
}

MCP Tool: system_health

Health check with component status:

{
  "status": "healthy",
  "checks": {
    "database": true,
    "vectorSearch": true,
    "github": false
  }
}

Logging

Set log level via CLI:

# Debug logging
npx aistack -v mcp start

# Quiet (errors only)
npx aistack -q mcp start

Log levels: debug < info < warn < error

Log Output Format

[2024-01-01T00:00:00.000Z] [INFO] [mcp] Registered MCP tools {"count":30}
[2024-01-01T00:00:01.000Z] [DEBUG] [mcp] Calling tool {"name":"agent_spawn","args":{...}}

Real-Time Agent Monitoring

Use agent watch command for live monitoring of agent activity:

# Basic monitoring (2-second refresh)
npx aistack agent watch

# Fast refresh (1-second interval)
npx aistack agent watch --interval 1

# Monitor specific session
npx aistack agent watch --session <session-id>

# Monitor only running agents
npx aistack agent watch --status running

# JSON output for scripting
npx aistack agent watch --json

What You See:

  • Active agent count vs. max concurrent limit
  • Agent table: name, type, status, uptime, current task
  • Status distribution: idle, running, completed, failed, stopped
  • Auto-refresh indicator

Use Cases:

  • Development: Monitor agent spawning during development
  • Debugging: Track agent status transitions in real-time
  • Load Testing: Verify concurrency limits are enforced
  • Scripting: Use --json mode for automated monitoring

Keyboard Controls:

  • Ctrl+C - Stop watching and exit (preserves output)

Tips:

  • Use --no-clear to avoid screen clearing (useful for terminal multiplexers)
  • Combine with --type and --status filters to focus on specific agents
  • Minimum refresh interval is 1 second to prevent excessive CPU usage

Troubleshooting

Common Issues

MCP Server Won't Start

Symptoms: Claude Code shows "server unavailable"

Diagnosis:

# Test server directly
npx aistack mcp start

Solutions:

  1. Check Node.js version: node --version (must be >= 20)
  2. Verify config file exists and is valid JSON
  3. Check file permissions on config and data directory

Database Errors

Symptoms: "SQLITE_ERROR" or "database locked"

Diagnosis:

# Check database integrity
sqlite3 ./data/aistack.db "PRAGMA integrity_check"

Solutions:

  1. Ensure only one process accesses database
  2. Check disk space
  3. Restore from backup if corrupted

API Key Errors

Symptoms: "Unauthorized" or "Invalid API key"

Diagnosis:

# Check environment variable
echo $ANTHROPIC_API_KEY

Solutions:

  1. Verify API key is set correctly
  2. Check config file interpolation syntax: ${VAR_NAME}
  3. Test API key directly with curl

Vector Search Not Working

Symptoms: Search returns only FTS results

Diagnosis:

# Check config
cat aistack.config.json | grep vectorSearch

Solutions:

  1. Ensure vectorSearch.enabled: true
  2. Verify embedding provider API key
  3. Check entries have embeddings: SELECT COUNT(*) FROM memory WHERE embedding IS NOT NULL

GitHub Integration Fails

Symptoms: GitHub tools return errors

Diagnosis:

# Check gh CLI
gh auth status

Solutions:

  1. Authenticate gh CLI: gh auth login
  2. Verify GitHub config: github.enabled: true, useGhCli: true
  3. Check repository permissions

Debug Mode

Enable detailed logging:

# Via CLI
npx aistack -v mcp start

# Via environment
DEBUG=* npx aistack mcp start

Reset State

# Clear database (WARNING: deletes all data)
rm ./data/aistack.db

# Reinitialize
npx aistack init

Backup & Recovery

Database Backup

# SQLite backup command
sqlite3 ./data/aistack.db ".backup './backups/aistack-$(date +%Y%m%d).db'"

# Or simple copy (when server stopped)
cp ./data/aistack.db ./backups/

Automated Backup Script

#!/bin/bash
# backup.sh

BACKUP_DIR="./backups"
DB_PATH="./data/aistack.db"
RETENTION_DAYS=7

# Create backup
mkdir -p "$BACKUP_DIR"
sqlite3 "$DB_PATH" ".backup '$BACKUP_DIR/aistack-$(date +%Y%m%d-%H%M%S).db'"

# Clean old backups
find "$BACKUP_DIR" -name "aistack-*.db" -mtime +$RETENTION_DAYS -delete

Recovery

# Stop server first

# Restore from backup
cp ./backups/aistack-20240101.db ./data/aistack.db

# Restart server

Performance Tuning

Memory Configuration

For large datasets, adjust SQLite pragmas:

// In custom initialization
db.pragma('cache_size = -64000');  // 64MB cache
db.pragma('mmap_size = 268435456'); // 256MB mmap

Agent Limits

{
  "agents": {
    "maxConcurrent": 10,      // Increase for parallel work
    "defaultTimeout": 600     // Increase for long tasks
  }
}

For better vector search performance:

  1. Use text-embedding-3-small (faster, 1536 dims)
  2. Limit search to specific namespaces
  3. Batch embedding generation

Runbooks

Runbook: Server Restart

  1. Check current status: npx aistack status
  2. Stop server (if running as daemon)
  3. Clear any stale locks: rm ./data/*.lock
  4. Start server: npx aistack mcp start
  5. Verify health: Use system_health tool

Runbook: Database Migration

  1. Backup current database
  2. Stop server
  3. Run migration SQL if needed
  4. Update config version
  5. Start server
  6. Verify data integrity

Runbook: API Key Rotation

  1. Generate new API key from provider
  2. Update environment variable
  3. Restart server
  4. Verify functionality
  5. Revoke old key

Runbook: Plugin Installation

  1. Review plugin source code
  2. Copy to plugins directory
  3. Restart server (auto-discovery)
  4. Verify plugin loaded: Check logs
  5. Test plugin functionality

Runbook: Capacity Planning

Estimate storage needs:

  • Memory entries: ~1KB per entry (without embeddings)
  • Embeddings: +6KB per entry (1536 dims)
  • FTS index: ~20% of content size

Estimate API costs:

  • Embeddings: ~$0.02 per 1M tokens
  • Chat: Varies by model and usage

API Cost Considerations

When using semantic drift detection and vector search features, understanding API costs helps with capacity planning and budgeting.

Drift Detection Cost Overview

Drift detection uses embedding API calls to compare task descriptions against parent context:

  • Task with parent: 2 API calls per task
    • One call to generate embedding for drift comparison
    • One call to index the task for future searches
  • Standalone task: 1 API call (indexing only, if drift detection enabled)
  • Memory operations: 1 API call per entry indexed

Cost Calculation Table

Based on OpenAI's text-embedding-3-small pricing (~$0.02 per 1M tokens, typical task ~100 tokens):

OperationAPI CallsEst. Cost (OpenAI)
Task with parent2~$0.000008
Standalone task1~$0.000004
Memory entry index1~$0.000004
Vector search query1~$0.000004

Usage Pattern Examples

Usage LevelTasks/DayDaily CostMonthly Cost
Light100~$0.0008~$0.024
Medium1,000~$0.008~$0.24
Heavy10,000~$0.08~$2.40

Costs assume average of 1.5 API calls per task (mix of parent and standalone tasks).

Cost Optimization Strategies

  1. Use Ollama for free local embeddings (see below)
  2. Disable drift detection when not needed:
    {
      "driftDetection": {
        "enabled": false
      }
    }
    
  3. Use async embedding (default) - doesn't reduce cost but improves responsiveness:
    {
      "driftDetection": {
        "asyncEmbedding": true
      }
    }
    
  4. Batch operations when creating multiple related tasks

Drift Detection Configuration

Full configuration with cost-relevant options:

{
  "driftDetection": {
    "enabled": true,
    "threshold": 0.95,
    "asyncEmbedding": true
  }
}
OptionDescriptionCost Impact
enabledEnable/disable drift detectionDisabling eliminates drift check calls
thresholdSimilarity threshold (0.0-1.0)No cost impact, affects sensitivity
asyncEmbeddingProcess embeddings asynchronouslyNo cost impact, improves UX

Note: When asyncEmbedding: true (default), child tasks created immediately after a parent may not have the parent's embedding available for drift checking. This can result in false negatives. Set asyncEmbedding: false for guaranteed drift detection accuracy when using behavior: "prevent".

Cost-Free Alternative: Ollama

Use Ollama for completely local, free embeddings:

{
  "memory": {
    "vectorSearch": {
      "enabled": true,
      "provider": "ollama",
      "model": "nomic-embed-text"
    }
  }
}

Requirements:

  • Ollama installed and running locally
  • nomic-embed-text model pulled: ollama pull nomic-embed-text
  • Slightly slower than cloud APIs but zero cost

Comparison:

ProviderCostSpeedSetup
OpenAI~$0.02/1M tokensFastAPI key required
OllamaFreeModerateLocal installation

Docker Deployment

Dockerfile

FROM node:20-slim

WORKDIR /app

COPY package*.json ./
RUN npm ci --production

COPY dist ./dist
COPY templates ./templates

ENV NODE_ENV=production

ENTRYPOINT ["node", "dist/cli/index.js"]
CMD ["mcp", "start"]

Docker Compose

version: '3.8'
services:
  agentstack:
    build: .
    volumes:
      - ./data:/app/data
      - ./aistack.config.json:/app/aistack.config.json:ro
    environment:
      - ANTHROPIC_API_KEY
      - OPENAI_API_KEY
    stdin_open: true
    tty: true