refactor: reorganize documentation and configuration files for improved clarity

This commit is contained in:
czlonkowski
2025-06-12 15:03:12 +02:00
parent 8bf670c31e
commit f831b02415
21 changed files with 1094 additions and 1841 deletions

View File

@@ -49,11 +49,3 @@ Yes! Contributions are welcome. By contributing, you agree that your contributio
For commercial licensing or custom terms, please contact the maintainers through the GitHub repository.
## Comparison with n8n's licensing
This project uses a similar approach to n8n:
- Same Sustainable Use License for the core functionality
- Source-available but with commercial restrictions
- Designed to prevent exploitation while enabling legitimate use
The main difference is that we don't currently have enterprise features (.ee. files) - all functionality is available under the single license.

View File

@@ -1,155 +0,0 @@
# n8n-MCP Enhanced Documentation System
This is the enhanced n8n-MCP integration that provides comprehensive node documentation, including operations, API methods, examples, and rich metadata through the Model Context Protocol (MCP).
## Overview
The enhanced system provides:
- **Rich Node Documentation**: Complete documentation including markdown content, operations, API methods, and code examples
- **Full-Text Search**: SQLite FTS5-powered search across node names, descriptions, and documentation
- **Comprehensive Node Information**: Source code, credentials, examples, templates, and metadata in a single query
- **Automatic Documentation Extraction**: Fetches and parses documentation from the official n8n-docs repository
## Available MCP Tools
### 1. `get_node_info`
Get comprehensive information about a specific n8n node.
**Parameters:**
- `nodeType` (string, required): The node type identifier (e.g., 'n8n-nodes-base.slack')
**Returns:**
- Complete node information including:
- Basic metadata (name, displayName, description, category)
- Documentation (markdown, URL, title)
- Operations and API methods
- Code examples and templates
- Related resources and required scopes
- Source code (node and credential)
- Example workflow and parameters
### 2. `search_nodes`
Search n8n nodes with full-text search and advanced filtering.
**Parameters:**
- `query` (string, optional): Search query for full-text search
- `category` (string, optional): Filter by node category
- `packageName` (string, optional): Filter by package name
- `hasCredentials` (boolean, optional): Filter nodes that require credentials
- `isTrigger` (boolean, optional): Filter trigger nodes only
- `limit` (number, optional): Maximum results to return (default: 20)
**Returns:**
- Array of matching nodes with summary information
### 3. `get_node_statistics`
Get statistics about the node documentation database.
**Returns:**
- Total nodes, packages, and storage statistics
- Nodes with documentation, examples, and credentials
- Package distribution
### 4. `rebuild_documentation_database`
Rebuild the node documentation database with the latest information.
**Parameters:**
- `packageFilter` (string, optional): Only rebuild nodes from specific package
**Returns:**
- Rebuild statistics and status
## Database Schema
The system uses a SQLite database with the following main table:
```sql
CREATE TABLE nodes (
node_type TEXT UNIQUE NOT NULL,
name TEXT NOT NULL,
display_name TEXT,
description TEXT,
category TEXT,
source_code TEXT NOT NULL,
documentation_markdown TEXT,
operations TEXT, -- JSON array of OperationInfo
api_methods TEXT, -- JSON array of ApiMethodMapping
documentation_examples TEXT, -- JSON array of CodeExample
templates TEXT, -- JSON array of TemplateInfo
related_resources TEXT, -- JSON array of RelatedResource
-- ... additional fields
);
```
## Building the Documentation Database
To build or rebuild the documentation database:
```bash
# Using npm script
npm run docs:rebuild
# Or directly
npx ts-node src/scripts/rebuild-database.ts
```
This will:
1. Clone/update the n8n-docs repository
2. Extract source code for all available nodes
3. Parse and extract enhanced documentation
4. Generate example workflows
5. Store everything in the SQLite database
## Usage Example
```typescript
// Get comprehensive information about the Slack node
const slackInfo = await mcpClient.callTool('get_node_info', {
nodeType: 'n8n-nodes-base.slack'
});
// Search for all trigger nodes with credentials
const triggers = await mcpClient.callTool('search_nodes', {
isTrigger: true,
hasCredentials: true
});
// Get database statistics
const stats = await mcpClient.callTool('get_node_statistics', {});
```
## Architecture
The enhanced system consists of:
1. **NodeDocumentationService**: Main service that manages the SQLite database
2. **EnhancedDocumentationFetcher**: Fetches and parses documentation from n8n-docs
3. **ExampleGenerator**: Generates example workflows and parameters
4. **MCP Server**: Exposes the tools through the Model Context Protocol
## Development
```bash
# Install dependencies
npm install
# Build TypeScript
npm run build
# Run tests
npm test
# Start MCP server
npm start
```
## Environment Variables
- `NODE_DB_PATH`: Path to the SQLite database (default: `./data/nodes.db`)
- `N8N_API_URL`: n8n instance URL
- `N8N_API_KEY`: n8n API key for workflow operations
## License
Licensed under the Sustainable Use License v1.0

326
README.md
View File

@@ -1,326 +0,0 @@
# n8n Node Documentation MCP Server
An MCP (Model Context Protocol) server that provides n8n node documentation, source code, and usage examples to AI assistants like Claude.
## Purpose
This MCP server serves as a comprehensive knowledge base for AI assistants to understand and work with n8n nodes. It provides:
- **Complete node source code** - The actual TypeScript/JavaScript implementation of each n8n node
- **Official documentation** - Markdown documentation from the n8n-docs repository
- **Usage examples** - Sample workflow JSON showing how to use each node
- **Search capabilities** - Full-text search across node names, descriptions, and documentation
## Features
- 🔍 **Full-text search** - Search nodes by name, description, or documentation content
- 📚 **Complete documentation** - Fetches and indexes official n8n documentation
- 💻 **Source code access** - Provides full source code for each node
- 🎯 **Usage examples** - Auto-generates example workflows for each node type
- 🔄 **Database rebuild** - Rebuilds the entire database with latest node information
-**Fast SQLite storage** - All data stored locally for instant access
## Installation
### Prerequisites
- Node.js 18+
- Git (for cloning n8n-docs)
### Quick Start
```bash
# Clone the repository
git clone https://github.com/yourusername/n8n-mcp.git
cd n8n-mcp
# Install dependencies
npm install
# Copy environment configuration
cp .env.example .env
# Build the project
npm run build
# Initialize and rebuild the database with all nodes
npm run db:rebuild:v2
# Start the local MCP server (for Claude Desktop)
npm run start:v2
```
### Deployment Options
This MCP server can be deployed in two ways:
1. **Local Installation** - Run on your machine and connect Claude Desktop locally
2. **Remote Deployment** - Deploy to a VM/server and connect Claude Desktop over HTTPS
For remote deployment instructions, see [docs/REMOTE_DEPLOYMENT.md](docs/REMOTE_DEPLOYMENT.md).
## Installing in Claude Desktop
### 1. Build the project first
```bash
npm install
npm run build
npm run db:rebuild:v2 # This indexes all n8n nodes
```
### 2. Locate your Claude Desktop configuration
- **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
- **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
- **Linux**: `~/.config/Claude/claude_desktop_config.json`
### 3. Edit the configuration file
```json
{
"mcpServers": {
"n8n-nodes": {
"command": "node",
"args": ["/absolute/path/to/n8n-mcp/dist/index-v2.js"],
"env": {
"NODE_DB_PATH": "/absolute/path/to/n8n-mcp/data/nodes-v2.db"
}
}
}
}
```
**Important**: Use absolute paths, not relative paths like `~/` or `./`
### 4. Restart Claude Desktop
After saving the configuration, completely quit and restart Claude Desktop.
### 5. Verify the connection
In Claude, you should see "n8n-nodes" in the MCP connections. Try asking:
- "What n8n nodes are available?"
- "Show me how to use the IF node in n8n"
- "Search for webhook nodes in n8n"
- "Show me the source code for the HTTP Request node"
### Remote Server Configuration
If you're connecting to a remote server instead of local installation:
```json
{
"mcpServers": {
"n8n-nodes-remote": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/client-http",
"https://n8ndocumentation.aiservices.pl/mcp"
],
"env": {
"MCP_AUTH_TOKEN": "your-auth-token-from-server"
}
}
}
}
```
Replace `n8ndocumentation.aiservices.pl` with your actual domain and use the auth token configured on your server.
## Available MCP Tools
### `list_nodes`
Lists all available n8n nodes with basic information.
- Parameters: `category`, `packageName`, `isTrigger` (all optional)
### `get_node_info`
Gets complete information about a specific node including source code, documentation, and examples.
- Parameters: `nodeType` (required) - e.g., "n8n-nodes-base.if", "If", "webhook"
### `search_nodes`
Searches for nodes by name, description, or documentation content.
- Parameters: `query` (required), `category`, `hasDocumentation`, `limit` (optional)
### `get_node_example`
Gets example workflow JSON for a specific node.
- Parameters: `nodeType` (required)
### `get_node_source_code`
Gets only the source code of a node.
- Parameters: `nodeType` (required), `includeCredentials` (optional)
### `get_node_documentation`
Gets only the documentation for a node.
- Parameters: `nodeType` (required), `format` (optional: "markdown" or "plain")
### `rebuild_database`
Rebuilds the entire node database with latest information.
- Parameters: `includeDocumentation` (optional, default: true)
### `get_database_statistics`
Gets statistics about the node database.
- No parameters required
## Example Usage
When you ask Claude about the IF node, it will use the MCP tools to provide:
```json
{
"nodeType": "n8n-nodes-base.if",
"name": "If",
"displayName": "If",
"description": "Route items based on comparison operations",
"sourceCode": "// Full TypeScript source code...",
"documentation": "# If Node\n\nThe If node splits a workflow...",
"exampleWorkflow": {
"nodes": [{
"parameters": {
"conditions": {
"conditions": [{
"leftValue": "={{ $json }}",
"rightValue": "",
"operator": {
"type": "object",
"operation": "notEmpty"
}
}]
}
},
"type": "n8n-nodes-base.if",
"position": [220, 120],
"name": "If"
}],
"connections": {
"If": {
"main": [[], []]
}
}
}
}
```
## Database Management
### Initial Setup
The database is automatically created when you run:
```bash
npm run db:rebuild:v2
```
This process:
1. Clones/updates the n8n-docs repository
2. Extracts source code from all n8n nodes
3. Fetches documentation for each node
4. Generates usage examples
5. Stores everything in SQLite with full-text search
### Manual Rebuild
To update the database with latest nodes:
```bash
npm run db:rebuild:v2
```
### Database Location
The SQLite database is stored at: `data/nodes-v2.db`
## Development
```bash
# Run in development mode (local stdio)
npm run dev:v2
# Run HTTP server for remote access
npm run dev:http
# Run tests
npm run test:v2
# Type checking
npm run typecheck
```
### Running Remote Server
To run the server for remote access:
```bash
# Copy and configure environment
cp .env.example .env
# Edit .env with your domain and auth token
# Run in production mode
npm run start:http
# Or with PM2 for production
pm2 start dist/index-http.js --name n8n-mcp
```
## Troubleshooting
### Claude Desktop doesn't show the MCP server
1. Ensure you've restarted Claude Desktop after editing the config
2. Check the config file is valid JSON (no trailing commas)
3. Verify the absolute paths are correct
4. Check Claude's developer console for errors (Help → Developer)
### "Connection failed" in Claude
1. Ensure the MCP server is built (`npm run build`)
2. Check that the database exists (`data/nodes-v2.db`)
3. Verify the NODE_DB_PATH in Claude config points to the correct database file
### Database rebuild fails
Some nodes may fail to extract (deprecated nodes, triggers without main node file). This is normal. The rebuild will continue and index all available nodes.
### No documentation for some nodes
Not all nodes have documentation in the n8n-docs repository. The server will still provide source code and generated examples for these nodes.
## Project Structure
```
n8n-mcp/
├── src/
│ ├── mcp/
│ │ ├── server-v2.ts # MCP server implementation
│ │ └── tools-v2.ts # MCP tool definitions
│ ├── services/
│ │ └── node-documentation-service.ts # Database service
│ ├── utils/
│ │ ├── documentation-fetcher.ts # n8n-docs fetcher
│ │ ├── example-generator.ts # Example generator
│ │ └── node-source-extractor.ts # Source extractor
│ └── scripts/
│ └── rebuild-database-v2.ts # Database rebuild
└── data/
└── nodes-v2.db # SQLite database
```
## License
This project is licensed under the [Sustainable Use License](LICENSE).
### What does this mean?
-**Free to use** for internal business purposes
-**Free to use** for personal/non-commercial projects
-**Free to modify** for your own use
-**Free to share** with others (non-commercially)
-**Cannot** host as a service for others
-**Cannot** include in commercial products without permission
This is a "fair-code" license similar to n8n's approach. See [LICENSE_FAQ.md](LICENSE_FAQ.md) for more details.
## Support
For issues and questions, please use the GitHub issue tracker.
For commercial licensing inquiries, please open an issue with the "licensing" tag.

