8
n8n 中文网amn8n.com

构建自定义PostgreSQL MCP服务器

中级

这是一个Building Blocks, AI领域的自动化工作流,包含 15 个节点。主要使用 Switch, Postgres, PostgresTool, McpTrigger, ToolWorkflow 等节点,结合人工智能技术实现智能自动化。 构建自定义PostgreSQL MCP服务器

前置要求
  • PostgreSQL 数据库连接信息
工作流预览
可视化展示节点连接关系,支持缩放和平移
导出工作流
复制以下 JSON 配置到 n8n 导入,即可使用此工作流
{
  "meta": {
    "instanceId": "408f9fb9940c3cb18ffdef0e0150fe342d6e655c3a9fac21f0f644e8bedabcd9",
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "0c49141e-128c-424e-afdf-ea131b7a3dd8",
      "name": "获取表结构",
      "type": "n8n-nodes-base.postgresTool",
      "position": [
        -460,
        220
      ],
      "parameters": {
        "query": "SELECT column_name, data_type FROM information_schema.columns WHERE table_name = $1",
        "options": {
          "queryReplacement": "={{ $fromAI('tableName', 'The name of the table.') }}"
        },
        "operation": "executeQuery",
        "descriptionType": "manual",
        "toolDescription": "Read a table's schema."
      },
      "credentials": {
        "postgres": {
          "id": "elRn5sxKOfCdlEs6",
          "name": "Postgres account"
        }
      },
      "typeVersion": 2.6
    },
    {
      "id": "8ffeefb9-357c-41bc-8239-0c07c706be97",
      "name": "列出表",
      "type": "n8n-nodes-base.postgresTool",
      "position": [
        -340,
        300
      ],
      "parameters": {
        "query": "SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'",
        "options": {},
        "operation": "executeQuery",
        "descriptionType": "manual",
        "toolDescription": "List all available tables."
      },
      "credentials": {
        "postgres": {
          "id": "elRn5sxKOfCdlEs6",
          "name": "Postgres account"
        }
      },
      "typeVersion": 2.6
    },
    {
      "id": "efcf7ff3-976e-448a-9d47-47a98f3b0fcb",
      "name": "当被其他工作流执行时",
      "type": "n8n-nodes-base.executeWorkflowTrigger",
      "position": [
        280,
        200
      ],
      "parameters": {
        "workflowInputs": {
          "values": [
            {
              "name": "operation"
            },
            {
              "name": "tableName"
            },
            {
              "name": "values",
              "type": "object"
            },
            {
              "name": "where",
              "type": "object"
            }
          ]
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "abd292d7-fc2b-4e98-a474-b50e44d16b6c",
      "name": "创建表记录",
      "type": "@n8n/n8n-nodes-langchain.toolWorkflow",
      "position": [
        -240,
        400
      ],
      "parameters": {
        "name": "CreateTableRows",
        "workflowId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $workflow.id }}"
        },
        "description": "调用此工具在数据库中创建一行。",
        "workflowInputs": {
          "value": {
            "where": "={{ {} }}",
            "values": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('values', `An object of key-value pair where key represents the column name.`, 'string') }}",
            "operation": "insert",
            "tableName": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('tableName', `Name of table to update`, 'string') }}"
          },
          "schema": [
            {
              "id": "operation",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "operation",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "tableName",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "tableName",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "values",
              "type": "object",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "values",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "where",
              "type": "object",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "where",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "4a71d42a-99a5-489e-b449-09c3c5081505",
      "name": "读取表记录",
      "type": "n8n-nodes-base.postgres",
      "position": [
        760,
        0
      ],
      "parameters": {
        "query": "SELECT * FROM {{ $json.tableName }}\n{{ $json.where && Object.keys($json.where).length > 0\n  ? `WHERE ` + Object.keys($json.where).map((key,idx) => `${key} = $${idx+1}`).join(' AND ')\n  : ''\n}}",
        "options": {
          "queryReplacement": "={{ Object.values($json.where).join(',') }}"
        },
        "operation": "executeQuery"
      },
      "credentials": {
        "postgres": {
          "id": "elRn5sxKOfCdlEs6",
          "name": "Postgres account"
        }
      },
      "typeVersion": 2.6,
      "alwaysOutputData": true
    },
    {
      "id": "bdc60aa8-9ab1-4bbd-8b9e-89c968d54043",
      "name": "Operation",
      "type": "n8n-nodes-base.switch",
      "position": [
        460,
        200
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "outputKey": "READ",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "81b134bc-d671-4493-b3ad-8df9be3f49a6",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.operation }}",
                    "rightValue": "read"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "INSERT",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "8d57914f-6587-4fb3-88e0-aa1de6ba56c1",
                    "operator": {
                      "name": "filter.operator.equals",
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.operation }}",
                    "rightValue": "insert"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "UPDATE",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "7c38f238-213a-46ec-aefe-22e0bcb8dffc",
                    "operator": {
                      "name": "filter.operator.equals",
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.operation }}",
                    "rightValue": "update"
                  }
                ]
              },
              "renameOutput": true
            }
          ]
        },
        "options": {}
      },
      "typeVersion": 3.2
    },
    {
      "id": "cdb5b556-3638-4fa5-94c6-bff0c03f6c89",
      "name": "更新表记录",
      "type": "n8n-nodes-base.postgres",
      "position": [
        760,
        400
      ],
      "parameters": {
        "query": "UPDATE {{ $json.tableName }}\nSET\n  {{ Object.keys($json.values)\n  .map((key,idx) => `${key} = $${idx+1}`)\n  .join(',')\n}}\nWHERE\n  {{ Object.keys($json.where)\n  .map((key,idx) => `${key} = $${idx+Object.keys($json.values).length+1}`)\n  .join(' AND ')\n}}",
        "options": {
          "queryReplacement": "={{ Object.values($json.values).join(',') }},{{ Object.values($json.where).join(',') }}"
        },
        "operation": "executeQuery"
      },
      "credentials": {
        "postgres": {
          "id": "elRn5sxKOfCdlEs6",
          "name": "Postgres account"
        }
      },
      "typeVersion": 2.6
    },
    {
      "id": "9263fc78-321e-4c83-90d3-890dd87d6aed",
      "name": "更新表记录",
      "type": "@n8n/n8n-nodes-langchain.toolWorkflow",
      "position": [
        -100,
        320
      ],
      "parameters": {
        "name": "UpdateTableRows",
        "workflowId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $workflow.id }}"
        },
        "description": "调用此工具在数据库中创建一行。",
        "workflowInputs": {
          "value": {
            "where": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('where', `An object of key-value pair where key represents the column name.`, 'string') }}",
            "values": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('values', `An object of key-value pair where key represents the column name.`, 'string') }}",
            "operation": "=update",
            "tableName": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('tableName', `Table to update`, 'string') }}"
          },
          "schema": [
            {
              "id": "operation",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "operation",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "tableName",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "tableName",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "values",
              "type": "object",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "values",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "where",
              "type": "object",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "where",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "dd7e28fb-b2c7-4084-bc9b-9aa3e0187682",
      "name": "创建表记录",
      "type": "n8n-nodes-base.postgres",
      "position": [
        760,
        200
      ],
      "parameters": {
        "query": "INSERT INTO {{ $json.tableName }}\n  ({{ Object.keys($json.values).join(',') }})\nVALUES\n  ({{ Object.keys($json.values).map((_,idx) => `$${idx+1}`).join(',') }})",
        "options": {
          "queryReplacement": "={{ Object.values($json.values).join(',') }}"
        },
        "operation": "executeQuery"
      },
      "credentials": {
        "postgres": {
          "id": "elRn5sxKOfCdlEs6",
          "name": "Postgres account"
        }
      },
      "typeVersion": 2.6
    },
    {
      "id": "324503c0-117b-45ec-97dd-7074eb1db22e",
      "name": "读取表行",
      "type": "@n8n/n8n-nodes-langchain.toolWorkflow",
      "position": [
        20,
        240
      ],
      "parameters": {
        "name": "ReadTableRows",
        "workflowId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $workflow.id }}"
        },
        "description": "调用此工具读取数据库中的一行。",
        "workflowInputs": {
          "value": {
            "where": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('where', `An object of key-value pair where key represents the column name.`, 'string') }}",
            "values": "{}",
            "operation": "read",
            "tableName": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('tableName', ``, 'string') }}"
          },
          "schema": [
            {
              "id": "operation",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "operation",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "tableName",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "tableName",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "values",
              "type": "object",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "values",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "where",
              "type": "object",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "where",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "9cf39ca3-b704-49ce-b6e2-db2703c4acad",
      "name": "便签",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -520,
        -120
      ],
      "parameters": {
        "color": 7,
        "width": 680,
        "height": 660,
        "content": "## 1. 设置 MCP 服务器触发器"
      },
      "typeVersion": 1
    },
    {
      "id": "ac3d9b98-8f1e-4abd-972c-1725aac1ad1e",
      "name": "PostgreSQL MCP 服务器",
      "type": "@n8n/n8n-nodes-langchain.mcpTrigger",
      "position": [
        -340,
        20
      ],
      "webhookId": "a5fd7047-e31b-4c0d-bd68-c36072c3da0d",
      "parameters": {
        "path": "a5fd7047-e31b-4c0d-bd68-c36072c3da0d"
      },
      "typeVersion": 1
    },
    {
      "id": "416a09d5-c327-410d-b951-a2d08402c6fe",
      "name": "便签1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        180,
        -120
      ],
      "parameters": {
        "color": 7,
        "width": 820,
        "height": 720,
        "content": "## 2. 通过防止原始 SQL 语句保持安全"
      },
      "typeVersion": 1
    },
    {
      "id": "0187fb3f-4c31-461d-84e9-4a4a0bf4188d",
      "name": "便签2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1000,
        -560
      ],
      "parameters": {
        "width": 440,
        "height": 1320,
        "content": "## 试试看!"
      },
      "typeVersion": 1
    },
    {
      "id": "bc4e427f-f6fd-4243-844a-8edf2dc1a0e9",
      "name": "便签3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -520,
        -240
      ],
      "parameters": {
        "color": 5,
        "width": 380,
        "height": 100,
        "content": "### 始终验证您的服务器!"
      },
      "typeVersion": 1
    }
  ],
  "pinData": {},
  "connections": {
    "Operation": {
      "main": [
        [
          {
            "node": "ReadTableRecord",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "CreateTableRecord",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "UpdateTableRecord",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "ListTables": {
      "ai_tool": [
        [
          {
            "node": "PostgreSQL MCP Server",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "ReadTableRows": {
      "ai_tool": [
        [
          {
            "node": "PostgreSQL MCP Server",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "GetTableSchema": {
      "ai_tool": [
        [
          {
            "node": "PostgreSQL MCP Server",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "ReadTableRecord": {
      "main": [
        []
      ]
    },
    "CreateTableRecords": {
      "ai_tool": [
        [
          {
            "node": "PostgreSQL MCP Server",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "UpdateTableRecords": {
      "ai_tool": [
        [
          {
            "node": "PostgreSQL MCP Server",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "When Executed by Another Workflow": {
      "main": [
        [
          {
            "node": "Operation",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
常见问题

如何使用这个工作流?

复制上方的 JSON 配置代码,在您的 n8n 实例中创建新工作流并选择「从 JSON 导入」,粘贴配置后根据需要修改凭证设置即可。

这个工作流适合什么场景?

中级 - 构建模块, 人工智能

需要付费吗?

本工作流完全免费,您可以直接导入使用。但请注意,工作流中使用的第三方服务(如 OpenAI API)可能需要您自行付费。

工作流信息
难度等级
中级
节点数量15
分类2
节点类型7
难度说明

适合有一定经验的用户,包含 6-15 个节点的中等复杂度工作流

作者
Jimleuk

Jimleuk

@jimleuk

Freelance consultant based in the UK specialising in AI-powered automations. I work with select clients tackling their most challenging projects. For business enquiries, send me an email at hello@jimle.uk LinkedIn: https://www.linkedin.com/in/jimleuk/ X/Twitter: https://x.com/jimle_uk

外部链接
在 n8n.io 查看

分享此工作流