Skip to main content
Glama
NestorPVsf

n8n-workflows-mcp

by NestorPVsf

n8n-workflows-mcp

Turn your deployed n8n workflows into tools your AI agents can call — without rewriting anything.

CI npm

An MCP (Model Context Protocol) server that exposes the n8n workflows you already have running in production as tools an AI agent can discover and execute. No SDK, no rewriting integrations, no duplicating credentials inside the agent.

This is not the official n8n MCP server. That one lets an agent build workflows through the n8n Workflow SDK. This one runs the workflows you already built — it is the operational complement, not a competitor.

Demo: an agent listing and inspecting tagged n8n workflows

Why

Thousands of teams have n8n automations deployed with real business logic: tested integrations, configured credentials, flows already running in production. AI agents can't use them today. The usual options are to reimplement the integration inside the agent (duplicating both work and secrets) or to manually bridge the chat and the automation by hand.

This server closes that gap: any workflow tagged for exposure becomes callable through four generic tools (list_workflows, get_workflow_schema, execute_workflow, get_execution_status) — it does not register a separate MCP tool per workflow. That gets you three things:

  • Reuse — an automation you already validated becomes an agent capability without rewriting a line of it.

  • Control and security — the workflow runs on your infrastructure with your credentials; the agent never sees third-party API keys. The mcp tag is an explicit governance boundary: you expose what you decide, nothing else.

  • A standard, not a lock-in — because it's MCP, it works with Claude, custom agents, and any current or future MCP client.

Useful if you're an automation consultant adding agents on top of existing n8n stacks, a team that already invested in n8n and wants agentic AI without migrating anything, or a maker wiring personal automations into an agent.

Related MCP server: n8n-manager-mcp

How it works

 AI agent (MCP client)
        │  stdio (JSON-RPC)
        ▼
 n8n-workflows-mcp  ───────────────►  n8n REST API   (discovery, schema, execution status)
        │                              GET /workflows, /workflows/:id, /executions/:id
        └────────────────────────────► n8n webhook    (execution)
                                        POST/GET /webhook/:path
                                             │
                                             ▼
                                     your n8n instance

Discovery and execution are opt-in by design: only workflows tagged with a configured tag (mcp by default) are ever listed, described, or run. Anything without that tag is invisible to the agent, even if the API key used could technically reach it.

Quickstart

Requirements

  • Node.js >= 22

  • An n8n instance reachable over HTTP(S), with the REST API enabled

  • An n8n API key (Settings → n8n API → Create an API key)

1. Tag a workflow in n8n

Open the workflow → Tags → add a tag named mcp (or whatever you set N8N_MCP_TAG to). Only tagged workflows become visible to the agent.

2. Point your MCP client at it

Claude Desktop / Claude Code config (claude_desktop_config.json or .mcp.json) — npx fetches the package on first run, no install step:

{
  "mcpServers": {
    "n8n-workflows": {
      "command": "npx",
      "args": ["-y", "n8n-workflows-mcp"],
      "env": {
        "N8N_BASE_URL": "https://your-n8n-instance.example.com",
        "N8N_API_KEY": "your-api-key",
        "N8N_MCP_TAG": "mcp"
      }
    }
  }
}

Restart the client. The agent now has four tools scoped to whatever you've tagged mcp.

From source (for development or to run a local build):

git clone https://github.com/NestorPVsf/n8n-workflows-mcp.git
cd n8n-workflows-mcp
npm install
npm run build

Then point the MCP client at the local build instead of npx, keeping the same env block as above:

{
  "mcpServers": {
    "n8n-workflows": {
      "command": "node",
      "args": ["/absolute/path/to/n8n-workflows-mcp/dist/index.js"],
      "env": {
        "N8N_BASE_URL": "https://your-n8n-instance.example.com",
        "N8N_API_KEY": "your-api-key",
        "N8N_MCP_TAG": "mcp"
      }
    }
  }
}

Configuration

All configuration is via environment variables, read once at startup (src/config.ts). Missing or invalid required values make the server fail fast with a clear error instead of starting in a broken state.

Variable

Required

Default

Notes

N8N_BASE_URL

Yes

Base URL of your n8n instance, no trailing slash. Must be a valid URL.

N8N_API_KEY

Yes*

REST API key, sent as X-N8N-API-KEY on every discovery request. Mutually exclusive with N8N_API_KEY_FILE — exactly one is required.

N8N_API_KEY_FILE

Yes*

Path to a file whose (trimmed) contents are the API key. Mutually exclusive with N8N_API_KEY.

N8N_MCP_TAG

No

mcp

Tag used as the discovery/execution boundary.