101
README_CLAUDE_SETUP.md Normal file
View File

@@ -0,0 +1,101 @@
# Claude Desktop Configuration for n8n-MCP
## Setup Instructions
1. **Build the project first:**
```bash
cd /Users/romualdczlonkowski/Pliki/n8n-mcp/n8n-mcp
npm run build
npm run rebuild
```
2. **Locate your Claude Desktop config file:**
- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
- Windows: `%APPDATA%\Claude\claude_desktop_config.json`
- Linux: `~/.config/Claude/claude_desktop_config.json`
3. **Add the n8n-documentation server to your config:**
```json
{
"mcpServers": {
"n8n-documentation": {
"command": "node",
"args": [
"/Users/romualdczlonkowski/Pliki/n8n-mcp/n8n-mcp/dist/mcp/index.js"
],
"env": {
"NODE_ENV": "production"
}
}
}
}
```
**Note**: Update the path in `args` to match your actual installation directory.
4. **Restart Claude Desktop** to load the new configuration.
## Available Tools
Once configured, you'll have access to these tools in Claude:
- **`list_nodes`** - List and filter n8n nodes
```
list_nodes({ package: "n8n-nodes-base", limit: 10 })
```
- **`get_node_info`** - Get detailed information about a specific node
```
get_node_info({ nodeType: "httpRequest" })
```
- **`search_nodes`** - Search across all node documentation
```
search_nodes({ query: "webhook", limit: 20 })
```
- **`list_ai_tools`** - List nodes that can be used as AI Agent tools
```
list_ai_tools({})
```
- **`get_node_documentation`** - Get full documentation for a node
```
get_node_documentation({ nodeType: "slack" })
```
- **`get_database_statistics`** - Get statistics about the node database
```
get_database_statistics({})
```
## Troubleshooting
1. **If the server doesn't appear in Claude:**
- Check that the path in `args` is absolute and correct
- Ensure you've run `npm run build` and `npm run rebuild`
- Check `~/.n8n-mcp/logs/` for error logs
2. **If tools return errors:**
- Ensure the database exists: `data/nodes.db`
- Run `npm run validate` to check the database
- Rebuild if necessary: `npm run rebuild`
3. **For development/testing:**
You can also run with more verbose logging:
```json
{
"mcpServers": {
"n8n-documentation": {
"command": "node",
"args": [
"/path/to/your/n8n-mcp/dist/mcp/index.js"
],
"env": {
"NODE_ENV": "development",
"LOG_LEVEL": "debug"
}
}
}
}
```

View File

@@ -0,0 +1,11 @@
{
"mcpServers": {
"n8n-documentation": {
"command": "/Users/romualdczlonkowski/Pliki/n8n-mcp/n8n-mcp/mcp-server.sh",
"args": [],
"env": {
"NODE_ENV": "production"
}
}
}
}

View File

@@ -0,0 +1,8 @@
{
"mcpServers": {
"n8n-documentation": {
"command": "{REPLACE_WITH_PATH_TO_MCP_SERVER_V20_SH}/n8n-mcp/n8n-mcp/mcp-server-v20.sh",
"args": []
}
}
}

View File

@@ -0,0 +1,10 @@
{
"mcpServers": {
"n8n-documentation": {
"command": "node",
"args": [
"/Users/romualdczlonkowski/Pliki/n8n-mcp/n8n-mcp/dist/mcp/index.js"
]
}
}
}

View File

@@ -1,170 +0,0 @@
# AI Agent Node Extraction Test Guide
This document describes how to test the n8n Documentation MCP Server's ability to extract and provide node source code, including the AI Agent node from n8n.
## Overview
The n8n Documentation MCP Server provides comprehensive node information including:
- Source code extraction
- Official documentation
- Usage examples
- Node metadata
## Test Scenario
An MCP client (like Claude) requests the source code for n8n's AI Agent node, and the documentation server successfully extracts and returns it.
## Implementation Overview
### 1. Available MCP Tools
- **`get_node_source_code`**: Extracts source code for any n8n node
- **`get_node_info`**: Gets complete node information including docs and examples
- **`list_nodes`**: Lists all available n8n nodes
- **`search_nodes`**: Search nodes by name or content
- **`get_node_documentation`**: Gets only the documentation for a node
- **`get_node_example`**: Gets example workflow for a node
### 2. Key Components
- **`NodeSourceExtractor`** (`src/utils/node-source-extractor.ts`): Handles file system access to extract node source code
- **`NodeDocumentationService`** (`src/services/node-documentation-service.ts`): Manages SQLite database with node information
- **`DocumentationFetcher`** (`src/utils/documentation-fetcher.ts`): Fetches docs from n8n-docs repository
### 3. Test Infrastructure
- **Docker setup** (`docker-compose.test.yml`): Mounts n8n's node_modules for source access
- **Test scripts**: Multiple test approaches for different scenarios
## Running the Tests
### Option 1: Docker-based Test
```bash
# Build the project
npm run build
# Run the comprehensive test
./scripts/test-ai-agent-extraction.sh
```
This script will:
1. Build Docker containers
2. Start n8n and MCP server
3. Check for AI Agent node availability
4. Test source code extraction
### Option 2: Standalone MCP Test
```bash
# Build the project
npm run build
# Ensure n8n is running (locally or in Docker)
docker-compose -f docker-compose.test.yml up -d n8n
# Run the MCP client test
node tests/test-mcp-extraction.js
```
### Option 3: Manual Testing
1. Start the environment:
```bash
docker-compose -f docker-compose.test.yml up -d
```
2. Use any MCP client to connect and request:
```json
{
"method": "tools/call",
"params": {
"name": "get_node_source_code",
"arguments": {
"nodeType": "@n8n/n8n-nodes-langchain.Agent",
"includeCredentials": true
}
}
}
```
## Expected Results
### Successful Extraction Response
```json
{
"nodeType": "@n8n/n8n-nodes-langchain.Agent",
"sourceCode": "/* AI Agent node JavaScript code */",
"location": "/usr/local/lib/node_modules/n8n/node_modules/@n8n/n8n-nodes-langchain/dist/nodes/agents/Agent/Agent.node.js",
"credentialCode": "/* Optional credential code */",
"packageInfo": {
"name": "@n8n/n8n-nodes-langchain",
"version": "1.x.x",
"description": "LangChain nodes for n8n"
}
}
```
## How It Works
1. **MCP Client Request**: Client calls `get_node_source_code` tool with node type
2. **Server Processing**: MCP server receives request and invokes `NodeSourceExtractor`
3. **File System Search**: Extractor searches known n8n paths for the node file
4. **Source Extraction**: Reads the JavaScript source code and optional credential files
5. **Response Formation**: Returns structured data with source code and metadata
## Troubleshooting
### Node Not Found
If the AI Agent node is not found:
1. Check if langchain nodes are installed:
```bash
docker exec n8n-test ls /usr/local/lib/node_modules/n8n/node_modules/@n8n/
```
2. Install langchain nodes:
```bash
docker exec n8n-test npm install -g @n8n/n8n-nodes-langchain
```
### Permission Issues
Ensure the MCP container has read access to n8n's node_modules:
```yaml
volumes:
- n8n_modules:/usr/local/lib/node_modules/n8n/node_modules:ro
```
### Alternative Node Types
You can test with other built-in nodes:
- `n8n-nodes-base.HttpRequest`
- `n8n-nodes-base.Code`
- `n8n-nodes-base.If`
## Success Criteria
The test is successful when:
1. ✅ MCP server starts and accepts connections
2. ✅ Client can discover the `get_node_source_code` tool
3. ✅ Server locates the AI Agent node in the file system
4. ✅ Complete source code is extracted and returned
5. ✅ Response includes metadata (location, package info)
## Security Considerations
- Source code extraction is read-only
- Access is limited to n8n's node_modules directory
- Authentication token required for MCP server access
- No modification of files is possible
## Next Steps
After successful testing:
1. Deploy to production environment
2. Configure proper authentication
3. Set up monitoring for extraction requests
4. Document available node types for users

