Skip to main content

Overview

The n8n-MCP server uses SQLite’s FTS5 (Full-Text Search 5) engine to provide fast, typo-tolerant search across thousands of n8n nodes. This system allows you to quickly find nodes by name, description, category, or functionality.

Search Architecture

FTS5 Index

All nodes are indexed using SQLite’s FTS5 virtual table with the following fields:
  • displayName - Node display name (highest weight)
  • description - Full node description
  • category - Node category (e.g., “Communication”, “Data Transformation”)
  • all_text - Combined searchable text including properties
CREATE VIRTUAL TABLE nodes_fts USING fts5(
  node_type,
  display_name,
  description,
  category,
  all_text,
  tokenize = 'unicode61 remove_diacritics 1'
)
FTS5 Benefits:
  • Sub-millisecond search across 500+ nodes
  • Typo-tolerant with fuzzy matching
  • Phrase search with quoted strings
  • Boolean operators (AND, OR, NOT)
  • Ranked results by relevance

Search Modes

OR Mode (Default)

Matches nodes containing any of the search terms. Produces the broadest results.
{
  "query": "slack message",
  "mode": "OR"
}
Example Results:
  • Slack (contains “slack”)
  • Discord (contains “message”)
  • Email (contains “message”)
  • Mattermost (similar to “slack”)
The query is split into terms: ["slack", "message"]SQL: WHERE nodes_fts MATCH 'slack OR message'Nodes are ranked by:
  1. How many terms match (both > one)
  2. Field where match occurs (displayName > description)
  3. Position in field (earlier is better)

AND Mode

Matches nodes containing all of the search terms. Produces narrower, more precise results.
{
  "query": "http json",
  "mode": "AND"
}
Example Results:
  • HTTP Request (has both “http” and “json”)
  • Webhook (supports “http” and “json”)
The query is split into terms: ["http", "json"]SQL: WHERE nodes_fts MATCH 'http AND json'All terms must be present somewhere in the node’s indexed content.

FUZZY Mode

Typo-tolerant matching using FTS5’s prefix search. Best for:
  • Unsure of exact spelling
  • Partial word matching
  • Discovering related nodes
{
  "query": "postgr",
  "mode": "FUZZY"
}
Example Results:
  • PostgreSQL (matches “postgr*”)
  • Postgres (matches “postgr*”)
Each term gets a wildcard suffix: ["postgr*"]SQL: WHERE nodes_fts MATCH 'postgr*'Matches any word starting with the search term. More forgiving than exact matching.

Search Filters

Source Filter

Filter nodes by their source/origin:
{
  "query": "database",
  "source": "core"  // "all", "core", "community", "verified"
}
Source Types:
{"source": "core"}
Official n8n nodes (package: n8n-nodes-base)Examples:
  • HTTP Request
  • Webhook
  • Code
  • Set
  • If
{"source": "community"}
Third-party community-built nodesExamples:
  • Custom integrations
  • Specialized tools
  • Beta features
{"source": "verified"}
Community nodes verified by n8n team for quality and securityFilter ensures:
  • Code reviewed
  • Actively maintained
  • Security vetted

Result Limit

Control the number of results returned (default: 20, max: 100):
{
  "query": "trigger",
  "limit": 10
}
Performance: Smaller limits return faster. Use pagination with offset for large result sets.

Including Examples

Get real-world configuration examples from popular templates:
{
  "query": "slack",
  "includeExamples": true  // Returns top 2 template configs per node
}
Example Response:
{
  "nodeType": "n8n-nodes-base.slack",
  "displayName": "Slack",
  "examples": [
    {
      "templateId": 1234,
      "templateName": "Slack Notification System",
      "config": {
        "resource": "message",
        "operation": "send",
        "channel": "#general",
        "text": "New user signup!"
      }
    },
    {
      "templateId": 5678,
      "templateName": "Customer Support Bot",
      "config": {
        "resource": "channel",
        "operation": "create",
        "name": "support-tickets"
      }
    }
  ]
}
Use Cases for Examples:
  • Learn common configuration patterns
  • Bootstrap new workflows faster
  • Discover advanced features
  • Avoid configuration mistakes

Search Strategies

Finding Trigger Nodes

{
  "query": "trigger schedule timer cron",
  "mode": "OR",
  "source": "core"
}
Common trigger keywords:
  • trigger, webhook, schedule, watch, poll
  • cron, interval, timer
  • email, form, chat

Finding Integration Nodes

