Skip to the content.

Table of Contents

n8n MCP Server Guide

Introduction and Objectives

This guide describes the best practices and architecture for building and maintaining Common Process Servers (MCP) using n8n. The goal is to promote modularity, reusability, and maintainability of workflows.

Basic Concepts

MCP Server Trigger

The MCP Server Trigger (node type: @n8n/n8n-nodes-langchain.mcpTrigger) is a specialized node in n8n that acts as an entry point for requests to the MCP server. It allows defining the server’s input and output interface and receives external requests to execute one or more tools.

Subworkflows

Subworkflows (secondary workflows) are n8n workflows that can be called from other workflows. They are fundamental for modularity in the MCP architecture, allowing specific logic to be encapsulated in reusable units. These subworkflows implement the logic of a specific tool.

toolWorkflow Node

The toolWorkflow node (node type: @n8n/n8n-nodes-langchain.toolWorkflow) is used in the main MCP server flow to call a subworkflow (tool). It acts as a bridge, configuring how the subworkflow is called and how its inputs and outputs are mapped. The tool’s ATDF description is placed in this node.

MCP Best Practices

Architecture

Naming Conventions

Standard Output

Validation

Security

Documentation

Versioning

Key Principles for Workflow Robustness

To ensure that MCP servers and their tools (subworkflows) are reliable and easy to debug, these fundamental principles should be followed:

  1. Adherence to Standard Output Format: Every subworkflow (tool) must consistently return the Standard Output Format JSON, whether for success (status: "success") or error (status: "error"), including the appropriate data and meta fields.
  2. Exhaustive Input Validation: Each subworkflow must rigorously validate its input parameters at the beginning. See the Input Validation and Uniform Errors section.
  3. Explicit Error Handling in Critical Nodes: For nodes that perform operations prone to failure (e.g., external API calls with HTTP Request, interactions with services like Google Calendar), explicitly configure error handling. This can be done using the “Settings” > “Continue On Fail” option in the node, followed by an IF node to check if $json.error exists and thus direct the flow to prepare a standard error response. Alternatively, the node’s “Error Workflow” option can be used to direct the failure to a dedicated error handling workflow.
  4. Coverage of All Logical Paths: Ensure that all possible branches within a workflow (e.g., in IF or Switch nodes) explicitly end in a node that generates a standard output (success or error). Avoid “dead ends” where a branch does not produce a formatted response, which could lead to silent errors or unexpected responses.
  5. Strategic Use of n8n “Error Workflows”:
    • Node Level: For critical or complex nodes like @n8n/n8n-nodes-langchain.toolWorkflow, configuring a specific “Error Workflow” in the node’s “Settings” tab can provide granular fault handling.
    • Instance Level (Global): Configuring a global “Error Workflow” for the n8n instance (from n8n “Settings”) serves as a final safety net to capture and handle any uncontrolled errors that may occur in any workflow.
  6. Meaningful Logging: Implement logging of important events, key input parameters, and errors at critical points in the workflows. Use the n8n-nodes-base.logMessage node or external observability tools. This is crucial for debugging and monitoring. (See “Testing and Debugging > Log Interpretation”).

Compliance with these principles is fundamental and is detailed or exemplified in later sections such as Testing and Debugging and Global Error Handling in the Main MCP Server Flow.

General Architecture

Basic Structure

The MCP architecture is based on a main flow (the MCP server) that uses an @n8n/n8n-nodes-langchain.mcpTrigger as an entry point. This flow orchestrates the execution of subworkflows (tools) through @n8n/n8n-nodes-langchain.toolWorkflow nodes.