View File

@@ -1,175 +0,0 @@
# Quick Deployment Guide for n8ndocumentation.aiservices.pl
This guide walks through deploying the n8n Documentation MCP Server to a VM.
## Prerequisites
- Ubuntu 20.04+ VM with root access
- Domain pointing to your VM (e.g., n8ndocumentation.aiservices.pl)
- Node.js 18+ installed on your local machine
- Git installed locally
## Step 1: Prepare Local Environment
```bash
# Clone the repository
git clone https://github.com/yourusername/n8n-mcp.git
cd n8n-mcp
# Install dependencies
npm install
# Copy and configure environment
cp .env.example .env
```
## Step 2: Configure for Production
Edit `.env` file:
```bash
# Change these values:
NODE_ENV=production
MCP_DOMAIN=n8ndocumentation.aiservices.pl
MCP_CORS=true
# Generate and set auth token:
openssl rand -hex 32
# Copy the output and set:
MCP_AUTH_TOKEN=your-generated-token-here
```
## Step 3: Build and Deploy
```bash
# Build the project
npm run build
# Run the deployment script
./scripts/deploy-to-vm.sh
```
If you don't have SSH key authentication set up, you'll be prompted for the server password.
## Step 4: Server Setup (First Time Only)
SSH into your server and run:
```bash
# Install Node.js 18+
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt install -y nodejs
# Install PM2
sudo npm install -g pm2
# Install Nginx
sudo apt install -y nginx
# Copy Nginx configuration
sudo cp /opt/n8n-mcp/scripts/nginx-n8n-mcp.conf /etc/nginx/sites-available/n8n-mcp
sudo ln -s /etc/nginx/sites-available/n8n-mcp /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
# Get SSL certificate
sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d n8ndocumentation.aiservices.pl
# Setup PM2 startup
pm2 startup
# Follow the instructions it provides
```
## Step 5: Configure Claude Desktop
Add to your Claude Desktop configuration:
```json
{
"mcpServers": {
"n8n-nodes-remote": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/client-http",
"https://n8ndocumentation.aiservices.pl/mcp"
],
"env": {
"MCP_AUTH_TOKEN": "your-auth-token-from-env-file"
}
}
}
}
```
## Verify Deployment
Test the endpoints:
```bash
# Health check
curl https://n8ndocumentation.aiservices.pl/health
# Statistics (public)
curl https://n8ndocumentation.aiservices.pl/stats
# MCP endpoint (requires auth)
curl -X POST https://n8ndocumentation.aiservices.pl/mcp \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-auth-token" \
-d '{"jsonrpc": "2.0", "method": "tools/list", "id": 1}'
```
## Management Commands
On the server:
```bash
# View logs
pm2 logs n8n-docs-mcp
# Restart service
pm2 restart n8n-docs-mcp
# View status
pm2 status
# Rebuild database
cd /opt/n8n-mcp
npm run db:rebuild:v2
pm2 restart n8n-docs-mcp
```
## Troubleshooting
### Service won't start
```bash
# Check logs
pm2 logs n8n-docs-mcp --lines 50
# Check if port is in use
sudo lsof -i :3000
```
### SSL issues
```bash
# Renew certificate
sudo certbot renew
```
### Database issues
```bash
# Rebuild database
cd /opt/n8n-mcp
rm data/nodes-v2.db
npm run db:rebuild:v2
```
## Security Notes
1. Keep your `MCP_AUTH_TOKEN` secret
2. Regularly update dependencies: `npm update`
3. Monitor logs for suspicious activity
4. Use fail2ban to prevent brute force attacks
5. Keep your VM updated: `sudo apt update && sudo apt upgrade`

View File

@@ -1,133 +0,0 @@
# Enhanced Documentation Parser for n8n-MCP
## Overview
We have successfully enhanced the markdown parser in DocumentationFetcher to extract rich, structured content from n8n documentation. This enhancement enables AI agents to have deeper understanding of n8n nodes, their operations, API mappings, and usage patterns.
## Key Features Implemented
### 1. Enhanced Documentation Structure
The `EnhancedDocumentationFetcher` class extracts and structures documentation into:
```typescript
interface EnhancedNodeDocumentation {
markdown: string; // Raw markdown content
url: string; // Documentation URL
title?: string; // Node title
description?: string; // Node description
operations?: OperationInfo[]; // Structured operations
apiMethods?: ApiMethodMapping[]; // API endpoint mappings
examples?: CodeExample[]; // Code examples
templates?: TemplateInfo[]; // Template references
relatedResources?: RelatedResource[]; // Related docs
requiredScopes?: string[]; // OAuth scopes
metadata?: DocumentationMetadata; // Frontmatter data
}
```
### 2. Operations Extraction
The parser correctly identifies and extracts hierarchical operations:
- **Resource Level**: e.g., "Channel", "Message", "User"
- **Operation Level**: e.g., "Archive", "Send", "Get"
- **Descriptions**: Detailed operation descriptions
Example from Slack node:
- Channel.Archive: "a channel"
- Message.Send: "a message"
- User.Get: "information about a user"
### 3. API Method Mapping
Extracts mappings between n8n operations and actual API endpoints from markdown tables:
```
Channel.Archive → conversations.archive (https://api.slack.com/methods/conversations.archive)
Message.Send → chat.postMessage (https://api.slack.com/methods/chat.postMessage)
```
### 4. Enhanced Database Schema
Created a new schema to store the rich documentation:
- `nodes` table: Extended with documentation fields
- `node_operations`: Stores all operations for each node
- `node_api_methods`: Maps operations to API endpoints
- `node_examples`: Stores code examples
- `node_resources`: Related documentation links
- `node_scopes`: Required OAuth scopes
### 5. Full-Text Search Enhancement
The FTS index now includes:
- Documentation title and description
- Operations and their descriptions
- API method names
- Full markdown content
## Usage Examples
### Basic Usage
```javascript
const fetcher = new EnhancedDocumentationFetcher();
const doc = await fetcher.getEnhancedNodeDocumentation('n8n-nodes-base.slack');
// Access structured data
console.log(`Operations: ${doc.operations.length}`);
console.log(`API Methods: ${doc.apiMethods.length}`);
```
### With Database Storage
```javascript
const storage = new EnhancedSQLiteStorageService();
const nodeInfo = await extractor.extractNodeSource('n8n-nodes-base.slack');
const storedNode = await storage.storeNodeWithDocumentation(nodeInfo);
// Access counts
console.log(`Stored ${storedNode.operationCount} operations`);
console.log(`Stored ${storedNode.apiMethodCount} API methods`);
```
## Benefits for AI Agents
1. **Comprehensive Understanding**: AI agents can now understand not just what a node does, but exactly which operations are available and how they map to API endpoints.
2. **Better Search**: Enhanced FTS allows searching across operations, descriptions, and documentation content.
3. **Structured Data**: Operations and API methods are stored as structured data, making it easier for AI to reason about node capabilities.
4. **Rich Context**: Related resources, examples, and metadata provide additional context for better AI responses.
## Implementation Files
- `/src/utils/enhanced-documentation-fetcher.ts`: Main parser implementation
- `/src/services/enhanced-sqlite-storage-service.ts`: Database storage with rich schema
- `/src/db/enhanced-schema.sql`: Enhanced database schema
- `/tests/demo-enhanced-documentation.js`: Working demonstration
## Future Enhancements
1. **Example Extraction**: Improve code example extraction from documentation
2. **Parameter Parsing**: Extract operation parameters and their types
3. **Credential Requirements**: Parse specific credential field requirements
4. **Version Tracking**: Track documentation versions and changes
5. **Caching**: Implement smart caching for documentation fetches
## Testing
Run the demo to see the enhanced parser in action:
```bash
npm run build
node tests/demo-enhanced-documentation.js
```
This will show:
- Extraction of 40+ operations from Slack node
- API method mappings with URLs
- Resource grouping and organization
- Related documentation links

