An MCP server for working with n8n — modeled directly on czlonkowski/n8n-mcp. Two halves:
- Node knowledge, always available: search and validate against 538
real n8n node schemas (all of
n8n-nodes-basethat could be extracted, plus the AI/LangChain node package), backed by SQLite + FTS5 — not a hand-picked sample, not hand-typed guesses. - Live n8n management, once you point it at a real instance: create, read, update, delete, and activate workflows; list/inspect executions; manage credentials; trigger a workflow via its webhook — all through n8n's actual public REST API.
| n8n-mcp (real) | n8n-mcp-mini (this) | |
|---|---|---|
| Node coverage | ~1,650 nodes (820 core + 830 community) | 538 nodes — 432/438 core + 106/122 AI/langchain (see EXTRACTION.md for the handful that failed to extract) |
| Community node packages (830 third-party npm packages) | Included | Not included — no single source to bulk-fetch/vet 830 separately-published packages |
| Storage | SQLite + FTS5 | SQLite + FTS5 (same approach, smaller scale) |
| Template library (2,352 workflows) | Included, scraped/maintained over time | Not included — no documented public API to pull this from; didn't want to ship unverified guesses |
| search_nodes / get_node / validate_node / validate_workflow | Yes | Yes |
| Live n8n instance management (create/update/delete workflows, executions, credentials) | Yes, 13 tools | Yes, 18 tools — same underlying REST API |
| n8n_update_partial_workflow (diff-based) / n8n_autofix_workflow | Yes | Not included — only full-replace update (n8n_update_workflow), matching what n8n's public API actually exposes (there's no partial-update endpoint; the real project builds diffing on top) |
| Hosted option | dashboard.n8n-mcp.com | N/A — local only |
The two gaps that matter most — community nodes and the template library — are gaps in available data, not effort: neither is something this environment could fetch, verify, or safely fabricate. Everything else here is a real, working reimplementation of the same architecture, tested end to end.
cd n8n-mcp-mini
npm installRequires Node.js 18+. better-sqlite3 downloads a prebuilt binary for your
platform automatically on most systems. If npm install fails while
building it, you likely need a C++ toolchain + Python (see
better-sqlite3's install notes) —
or just retry npm install, since the prebuilt-binary download occasionally
fails transiently.
npm start- In n8n: Settings → n8n API → Create an API key.
- Set two environment variables when launching this server:
N8N_API_URL— e.g.https://your-instance.example.com/api/v1(include the/api/v1)N8N_API_KEY— the key you created
Without these, the node-knowledge tools work as normal and the n8n_*
tools return a clear "not configured" error instead of failing mysteriously.
{
"mcpServers": {
"n8n-mini": {
"command": "node",
"args": ["/absolute/path/to/n8n-mcp-mini/src/index.js"],
"env": {
"N8N_API_URL": "https://your-instance.example.com/api/v1",
"N8N_API_KEY": "your-api-key"
}
}
}
}(Omit env entirely to run node-knowledge-only, no live instance.)
claude mcp add n8n-mini -- node /absolute/path/to/n8n-mcp-mini/src/index.js| Tool | What it does |
|---|---|
tools_documentation |
Usage guide — call this first if unsure where to start |
search_nodes |
Full-text search (SQLite FTS5, BM25-ranked) across all 538 nodes |
list_categories |
List categories with counts (real n8n categorization, not invented) |
list_packages |
Node counts by source package (n8n-nodes-base, @n8n/n8n-nodes-langchain) |
get_node |
Get a node's schema — detail: minimal|standard|full, or propertyQuery |
validate_node |
Check parameters against a node's schema, respecting displayOptions.show/hide |
validate_workflow |
Full workflow validation: unknown types, required fields, connections, expressions |
validate_workflow_connections |
Just the structural checks (names, references, cycles, unreached nodes) |
validate_workflow_expressions |
Scan for unbalanced/empty {{ }} expressions |
| Tool | What it does |
|---|---|
n8n_health_check |
Verify connectivity + auth |
n8n_list_workflows / n8n_get_workflow |
Browse/inspect workflows |
n8n_create_workflow / n8n_update_workflow (full replace) / n8n_delete_workflow |
Manage workflows |
n8n_activate_workflow / n8n_deactivate_workflow |
Publish/unpublish |
n8n_validate_workflow |
Fetch a live workflow by id and run local validation against it |
n8n_list_executions / n8n_get_execution / n8n_delete_execution |
Execution history |
n8n_list_credentials / n8n_get_credential / n8n_get_credential_schema / n8n_create_credential / n8n_delete_credential |
Credential management (secrets are never returned by n8n's API, by design) |
n8n_trigger_webhook |
Call a workflow's Webhook/Form trigger URL directly — n8n's public API has no "run this now" endpoint, so this is the real mechanism |
n8n's Slack node requires channelId and other fields only once you've
picked a resource/operation/select combination — supplying
{ resource: "message", operation: "post", text: "hi" } alone looks
plausible but fails at runtime because select (which channel-lookup mode
to use) was never set. validate_node catches this before you ever open
n8n, by evaluating each property's displayOptions.show/hide rules
against your config — the same mechanism n8n's own UI uses to decide which
fields to show.
Validated against n8n's real JSON format — the same shape n8n's own API
and UI use, so a validated workflow can go straight to n8n_create_workflow
or be pasted into n8n's canvas:
{
"name": "Notify on new signup",
"nodes": [
{ "name": "Start", "type": "n8n-nodes-base.manualTrigger", "parameters": {} },
{ "name": "Fetch", "type": "n8n-nodes-base.httpRequest", "parameters": { "url": "https://api.example.com/signups/latest" } },
{ "name": "Notify", "type": "n8n-nodes-base.slack", "parameters": { "resource": "message", "operation": "post", "select": "channel", "channelId": "C0123", "text": "New signup!" } }
],
"connections": {
"Start": { "main": [[{ "node": "Fetch", "type": "main", "index": 0 }]] },
"Fetch": { "main": [[{ "node": "Notify", "type": "main", "index": 0 }]] }
},
"settings": {}
}Connections are keyed by node name (not id), and settings is required
by n8n's API on create/update (the client auto-fills {} if you omit it).
src/n8nClient.js was written directly against n8n's published OpenAPI spec
(n8n-io/n8n:packages/cli/src/public-api/v1/openapi.yml) — base path
/api/v1, auth header X-N8N-API-KEY, exact request/response shapes per
endpoint. It's tested against a local mock server that reproduces that same
shape (test/mock_n8n_server.js), since no real n8n instance is available
in this environment. One notable finding baked into the design: n8n's
public API has no endpoint to execute a workflow on demand — the
documented way is calling the workflow's own Webhook/Form trigger URL,
which is what n8n_trigger_webhook does.
Node schemas are extracted directly from the real n8n-nodes-base@2.15.1
and @n8n/n8n-nodes-langchain@2.34.2 npm packages — not hand-typed guesses,
and merged with n8n's own per-node categorization metadata (.node.json
sidecar files: real categories, search aliases, docs URLs). See
EXTRACTION.md for the full method, the handful of nodes
that failed to extract and why, licensing notes, and exactly what's
excluded (community nodes, template library) and why.
npm test
# or individually:
node test/unit.test.js # store + validation logic, direct (11 tests)
node test/n8nClient.test.js # REST client against a local mock n8n server (14 tests)
node test/mcp.smoke.js # spawns the real server, drives all 27 tools over MCP/stdio