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
| Variable | Description | Required |
|---|---|---|
ANTHROPIC_API_KEY | Anthropic API key | If using Anthropic |
OPENAI_API_KEY | OpenAI API key | If using OpenAI/embeddings |
GITHUB_TOKEN | GitHub token | If not using gh CLI |
CLI Providers
AgentStack supports CLI-based providers for agent execution:
| Provider | CLI Tool | Installation |
|---|---|---|
| Claude Code | claude | npm install -g @anthropic-ai/claude-code |
| Gemini CLI | gemini | pip install google-generativeai |
| Codex | codex | Install 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
--jsonmode for automated monitoring
Keyboard Controls:
Ctrl+C- Stop watching and exit (preserves output)
Tips:
- Use
--no-clearto avoid screen clearing (useful for terminal multiplexers) - Combine with
--typeand--statusfilters 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:
- Check Node.js version:
node --version(must be >= 20) - Verify config file exists and is valid JSON
- 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:
- Ensure only one process accesses database
- Check disk space
- Restore from backup if corrupted
API Key Errors
Symptoms: "Unauthorized" or "Invalid API key"
Diagnosis:
# Check environment variable
echo $ANTHROPIC_API_KEY
Solutions:
- Verify API key is set correctly
- Check config file interpolation syntax:
${VAR_NAME} - 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:
- Ensure
vectorSearch.enabled: true - Verify embedding provider API key
- 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:
- Authenticate gh CLI:
gh auth login - Verify GitHub config:
github.enabled: true, useGhCli: true - 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
}
}
Vector Search
For better vector search performance:
- Use
text-embedding-3-small(faster, 1536 dims) - Limit search to specific namespaces
- Batch embedding generation
Runbooks
Runbook: Server Restart
- Check current status:
npx aistack status - Stop server (if running as daemon)
- Clear any stale locks:
rm ./data/*.lock - Start server:
npx aistack mcp start - Verify health: Use
system_healthtool
Runbook: Database Migration
- Backup current database
- Stop server
- Run migration SQL if needed
- Update config version
- Start server
- Verify data integrity
Runbook: API Key Rotation
- Generate new API key from provider
- Update environment variable
- Restart server
- Verify functionality
- Revoke old key
Runbook: Plugin Installation
- Review plugin source code
- Copy to plugins directory
- Restart server (auto-discovery)
- Verify plugin loaded: Check logs
- 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):
| Operation | API Calls | Est. Cost (OpenAI) |
|---|---|---|
| Task with parent | 2 | ~$0.000008 |
| Standalone task | 1 | ~$0.000004 |
| Memory entry index | 1 | ~$0.000004 |
| Vector search query | 1 | ~$0.000004 |
Usage Pattern Examples
| Usage Level | Tasks/Day | Daily Cost | Monthly Cost |
|---|---|---|---|
| Light | 100 | ~$0.0008 | ~$0.024 |
| Medium | 1,000 | ~$0.008 | ~$0.24 |
| Heavy | 10,000 | ~$0.08 | ~$2.40 |
Costs assume average of 1.5 API calls per task (mix of parent and standalone tasks).
Cost Optimization Strategies
- Use Ollama for free local embeddings (see below)
- Disable drift detection when not needed:
{ "driftDetection": { "enabled": false } } - Use async embedding (default) - doesn't reduce cost but improves responsiveness:
{ "driftDetection": { "asyncEmbedding": true } } - Batch operations when creating multiple related tasks
Drift Detection Configuration
Full configuration with cost-relevant options:
{
"driftDetection": {
"enabled": true,
"threshold": 0.95,
"asyncEmbedding": true
}
}
| Option | Description | Cost Impact |
|---|---|---|
enabled | Enable/disable drift detection | Disabling eliminates drift check calls |
threshold | Similarity threshold (0.0-1.0) | No cost impact, affects sensitivity |
asyncEmbedding | Process embeddings asynchronously | No 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. SetasyncEmbedding: falsefor guaranteed drift detection accuracy when usingbehavior: "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-textmodel pulled:ollama pull nomic-embed-text- Slightly slower than cloud APIs but zero cost
Comparison:
| Provider | Cost | Speed | Setup |
|---|---|---|---|
| OpenAI | ~$0.02/1M tokens | Fast | API key required |
| Ollama | Free | Moderate | Local 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
Related Documents
- SECURITY.md - Security considerations
- DATA.md - Database schema details
- API.md - Tool reference