View File

@@ -1,232 +0,0 @@
# Production Deployment Guide
This guide covers deploying the n8n Documentation MCP Server in production environments.
## Overview
The n8n Documentation MCP Server provides node documentation and source code to AI assistants. It can be deployed:
- **Locally** - Using stdio transport for Claude Desktop on the same machine
- **Remotely** - Using HTTP transport for access over the internet
For remote deployment with full VM setup instructions, see [REMOTE_DEPLOYMENT.md](./REMOTE_DEPLOYMENT.md).
## Local Production Deployment
### Prerequisites
- Node.js 18+ installed
- Git installed
- 500MB available disk space
### Quick Start
1. **Clone and setup**
```bash
git clone https://github.com/yourusername/n8n-mcp.git
cd n8n-mcp
npm install
npm run build
```
2. **Initialize database**
```bash
npm run db:rebuild:v2
```
3. **Configure Claude Desktop**
Edit Claude Desktop config (see README.md for paths):
```json
{
"mcpServers": {
"n8n-nodes": {
"command": "node",
"args": ["/absolute/path/to/n8n-mcp/dist/index-v2.js"],
"env": {
"NODE_DB_PATH": "/absolute/path/to/n8n-mcp/data/nodes-v2.db"
}
}
}
}
```
## Docker Deployment
### Using Docker Compose
1. **Create docker-compose.yml**
```yaml
version: '3.8'
services:
n8n-docs-mcp:
build: .
volumes:
- ./data:/app/data
environment:
- NODE_ENV=production
- NODE_DB_PATH=/app/data/nodes-v2.db
command: node dist/index-v2.js
```
2. **Build and run**
```bash
docker-compose up -d
```
### Using Dockerfile
```dockerfile
FROM node:18-alpine
WORKDIR /app
# Copy package files
COPY package*.json ./
RUN npm ci --only=production
# Copy built files
COPY dist/ ./dist/
COPY data/ ./data/
# Set environment
ENV NODE_ENV=production
ENV NODE_DB_PATH=/app/data/nodes-v2.db
# Run the server
CMD ["node", "dist/index-v2.js"]
```
## Database Management
### Automatic Rebuilds
Schedule regular database updates to get latest node documentation:
```bash
# Add to crontab
0 2 * * * cd /path/to/n8n-mcp && npm run db:rebuild:v2
```
### Manual Rebuild
```bash
npm run db:rebuild:v2
```
### Database Location
The SQLite database is stored at: `data/nodes-v2.db`
### Backup
```bash
# Simple backup
cp data/nodes-v2.db data/nodes-v2.db.backup
# Timestamped backup
cp data/nodes-v2.db "data/nodes-v2-$(date +%Y%m%d-%H%M%S).db"
```
## Monitoring
### Database Statistics
Check the database status:
```bash
# Using SQLite directly
sqlite3 data/nodes-v2.db "SELECT COUNT(*) as total_nodes FROM nodes;"
# Using the MCP tool (in Claude)
# "Get database statistics for n8n nodes"
```
### Logs
For local deployment:
```bash
# Run with logging
NODE_ENV=production node dist/index-v2.js 2>&1 | tee app.log
```
## Performance Optimization
### SQLite Optimization
The database uses these optimizations by default:
- WAL mode for better concurrency
- Memory-mapped I/O
- Full-text search indexes
### System Requirements
- **Minimum**: 256MB RAM, 500MB disk
- **Recommended**: 512MB RAM, 1GB disk
- **CPU**: Minimal requirements (mostly I/O bound)
## Security
### Local Deployment
- No network exposure (stdio only)
- File system permissions control access
- No authentication needed
### Remote Deployment
See [REMOTE_DEPLOYMENT.md](./REMOTE_DEPLOYMENT.md) for:
- HTTPS configuration
- Authentication setup
- Firewall rules
- Security best practices
## Troubleshooting
### Database Issues
If the database is missing or corrupted:
```bash
# Rebuild from scratch
rm data/nodes-v2.db
npm run db:rebuild:v2
```
### Memory Issues
If running on limited memory:
```bash
# Limit Node.js memory usage
NODE_OPTIONS="--max-old-space-size=256" node dist/index-v2.js
```
### Permission Issues
Ensure proper file permissions:
```bash
chmod 644 data/nodes-v2.db
chmod 755 data/
```
## Updates
To update to the latest version:
```bash
# Pull latest code
git pull
# Install dependencies
npm install
# Rebuild
npm run build
# Rebuild database
npm run db:rebuild:v2
```
## Support
For issues and questions:
- GitHub Issues: https://github.com/yourusername/n8n-mcp/issues
- Check logs for error messages
- Verify database integrity

View File