N8N_WEBHOOK_AUTH_HEADER_NAME

No

Name of a header sent on every webhook call. Requires a value (below) if set.

N8N_WEBHOOK_AUTH_HEADER_VALUE

No

Value of that header. Requires the name above if set. Mutually exclusive with N8N_WEBHOOK_AUTH_HEADER_VALUE_FILE. Leave unset (along with the file variant) to disable.

N8N_WEBHOOK_AUTH_HEADER_VALUE_FILE

No

Path to a file whose (trimmed) contents are the webhook auth header value. Mutually exclusive with N8N_WEBHOOK_AUTH_HEADER_VALUE.

* Exactly one of N8N_API_KEY / N8N_API_KEY_FILE must be set.

The *_FILE variants follow the Docker/Kubernetes secrets convention (read the secret from a mounted file instead of an env var) and are the recommended way to configure this server: they keep the actual secret out of the MCP client's JSON config, which is often stored in plaintext, synced, or checked into a dotfiles repo. The file is read once at startup, trimmed of surrounding whitespace, and treated exactly like the direct env var from then on. On POSIX systems, the server warns on stderr (without failing) if the file is readable by group or other users, since that undermines the point of keeping the secret out of the config file.

Tools

Tool

Arguments

Returns

list_workflows

none

Array of { id, name, description? } — only workflows tagged with the configured tag.

get_workflow_schema

workflowId: string

{ name, httpMethod, webhookPath, inputSchema, schemaSource: "sticky-note" | "generic", note? } — the webhook trigger details and a best-effort input schema.

execute_workflow

workflowId: string, input?: Record<string, unknown>

{ status, body } — the raw HTTP response from the workflow's webhook.

get_execution_status

executionId: string

{ id, status, startedAt?, stoppedAt? }

Every call to get_workflow_schema and execute_workflow re-fetches the workflow and re-checks the tag, so a workflow untagged mid-session stops being usable immediately — the agent doesn't get to act on a stale, cached authorization. This isn't perfectly atomic: an in-flight call that already passed the tag check completes even if the workflow is untagged a moment later (TOCTOU) — only the next call is guaranteed to see the change.

