Implement SQLite database with full-text search for n8n node documentation

Major features implemented:
- SQLite storage service with FTS5 for fast node search
- Database rebuild mechanism for bulk node extraction
- MCP tools: search_nodes, extract_all_nodes, get_node_statistics
- Production Docker deployment with persistent storage
- Management scripts for database operations
- Comprehensive test suite for all functionality

Database capabilities:
- Stores node source code and metadata
- Full-text search by node name or content
- No versioning (stores latest only as per requirements)
- Supports complete database rebuilds
- ~4.5MB database with 500+ nodes indexed

Production features:
- Automated deployment script
- Docker Compose production configuration
- Database initialization on first run
- Volume persistence for data
- Management utilities for operations

Documentation:
- Updated README with complete instructions
- Production deployment guide
- Clear troubleshooting section
- API reference for all new tools

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
czlonkowski
2025-06-07 21:12:17 +00:00
parent 0cff8fbe6a
commit 078b67ff35
42 changed files with 33875 additions and 196 deletions

140
scripts/deploy-production.sh Executable file
View File

@@ -0,0 +1,140 @@
#!/bin/bash
# Production deployment script for n8n-MCP
set -e
echo "🚀 n8n-MCP Production Deployment Script"
echo "======================================"
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Function to check if command exists
command_exists() {
command -v "$1" >/dev/null 2>&1
}
# Function to generate secure password
generate_password() {
openssl rand -base64 32 | tr -d "=+/" | cut -c1-25
}
# Check prerequisites
echo -e "\n${YELLOW}Checking prerequisites...${NC}"
if ! command_exists docker; then
echo -e "${RED}❌ Docker is not installed. Please install Docker first.${NC}"
exit 1
fi
if ! command_exists docker compose; then
echo -e "${RED}❌ Docker Compose v2 is not installed. Please install Docker Compose v2.${NC}"
exit 1
fi
if ! command_exists node; then
echo -e "${RED}❌ Node.js is not installed. Please install Node.js first.${NC}"
exit 1
fi
echo -e "${GREEN}✅ All prerequisites met${NC}"
# Check for .env file
if [ ! -f .env ]; then
echo -e "\n${YELLOW}Creating .env file...${NC}"
# Generate secure passwords
N8N_BASIC_AUTH_PASSWORD=$(generate_password)
N8N_API_KEY=$(generate_password)
cat > .env << EOF
# n8n Configuration
N8N_BASIC_AUTH_USER=admin
N8N_BASIC_AUTH_PASSWORD=${N8N_BASIC_AUTH_PASSWORD}
N8N_HOST=localhost
N8N_API_KEY=${N8N_API_KEY}
# MCP Configuration
MCP_LOG_LEVEL=info
NODE_ENV=production
EOF
echo -e "${GREEN}✅ Created .env file with secure defaults${NC}"
echo -e "${YELLOW}⚠️ Please note your credentials:${NC}"
echo -e " n8n Username: admin"
echo -e " n8n Password: ${N8N_BASIC_AUTH_PASSWORD}"
echo -e " API Key: ${N8N_API_KEY}"
echo -e "${YELLOW} Save these credentials securely!${NC}"
else
echo -e "${GREEN}✅ Using existing .env file${NC}"
fi
# Build the project
echo -e "\n${YELLOW}Building the project...${NC}"
npm install
npm run build
if [ $? -ne 0 ]; then
echo -e "${RED}❌ Build failed. Please fix the errors and try again.${NC}"
exit 1
fi
echo -e "${GREEN}✅ Build completed successfully${NC}"
# Build Docker image
echo -e "\n${YELLOW}Building Docker image...${NC}"
docker compose -f docker-compose.prod.yml build
if [ $? -ne 0 ]; then
echo -e "${RED}❌ Docker build failed. Please check the logs.${NC}"
exit 1
fi
echo -e "${GREEN}✅ Docker image built successfully${NC}"
# Start services
echo -e "\n${YELLOW}Starting services...${NC}"
docker compose -f docker-compose.prod.yml up -d
if [ $? -ne 0 ]; then
echo -e "${RED}❌ Failed to start services. Please check the logs.${NC}"
exit 1
fi
echo -e "${GREEN}✅ Services started successfully${NC}"
# Wait for services to be healthy
echo -e "\n${YELLOW}Waiting for services to be healthy...${NC}"
sleep 10
# Check service health
N8N_HEALTH=$(docker compose -f docker-compose.prod.yml ps n8n --format json | jq -r '.[0].Health // "unknown"')
MCP_HEALTH=$(docker compose -f docker-compose.prod.yml ps n8n-mcp --format json | jq -r '.[0].Health // "unknown"')
if [ "$N8N_HEALTH" = "healthy" ] && [ "$MCP_HEALTH" = "healthy" ]; then
echo -e "${GREEN}✅ All services are healthy${NC}"
else
echo -e "${YELLOW}⚠️ Services might still be starting up...${NC}"
echo -e " n8n status: $N8N_HEALTH"
echo -e " MCP server status: $MCP_HEALTH"
fi
# Display access information
echo -e "\n${GREEN}🎉 Deployment completed successfully!${NC}"
echo -e "\n${YELLOW}Access Information:${NC}"
echo -e " n8n UI: http://localhost:5678"
echo -e " MCP Server: Running internally (accessible by n8n)"
echo -e "\n${YELLOW}Next Steps:${NC}"
echo -e " 1. Access n8n at http://localhost:5678"
echo -e " 2. Log in with the credentials from .env file"
echo -e " 3. Create a new workflow and add the MCP node"
echo -e " 4. Configure the MCP node to connect to the internal server"
echo -e "\n${YELLOW}Useful Commands:${NC}"
echo -e " View logs: docker compose -f docker-compose.prod.yml logs -f"
echo -e " Stop services: docker compose -f docker-compose.prod.yml down"
echo -e " Rebuild database: docker compose -f docker-compose.prod.yml exec n8n-mcp node dist/scripts/rebuild-database.js"
echo -e " View database stats: docker compose -f docker-compose.prod.yml exec n8n-mcp sqlite3 /app/data/nodes.db 'SELECT COUNT(*) as total_nodes FROM nodes;'"