@@ -1,434 +0,0 @@
# Remote Deployment Guide
This guide explains how to deploy the n8n Documentation MCP Server to a remote VM (such as Hetzner) and connect to it from Claude Desktop.
**Quick Start**: For a streamlined deployment to n8ndocumentation.aiservices.pl, see [DEPLOYMENT_QUICKSTART.md](./DEPLOYMENT_QUICKSTART.md).
## Overview
The n8n Documentation MCP Server can be deployed as a remote HTTP service, allowing Claude Desktop to access n8n node documentation over the internet. This is useful for:
- Centralized documentation serving for teams
- Accessing documentation without local n8n installation
- Cloud-based AI development workflows
## Architecture
```
Claude Desktop → Internet → MCP Server (HTTPS) → SQLite Database
n8n Documentation
```
## Prerequisites
- A VM with Ubuntu 20.04+ or similar Linux distribution
- Node.js 18+ installed
- A domain name (e.g., `n8ndocumentation.aiservices.pl`)
- SSL certificate (Let's Encrypt recommended)
- Basic knowledge of Linux server administration
## Deployment Steps
### 1. Server Setup
SSH into your VM and prepare the environment:
```bash
# Update system packages
sudo apt update && sudo apt upgrade -y
# Install Node.js 18+ (if not already installed)
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt install -y nodejs
# Install git and build essentials
sudo apt install -y git build-essential
# Install PM2 for process management
sudo npm install -g pm2
# Create application directory
sudo mkdir -p /opt/n8n-mcp
sudo chown $USER:$USER /opt/n8n-mcp
```
### 2. Clone and Build
```bash
cd /opt
git clone https://github.com/yourusername/n8n-mcp.git
cd n8n-mcp
# Install dependencies
npm install
# Build the project
npm run build
# Initialize database
npm run db:rebuild:v2
```
### 3. Configure Environment
Create the production environment file:
```bash
cp .env.example .env
nano .env
```
Configure with your domain and security settings:
```env
# Remote Server Configuration
MCP_PORT=3000
MCP_HOST=0.0.0.0
MCP_DOMAIN=n8ndocumentation.aiservices.pl
# Authentication - REQUIRED for production
# Generate secure token: openssl rand -hex 32
MCP_AUTH_TOKEN=your-generated-secure-token-here
# Enable CORS for browser access
MCP_CORS=true
# Database path
NODE_DB_PATH=/opt/n8n-mcp/data/nodes-v2.db
# Production environment
NODE_ENV=production
MCP_LOG_LEVEL=info
```
### 4. Setup SSL with Nginx
Install and configure Nginx as a reverse proxy with SSL:
```bash
# Install Nginx and Certbot
sudo apt install -y nginx certbot python3-certbot-nginx
# Create Nginx configuration
sudo nano /etc/nginx/sites-available/n8n-mcp
```
Add the following configuration:
```nginx
server {
listen 80;
server_name n8ndocumentation.aiservices.pl;
location / {
return 301 https://$server_name$request_uri;
}
}
server {
listen 443 ssl;
server_name n8ndocumentation.aiservices.pl;
# SSL will be configured by Certbot
# Security headers
add_header X-Content-Type-Options nosniff;
add_header X-Frame-Options DENY;
add_header X-XSS-Protection "1; mode=block";
# Proxy settings
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade;
# Increase timeouts for MCP operations
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
}
```
Enable the site and obtain SSL certificate:
```bash
# Enable the site
sudo ln -s /etc/nginx/sites-available/n8n-mcp /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
# Obtain SSL certificate
sudo certbot --nginx -d n8ndocumentation.aiservices.pl
```
### 5. Start with PM2
Create PM2 ecosystem file:
```bash
nano /opt/n8n-mcp/ecosystem.config.js
```
```javascript
module.exports = {
apps: [{
name: 'n8n-mcp',
script: './dist/index-http.js',
cwd: '/opt/n8n-mcp',
instances: 1,
autorestart: true,
watch: false,
max_memory_restart: '1G',
env: {
NODE_ENV: 'production'
},
error_file: '/opt/n8n-mcp/logs/error.log',
out_file: '/opt/n8n-mcp/logs/out.log',
log_file: '/opt/n8n-mcp/logs/combined.log',
time: true
}]
};
```
Start the application:
```bash
# Create logs directory
mkdir -p /opt/n8n-mcp/logs
# Start with PM2
pm2 start ecosystem.config.js
# Save PM2 configuration
pm2 save
# Setup PM2 to start on boot
pm2 startup
```
### 6. Configure Firewall
```bash
# Allow SSH, HTTP, and HTTPS
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
```
## Claude Desktop Configuration
### 1. Get your auth token
From your server, get the configured auth token:
```bash
grep MCP_AUTH_TOKEN /opt/n8n-mcp/.env
```
### 2. Configure Claude Desktop
Edit your Claude Desktop configuration:
**macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
**Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
**Linux**: `~/.config/Claude/claude_desktop_config.json`
Add the remote MCP server:
```json
{
"mcpServers": {
"n8n-nodes-remote": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/client-http",
"https://n8ndocumentation.aiservices.pl/mcp"
],
"env": {
"MCP_AUTH_TOKEN": "your-auth-token-here"
}
}
}
}
```
### 3. Restart Claude Desktop
Quit and restart Claude Desktop to load the new configuration.
## Server Management
### Viewing Logs
```bash
# View real-time logs
pm2 logs n8n-mcp
# View error logs
tail -f /opt/n8n-mcp/logs/error.log
# View Nginx logs
sudo tail -f /var/log/nginx/access.log
sudo tail -f /var/log/nginx/error.log
```
### Rebuilding Database
To update the node documentation database:
```bash
cd /opt/n8n-mcp
# Stop the server
pm2 stop n8n-mcp
# Rebuild database
npm run db:rebuild:v2
# Restart server
pm2 restart n8n-mcp
```
### Updating the Server
```bash
cd /opt/n8n-mcp
# Pull latest changes
git pull
# Install dependencies
npm install
# Build
npm run build
# Restart
pm2 restart n8n-mcp
```
## Security Considerations
1. **Authentication Token**: Always use a strong, randomly generated token
```bash
openssl rand -hex 32
```
2. **HTTPS**: Always use HTTPS in production. The setup above includes automatic SSL with Let's Encrypt.
3. **Firewall**: Only open necessary ports (22, 80, 443)
4. **Updates**: Keep the system and Node.js updated regularly
5. **Monitoring**: Set up monitoring for the service:
```bash
# PM2 monitoring
pm2 install pm2-logrotate
pm2 set pm2-logrotate:max_size 10M
pm2 set pm2-logrotate:retain 7
```
## API Endpoints
Once deployed, your server provides:
- `GET https://n8ndocumentation.aiservices.pl/` - Server information
- `GET https://n8ndocumentation.aiservices.pl/health` - Health check
- `GET https://n8ndocumentation.aiservices.pl/stats` - Database statistics
- `POST https://n8ndocumentation.aiservices.pl/mcp` - MCP protocol endpoint
- `POST https://n8ndocumentation.aiservices.pl/rebuild` - Rebuild database (requires auth)
## Troubleshooting
### Connection Issues
1. Check if the server is running:
```bash
pm2 status
curl https://n8ndocumentation.aiservices.pl/health
```
2. Verify Nginx is working:
```bash
sudo nginx -t
sudo systemctl status nginx
```
3. Check firewall:
```bash
sudo ufw status
```
### Authentication Failures
1. Verify the token matches in both `.env` and Claude config
2. Check server logs for auth errors:
```bash
pm2 logs n8n-mcp --lines 100
```
### Database Issues
1. Check database exists:
```bash
ls -la /opt/n8n-mcp/data/nodes-v2.db
```
2. Rebuild if necessary:
```bash
cd /opt/n8n-mcp
npm run db:rebuild:v2
```
## Monitoring and Maintenance
### Health Monitoring
Set up external monitoring (e.g., UptimeRobot) to check:
- `https://n8ndocumentation.aiservices.pl/health`
### Backup
Regular backups of the database:
```bash
# Create backup script
cat > /opt/n8n-mcp/backup.sh << 'EOF'
#!/bin/bash
BACKUP_DIR="/opt/n8n-mcp/backups"
mkdir -p $BACKUP_DIR
cp /opt/n8n-mcp/data/nodes-v2.db "$BACKUP_DIR/nodes-v2-$(date +%Y%m%d-%H%M%S).db"
# Keep only last 7 backups
find $BACKUP_DIR -name "nodes-v2-*.db" -mtime +7 -delete
EOF
chmod +x /opt/n8n-mcp/backup.sh
# Add to crontab (daily at 2 AM)
(crontab -l 2>/dev/null; echo "0 2 * * * /opt/n8n-mcp/backup.sh") | crontab -
```
## Cost Optimization
For a small Hetzner VM (CX11 - 1 vCPU, 2GB RAM):
- Monthly cost: ~€4-5
- Sufficient for serving documentation to multiple Claude instances
- Can handle hundreds of concurrent connections
## Support
For issues specific to remote deployment:
1. Check server logs first
2. Verify network connectivity
3. Ensure all dependencies are installed
4. Check GitHub issues for similar problems

View File

@@ -1,81 +0,0 @@
# Slack Documentation Fix Summary
## Issues Fixed
### 1. Documentation Fetcher Was Getting Wrong Files
**Problem**: When searching for Slack node documentation, the fetcher was finding credential documentation instead of node documentation.
**Root Cause**:
- Documentation files in n8n-docs repository are named with full node type (e.g., `n8n-nodes-base.slack.md`)
- The fetcher was searching for just the node name (e.g., `slack.md`)
- This caused it to find `slack.md` in the credentials folder first
**Fix Applied**:
- Updated `getNodeDocumentation()` to search for full node type first
- Added logic to skip credential documentation files by checking:
- If file path includes `/credentials/`
- If content has "credentials" in title without "node documentation"
- Fixed search order to prioritize correct documentation
### 2. Node Source Extractor Case Sensitivity
**Problem**: Slack node source code wasn't found because the directory is capitalized (`Slack/`) but search was case-sensitive.
**Root Cause**:
- n8n node directories use capitalized names (e.g., `Slack/`, `If/`)
- Extractor was searching with lowercase names from node type
**Fix Applied**:
- Added case variants to try when searching:
- Original case
- Capitalized first letter
- All lowercase
- All uppercase
- Now properly finds nodes regardless of directory naming convention
### 3. Missing Information in Database
**Problem**: Node definitions weren't being properly parsed from compiled JavaScript.
**Fix Applied**:
- Improved `parseNodeDefinition()` to extract individual fields using regex
- Added extraction for:
- displayName
- description
- icon
- category/group
- version
- trigger/webhook detection
## Test Results
After applying fixes:
- ✅ Slack node source code is correctly extracted
- ✅ Slack node documentation (not credentials) is fetched
- ✅ Documentation URL points to correct page
- ✅ All information is properly stored in database
## Files Modified
1. `/src/utils/documentation-fetcher.ts`
- Fixed path searching logic
- Added credential documentation filtering
- Improved search order
2. `/src/utils/node-source-extractor.ts`
- Added case-insensitive directory searching
- Improved path detection for different node structures
3. `/src/services/node-documentation-service.ts`
- Enhanced node definition parsing
- Better extraction of metadata from source code
## Verification
Run the test to verify the fix:
```bash
node tests/test-slack-fix.js
```
This should show:
- Source code found at correct location
- Documentation is node documentation (not credentials)
- All fields properly extracted and stored

View File

@@ -1,18 +0,0 @@
{
"mcpServers": {
"puppeteer": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-puppeteer"
]
},
"n8n-nodes": {
"command": "node",
"args": ["/Users/romualdczlonkowski/Pliki/n8n-mcp/n8n-mcp/dist/index-v2.js"],
"env": {
"NODE_DB_PATH": "/Users/romualdczlonkowski/Pliki/n8n-mcp/n8n-mcp/data/nodes-v2.db"
}
}
}
}

View File