graph TD
    A[@n8n/n8n-nodes-langchain.mcpTrigger] --> B{Switch Node (Router based on AI Agent's tool name)};
    B -- tool_A_name --> C1["@n8n/n8n-nodes-langchain.toolWorkflow (configured for SWF_Tool_A)"];
    B -- tool_B_name --> C2["@n8n/n8n-nodes-langchain.toolWorkflow (configured for SWF_Tool_B)"];
    C1 --> D[Response Handling / Preparation for AI Agent];
    C2 --> D;

The mcpTrigger receives a request, a Switch node (or similar logic) determines which tool to execute, and a specific toolWorkflow node calls the corresponding subworkflow.

Advantages of Using Subworkflows

Designing MCP Tools (Subworkflows)

Standard Output Format

Success

The status field will always be "success". The data field contains the useful result of the tool.

{
  "status": "success",
  "data": {
    "specific_result": "value",
    "other_data": 123
  },
  "meta": {
    "timestamp": "2023-10-27T10:30:00Z"
  }
}

(Note: meta.timestamp can be generated with `` in a Set node).

Error

The status field will always be "error". The data field contains error details. The message or text field within data provides a human-readable message.

{
  "status": "error",
  "data": {
    "code": "UNIQUE_ERROR_CODE",
    "message": "Readable error description.",
    "text": "Readable error description (alternative if 'text' is used).",
    "details": {
      "field": "name_of_field_with_error",
      "expected": "expected_type_or_format",
      "solution": "How to fix the problem or what is expected."
    }
  },
  "meta": {
    "timestamp": "2023-10-27T10:35:00Z"
  }
}

(Prefer message or text consistently. If examples use text, use text. Ensure error codes like UNIQUE_ERROR_CODE are uppercase and backticked if referenced in text.).

Input Validation and Uniform Errors

{
  "status": "error",
  "data": {
    "code": "VALIDATION_ERROR",
    "message": "Invalid input parameters.",
    "details": {
      "field": "user_id",
      "expected": "string, non-empty",
      "solution": "Provide a valid user_id."
    }
  },
  "meta": {
    "timestamp": "2023-10-27T10:40:00Z"
  }
}

Visual Base Template for Subworkflows (Tools)

Subworkflows acting as tools are typically initiated by an n8n-nodes-base.executeWorkflowTrigger (execute workflow trigger) when called from the main flow (via an @n8n/n8n-nodes-langchain.toolWorkflow). It is crucial to follow the Key Principles for Workflow Robustness when designing these templates.

Example: Subworkflow “SWF_ValidateDateRange”

  1. Start (Trigger): n8n-nodes-base.executeWorkflowTrigger node. Receives parameters like Start (start date) and End (end date) from the toolWorkflow node in the main flow.
  2. Input Validation: n8n-nodes-base.if node (e.g., “Validate dates”). Checks if dates are valid, if Start is before End, etc. (Robustness Principle #2).
    • If validation fails, a (FALSE) branch leads to an n8n-nodes-base.set node (e.g., “Error: Invalid Dates”) to construct the standard error JSON (Robustness Principle #1).
  3. Main Logic (if validation is correct): May include other nodes to process dates if necessary. In this example, the validation itself is the main logic.
  4. Successful Output: n8n-nodes-base.set node (e.g., “Success: Valid Range”). Prepares the standard successful JSON response (Robustness Principle #1).
    {
      "status": "success",
      "data": {
        "message": "The date range is valid.",
        "start_date": "",
        "end_date": ""
      },
      "meta": {
        "timestamp": ""
      }
    }
    
  5. Error Output (from validation or main logic): n8n-nodes-base.set node (e.g., “Error: Invalid Dates”). Prepares the standard error JSON response (Robustness Principle #1).
    {
      "status": "error",
      "data": {
        "code": "INVALID_DATE_RANGE",
        "text": "The start date must be before the end date.",
        "details": {
          "field_start": "",
          "field_end": "",
          "condition": "Start < End"
        }
      },
      "meta": {
        "timestamp": ""
      }
    }
    

    (Note: The “ValidateDateRange” example uses data.text for the message, so it’s reflected here. The error code INVALID_DATE_RANGE is uppercase.)

  6. End of Subworkflow: The subworkflow ends. Data prepared in the Set node of the executed branch (success or error) is implicitly returned to the calling flow (to the toolWorkflow node). Ensure coverage of all logical paths (Robustness Principle #4).
graph TD
    A[n8n-nodes-base.executeWorkflowTrigger <br> (Receives: Start, End)] --> B{n8n-nodes-base.if <br> (Validate Dates: Start < End?)};
    B -- TRUE (Valid) --> S_PREP[n8n-nodes-base.set <br> (Prepare Success JSON: status=success, data={message, dates}, meta)];
    S_PREP --> Z[End of Subworkflow <br> (Returns JSON from S_PREP)];
    B -- FALSE (Invalid) --> E_PREP[n8n-nodes-base.set <br> (Prepare Error JSON: status=error, data={code, text, details}, meta)];
    E_PREP --> Z;

Main Flow Example (MCP Server)

The main flow uses an @n8n/n8n-nodes-langchain.mcpTrigger as an entry point.

  1. MCP Server Trigger: @n8n/n8n-nodes-langchain.mcpTrigger node. Defines the endpoint, and is where the AI Agent (Langchain) sends requests to execute tools.
  2. Request Validation (Optional, delegated to mcpTrigger): The mcpTrigger handles part of the agent’s request validation.
  3. Router/Dispatcher (Switch Node): An n8n-nodes-base.switch node directs execution based on the tool name requested by the AI agent (e.g., ``). Each Switch output connects to a specific @n8n/n8n-nodes-langchain.toolWorkflow node. (See “Global Error Handling in the Main MCP Server Flow” for routing errors).
  4. Subworkflow Call (Tool): The @n8n/n8n-nodes-langchain.toolWorkflow node is responsible for:
    • Identifying the subworkflow to execute (configured in its parameters).
    • Mapping inputs for the subworkflow (e.g., using expressions like `` to take parameters from the AI agent’s request).
    • Executing the subworkflow.
    • Receiving the response (success/error JSON) from the subworkflow. (See “Global Error Handling in the Main MCP Server Flow” for toolWorkflow failures or invalid responses).
  5. Subworkflow Response Handling: The output of the toolWorkflow (which is the subworkflow’s output) can be further processed if necessary before being returned to the mcpTrigger.
  6. Response to AI Agent: The mcpTrigger is responsible for sending the response back to the AI agent.

General Considerations

Integrating the ATDF Format (Automatic Tool Definition Format)

How to Integrate It

The ATDF description block (in YAML format) should be included directly in the description parameter of the @n8n/n8n-nodes-langchain.toolWorkflow node that calls the corresponding subworkflow. This toolWorkflow node acts as the representation of the tool within the main MCP server and is what the AI agent “sees”.

ATDF Block Example (YAML)

This block would be placed in the “Description” field of an @n8n/n8n-nodes-langchain.toolWorkflow node that is configured to call the SWF_Get_User_Profile subworkflow.

---
description: Gets a user's profile from their ID.
how_to_use:
  inputs:
    - name: user_id # This 'name' is what the AI Agent will use
      type: string
      required: true
      description: Unique identifier of the user.
  outputs:
    status: string (success/error)
    data: (if status is success)
      name: string
      email: string
    data: (if status is error)
      code: string
      text: string # or message, be consistent
      details: object
    meta:
      timestamp: string (ISO 8601)
when_to_use: When detailed information for a specific user is required.
---

Annotated ATDF Mini-Template (YAML)

---
# Descriptive name of the tool, visible to the AI agent.
# name: tool.my_action.my_entity
# (The 'name' is usually handled by the MCP Trigger or ToolWorkflow,
#  this ATDF section goes into the 'description' field of that node)

# Concise description of what the tool does.
description: Performs a specific action on an entity.

# Instructions on how to use the tool, including inputs and outputs.
how_to_use:
  inputs:
    # List of input parameters the tool expects.
    - name: required_parameter
      type: string # Common types: string, number, boolean, object, array
      required: true # true if the parameter is mandatory, false if optional.
      description: Detailed description of this parameter and its purpose.
                  # Include value examples if helpful.
    - name: optional_parameter
      type: number
      required: false
      description: Parameter that is not strictly necessary.
      default: 10 # Default value if not provided (informative for ATDF).

  outputs:
    # Description of the output structure the tool returns.
    # This must align with the Standard Output Format of the guide.
    status: string # Always "success" or "error".
    data: object # Container for the response data.
      # Sub-fields of 'data' if status is "success":
      # success_result: string
      # other_data: number
      # Sub-fields of 'data' if status is "error":
      # code: string
      # message: string (or text)
      # details: object (with fields field, expected, solution)
    meta: object # Response metadata.
      # timestamp: string # Date and time in ISO 8601 format.

# When this tool should be used. Describe appropriate use cases.
when_to_use: Ideal for when [describe use scenario] is needed.
             Do not use if [describe contraindications or alternatives].
---

Validating ATDF Syntax (YAML)

ATDF is written in YAML. To ensure your ATDF description syntax is correct before pasting it into an n8n node’s description field, it is highly recommended to validate it. You can use:

Using MCP Sub-servers as Tools

A main MCP server can use tools exposed by other MCP servers (sub-servers) using the @n8n/n8n-nodes-langchain.mcpClient node.

Configuration

Advantages

Visual Example (Flowchart)

flowchart LR
  A[Main MCP Agent] --> B("@n8n/n8n-nodes-langchain.mcpClient");
  B -- sseEndpoint: http://github-mcp/sse --> C[GitHub MCP Sub-server (@mcpTrigger)];
  B -- sseEndpoint: http://docs-mcp/sse --> D[Docs MCP Sub-server (@mcpTrigger)];
  B -- sseEndpoint: http://code-mcp/sse --> E[Code MCP Sub-server (@mcpTrigger)];

The mcpClient node (B) in the Main MCP Agent connects to various MCP sub-servers (C, D, E), each with its own @n8n/n8n-nodes-langchain.mcpTrigger.

Considerations for Describing External Tools (via MCP Client)

When a main MCP server uses tools from an MCP sub-server via the @n8n/n8n-nodes-langchain.mcpClient node:

Frequently Asked Questions (FAQ)

1. What happens if a subworkflow (tool) fails unexpectedly?

2. Can a subworkflow invoke another subworkflow?

3. How to correctly version subworkflows and maintain compatibility?

Testing and Debugging

This section focuses on how to verify the implementation of the Key Principles for Workflow Robustness and debug issues.

1. Testing Subworkflows (Tools) in Isolation

2. Log Interpretation (See Robustness Principle #6 on the importance of logging)

3. Capturing Silent or Unexpected Errors

Export/Import and Git Versioning Guide

1. Exporting and Importing Workflows in n8n

2. Git Versioning Strategy

3. Repository Organization (Suggestions)

4. Basic Git Workflow

Using Tags in n8n Workflows

1. Benefits of Using Tags

2. How to Use Tags in n8n

3. Suggested Tagging Strategies for MCP Servers and Tools

4. Combined Examples

5. Filtering by Tags

Recommendation: Define a tagging convention for your team or organization and be consistent in its application. A good tagging system is invaluable as your n8n instance grows.

Global Error Handling in the Main MCP Server Flow

This section addresses how the main MCP server flow should handle failures related to tool orchestration, complementing the Key Principles for Workflow Robustness that apply to each subworkflow.

1. Importance of Error Handling at the Main Server Level

2. Error Scenarios in the Main Flow and How to Handle Them

a. @n8n/n8n-nodes-langchain.toolWorkflow Node Failure - Possible Cause: The subworkflow specified in the toolWorkflow node does not exist (e.g., incorrect ID, not imported), or there is a critical issue with the toolWorkflow node’s own configuration that prevents it from even attempting to execute the subworkflow. - Handling: - Apply Robustness Principle #5: Configure the “Settings” > “Error Workflow” tab for the @n8n/n8n-nodes-langchain.toolWorkflow node. This dedicated Error Workflow can then generate a standard JSON response (e.g., with status: "error", data.code: "TOOL_EXECUTION_FAILED", and an appropriate message). - A global n8n instance “Error Workflow” (Robustness Principle #5) would also act as a safeguard.

b. Subworkflow Returns a Structurally Invalid Response - Possible Cause: A subworkflow (tool) finishes and returns data, but it does not conform to the expected format (e.g., missing status field, or status is neither "success" nor "error"). This indicates a breach of Robustness Principle #1 by the subworkflow. - Handling: - After each @n8n/n8n-nodes-langchain.toolWorkflow node in the main flow (or after a Switch node routing to several toolWorkflows), add an n8n-nodes-base.if node to validate the response structure. - IF Conditions: Check if the status field exists and if it is either "success" OR "error". - IF FALSE Branch (Invalid Response): - Connect to an n8n-nodes-base.set node that constructs a standard error response. - Example error JSON: json { "status": "error", "data": { "code": "INVALID_TOOL_RESPONSE_STRUCTURE", "message": "The tool returned a response with an unexpected structure.", "details": { "tool_name": "", "received_response_preview": "" } }, "meta": { "timestamp": "" } } - IF TRUE Branch (Valid Response): Continue the flow normally.

c. Error in Router (e.g., Switch Node) - Possible Cause: The tool name provided by the AI agent does not match any of the routes defined in the Switch node. - Handling: - The Switch node in n8n has a “Default” or “Fallback” output. Connect this output to an n8n-nodes-base.set node. - This Set node should generate a standard error response (Robustness Principle #1) indicating the tool was not found. - Example error JSON: json { "status": "error", "data": { "code": "TOOL_NOT_FOUND", "message": "The requested tool is not available or not recognized.", "details": { "requested_tool_name": "" } }, "meta": { "timestamp": "" } }

3. Additional Considerations

Robust error handling at the main MCP server flow level complements error handling within each subworkflow, creating a more resilient and predictable system.