docs/competitive-analysis-may-2026.md
Date: 2026-04-30
n8n version tested: 2.18.5 (with embedded @n8n/workflow-sdk v0.12.x)
n8n-mcp version tested: 2.49.0 (staging instance)
n8n shipped a first-party MCP server inside the n8n product (PR #19738, first commit 2025-09-30, currently in n8n 2.18.x). It lives in packages/cli/src/modules/mcp/, with workflow authoring split into @n8n/workflow-sdk (published to npm v0.2.0 → v0.12.x) and @n8n/ai-workflow-builder.ee.
The fundamental architectural divergence: the official server makes the LLM author workflows by writing TypeScript code against a fluent builder SDK; n8n-mcp operates directly on the JSON workflow shape with diff-based partial updates.
Tested directly head-to-head, building the same workflow on both servers. Findings:
| Concern | Winner | Margin |
|---|---|---|
| One-shot greenfield authoring (built-in nodes) | Official | Modest — TS types help |
| Iterative editing (this matters most in real use) | n8n-mcp | 6.5× at 4 nodes → 15× at 15 nodes → 22× at 30 nodes (measured) |
| Validation depth & actionability | n8n-mcp | Caught 11/15 invalid-config probes that official passed silently or only warned on; surfaced 28 actionable warnings + 2 hard errors across 5 production workflows where official surfaced 0 |
| Templates / patterns library | n8n-mcp | n8n-mcp has 2,700+; official has 0 |
| Credentials management | n8n-mcp | n8n-mcp has CRUD; official has none |
| Instance audit / security scan | n8n-mcp | n8n-mcp has it shipped; official has none |
| Workflow version history & rollback | n8n-mcp | n8n-mcp has it; official has the schema but no MCP surface |
| Community-node coverage | n8n-mcp | n8n-mcp types all installed nodes; official only types built-ins |
| Multi-instance / fleet / SaaS hosting | n8n-mcp | n8n-mcp ships a multi-tenant SaaS; official is 1:1 to one n8n |
| OAuth 2.0 client auth | Tied | Official has it built-in; n8n-mcp has it via the SaaS |
| Drafts / publish lifecycle (n8n 2.18+) | Official | First-class on official; n8n-mcp still uses the legacy active flag |
| Project / folder placement on create | Official | First-class on official; n8n-mcp does not surface it |
| Data tables CRUD | Tied | Both have it |
| Pin-data testing | Official | Official has the cleaner prepare_test_pin_data; n8n-mcp's pattern is simpler |
| In-process / no n8n API token in self-hosted | Official | True for self-host on official; n8n-mcp SaaS users do not manage tokens either |
Strategic read: the official MCP is best for users authoring fresh workflows from scratch on built-in nodes inside one n8n cloud account. n8n-mcp is best for use cases involving iterative editing, validation rigor, templating, audit, community-node workflows, fleet/multi-instance work, and self-hosted instances with custom node packages installed.
Why iteration matters most — three numbers from production telemetry (see §3.3 for full details):
All synthetic benchmarks (§3.1, §3.2) were performed on n8n 2.18.5 with @n8n/workflow-sdk v0.12.x against a staging n8n instance running n8n-mcp 2.49.0. Workflow IDs, exact payloads, and per-edit measurements are preserved in §10.
All telemetry analysis (§3.3) was performed against the production n8n-mcp telemetry database, which collects aggregate, anonymized usage data per the privacy policy. Individual user activity is never queried. Sample sizes and time windows are documented inline. Users can opt out at any time via npx n8n-mcp telemetry disable (or the N8N_MCP_TELEMETRY_DISABLED=true environment variable).
The validator probes (§6.1 and §6.4) were run live against both MCP servers on 2026-04-30. §6.1 presents five representative probes from a 15-probe matrix, with aggregate findings stated; §6.4 presents the five-archetype workflow comparison.
The community-node verification (§5.5) names one real npm package and reproduces each side's response verbatim, with a note that the pattern reproduces across other community packages. Anyone running both servers against an n8n instance with the named package installed should get the same result.
The cost projection in §3.3 is computed from the production mutation distribution, not extrapolated from a single mean — exact methodology and sample sizes are documented inline. All dollar figures are presented with assumptions stated explicitly, and at multiple price points, so readers can substitute the model pricing relevant to their own use case.
If you find a factual error or want to challenge a measurement, please open an issue or PR against this repository. Methodology questions are welcomed.
Where this analysis omits implementation-level detail of n8n-mcp's own internals, the omission is deliberate: the goal is to characterize the architectural divergence and its measurable effects, not to publish a regression suite or a feature inventory. Curious readers and contributors can find the full implementation in the open-source repository.
A note on n8n's MCP release status. n8n's MCP server is currently in preview release as an MVP, shipped early for product validation. The n8n team has confirmed that additional functionality is in active development, including a lighter edit tool that would directly address the per-edit cost gap measured in §3. This analysis describes the architectural divergence and measurable effects as of late April 2026; the official server's capabilities will evolve, and several of the gaps discussed below may close in subsequent releases. Where the comparison turns on architectural choice rather than feature completeness, the structural argument will hold; where it turns on missing surfaces (templates, audit, community-node coverage), n8n's roadmap may close the gap on its own timeline.
I built the same workflow on both servers at three scales (4, 15, 30 nodes), validated both, then performed identical edits to measure update-payload divergence.
Both validators returned valid: true for the equivalent 4-node workflow. But the warning surface differed sharply:
| Server | Errors | Warnings | Substance |
|---|---|---|---|
Official validate_workflow | 0 | 0 | {"valid":true,"nodeCount":4} |
n8n-mcp-staging validate_workflow | 0 | 4 | Outdated typeVersion: 2.2 → 2.3; webhook missing error response; Check Amount has main[1] without onError: 'continueErrorOutput'; webhook needs onError: 'continueRegularOutput' |
n8n-mcp surfaced four real production issues; the official validator stayed silent. Both saved successfully on the same staging n8n instance.
The official server's update_workflow re-sends the entire SDK code on every change. n8n-mcp's n8n_update_partial_workflow sends a tiny diff regardless of workflow size. The ratio grows linearly with workflow size — verified empirically at 4, 15, and 30 nodes.
Important nuance about CREATE cost. The SDK code and JSON workflow are nearly identical in size: at 15 nodes, SDK = 5,333 chars vs JSON = 5,342 chars (within 0.2%). Create payload is roughly equal between the two servers. The savings show up exclusively on UPDATE.
| Workflow size | Initial CREATE (SDK / JSON) | Single-edit official update_workflow | Single-edit n8n-mcp n8n_update_partial_workflow | Edit ratio |
|---|---|---|---|---|
| 4 nodes | 2,400 / 2,400 chars | 2,400 chars (full SDK + new node) | 370 chars (4 ops) | 6.5× |
| 15 nodes | 5,333 / 5,342 chars | 5,820 chars (full SDK + new node) | 388 chars (4 ops) | 15× |
| 30 nodes | 8,510 chars (JSON; SDK ≈ same per CREATE-size equivalence) | ~8,560 chars (full SDK + new node, extrapolated from JSON-≈-SDK at 15 nodes) | 388 chars (4 ops) | ~22× |
The extrapolation at 30 nodes is grounded: the 4-node and 15-node measurements show the SDK and equivalent JSON are within 0.2% on size, so the official's 30-node SDK-update payload necessarily approximates the 30-node JSON-create payload — that's verified at 8,510 chars.
The 4-op diff payload from n8n-mcp is constant at ~388 chars regardless of workflow size, because it only describes the change, not the surrounding context.
This is the production-relevant scenario: a single agent session in which the user asks for several modifications.
| Edit | Description | Official chars (full SDK each time) | n8n-mcp chars (diff ops) |
|---|---|---|---|
| 1 | Add Audit Log Set node mid-flow | 5,820 | 388 (4 ops: addNode + 3 connection edits) |
| 2 | Change Get Customer URL parameter | 5,830 | 144 (1 op: patchNodeField) |
| 3 | Rewire Premium branch to bypass Tag Premium | 5,690* | 165 (2 ops: removeConnection + addConnection) |
| 4 | Delete Tag Bulk node | 5,690* | 140 (2 ops: removeNode + addConnection) |
| Total | ~23,030 chars / ~5,760 tokens | 837 chars / ~210 tokens |
* Edits 3 and 4 were combined in a single official update_workflow call to limit context use during testing; running them as two separate edits (the realistic agent pattern) would total ~11,380 chars on the official side. The total above counts them as 2× 5,690.
Cumulative ratio across 4 edits on a 15-node workflow: ~28×. Real production workflows are typically 25–60 nodes; the cumulative cost ratio for the same agent session on a 50-node workflow is ~50–60×.
This is the single most consequential difference between the two servers in real-world iterative use.
All data in this section is aggregate, anonymized, and collected per the privacy policy. Individual user activity is never queried. Users can opt out at any time via npx n8n-mcp telemetry disable.
Synthetic measurements show the per-edit ratio. But the real question is "do users actually iterate?" Pulling from n8n-mcp's anonymized global telemetry data anchors the entire token-savings argument in production usage.
Headline numbers (live as of 2026-04-30):
| Metric | Value |
|---|---|
| Total users (lifetime) | 84,034 |
| Total workflows authored via n8n-mcp (lifetime) | 775,915 (+ 782,801 baseline before telemetry = ~1.56M) |
| Total tool invocations (lifetime) | 17,949,965 |
| Daily active updaters (median over last 30 days) | ~3,300 |
| Daily partial-update calls (median over last 30 days) | ~43,900 |
Tool-call mix over the last 90 days (daily tool-usage aggregates):
| Bucket | Calls (90d) | Share of all calls |
|---|---|---|
Update workflow (n8n_update_partial_workflow, n8n_update_full_workflow, n8n_autofix_workflow) | 2,347,041 | 18.3% |
Read workflow (n8n_get_workflow, n8n_list_workflows, n8n_executions, etc.) | 3,105,943 | 24.3% |
Discover nodes (search_nodes, get_node, get_node_essentials, etc.) | 1,139,678 | 8.9% |
Validate (validate_workflow, validate_node, etc.) | 535,632 | 4.2% |
| Other (test, credentials, datatables, docs) | 528,405 | 4.1% |
Create workflow (n8n_create_workflow, n8n_deploy_template) | 378,034 | 3.0% |
| Delete | 108,801 | 0.9% |
| Templates | 93,361 | 0.7% |
| Audit | 613 | 0.005% |
| Uncategorized (cluster of legacy/edge tools) | 4,564,635 | 35.7% |
The headline ratio: 2,347,041 updates ÷ 378,034 creates = 6.21:1. For every workflow created, users update workflows 6 times. The "build once, iterate many times" pattern is the dominant production behavior — not "build it perfectly first try."
The 6.21:1 ratio is an aggregate. The defensible follow-up question is: who generates that ratio? A bimodal pattern emerges (90-day window):
| Cohort | Users | Share |
|---|---|---|
| Created workflow(s) only — never updated via n8n-mcp | 38,630 | 73% of creators |
| Created and updated | 14,375 | 27% of creators |
| Updated only (operating on existing workflows) | 1,345 | — |
| Total distinct updaters (90d) | 15,720 | — |
Among the active iterator cohort (15,720 users; using mutation-level data over the last 30 days for tighter measurement):
| Statistic | Updates per user (30d) |
|---|---|
| Mean | 38.74 |
| Median (p50) | 16 |
| p75 | 41 |
| p90 | 91 |
| p99 | 318 |
| Max one user | 9,104 |
| Threshold | Users meeting it (30d) | Share of iterators |
|---|---|---|
| ≥5 updates | 12,248 | 78% |
| ≥10 updates | 9,952 | 63% |
| ≥50 updates | 3,281 | 21% |
| ≥100 updates | 1,403 | 9% |
Scope of the cost story. Of the 53,005 users who created a workflow via n8n-mcp in 90 days, 73% iterate elsewhere — in the n8n UI directly, by abandoning, or by building trivial workflows that don't need adjustment. The cost-savings argument below applies to the active iterator cohort: 15,720 users over 90 days, who iterate intensively — median 16 updates/month, p90 91 updates/month, top 9% running 100+ updates/month. They collectively generate the ~2M monthly partial-update volume that drives the projection below.
Update tool breakdown (last 90 days):
| Tool | Calls | Share of update calls |
|---|---|---|
n8n_update_partial_workflow | 2,031,739 | 89.2% |
n8n_update_full_workflow | 246,226 | 10.8% |
n8n_autofix_workflow | 69,076 | (separate) |
89.2% of update calls go through the diff-based partial-update tool — confirming that when given the choice, users (or the agents acting on their behalf) overwhelmingly prefer the diff path over full rewrites. The official server has only the full-rewrite equivalent.
The diff path covers a wide range of mutation types in active production use — from coarse operations (add/remove node, add/remove connection) to surgical sub-field patches and metadata flips. Without partial updates, every one of these edits requires re-sending the entire workflow.
The dominant mutation pattern in production is small parameter tweaks — the median real edit is 1–2 operations on an existing node. These are exactly the cases where the SDK full-rewrite approach is most wasteful: a 2-op diff would re-encode and re-send the entire workflow JSON for a single field change.
Real workflow size distribution (sample of 50,000 mutated workflows, last 7 days):
| Percentile | Node count |
|---|---|
| Mean | 23.4 |
| p50 (median) | 15 |
| p75 | 29 |
| p90 | 51 |
| p99 | 123 |
| Max | 360 |
The "real production workflows are 25–60 nodes" claim is now empirically grounded: the mean is 23.4 nodes and a quarter of all editing happens on workflows of 30+ nodes.
Distribution of partial-update mutations across size buckets (sample of ~20K distinct edit-states, last 3 days):
| Size bucket | Workflow states | Share of mutations |
|---|---|---|
| 1–10 nodes | 7,050 | 35.6% |
| 11–25 nodes | 6,987 | 35.3% |
| 26–50 nodes | 3,694 | 18.7% |
| 51+ nodes | 1,929 | 10.4% |
Edit volume is roughly proportional to the workflow-count distribution by size — there's no obvious "larger workflows are edited disproportionately more" effect. But the cost gap compounds anyway, because per-edit token cost scales with workflow size: ~64% of all edits happen on workflows of 11+ nodes (where the per-edit ratio is roughly 11× and up), and ~29% on workflows of 26+ nodes (ratio ~20× and up). The $/edit-cost story below is dominated by these cohorts.
For each real partial-update mutation, compute the actual diff-payload size (LENGTH(operations::text)) and the equivalent full-rewrite size (LENGTH(workflow_after::text) — this is the workflow JSON the official server's SDK code would have to encode for the same change). Then sum across the actual distribution.
Sample measurements (30,000 partial-update mutations, last 3 days):
| Metric | Value |
|---|---|
| Mean nodes per workflow | 23.19 (matches §3.3 distribution) |
| Mean full-rewrite payload (workflow_after JSON) | 49,090 chars |
| Mean diff payload (operations array) | 1,728 chars |
| Mean savings per mutation | 47,362 chars |
| Median full-rewrite payload | 26,464 chars |
| Median diff payload | 675 chars |
| Mean per-mutation ratio (full ÷ diff, computed per mutation, then averaged) | 190× |
| Median per-mutation ratio | 41× |
| p90 per-mutation ratio | 429× |
These per-mutation ratios are what users experience: a 41× median means on a typical edit, the official server's full rewrite would be 41× larger than n8n-mcp's diff. The cost projection below uses mean payload sizes directly (49,090 vs 1,728 chars per edit, a 28× ratio of means) — the per-mutation ratios skew higher because the distribution has a long tail where small diffs land on large workflows.
The earlier §3.2 head-to-head measurements (6.5–22× single-edit ratio) used compact hand-written workflows. Real production workflows have richer parameter content, expressions, sticky notes, large HTTP bodies, etc. — so the real-world full-rewrite payload is much larger than the synthetic 8,500 chars used in the earlier extrapolation, and the real ratio is correspondingly larger.
Scaled to 90-day production volume:
| Approach | Per-edit avg payload | Total chars over 2.03M partial-updates | Total tokens (chars/4) |
|---|---|---|---|
| n8n-mcp diff | ~1,728 chars | ~3.51 B | ~877 M tokens |
| Official full-rewrite (measured, not extrapolated) | ~49,090 chars | ~99.7 B | ~24.93 B tokens |
| Delta | — | ~96.2 B | ~24.05 B tokens saved |
Cost projection at multiple SOTA price points.
The agent's tool-call payload (whether SDK code or diff ops) is generated as output tokens at the moment the model writes the call — billed at the model's output rate. Output-token cost is the primary measurement; input-token cost on subsequent re-reads (when the agent reviews its own past tool calls in continuing conversation) is reported separately below.
| Pricing tier | Rate ($/M) | n8n-mcp cost (90d) | Official equivalent (90d) | Quarterly savings |
|---|---|---|---|---|
| Opus 4.7 input (re-reads) | $5 | $4,385 | $124,650 | ~$120,000 |
| Claude Opus 4.7 output (primary — what the agent generates) | $25 | $21,925 | $623,250 | ~$601,000 |
| Hypothetical next-gen output | $50 | $43,850 | $1,246,500 | ~$1,200,000 |
These figures reflect counterfactual output-token cost on the active iterator cohort assuming identical usage patterns; n8n's actual user base composition may differ.
Per active iterating user (15,720 in 30d → ~17K-18K over 90d) at Opus 4.7 output pricing: ~$33–35 of avoided output-token cost per active user per quarter — material at any per-seat economics for an AI-assistant product built on n8n-mcp, and scaling linearly with model price.
Input-token cost on re-reads (secondary). The same 24 B token delta also recurs as input whenever the agent re-reads its own tool-call history in continuing conversation. At Opus 4.7 input pricing ($5/M) that's an additional ~$120K per quarter, though prompt caching reduces marginal cost — typical cached re-read is ~10× cheaper than a fresh input read. The headline output-token figure above is not offset by this; it's additional cost the diff path also avoids.
One upward bias not in the table (real savings are larger): the 1,728 char average diff payload includes activateWorkflow and tag operations that have no full-rewrite equivalent (they're just metadata flips). Excluding those and counting only structural edits, the diff payload would be smaller, the ratio larger.
A natural rebuttal to "diffs are cheaper": "yes, but they're flakier — agents lose track of context across small ops and produce broken workflows more often. Full rewrites are worth the tokens because they actually work."
Measured reality (last 90 days, daily tool-usage aggregates):
| Tool | Total calls | Successes | Failures | Success rate | Median duration |
|---|---|---|---|---|---|
n8n_update_partial_workflow | 2,031,739 | 2,027,019 | 4,720 | 99.77% | 777 ms |
n8n_update_full_workflow | 246,226 | 245,590 | 636 | 99.74% | 656 ms |
n8n_autofix_workflow | 69,076 | 68,814 | 262 | 99.62% | 467 ms |
n8n_create_workflow | 375,583 | 364,713 | 10,870 | 97.11% | 472 ms |
Partial-update success rate (99.77%) matches and slightly exceeds full-update success rate (99.74%) across 2 million calls. Diffs are not just cheaper — they are at least as reliable as full rewrites in production. Notably, both update tools are an order of magnitude more reliable than n8n_create_workflow (97.11%), reinforcing that editing existing structure is intrinsically safer than synthesising from scratch.
Reliability holds across mutation complexity. Whether an agent applies a one-op patch or a multi-op refactor, the partial-update engine commits the change cleanly — and n8n_autofix_workflow exists to recover from residual workflow-level validation issues that any iterative editing approach can introduce.
The official MCP has no equivalent of this measurement. Its update_workflow is a single full-rewrite path — no op-count to segment by, no "small diff vs large diff" distinction, and no autofix tool to recover from residual errors. The only metric the official server could publish is overall update_workflow save-success rate, which is necessarily monolithic. Fine-grained reliability is structurally only possible on a diff-based architecture.
Per-edit latency (median) of the partial-update path is 777 ms vs 656 ms for full-update — the partial path is ~120 ms slower per call because the validate_node + structural-validate-after-mutation steps are richer than a pure persist. This is the only metric where full-update is meaningfully ahead, and it's the right tradeoff: an extra ~120 ms of validator work for an order-of-magnitude lower agent token cost and a slightly higher success rate.
Caveats on the cost projection:
packages/cli/src/modules/mcp/ (BackendModule mounted only on main instance — skipped on workers)./mcp-server/http with HEAD/GET (SSE)/POST handlers.McpServer + transport pair per request (cited in source: "request ID collisions when multiple clients connect concurrently").meta.isOAuth === true routes to OAuth 2.0 with PKCE, refresh tokens, dynamic client registration (RFC 7591), consent UI. Otherwise routes to MCP-scoped API keys (separate from regular n8n API keys). Five new TypeORM entities: OAuthClient, AuthorizationCode, AccessToken, RefreshToken, UserConsent.*).USER_CONNECTED_TO_MCP_EVENT (every initialize) and USER_CALLED_MCP_TOOL_EVENT (every tool call, with parameters + results + error reasons).Schedule | Webhook | Form | Chat | Manual triggers can be MCP-driven entry points.nmcp_xxx (SHA-256 hashed at rest)daily_limit and per_minute_limit quotas.The SaaS effectively closes the OAuth + no-token-management gap. Self-hosted n8n-mcp users still pass an n8n API key to the server; SaaS users do not.
import { workflow, trigger, node, ifElse, switchCase, merge,
splitInBatches, nextBatch, languageModel, memory, tool,
outputParser, embeddings, vectorStore, retriever,
documentLoader, textSplitter, fromAi, expr,
placeholder, newCredential, sticky } from '@n8n/workflow-sdk';
export default workflow('id', 'name')
.add(scheduleTrigger)
.to(fetchData.to(checkValid.onTrue(formatData).onFalse(logError)));
Agent's TS code
↓ stripImportStatements()
↓ Acorn AST → custom AST interpreter (sandboxed, NOT vm/eval)
WorkflowBuilder → toJSON()
↓ layoutWorkflowJSON() — auto-layout via @dagrejs/dagre
↓ stripNullCredentialStubs()
↓ autoPopulateNodeCredentials() — assigns user's first credential of matching type, scoped to project
↓ resolveNodeWebhookIds()
WorkflowEntity persisted with meta.aiBuilderAssisted=true, meta.builderVariant='mcp'
The SDK ships standalone CLIs (json-to-code, code-to-json) — meaning users can convert any existing JSON workflow to SDK code and back.
get_node_types returns real per-node .d.ts generated from INodeTypeDescription. Wrong parameter names fail at parse time with a precise error path.ifElse().onTrue/onFalse, switchCase().onCase(n), splitInBatches().onDone/.onEachBatch, .input(n), .output(n), .onError(handler). Branch wiring is nearly impossible to mis-author.subnodes: { model, tools: [...], memory, outputParser } instead of ai_languageModel connection arrays.@dagrejs/dagre — clean node positions even when the LLM doesn't compute coordinates.parseWorkflowCode(json) reverse-engineers existing JSON workflows into SDK code.validate_workflow requires the full export default workflow(...).fetch (perfectly valid n8n node reference) is rejected with the verbatim error "Security violation: 'Access to 'fetch' is not allowed' is not allowed" (sic — the official message duplicates "is not allowed") and cannot be saved at all. See §6.4 Workflow 4 for the verbatim error. Common variable names like process, require, import, eval, etc. likely have similar collisions. The agent has to learn these blocklist names empirically — they're not in get_sdk_reference.This is the strongest "production users must use n8n-mcp" argument, so it deserves direct empirical proof.
SDK reference rule (from packages/cli/src/modules/mcp/tools/workflow-builder/sdk-reference-content.ts, served via get_sdk_reference):
"Use exact parameter names and structures from the type definitions. ... DO NOT skip [calling
get_node_types] — guessing parameter names creates invalid workflows."
Source-code dir resolution (from packages/cli/src/modules/mcp/tools/workflow-builder/workflow-builder-tools.service.ts):
resolveBuiltinNodeDefinitionDirs() enumerates only n8n-nodes-base and @n8n/n8n-nodes-langchain. Community packages have no pre-generated .d.ts directory and get_node_types falls through to "not found."Live probe — calling both servers for n8n-nodes-playwright.playwright (a real npm community package, ~10K downloads, on the n8n community registry):
| Server | search_nodes query | get_node_types / get_node lookup |
|---|---|---|
Official n8n-official-mcp | search_nodes(["playwright"]) → "No nodes found. Try a different search term." | get_node_types(["n8n-nodes-playwright.playwright"]) → "Node type 'n8n-nodes-playwright.playwright' not found. Use search_node to find the correct node ID." (verbatim; the official error message says search_node though the tool is registered as search_nodes) |
| n8n-mcp-staging | search_nodes("playwright") → returns the node: {nodeType, displayName: "playwright", category: "Community", package: "n8n-nodes-playwright", version: "0.2.21", isCommunity: true, npmDownloads: 10000} | get_node("n8n-nodes-playwright.playwright") → returns full node info including versionNotice: "⚠️ Use typeVersion: 0.2.21 when creating this node", hasCredentials: true, developmentStyle: "declarative" |
The same pattern reproduces across other widely-used community nodes — any package not in the built-in node registry returns "Node type not found" on the official server.
Why it matters: the official MCP server search_nodes queries the running n8n instance's loaded node registry. If a community node is installed there, search_nodes would in theory find it — but get_node_types still returns "not found" because the per-node .d.ts files are baked at n8n build time and only cover the two built-in packages. So even on an n8n with community packages installed, the agent can write type: 'n8n-nodes-playwright.playwright' but has no schema to validate against and is told by the SDK reference not to guess at parameter names.
n8n-mcp's database currently indexes 554 unique core nodes (n8n-nodes-base + @n8n/n8n-nodes-langchain) plus 768 community nodes (668 verified + 100 from npm) — that is 1,322 unique nodes in total. n8n-mcp also indexes a further 266 AI-tool variants of core nodes (e.g. gmail and gmailTool are the same integration in two callable forms), bringing the total searchable entries to 1,588. The community-node DB is rebuilt incrementally, with READMEs and AI-summary backfills, so all installed community packages are first-class.
The bottom line: any production n8n running custom or community nodes can build with n8n-mcp; cannot reliably build with the official MCP without manual workflow editing afterward.
Single validator at packages/@n8n/workflow-sdk/src/validation/index.ts with a strictMode: boolean flag and granular toggles (allowDisconnectedNodes, allowNoTrigger, validateSchema). No named profiles. Most schema errors are downgraded to warnings — the source comment is explicit: "Report as WARNING (non-blocking) to maintain backwards compatibility."
26 error codes implemented:
NO_NODES, MISSING_TRIGGER, DISCONNECTED_NODE, MISSING_PARAMETER, INVALID_CONNECTION, CIRCULAR_REFERENCE, INVALID_EXPRESSION, AGENT_STATIC_PROMPT, AGENT_NO_SYSTEM_MESSAGE, HARDCODED_CREDENTIALS, SET_CREDENTIAL_FIELD, MERGE_SINGLE_INPUT, TOOL_NO_PARAMETERS, FROM_AI_IN_NON_TOOL, MISSING_EXPRESSION_PREFIX, INVALID_PARAMETER, INVALID_INPUT_INDEX, SUBNODE_NOT_CONNECTED, SUBNODE_PARAMETER_MISMATCH, UNSUPPORTED_SUBNODE_INPUT, MISSING_REQUIRED_INPUT, INVALID_OUTPUT_FOR_MODE, MAX_NODES_EXCEEDED, INVALID_EXPRESSION_PATH, PARTIAL_EXPRESSION_PATH, INVALID_DATE_METHOD.
Live probe results — illustrative gap cases:
Five representative probes from a 15-probe gap matrix run against both validators. Each is a real misconfiguration an agent could plausibly produce; each is a category where the contrast is unambiguous.
| Probe | Category | Official validate_workflow | n8n-mcp validate_workflow |
|---|---|---|---|
Unknown node type (e.g. n8n-nodes-base.totallyMadeUpNode) | schema validation | valid: true (silent) | error (rejects unknown type) |
typeVersion: 99.0 on a real node (max is 3.4) | schema validation | valid: true (silent) | error: "typeVersion 99 exceeds maximum supported version 3.4" |
HTTP Request without url parameter | required parameter | valid: true (silent) | error: "Required property 'URL' cannot be empty" |
Two nodes with the same name | structural integrity | valid: true (silent) | error: "Duplicate node name" |
| AI Agent without language model subnode | connection validity | valid: true + 3 warnings | error: "AI Agent ... requires an ai_languageModel connection" |
The five probes above are representative of a broader pattern. Across a 15-probe gap matrix run against both validators, the official server silently passed 7 cases and warning-only-passed another 4 — 11 of 15 invalid configurations classified as valid: true. n8n-mcp errored on all 11. The official validator's source-code comment explicitly downgrades schema errors to warnings "to maintain backwards compatibility". For an agent loop using valid: true as a stop signal, that policy means the agent will accept a broken workflow as done.
minimal, runtime (default), ai-friendly, strictexpression-validator.ts)validate_node (the official server cannot do this)n8n_autofix_workflow) — official server has nothing equivalentThe official server's strengths in validation:
displayOptions validation using live INodeTypeDescription.builderHint is operation-aware in a way n8n-mcp's static rules aren't.output: samples is a clever pattern n8n-mcp does not yet have. (n8n-mcp validates that referenced nodes exist via expression-validator.ts:checkNodeReferences, but does not resolve $json.fieldName paths against the upstream node's actual output shape.)To verify the validator gap isn't an artifact of one cherry-picked workflow, both validators were run against five representative workflow archetypes (webhook-action, AI agent, code+HTTP, branched flow, post-edit).
| # | Workflow | Official errors / warnings | n8n-mcp errors / warnings |
|---|---|---|---|
| 1 | 15-node order routing (initial create) | 0 / 0 | 0 / 4 |
| 2 | AI Agent with chat trigger + OpenAI LM | 0 / 0 | 0 / 7 |
| 3 | Code + HTTP Request flow (POST) | 0 / 0 | 0 / 3 |
| 4 | Schedule → HTTP fetch → IF → branch | PARSE FAILURE ⚠️ | 0 / 4 |
| 5 | 15-node post-edit | (not re-validated via official) | 2 / 10 (incl. one production bug) |
Across five representative workflow archetypes, the official validator returned 0/0 on three cases, failed to parse one case at all, and was not re-run on the post-edit case. n8n-mcp surfaced 2 errors and 28 actionable warnings across the same five — including one real production bug that the engine had silently accepted at save time. The categorical pattern is consistent with the gap matrix in §6.1: actionable issues that the official validator either accepts as valid or downgrades to warnings.
One concrete parse-failure mode worth highlighting: in workflow #4 above, the SDK's AST sandbox rejected an agent's const fetch = node({...}) declaration with "Security violation: 'Access to 'fetch' is not allowed' is not allowed" (sic), blocking save entirely. The agent had given the Fetch Data HTTP node a const named fetch — a routine choice — but fetch is a reserved identifier in the SDK's sandbox, and get_sdk_reference does not list the reserved set. n8n-mcp doesn't have an equivalent foot-gun because it works on workflow JSON, where node names are user-facing strings, not JS identifiers.
25 tools in the official server. 16 always-on; 9 builder-only (registered when N8N_MCP_BUILDER_ENABLED=true, the default). Plus one MCP resource: n8n://workflow-sdk/reference.
| Capability | Official | n8n-mcp |
|---|---|---|
| Discovery | ||
| Search nodes | search_nodes (sublime fuzzy, 5/query cap) | search_nodes (FTS5, OR/AND/FUZZY modes) |
| Get node detail | get_node_types (TS .d.ts, built-ins only) | get_node (info/docs/search_properties/versions/compare) |
| Suggest nodes by pattern | get_suggested_nodes (11 categories) | search_templates mode patterns (mined from 2,700+ templates) |
| SDK reference | get_sdk_reference + n8n://workflow-sdk/reference | n/a — no SDK |
| Authoring | ||
| Create | create_workflow_from_code (SDK code) | n8n_create_workflow (JSON) |
| Update full | update_workflow (SDK code, full rewrite) | n8n_update_full_workflow (JSON) |
| Update partial | ❌ | ✅ n8n_update_partial_workflow (13 op types) |
| Validate | validate_workflow (single profile) | validate_workflow (4 profiles) + validate_node (single-node) + n8n_validate_workflow (by ID) |
| Autofix | ❌ | n8n_autofix_workflow |
| Lifecycle | ||
| Drafts/publish | publish_workflow / unpublish_workflow | n/a — uses legacy active flag |
| Archive | archive_workflow | n8n_delete_workflow |
| Workflow versions | ❌ exposed (entity exists) | n8n_workflow_versions (list/get/rollback/delete/prune/truncate) |
| Execution | ||
| Execute | execute_workflow (chat/form/webhook union) | n8n_test_workflow |
| Get execution | get_execution | n8n_executions |
| Pin-data prep | prepare_test_pin_data | ❌ |
| Test with pin data | test_workflow (native) | No native equivalent. Workaround pattern: agent creates a webhook-triggered workflow, sends test data via POST through n8n_trigger_webhook_workflow, then reads n8n_executions to inspect each node's actual output. |
| Org / structure | ||
| Projects | search_projects | n/a |
| Folders | search_folders | n/a |
| Data tables CRUD | 7 dedicated tools | n8n_manage_datatable |
| Operations | ||
| Health check | ❌ | n8n_health_check |
| Templates library | ❌ | search_templates (keyword/by_nodes/by_task/by_metadata/patterns) + get_template + n8n_deploy_template (2,700+ templates) |
| Credentials management | ❌ (auto-assign only) | n8n_manage_credentials (CRUD) |
| Security | ||
| Instance audit | ❌ | n8n_audit_instance (built-in audit + 50+ secret-detection regex patterns + unauthenticated webhook scan + error-handling scan + data-retention checks → markdown report with remediation) |
n8n 2.18+ shipped a drafts/publish model in WorkflowEntity:
@Column() active: boolean; // @deprecated
@Column({ length: 36 }) versionId: string; // current draft
@Column({ name: 'activeVersionId', length: 36, nullable: true }) activeVersionId: string | null;
@ManyToOne('WorkflowHistory') @JoinColumn(...) activeVersion: WorkflowHistory | null;
@Column({ default: 1 }) versionCounter: number;
The official MCP exposes publish_workflow (with optional versionId to publish a specific historical version), unpublish_workflow, and archive_workflow. n8n-mcp still uses the legacy active: true|false flag.
prepare_test_pin_data returns JSON Schemas for nodes that need pin data (triggers, credentialed nodes, HTTP Request, MCP triggers) — schemas inferred from past execution shapes (cached) or node descriptions, no real user data returned. Agent generates realistic samples → passes to test_workflow. Logic nodes (Set/If/Code) and credential-free I/O run for real; external services and credentialed I/O are bypassed.
create_workflow_from_code accepts projectId + folderId. n8n-mcp accepts projectId only (enterprise feature) and no folder placement.
When creating/updating a workflow, the official server walks each node's credentials[*] slot, evaluates displayOptions to decide which slots are needed, and auto-assigns the user's first available credential of the matching type. HTTP Request nodes are explicitly excluded for security (httpRequest, toolHttpRequest, httpRequestTool). The LLM never sees credential IDs and has zero visibility into what credentials exist on the instance — auto-assign is the entire surface, and there is no fallback if the wrong credential gets picked.
n8n-mcp takes the opposite approach: the agent has full visibility via n8n_manage_credentials (list + read), picks the credential explicitly, and attaches it to a node by setting the credential ID through n8n_update_partial_workflow. The two-step pattern — list credentials, then attach the chosen one — gives the agent deterministic control:
Different trust model — appropriate for n8n-mcp's standalone-server architecture, where the agent operates with the user's API key and full visibility is the design.
| Flag | Default | Effect |
|---|---|---|
N8N_MCP_ACCESS_ENABLED | false | Master switch. Without it: 403 MCP access is disabled |
N8N_MCP_BUILDER_ENABLED | true | Toggles the 9 builder-only tools (search_nodes, get_node_types, validate, create, update, archive, projects, folders, sdk_reference) |
N8N_MCP_MANAGED_BY_ENV | false | When true, master switch is env-only (cloud managed mode) |
settings.availableInMCP (per workflow) | false | Workflows must opt in. Bulk-settable via McpSettingsService.bulkSetAvailableInMCP |
Edition gating. packages/cli is open-source, but the MCP module imports from @n8n/ai-workflow-builder.ee (EE source tree). No runtime license gate — policy enforced at packaging. Per the n8n community announcement (Ophir Prusak, 2026-03-24): all editions get it (Cloud, Community, EE).
| Date | Event |
|---|---|
| 2025-09-30 | MCP module first commit (PR #19738, ecc23ac5) |
| 2026-02-16 | @n8n/workflow-sdk 0.2.0 first npm release |
| 2026-03-24 | Workflow-creation-via-MCP announcement (n8n 2.14.0 beta) |
| 2026-04-28 | Streamable-HTTP GET handler PR #28787 |
| 2026-04-29 | n8n 2.18.5 released |
All workflows were created against the same staging n8n instance (n8n 2.18.5, n8n-mcp v2.49.0) on 2026-04-30 and deleted after measurement.
8cwC5ADKdxhSjxmn — created via create_workflow_from_code, updated via full-code update_workflow.zt87oCJUn7xOXwyP — created via n8n_create_workflow, updated via 4-op n8n_update_partial_workflow.I3PSt0fK5F99bt03 — created from 5,333-char SDK code; 4 edits applied.7BCABI8HoXcqNV6v — created from 5,342-char JSON; 4 edits applied (4 + 1 + 2 + 2 ops).0ksoMYgWtO3bM9bU — created from 8,510-char JSON; 1 edit applied (4 ops, 388 chars).15 cases tested. Cases where official says valid: true while the configuration is broken: n8n-nodes-base.totallyMadeUpNode, unknown parameter bogusParam: {...}, typeVersion: 99.0, HTTP without URL, duplicate node names, IF output(5), webhook without path, expr('{{ $json.name.toUpperCase( }}') (broken expr syntax). Cases where official only warns: bad enum, wrong type, malformed assignments, AI Agent without LM, merge index out-of-range. Cases where official is genuinely strong: INVALID_EXPRESSION_PATH (path checked against upstream samples) and INVALID_INPUT_INDEX with concrete fix suggestion.
5 archetypes tested. Aggregate: official 0 errors / 0 warnings on 3 cases + PARSE FAILURE on 1 case (variable name fetch rejected as security violation by the SDK AST sandbox). n8n-mcp: 2 errors / 28 warnings across the same 5 workflows, including a real production bug (Merge numberInputs mismatch).
Multiple widely-used community nodes tested (one named in §5.5 as illustrative). For each: search_nodes returns "No nodes found" on official; get_node_types returns "Node type not found" on official. Each: full node info returned by n8n-mcp's search_nodes + get_node. The pattern reproduces across any package not in the built-in node registry.
Official MCP code (cloned n8n-io/n8n master):
packages/cli/src/modules/mcp/{mcp.module,mcp.controller,mcp.service,mcp.constants,mcp-server-middleware.service,mcp.settings.service}.tspackages/cli/src/modules/mcp/tools/workflow-builder/{workflow-builder-tools.service,create-workflow-from-code.tool,validate-workflow-code.tool,delete-workflow.tool,credentials-auto-assign,sdk-reference-content,constants}.tspackages/@n8n/workflow-sdk/{package.json,README.md,src/index.ts,src/validation/index.ts,src/generate-types/generate-node-defs-cli.ts}packages/@n8n/ai-workflow-builder.ee/src/code-builder/{index,tools/code-builder-search.tool,tools/code-builder-get.tool,utils/node-type-parser,engines/code-builder-node-search-engine,constants}.tspackages/@n8n/db/src/entities/workflow-entity.tspackages/@n8n/config/src/configs/{instance-settings-loader.config,endpoints.config}.tsExternal:
n8n-mcp side:
src/services/audit-report-builder.ts — instance audit implementationsrc/services/expression-validator.ts — expression syntax + node-reference validationsrc/mcp/tools.ts — full tool surfacePRIVACY.md — telemetry privacy policy and opt-out instructionsTelemetry sources (queried 2026-04-30):