{
  "query": "slack api integration",
  "mode": "AND"
}
Integration patterns:
  • Service name + “api” (e.g., “slack api”)
  • Service name + “integration”
  • Use mode: "AND" for precision

Finding Data Processing Nodes

{
  "query": "transform filter map convert",
  "mode": "OR",
  "limit": 30
}
Data processing keywords:
  • transform, convert, parse, format
  • filter, map, merge, split
  • aggregate, group, sort

Fuzzy Discovery

When you’re not sure of the exact name:
{
  "query": "postgr",  // Will match PostgreSQL, Postgres
  "mode": "FUZZY"
}
{
  "query": "spread",  // Will match Spreadsheet, Google Sheets
  "mode": "FUZZY"
}

Advanced Query Syntax

Use quotes for exact phrase matching:
{
  "query": "\"execute command\"",
  "mode": "OR"
}
Matches only nodes with the exact phrase “execute command”. Exclude terms using NOT (must use explicit operators):
{
  "query": "database NOT sql",  // Find non-SQL databases
  "mode": "OR"
}
Negative search requires explicit query construction. The MCP tool handles this automatically when you use natural language like “database but not sql”.
Search within node properties using the get_node tool with mode="search_properties":
{
  "nodeType": "nodes-base.httpRequest",
  "mode": "search_properties",
  "propertyQuery": "auth",
  "maxPropertyResults": 20
}
This searches property names, display names, and descriptions within a specific node. Search Implementation:
// Recursive search with scoring
static searchPropertiesRecursive(
  properties: any[],
  query: string,
  matches: Array<{ property: any; score: number; path: string }>,
  path: string = ''
): void {
  for (const prop of properties) {
    let score = 0;
    
    // Exact match = 10 points
    if (prop.name.toLowerCase() === query) score = 10;
    // Prefix match = 8 points
    else if (prop.name.toLowerCase().startsWith(query)) score = 8;
    // Contains match = 5 points
    else if (prop.name.toLowerCase().includes(query)) score = 5;
    
    // Check displayName and description for matches
    if (prop.displayName?.toLowerCase().includes(query)) score = Math.max(score, 4);
    if (prop.description?.toLowerCase().includes(query)) score = Math.max(score, 3);
    
    if (score > 0) matches.push({ property: prop, score, path });
  }
}

Search Performance

Optimization Tips

Fast Searches:
  • Single-word queries: < 1ms
  • Multi-word OR queries: 1-5ms
  • Multi-word AND queries: 2-10ms
  • Fuzzy queries: 5-20ms
Slow Searches:
  • Very broad terms (“node”, “data”): 20-50ms
  • Complex boolean queries: 10-30ms

Caching

The FTS5 index is built once at startup and cached in memory:
// Index is created during database initialization
CREATE VIRTUAL TABLE IF NOT EXISTS nodes_fts USING fts5(
  node_type UNINDEXED,
  display_name,
  description,
  category,
  all_text
);

Common Patterns

Discovery Workflow

// 1. Broad search to explore options
const results = await search_nodes({
  query: "api http rest",
  mode: "OR",
  limit: 10
})

// 2. Narrow down with AND
const precise = await search_nodes({
  query: "http authentication",
  mode: "AND",
  limit: 5
})

// 3. Get details for selected node
const node = await get_node({
  nodeType: results[0].nodeType,
  detail: "standard"
})

Building with Templates

// 1. Search for relevant nodes
const nodes = await search_nodes({
  query: "webhook slack",
  mode: "AND",
  includeExamples: true  // Get real-world configs
})

// 2. Use example configs as starting points
const slackNode = nodes.find(n => n.nodeType.includes('slack'))
const exampleConfig = slackNode.examples[0].config

// 3. Customize and validate
const validation = await validate_node({
  nodeType: slackNode.nodeType,
  config: { ...exampleConfig, channel: "#my-channel" }
})

Search Results Structure

interface SearchResult {
  nodeType: string;              // "n8n-nodes-base.slack"
  displayName: string;           // "Slack"
  description: string;           // Full description
  category: string;              // "Communication"
  version: number;               // Latest version
  properties: number;            // Total property count
  
  // Optional fields
  examples?: Array<{             // When includeExamples=true
    templateId: number;
    templateName: string;
    config: Record<string, any>;
  }>;
  
  // Metadata
  source: 'core' | 'community' | 'verified';
  isAITool: boolean;
  isTrigger: boolean;
}

Next Steps

MCP Tools

Learn about all available MCP tools

Validation

Validate your node configurations

Build docs developers (and LLMs) love