See Execution semantics below for what execute_workflow actually guarantees (and doesn't) when a call fails.

Security model

  • The tag is the boundary. list_workflows, get_workflow_schema, and execute_workflow all filter on N8N_MCP_TAG. This is default-deny: a workflow is invisible to the agent until you explicitly opt it in.

  • Two separate auth mechanisms, not one. N8N_API_KEY authenticates against the n8n REST API for discovery (listing workflows, reading schema, checking execution status). N8N_WEBHOOK_AUTH_HEADER_NAME / N8N_WEBHOOK_AUTH_HEADER_VALUE is a separate shared secret sent only on webhook execution calls, verified inside the workflow itself if you choose to check it. Don't conflate the two — a leaked webhook secret does not grant REST API access, and vice versa.

  • Use a least-privilege API key. Where your n8n instance supports scoped keys or a dedicated service user, prefer that over reusing an administrator's personal API key.

  • Prefer the *_FILE env vars for secrets. N8N_API_KEY_FILE and N8N_WEBHOOK_AUTH_HEADER_VALUE_FILE let the actual secret live in a file (owned and permissioned like any other credential file) instead of the MCP client's JSON config, which many clients store in plaintext on disk and which is easy to accidentally commit, sync, or screenshot. The server reads the file once at startup and never re-reads it.

  • The credentials this server manages never pass through the agent. N8N_API_KEY and the webhook auth header are never included in tool results. This does not extend to whatever a workflow itself returns — if a workflow's webhook response echoes back a secret (by design or by mistake), the agent sees it, because execute_workflow returns the workflow's raw HTTP response body. Keeping secrets out of webhook responses is the workflow author's responsibility, not this server's.

Execution semantics

execute_workflow delivery is at-least-once, not exactly-once. A Webhook request timeout after 15 seconds. or Failed to reach webhook: ... error means the MCP server didn't get a confirmed response — it does not mean the workflow didn't run. The HTTP request may have reached n8n and triggered execution before the connection dropped or the client gave up.

There is no idempotency key in v1: retrying a timed-out execute_workflow call can run the workflow twice. If a workflow has side effects that aren't safe to duplicate (charging a card, sending an email, creating a record), either make the workflow idempotent on its own terms (e.g. dedupe on a request id you pass in input), or don't retry blindly — use get_execution_status / your own out-of-band signal to check whether the first attempt actually completed before deciding to retry. This is why execute_workflow is registered with MCP annotations destructiveHint: true, idempotentHint: false — a well-behaved client should already treat it with the same caution as any other non-idempotent write.

Known limitations

  • Only active workflows are listed. list_workflows asks n8n for active workflows only. Tagging a workflow that is switched off is not enough: n8n only serves the production /webhook/<path> URL for active workflows (inactive ones answer on the test URL, and only while the editor is listening), so an inactive workflow could be listed but never executed. If a workflow you tagged does not show up, check the Active toggle first.

  • Only webhook-triggered workflows are executable. get_workflow_schema and execute_workflow require a n8n-nodes-base.webhook trigger node; workflows started by other triggers (cron, manual, form) will list fine but fail schema/execution with a clear error. This mirrors n8n itself — there is no generic "run any workflow synchronously" API. Disabled webhook nodes are skipped when looking for the trigger; if a workflow somehow has more than one active webhook node, the first one found is used — there's no way to select between them.

  • Webhook responses must be JSON, text, or empty. execute_workflow reads the workflow's webhook response according to its Content-Type: JSON is parsed, text/* is returned as a string, and an empty/204 body becomes null. Any other Content-Type (binary, multipart, etc.) fails with an explicit "unsupported Content-Type" error rather than mangling the bytes.

  • Webhook responses are capped at 2MB. A larger response — whether declared via Content-Length or discovered while reading the body — fails with an explicit error instead of silently truncating or exhausting memory.

  • Redirects are never followed. Both the n8n REST API calls and webhook execution calls use redirect: "manual"; a 3xx response fails with an explicit error instead of resending N8N_API_KEY or the webhook auth header to whatever origin the Location header points at.

  • Schema inference is best-effort. If a workflow has a Sticky Note node whose content is JSON containing type or properties, that's used as the input schema. Otherwise the server falls back to a generic { type: "object", additionalProperties: true } schema and says so in the response. It never promises strict validation of a workflow's actual inputs.

  • stdio transport only in v1. No HTTP/SSE transport, no remote MCP client support yet.

  • Read + execute only. This server does not create, edit, activate, or deactivate workflows — that's the official n8n MCP server's job.

Development

npm install
npm run typecheck   # tsc --noEmit
npm run lint         # biome check .
npm test             # vitest run
npm run build         # tsdown
npm run dev           # tsdown --watch

Built with a TDD workflow — tests in test/ are written against each module before the implementation (src/n8n-client.ts, src/tools/*.ts, src/server.ts) and mock the n8n HTTP layer rather than hitting a real instance. See CONTRIBUTING.md for setup details and conventions, and DECISIONS.md for the reasoning behind the main design choices.

Work with me

I build AI systems that run in production — RAG pipelines, agent orchestration, workflow automation. This repo is open so you can see how I work. If you want to adapt it to your stack, go deeper than the code, or build something of your own, get in touch:

License

MIT — see LICENSE.

Available Tools

4 tools
execute_workflowA
Destructive

Executes a tagged n8n workflow through its webhook using the supplied JSON input. Delivery is at-least-once: a timeout or network error does not mean the workflow didn't run, so don't blindly retry on failure.

ParametersJSON Schema
NameRequiredDescriptionDefault
inputNo
workflowIdYes

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description goes beyond the annotations by disclosing at-least-once delivery semantics and explicitly warning against blind retries on timeout or network errors. This is valuable behavioral context that the annotations (idempotentHint=false, destructiveHint=true) do not fully convey. It does not contradict the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences, with no redundant words. The first sentence states the purpose, and the second adds a critical operational warning. It is front-loaded and every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers the core purpose and the most important behavioral caveat, but it omits details about the return value or how the workflow's execution status can be tracked afterward. Given the lack of an output schema and the existence of a get_execution_status sibling, this gap makes the tool somewhat incomplete for an agent to use confidently.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 0% schema description coverage, the description was expected to compensate by explaining the parameters. It mentions 'supplied JSON input' but gives no detail about the structure or content requirements, and it does not describe workflowId beyond what the schema already shows. This leaves the agent with very little semantic guidance.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('Executes a tagged n8n workflow') and the method ('through its webhook using the supplied JSON input'). It straightforwardly distinguishes this from sibling tools like list_workflows and get_execution_status by focusing on execution rather than listing or status retrieval.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description makes it clear that this tool runs a workflow, which implicitly signals when to use it compared to the read-only sibling tools. However, it does not explicitly state 'use this when you need to trigger a workflow' or mention any exclusions or alternatives, so it falls short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_execution_statusA

Fetches the status of a previously triggered n8n execution by id.

ParametersJSON Schema
NameRequiredDescriptionDefault
executionIdYes

TDQS

A3.5/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries full responsibility for behavioral disclosure. It only states 'Fetches the status' without elaborating on what the status includes, possible error conditions, authentication requirements, or side effects. The description is too sparse to convey meaningful behavioral traits beyond being a read operation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single 12-word sentence, front-loaded with the verb and resource. Every word contributes meaning, and there is no redundancy or fluff. It is appropriately sized for the tool's simplicity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple one-parameter tool, the description gives the core purpose but lacks an explicit link to execute_workflow's returned execution ID and does not describe the response structure (no output schema exists). It feels minimally complete but misses contextual details that would help an agent understand the full workflow.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema has 0% description coverage, so the description must clarify parameters. It adds 'by id' to indicate that executionId is the identifier of the execution, which aligns with the parameter name but does not provide format, examples, or relationship to other tools. This is marginal added value over the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description uses a specific verb 'Fetches' and a well-defined resource ('status of a previously triggered n8n execution by id'). It clearly distinguishes itself from sibling tools like list_workflows, get_workflow_schema, and execute_workflow by focusing on execution status retrieval.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'previously triggered' implies this tool is used after execute_workflow, but there is no explicit statement of when to use it versus alternatives or when not to use it. Sibling tool names provide context, but the description itself offers limited usage guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_workflow_schemaA

Returns the input schema and webhook details needed to call a given n8n workflow.

ParametersJSON Schema
NameRequiredDescriptionDefault
workflowIdYes

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the burden. It discloses that the tool returns schema and webhook details, which is a specific behavioral trait beyond a generic 'get'. It does not mention error cases or side effects, but for a simple getter this is adequate.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, focused sentence with no fluff. It conveys the core purpose and key return contents efficiently.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's simplicity (one parameter, no output schema, no annotations), the description is mostly complete. It explains what the tool returns and implies its role in workflow execution. It could mention error behavior or read-only nature, but the low complexity lowers the bar.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema has 0% description coverage, and the only parameter is workflowId. The description mentions 'given n8n workflow', which clarifies that workflowId refers to a workflow identifier but adds no format or usage details. The parameter name is self-explanatory, but the description doesn't fully compensate for the lack of schema description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Returns') and a specific resource ('input schema and webhook details needed to call a given n8n workflow'), clearly distinguishing this from sibling tools like execute_workflow or list_workflows. It answers 'what does it do?' precisely.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage context: it is needed before calling a workflow, as it provides the schema and webhook details required for that call. It does not explicitly name alternatives or exclusions, but the context is clear enough for an agent to infer when to use it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_workflowsA

Lists n8n workflows opted in through the configured MCP tag. This tag is the governance boundary for workflows this agent may call.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description must carry the burden. It discloses the filtering mechanism (MCP tag) and governance boundary, which is useful. However, it does not explicitly state whether the operation is read-only, describe return format, or mention pagination/rate limits. For a list operation, this is acceptable but not comprehensive.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is only two sentences, direct and front-loaded with the action. Every word contributes, explaining both what it does and why the tag matters. No redundancy or unnecessary detail.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's simplicity (no parameters, no output schema), the description provides adequate context: it names the resource, the filtering criteria, and the governance significance. It could add details about return values or pagination, but for a list tool, the description is fairly complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has 0 parameters, and the input schema is empty. The baseline for 0 params is 4. The description does not need to explain parameter semantics, but also adds no extra parameter context. Since there are no parameters to clarify, this score is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's function: 'Lists n8n workflows opted in through the configured MCP tag.' It uses a specific verb (lists) and resource (n8n workflows) and adds scope via the tag, distinguishing it from siblings like execute_workflow or get_execution_status.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies when to use this tool—to discover workflows the agent may call, governed by the MCP tag. It provides context about the governance boundary but does not explicitly mention alternatives or when not to use it. This is clear context without exclusions, so a 4.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 4 tool updatesv0.2.0
    • First observedexecute_workflow
    • First observedget_execution_status
    • First observedget_workflow_schema
    • First observedlist_workflows

TDQS

A4.2/5.0

Scored across 4 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: listing workflows, retrieving schema, executing a workflow, and checking execution status. No overlap or ambiguity exists between them.

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern (list_workflows, get_workflow_schema, execute_workflow, get_execution_status), making the naming predictable and uniform.

Tool Count5/5

With only 4 tools, the server is well-scoped for its purpose. Each tool is essential and earns its place without unnecessary bloat or missing core functionality.

Completeness5/5

The tool set covers the full execution lifecycle: discover workflows, understand their input schema, execute them, and check execution status. No obvious dead ends or missing operations for the stated purpose.

Maintenance

ActivitySlowing
ResponsivenessUnresponsive

Related MCP Connectors

Related MCP Servers