178
scripts/manage-production.sh Executable file
View File

@@ -0,0 +1,178 @@
#!/bin/bash
# Production management script for n8n-MCP
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Display usage
usage() {
echo -e "${BLUE}n8n-MCP Production Management Script${NC}"
echo -e "${YELLOW}Usage:${NC} $0 [command]"
echo
echo -e "${YELLOW}Commands:${NC}"
echo " status - Show service status"
echo " logs - View service logs"
echo " start - Start all services"
echo " stop - Stop all services"
echo " restart - Restart all services"
echo " rebuild-db - Rebuild the node database"
echo " db-stats - Show database statistics"
echo " backup - Backup data volumes"
echo " restore - Restore data volumes from backup"
echo " update - Update services to latest versions"
echo " shell - Open shell in MCP container"
echo
exit 1
}
# Check if docker compose file exists
if [ ! -f "docker-compose.prod.yml" ]; then
echo -e "${RED}❌ docker-compose.prod.yml not found. Run this script from the project root.${NC}"
exit 1
fi
# Main command handling
case "$1" in
status)
echo -e "${YELLOW}Service Status:${NC}"
docker compose -f docker-compose.prod.yml ps
;;
logs)
if [ -z "$2" ]; then
docker compose -f docker-compose.prod.yml logs -f --tail=100
else
docker compose -f docker-compose.prod.yml logs -f --tail=100 "$2"
fi
;;
start)
echo -e "${YELLOW}Starting services...${NC}"
docker compose -f docker-compose.prod.yml up -d
echo -e "${GREEN}✅ Services started${NC}"
;;
stop)
echo -e "${YELLOW}Stopping services...${NC}"
docker compose -f docker-compose.prod.yml down
echo -e "${GREEN}✅ Services stopped${NC}"
;;
restart)
echo -e "${YELLOW}Restarting services...${NC}"
docker compose -f docker-compose.prod.yml restart
echo -e "${GREEN}✅ Services restarted${NC}"
;;
rebuild-db)
echo -e "${YELLOW}Rebuilding node database...${NC}"
docker compose -f docker-compose.prod.yml exec n8n-mcp node dist/scripts/rebuild-database.js
;;
db-stats)
echo -e "${YELLOW}Database Statistics:${NC}"
docker compose -f docker-compose.prod.yml exec n8n-mcp sqlite3 /app/data/nodes.db << 'EOF'
.headers on
.mode column
SELECT
COUNT(*) as total_nodes,
COUNT(DISTINCT package_name) as total_packages,
ROUND(SUM(code_length) / 1024.0 / 1024.0, 2) as total_size_mb,
ROUND(AVG(code_length) / 1024.0, 2) as avg_size_kb
FROM nodes;
.print
.print "Top 10 packages by node count:"
SELECT package_name, COUNT(*) as node_count
FROM nodes
GROUP BY package_name
ORDER BY node_count DESC
LIMIT 10;
EOF
;;
backup)
BACKUP_DIR="backups/$(date +%Y%m%d_%H%M%S)"
echo -e "${YELLOW}Creating backup in ${BACKUP_DIR}...${NC}"
mkdir -p "$BACKUP_DIR"
# Stop services for consistent backup
docker compose -f docker-compose.prod.yml stop
# Backup volumes
docker run --rm -v n8n-mcp_n8n-data:/source -v $(pwd)/$BACKUP_DIR:/backup alpine tar czf /backup/n8n-data.tar.gz -C /source .
docker run --rm -v n8n-mcp_mcp-data:/source -v $(pwd)/$BACKUP_DIR:/backup alpine tar czf /backup/mcp-data.tar.gz -C /source .
# Copy .env file
cp .env "$BACKUP_DIR/"
# Restart services
docker compose -f docker-compose.prod.yml start
echo -e "${GREEN}✅ Backup completed in ${BACKUP_DIR}${NC}"
;;
restore)
if [ -z "$2" ]; then
echo -e "${RED}❌ Please specify backup directory (e.g., backups/20240107_120000)${NC}"
exit 1
fi
if [ ! -d "$2" ]; then
echo -e "${RED}❌ Backup directory $2 not found${NC}"
exit 1
fi
echo -e "${YELLOW}⚠️ This will replace all current data! Continue? (y/N)${NC}"
read -r confirm
if [ "$confirm" != "y" ]; then
echo "Restore cancelled"
exit 0
fi
echo -e "${YELLOW}Restoring from $2...${NC}"
# Stop services
docker compose -f docker-compose.prod.yml down
# Restore volumes
docker run --rm -v n8n-mcp_n8n-data:/target -v $(pwd)/$2:/backup alpine tar xzf /backup/n8n-data.tar.gz -C /target
docker run --rm -v n8n-mcp_mcp-data:/target -v $(pwd)/$2:/backup alpine tar xzf /backup/mcp-data.tar.gz -C /target
# Start services
docker compose -f docker-compose.prod.yml up -d
echo -e "${GREEN}✅ Restore completed${NC}"
;;
update)
echo -e "${YELLOW}Updating services...${NC}"
# Pull latest images
docker compose -f docker-compose.prod.yml pull
# Rebuild MCP image
docker compose -f docker-compose.prod.yml build
# Restart with new images
docker compose -f docker-compose.prod.yml up -d
echo -e "${GREEN}✅ Services updated${NC}"
;;
shell)
echo -e "${YELLOW}Opening shell in MCP container...${NC}"
docker compose -f docker-compose.prod.yml exec n8n-mcp /bin/sh
;;
*)
usage
;;
esac