@@ -0,0 +1,768 @@
# n8n-MCP Enhancement Implementation Plan v2.2
## Executive Summary
This revised plan addresses the core issues discovered during testing: empty properties/operations arrays and missing AI tool detection. We focus on fixing the data extraction and storage pipeline while maintaining the simplicity of v2.1.
## Key Issues Found & Solutions
### 1. Empty Properties/Operations Arrays
**Problem**: The MCP service returns empty arrays for properties, operations, and credentials despite nodes having this data.
**Root Cause**: The parser is correctly extracting data, but either:
- The data isn't being properly serialized to the database
- The MCP server isn't deserializing it correctly
- The property structure is more complex than expected
**Solution**: Enhanced property extraction and proper JSON handling
### 2. AI Tools Not Detected
**Problem**: No nodes are flagged as AI tools despite having `usableAsTool` property.
**Root Cause**: The property might be nested or named differently in the actual node classes.
**Solution**: Deep property search and multiple detection strategies
### 3. Missing Versioned Node Support
**Problem**: Versioned nodes aren't properly handled, leading to incomplete data.
**Solution**: Explicit version handling for nodes like HTTPRequest and Code
## Updated Architecture
```
n8n-mcp/
├── src/
│ ├── loaders/
│ │ └── node-loader.ts # Enhanced with better error handling
│ ├── parsers/
│ │ ├── property-extractor.ts # NEW: Dedicated property extraction
│ │ └── node-parser.ts # Updated parser with deep inspection
│ ├── mappers/
│ │ └── docs-mapper.ts # Existing (working fine)
│ ├── database/
│ │ └── node-repository.ts # NEW: Proper data serialization
│ ├── scripts/
│ │ └── rebuild.ts # Enhanced with validation
│ └── mcp/
│ └── server.ts # Fixed data retrieval
└── data/
└── nodes.db # Same schema
```
## Week 1: Core Fixes
### Day 1-2: Property Extractor
**NEW File**: `src/parsers/property-extractor.ts`
```typescript
export class PropertyExtractor {
/**
* Extract properties with proper handling of n8n's complex structures
*/
extractProperties(nodeClass: any): any[] {
const properties = [];
// Handle versioned nodes
if (nodeClass.nodeVersions) {
const versions = Object.keys(nodeClass.nodeVersions);
const latestVersion = Math.max(...versions.map(Number));
const versionedNode = nodeClass.nodeVersions[latestVersion];
if (versionedNode.description?.properties) {
return this.normalizeProperties(versionedNode.description.properties);
}
}
// Handle regular nodes
if (nodeClass.description?.properties) {
return this.normalizeProperties(nodeClass.description.properties);
}
return properties;
}
/**
* Extract operations from both declarative and programmatic nodes
*/
extractOperations(nodeClass: any): any[] {
const operations = [];
// Declarative nodes (with routing)
if (nodeClass.description?.routing) {
const routing = nodeClass.description.routing;
// Extract from request.resource and request.operation
if (routing.request?.resource) {
const resources = routing.request.resource.options || [];
const operationOptions = routing.request.operation?.options || {};
resources.forEach(resource => {
const resourceOps = operationOptions[resource.value] || [];
resourceOps.forEach(op => {
operations.push({
resource: resource.value,
operation: op.value,
name: `${resource.name} - ${op.name}`,
action: op.action
});
});
});
}
}
// Programmatic nodes - look for operation property
const props = this.extractProperties(nodeClass);
const operationProp = props.find(p => p.name === 'operation' || p.name === 'action');
if (operationProp?.options) {
operationProp.options.forEach(op => {
operations.push({
operation: op.value,
name: op.name,
description: op.description
});
});
}
return operations;
}
/**
* Deep search for AI tool capability
*/
detectAIToolCapability(nodeClass: any): boolean {
// Direct property check
if (nodeClass.description?.usableAsTool === true) return true;
// Check in actions for declarative nodes
if (nodeClass.description?.actions?.some(a => a.usableAsTool === true)) return true;
// Check versioned nodes
if (nodeClass.nodeVersions) {
for (const version of Object.values(nodeClass.nodeVersions)) {
if ((version as any).description?.usableAsTool === true) return true;
}
}
// Check for specific AI-related properties
const aiIndicators = ['openai', 'anthropic', 'huggingface', 'cohere', 'ai'];
const nodeName = nodeClass.description?.name?.toLowerCase() || '';
return aiIndicators.some(indicator => nodeName.includes(indicator));
}
/**
* Extract credential requirements with proper structure
*/
extractCredentials(nodeClass: any): any[] {
const credentials = [];
// Handle versioned nodes
if (nodeClass.nodeVersions) {
const versions = Object.keys(nodeClass.nodeVersions);
const latestVersion = Math.max(...versions.map(Number));
const versionedNode = nodeClass.nodeVersions[latestVersion];
if (versionedNode.description?.credentials) {
return versionedNode.description.credentials;
}
}
// Regular nodes
if (nodeClass.description?.credentials) {
return nodeClass.description.credentials;
}
return credentials;
}
private normalizeProperties(properties: any[]): any[] {
// Ensure all properties have consistent structure
return properties.map(prop => ({
displayName: prop.displayName,
name: prop.name,
type: prop.type,
default: prop.default,
description: prop.description,
options: prop.options,
required: prop.required,
displayOptions: prop.displayOptions,
typeOptions: prop.typeOptions,
noDataExpression: prop.noDataExpression
}));
}
}
```
### Day 3: Updated Parser
**Updated File**: `src/parsers/node-parser.ts`
```typescript
import { PropertyExtractor } from './property-extractor';
export class NodeParser {
private propertyExtractor = new PropertyExtractor();
parse(nodeClass: any, packageName: string): ParsedNode {
// Get base description (handles versioned nodes)
const description = this.getNodeDescription(nodeClass);
return {
style: this.detectStyle(nodeClass),
nodeType: this.extractNodeType(description, packageName),
displayName: description.displayName || description.name,
description: description.description,
category: this.extractCategory(description),
properties: this.propertyExtractor.extractProperties(nodeClass),
credentials: this.propertyExtractor.extractCredentials(nodeClass),
isAITool: this.propertyExtractor.detectAIToolCapability(nodeClass),
isTrigger: this.detectTrigger(description),
isWebhook: this.detectWebhook(description),
operations: this.propertyExtractor.extractOperations(nodeClass),
version: this.extractVersion(nodeClass),
isVersioned: !!nodeClass.nodeVersions
};
}
private getNodeDescription(nodeClass: any): any {
// For versioned nodes, get the latest version's description
if (nodeClass.baseDescription) {
return nodeClass.baseDescription;
}
if (nodeClass.nodeVersions) {
const versions = Object.keys(nodeClass.nodeVersions);
const latestVersion = Math.max(...versions.map(Number));
return nodeClass.nodeVersions[latestVersion].description || {};
}
return nodeClass.description || {};
}
private detectStyle(nodeClass: any): 'declarative' | 'programmatic' {
const desc = this.getNodeDescription(nodeClass);
return desc.routing ? 'declarative' : 'programmatic';
}
private extractNodeType(description: any, packageName: string): string {
// Ensure we have the full node type including package prefix
const name = description.name;
if (name.includes('.')) {
return name;
}
// Add package prefix if missing
const packagePrefix = packageName.replace('@n8n/', '').replace('n8n-', '');
return `${packagePrefix}.${name}`;
}
private extractCategory(description: any): string {
return description.group?.[0] ||
description.categories?.[0] ||
description.category ||
'misc';
}
private detectTrigger(description: any): boolean {
return description.polling === true ||
description.trigger === true ||
description.eventTrigger === true ||
description.name?.toLowerCase().includes('trigger');
}
private detectWebhook(description: any): boolean {
return (description.webhooks?.length > 0) ||
description.webhook === true ||
description.name?.toLowerCase().includes('webhook');
}
private extractVersion(nodeClass: any): string {
if (nodeClass.baseDescription?.defaultVersion) {
return nodeClass.baseDescription.defaultVersion.toString();
}
if (nodeClass.nodeVersions) {
const versions = Object.keys(nodeClass.nodeVersions);
return Math.max(...versions.map(Number)).toString();
}
return nodeClass.description?.version || '1';
}
}
```
### Day 4: Node Repository
**NEW File**: `src/database/node-repository.ts`
```typescript
import Database from 'better-sqlite3';
export class NodeRepository {
constructor(private db: Database.Database) {}
/**
* Save node with proper JSON serialization
*/
saveNode(node: ParsedNode): void {
const stmt = this.db.prepare(`
INSERT OR REPLACE INTO nodes (
node_type, package_name, display_name, description,
category, development_style, is_ai_tool, is_trigger,
is_webhook, is_versioned, version, documentation,
properties_schema, operations, credentials_required
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
`);
stmt.run(
node.nodeType,
node.packageName,
node.displayName,
node.description,
node.category,
node.style,
node.isAITool ? 1 : 0,
node.isTrigger ? 1 : 0,
node.isWebhook ? 1 : 0,
node.isVersioned ? 1 : 0,
node.version,
node.documentation || null,
JSON.stringify(node.properties, null, 2),
JSON.stringify(node.operations, null, 2),
JSON.stringify(node.credentials, null, 2)
);
}
/**
* Get node with proper JSON deserialization
*/
getNode(nodeType: string): any {
const row = this.db.prepare(`
SELECT * FROM nodes WHERE node_type = ?
`).get(nodeType);
if (!row) return null;
return {
nodeType: row.node_type,
displayName: row.display_name,
description: row.description,
category: row.category,
developmentStyle: row.development_style,
package: row.package_name,
isAITool: !!row.is_ai_tool,
isTrigger: !!row.is_trigger,
isWebhook: !!row.is_webhook,
isVersioned: !!row.is_versioned,
version: row.version,
properties: this.safeJsonParse(row.properties_schema, []),
operations: this.safeJsonParse(row.operations, []),
credentials: this.safeJsonParse(row.credentials_required, []),
hasDocumentation: !!row.documentation
};
}
/**
* Get AI tools with proper filtering
*/
getAITools(): any[] {
const rows = this.db.prepare(`
SELECT node_type, display_name, description, package_name
FROM nodes
WHERE is_ai_tool = 1
ORDER BY display_name
`).all();
return rows.map(row => ({
nodeType: row.node_type,
displayName: row.display_name,
description: row.description,
package: row.package_name
}));
}
private safeJsonParse(json: string, defaultValue: any): any {
try {
return JSON.parse(json);
} catch {
return defaultValue;
}
}
}
```
### Day 5: Enhanced Rebuild Script
**Updated File**: `src/scripts/rebuild.ts`
```typescript
#!/usr/bin/env node
import Database from 'better-sqlite3';
import { N8nNodeLoader } from '../loaders/node-loader';
import { NodeParser } from '../parsers/node-parser';
import { DocsMapper } from '../mappers/docs-mapper';
import { NodeRepository } from '../database/node-repository';
import * as fs from 'fs';
import * as path from 'path';
async function rebuild() {
console.log('🔄 Rebuilding n8n node database...\n');
const db = new Database('./data/nodes.db');
const loader = new N8nNodeLoader();
const parser = new NodeParser();
const mapper = new DocsMapper();
const repository = new NodeRepository(db);
// Initialize database
const schema = fs.readFileSync(path.join(__dirname, '../database/schema.sql'), 'utf8');
db.exec(schema);
// Clear existing data
db.exec('DELETE FROM nodes');
console.log('🗑️ Cleared existing data\n');
// Load all nodes
const nodes = await loader.loadAllNodes();
console.log(`📦 Loaded ${nodes.length} nodes from packages\n`);
// Statistics
const stats = {
successful: 0,
failed: 0,
aiTools: 0,
triggers: 0,
webhooks: 0,
withProperties: 0,
withOperations: 0,
withDocs: 0
};
// Process each node
for (const { packageName, nodeName, NodeClass } of nodes) {
try {
// Parse node
const parsed = parser.parse(NodeClass, packageName);
// Validate parsed data
if (!parsed.nodeType || !parsed.displayName) {
throw new Error('Missing required fields');
}
// Get documentation
const docs = await mapper.fetchDocumentation(parsed.nodeType);
parsed.documentation = docs;
// Save to database
repository.saveNode(parsed);
// Update statistics
stats.successful++;
if (parsed.isAITool) stats.aiTools++;
if (parsed.isTrigger) stats.triggers++;
if (parsed.isWebhook) stats.webhooks++;
if (parsed.properties.length > 0) stats.withProperties++;
if (parsed.operations.length > 0) stats.withOperations++;
if (docs) stats.withDocs++;
console.log(`✅ ${parsed.nodeType} [Props: ${parsed.properties.length}, Ops: ${parsed.operations.length}]`);
} catch (error) {
stats.failed++;
console.error(`❌ Failed to process ${nodeName}: ${error.message}`);
}
}
// Validation check
console.log('\n🔍 Running validation checks...');
const validationResults = validateDatabase(repository);
// Summary
console.log('\n📊 Summary:');
console.log(` Total nodes: ${nodes.length}`);
console.log(` Successful: ${stats.successful}`);
console.log(` Failed: ${stats.failed}`);
console.log(` AI Tools: ${stats.aiTools}`);
console.log(` Triggers: ${stats.triggers}`);
console.log(` Webhooks: ${stats.webhooks}`);
console.log(` With Properties: ${stats.withProperties}`);
console.log(` With Operations: ${stats.withOperations}`);
console.log(` With Documentation: ${stats.withDocs}`);
if (!validationResults.passed) {
console.log('\n⚠ Validation Issues:');
validationResults.issues.forEach(issue => console.log(` - ${issue}`));
}
console.log('\n✨ Rebuild complete!');
db.close();
}
function validateDatabase(repository: NodeRepository): { passed: boolean; issues: string[] } {
const issues = [];
// Check critical nodes
const criticalNodes = ['httpRequest', 'code', 'webhook', 'slack'];
for (const nodeType of criticalNodes) {
const node = repository.getNode(nodeType);
if (!node) {
issues.push(`Critical node ${nodeType} not found`);
continue;
}
if (node.properties.length === 0) {
issues.push(`Node ${nodeType} has no properties`);
}
}
// Check AI tools
const aiTools = repository.getAITools();
if (aiTools.length === 0) {
issues.push('No AI tools found - check detection logic');
}
return {
passed: issues.length === 0,
issues
};
}
// Run if called directly
if (require.main === module) {
rebuild().catch(console.error);
}
```
## Week 2: Testing and MCP Updates
### Day 6-7: Enhanced MCP Server
**Updated File**: `src/mcp/server.ts`
```typescript
import { NodeRepository } from '../database/node-repository';
// In the get_node_info handler
async function getNodeInfo(nodeType: string) {
const repository = new NodeRepository(db);
const node = repository.getNode(nodeType);
if (!node) {
// Try alternative formats
const alternatives = [
nodeType,
nodeType.replace('n8n-nodes-base.', ''),
`n8n-nodes-base.${nodeType}`,
nodeType.toLowerCase()
];
for (const alt of alternatives) {
const found = repository.getNode(alt);
if (found) {
node = found;
break;
}
}
if (!node) {
throw new Error(`Node ${nodeType} not found`);
}
}
return node;
}
// In the list_ai_tools handler
async function listAITools() {
const repository = new NodeRepository(db);
const tools = repository.getAITools();
return {
tools,
totalCount: tools.length,
requirements: {
environmentVariable: 'N8N_COMMUNITY_PACKAGES_ALLOW_TOOL_USAGE=true',
nodeProperty: 'usableAsTool: true'
}
};
}
```
### Day 8-9: Test Suite
**NEW File**: `src/scripts/test-nodes.ts`
```typescript
#!/usr/bin/env node
import Database from 'better-sqlite3';
import { NodeRepository } from '../database/node-repository';
const TEST_CASES = [
{
nodeType: 'httpRequest',
checks: {
hasProperties: true,
minProperties: 5,
hasDocumentation: true,
isVersioned: true
}
},
{
nodeType: 'slack',
checks: {
hasOperations: true,
minOperations: 10,
style: 'declarative'
}
},
{
nodeType: 'code',
checks: {
hasProperties: true,
properties: ['mode', 'language', 'jsCode']
}
}
];
async function runTests() {
const db = new Database('./data/nodes.db');
const repository = new NodeRepository(db);
console.log('🧪 Running node tests...\n');
let passed = 0;
let failed = 0;
for (const testCase of TEST_CASES) {
console.log(`Testing ${testCase.nodeType}...`);
try {
const node = repository.getNode(testCase.nodeType);
if (!node) {
throw new Error('Node not found');
}
// Run checks
for (const [check, expected] of Object.entries(testCase.checks)) {
switch (check) {
case 'hasProperties':
if (expected && node.properties.length === 0) {
throw new Error('No properties found');
}
break;
case 'minProperties':
if (node.properties.length < expected) {
throw new Error(`Expected at least ${expected} properties, got ${node.properties.length}`);
}
break;
case 'hasOperations':
if (expected && node.operations.length === 0) {
throw new Error('No operations found');
}
break;
case 'minOperations':
if (node.operations.length < expected) {
throw new Error(`Expected at least ${expected} operations, got ${node.operations.length}`);
}
break;
case 'properties':
const propNames = node.properties.map(p => p.name);
for (const prop of expected as string[]) {
if (!propNames.includes(prop)) {
throw new Error(`Missing property: ${prop}`);
}
}
break;
}
}
console.log(`✅ ${testCase.nodeType} passed all checks\n`);
passed++;
} catch (error) {
console.error(`❌ ${testCase.nodeType} failed: ${error.message}\n`);
failed++;
}
}
console.log(`\n📊 Test Results: ${passed} passed, ${failed} failed`);
db.close();
}
if (require.main === module) {
runTests().catch(console.error);
}
```
## Key Improvements in v2.2
1. **Dedicated Property Extraction**
- Handles versioned nodes properly
- Extracts operations from both declarative and programmatic nodes
- Deep search for AI tool capabilities
2. **Proper Data Serialization**
- NodeRepository ensures JSON is properly stored and retrieved
- Safe JSON parsing with defaults
- Consistent data structure
3. **Enhanced Validation**
- Validation checks in rebuild script
- Test suite for critical nodes
- Statistics tracking for better visibility
4. **Better Error Handling**
- Alternative node type lookups
- Graceful fallbacks
- Detailed error messages
5. **AI Tool Detection**
- Multiple detection strategies
- Check in versioned nodes
- Name-based heuristics as fallback
## Success Metrics Update
1. **Properties/Operations**: >90% of nodes should have non-empty arrays
2. **AI Tools**: Should detect at least 10-20 AI-capable nodes
3. **Critical Nodes**: 100% pass rate on test suite
4. **Documentation**: Maintain existing 89% coverage
5. **Performance**: Rebuild in <60 seconds (allowing for validation)
## Deployment Steps
```bash
# 1. Update code with v2.2 changes
npm install
# 2. Build TypeScript
npm run build
# 3. Run rebuild with validation
npm run rebuild
# 4. Run test suite
npm run test-nodes
# 5. Verify AI tools
npm run list-ai-tools
# 6. Start MCP server
npm start
```
## Summary
Version 2.2 focuses on fixing the core data extraction issues while maintaining the simplicity of the MVP approach. The key insight is that n8n's node structure is more complex than initially assumed, especially for versioned nodes and AI tool detection. By adding dedicated extraction logic and proper data handling, we can deliver accurate node information while keeping the implementation straightforward.</document_content>
</invoke>

View File

@@ -1,108 +0,0 @@
# n8n-MCP Implementation Report
## Summary
Successfully implemented the n8n-MCP Enhancement Plan v2.1 Final, delivering a functional MVP that provides accurate n8n node documentation through the Model Context Protocol (MCP).
## Achievements
### Week 1: Core Implementation ✅
1. **Node Loader** (`src/loaders/node-loader.ts`)
- Loads nodes from both `n8n-nodes-base` and `@n8n/n8n-nodes-langchain`
- Handles both array and object formats for node configurations
- Successfully loads 457 out of 458 nodes
2. **Simple Parser** (`src/parsers/simple-parser.ts`)
- Parses both declarative and programmatic nodes
- Detects versioned nodes (both VersionedNodeType and inline versioning)
- Extracts node metadata, properties, and operations
- Handles instantiation of nodes to access instance properties
3. **Documentation Mapper** (`src/mappers/docs-mapper.ts`)
- Maps nodes to their documentation files
- Handles both file and directory documentation structures
- Includes known fixes for problematic node names
- Achieves 89% documentation coverage (405/457 nodes)
4. **Database Schema** (`src/database/schema.sql`)
- Simple SQLite schema optimized for the MVP
- Stores all essential node information
- Includes indexes for performance
5. **Rebuild Script** (`src/scripts/rebuild.ts`)
- One-command database rebuild (`npm run rebuild`)
- Provides clear progress and error reporting
- Completes in under 30 seconds
### Week 2: Testing and Integration ✅
1. **Validation Script** (`src/scripts/validate.ts`)
- Tests critical nodes (HTTP Request, Code, Slack, Agent)
- Validates documentation coverage
- Provides database statistics
- 3 out of 4 critical nodes pass all tests
2. **MCP Server Updates** (`src/mcp/server-update.ts`)
- Implements all planned MCP tools:
- `list_nodes` - Filter and list nodes
- `get_node_info` - Detailed node information
- `search_nodes` - Full-text search
- `list_ai_tools` - List AI-capable nodes
- `get_node_documentation` - Fetch node docs
- `get_database_statistics` - Database stats
## Key Metrics
- **Nodes Loaded**: 457/458 (99.8%)
- **Documentation Coverage**: 405/457 (88.6%)
- **Versioned Nodes Detected**: 46
- **AI Tools**: 0 (none marked with usableAsTool flag)
- **Triggers**: 10
- **Packages Supported**: 2
## Known Limitations
1. **Slack Operations**: Unable to extract operations from some versioned nodes due to complex structure
2. **AI Tools Detection**: No nodes currently have the `usableAsTool` flag set
3. **One Failed Node**: One node from langchain package fails to load due to missing dependency
## Usage
```bash
# Setup
git clone https://github.com/n8n-io/n8n-docs.git n8n-docs
npm install
# Build
npm run build
# Rebuild database
npm run rebuild
# Validate
npm run validate
# Start MCP server
npm start
```
## Next Steps (Post-MVP)
1. Improve operations extraction for complex versioned nodes
2. Add real-time monitoring capabilities
3. Implement version history tracking
4. Add support for community nodes
5. Create web UI for browsing documentation
## Conclusion
The implementation successfully achieves the MVP goals:
- ✅ Accurate node-to-documentation mapping
- ✅ Coverage of official n8n packages
- ✅ Fast rebuild process (<30 seconds)
- Simple one-command operations
- Reliable processing of standard nodes
- Working MCP server with documentation tools
The system is ready for use and provides a solid foundation for future enhancements.

61
install_claude_config.sh Executable file
View File

@@ -0,0 +1,61 @@
#!/bin/bash
# Claude Desktop Configuration Installer for n8n-MCP
echo "🔧 n8n-MCP Claude Desktop Configuration Installer"
echo "================================================"
# Get the current directory
CURRENT_DIR="$(cd "$(dirname "$0")" && pwd)"
# Detect OS and set config path
if [[ "$OSTYPE" == "darwin"* ]]; then
CONFIG_PATH="$HOME/Library/Application Support/Claude/claude_desktop_config.json"
elif [[ "$OSTYPE" == "msys" || "$OSTYPE" == "win32" ]]; then
CONFIG_PATH="$APPDATA/Claude/claude_desktop_config.json"
else
CONFIG_PATH="$HOME/.config/Claude/claude_desktop_config.json"
fi
echo ""
echo "📍 Detected config location: $CONFIG_PATH"
echo "📂 n8n-MCP installation path: $CURRENT_DIR"
# Create directory if it doesn't exist
CONFIG_DIR=$(dirname "$CONFIG_PATH")
if [ ! -d "$CONFIG_DIR" ]; then
echo "📁 Creating config directory..."
mkdir -p "$CONFIG_DIR"
fi
# Backup existing config if it exists
if [ -f "$CONFIG_PATH" ]; then
echo "💾 Backing up existing config to ${CONFIG_PATH}.backup"
cp "$CONFIG_PATH" "${CONFIG_PATH}.backup"
fi
# Create the new config
cat > "$CONFIG_PATH" << EOF
{
"mcpServers": {
"n8n-documentation": {
"command": "node",
"args": [
"$CURRENT_DIR/dist/mcp/index.js"
],
"env": {
"NODE_ENV": "production"
}
}
}
}
EOF
echo "✅ Configuration installed!"
echo ""
echo "📋 Next steps:"
echo "1. Build the project: npm run build"
echo "2. Rebuild database: npm run rebuild"
echo "3. Restart Claude Desktop"
echo ""
echo "🚀 The n8n-documentation server will be available in Claude!"

41
mcp-server-v20.sh Executable file
View File

@@ -0,0 +1,41 @@
#!/bin/bash
# n8n-MCP Server Wrapper Script for Node v20.17.0
# This ensures the server runs with the correct Node version
# Get the directory where this script is located
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
# Change to the script directory
cd "$SCRIPT_DIR"
# Use Node v20.17.0 specifically (what Claude Desktop uses)
export PATH="/Users/romualdczlonkowski/.nvm/versions/node/v20.17.0/bin:$PATH"
# Verify we're using the right version
NODE_VERSION=$(node --version)
if [ "$NODE_VERSION" != "v20.17.0" ]; then
echo "Error: Wrong Node.js version. Expected v20.17.0, got $NODE_VERSION" >&2
exit 1
fi
# Check if node_modules exists
if [ ! -d "node_modules" ]; then
echo "Error: node_modules not found. Please run 'npm install' first." >&2
exit 1
fi
# Check if database exists
if [ ! -f "data/nodes.db" ]; then
echo "Error: Database not found. Please run 'npm run rebuild' first." >&2
exit 1
fi
# Check if dist directory exists
if [ ! -d "dist" ]; then
echo "Error: dist directory not found. Please run 'npm run build' first." >&2
exit 1
fi
# Run the MCP server
exec node "$SCRIPT_DIR/dist/mcp/index.js"

31
mcp-server.sh Executable file
View File

@@ -0,0 +1,31 @@
#!/bin/bash
# n8n-MCP Server Wrapper Script
# This ensures the server runs with the correct environment
# Get the directory where this script is located
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
# Change to the script directory
cd "$SCRIPT_DIR"
# Check if node_modules exists
if [ ! -d "node_modules" ]; then
echo "Error: node_modules not found. Please run 'npm install' first." >&2
exit 1
fi
# Check if database exists
if [ ! -f "data/nodes.db" ]; then
echo "Error: Database not found. Please run 'npm run rebuild' first." >&2
exit 1
fi
# Check if dist directory exists
if [ ! -d "dist" ]; then
echo "Error: dist directory not found. Please run 'npm run build' first." >&2
exit 1
fi
# Run the MCP server
exec node "$SCRIPT_DIR/dist/mcp/index.js"

View File

@@ -3,12 +3,45 @@
import { N8NDocumentationMCPServer } from './server-update';
import { logger } from '../utils/logger';
// Add error details to stderr for Claude Desktop debugging
process.on('uncaughtException', (error) => {
console.error('Uncaught Exception:', error);
logger.error('Uncaught Exception:', error);
process.exit(1);
});
process.on('unhandledRejection', (reason, promise) => {
console.error('Unhandled Rejection at:', promise, 'reason:', reason);
logger.error('Unhandled Rejection:', reason);
process.exit(1);
});
async function main() {
try {
console.error('Starting n8n Documentation MCP Server...');
console.error('Current directory:', process.cwd());
console.error('Script directory:', __dirname);
console.error('Node version:', process.version);
const server = new N8NDocumentationMCPServer();
await server.run();
} catch (error) {
console.error('Failed to start MCP server:', error);
logger.error('Failed to start MCP server', error);
// Provide helpful error messages
if (error instanceof Error && error.message.includes('nodes.db not found')) {
console.error('\nTo fix this issue:');
console.error('1. cd to the n8n-mcp directory');
console.error('2. Run: npm run build');
console.error('3. Run: npm run rebuild');
} else if (error instanceof Error && error.message.includes('NODE_MODULE_VERSION')) {
console.error('\nTo fix this Node.js version mismatch:');
console.error('1. cd to the n8n-mcp directory');
console.error('2. Run: npm rebuild better-sqlite3');
console.error('3. If that doesn\'t work, try: rm -rf node_modules && npm install');
}
process.exit(1);
}
}

View File

@@ -5,6 +5,8 @@ import {
ListToolsRequestSchema,
} from '@modelcontextprotocol/sdk/types.js';
import Database from 'better-sqlite3';
import { existsSync } from 'fs';
import path from 'path';
import { n8nDocumentationTools } from './tools-update';
import { logger } from '../utils/logger';
@@ -31,7 +33,34 @@ export class N8NDocumentationMCPServer {
private db: Database.Database;
constructor() {
this.db = new Database('./data/nodes.db');
// Try multiple database paths
const possiblePaths = [
path.join(process.cwd(), 'data', 'nodes.db'),
path.join(__dirname, '../../data', 'nodes.db'),
'./data/nodes.db'
];
let dbPath: string | null = null;
for (const p of possiblePaths) {
if (existsSync(p)) {
dbPath = p;
break;
}
}
if (!dbPath) {
logger.error('Database not found in any of the expected locations:', possiblePaths);
throw new Error('Database nodes.db not found. Please run npm run rebuild first.');
}
try {
this.db = new Database(dbPath);
logger.info(`Initialized database from: ${dbPath}`);
} catch (error) {
logger.error('Failed to initialize database:', error);
throw new Error(`Failed to open database: ${error instanceof Error ? error.message : 'Unknown error'}`);
}
logger.info('Initializing n8n Documentation MCP server');
this.server = new Server(