View File

@@ -23,11 +23,11 @@ npm run build
echo
echo "2. Building Docker image..."
docker-compose -f docker-compose.test.yml build
docker compose -f docker-compose.test.yml build
echo
echo "3. Starting test environment..."
docker-compose -f docker-compose.test.yml up -d
docker compose -f docker-compose.test.yml up -d
echo
echo "4. Waiting for services to be ready..."
@@ -36,7 +36,7 @@ sleep 10
# Wait for n8n to be healthy
echo " Waiting for n8n to be ready..."
for i in {1..30}; do
if docker-compose -f docker-compose.test.yml exec n8n wget --spider -q http://localhost:5678/healthz 2>/dev/null; then
if docker compose -f docker-compose.test.yml exec n8n wget --spider -q http://localhost:5678/healthz 2>/dev/null; then
echo -e " ${GREEN}✓ n8n is ready${NC}"
break
fi
@@ -48,7 +48,7 @@ echo
echo "5. Running MCP client test..."
# Create a simple test using the MCP server directly
docker-compose -f docker-compose.test.yml exec n8n-mcp node -e "
docker compose -f docker-compose.test.yml exec n8n-mcp node -e "
const http = require('http');
// Test data
@@ -107,12 +107,12 @@ if (!found) {
echo
echo "6. Alternative test - Direct file system check..."
docker-compose -f docker-compose.test.yml exec n8n find /usr/local/lib/node_modules -name "*Agent*.node.js" -type f 2>/dev/null | head -10 || true
docker compose -f docker-compose.test.yml exec n8n find /usr/local/lib/node_modules -name "*Agent*.node.js" -type f 2>/dev/null | head -10 || true
echo
echo "7. Test using curl to n8n API..."
# Get available node types from n8n
NODE_TYPES=$(docker-compose -f docker-compose.test.yml exec n8n curl -s http://localhost:5678/api/v1/node-types | jq -r '.data[].name' | grep -i agent | head -5) || true
NODE_TYPES=$(docker compose -f docker-compose.test.yml exec n8n curl -s http://localhost:5678/api/v1/node-types | jq -r '.data[].name' | grep -i agent | head -5) || true
if [ -n "$NODE_TYPES" ]; then
echo -e "${GREEN}✓ Found Agent nodes in n8n:${NC}"
@@ -126,7 +126,7 @@ echo "8. Cleanup..."
read -p "Stop test environment? (y/n) " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
docker-compose -f docker-compose.test.yml down
docker compose -f docker-compose.test.yml down
echo -e "${GREEN}✓ Test environment stopped${NC}"
fi