跳转到内容

Flowise 的 MCP 协议集成与工具发现

学习目标

  • 理解 Flowise MCPToolkit 的三种传输方式及其选择策略
  • 掌握 MCP 工具自动发现的流程:连接 → tools/list → 转换为 LangChain Tool
  • 了解 Flowise 的 MCP 安全设计:hostname deny list + secureFetch

前置知识

本章涉及 MCP 协议的通用原理,建议先阅读:

下文假设你已理解 MCP 协议的基本概念(Client/Server、Transport、Tool 等),直接聚焦 Flowise 的具体实现。


项目实践

MCPToolkit 架构

Flowise 的 MCP 集成位于 packages/components/nodes/tools/MCP/core.ts,核心类为 MCPToolkit

三种传输方式

传输方式适用场景配置参数
stdio本地 MCP Server(如 Claude CLI、自定义脚本)commandargsenv
SSE远程 MCP Server,服务端推送事件urlheaders
Streamable HTTP远程 MCP Server,HTTP 流式响应urlheaders

工具自动发现流程

关键代码逻辑

// 1. 初始化时连接并获取工具列表
async initialize() {
this.client = await this.createClient()
this._tools = await this.client.request({ method: 'tools/list' }, ListToolsResultSchema)
this.tools = await this.get_tools()
await this.client.close() // 初始化后关闭
}
// 2. 每次工具调用时新建连接(确保连接新鲜)
async call() {
this.client = await this.createClient(injectHeaders)
const result = await this.client.request(
{ method: 'tools/call', params: { name, arguments: args } },
CallToolResultSchema
)
// ...处理结果
}

传输回退策略

Flowise 实现了 SSE → HTTP 的回退机制:

try {
transport = new StreamableHTTPClientTransport(baseUrl, { headers })
await client.connect(transport)
} catch (error) {
// HTTP 连接失败,回退到 SSE
transport = new SSEClientTransport(baseUrl, {
eventSourceInit: { fetch: secureFetch }
})
await client.connect(transport)
}

MCP Server 类型

Flowise 内置了多种 MCP Server 集成:

MCP Server传输方式功能
SequentialThinkingstdio结构化推理链
GitHubstdioGitHub API 操作
BraveSearchstdioBrave 搜索
Browserlessstdio浏览器自动化
SlackstdioSlack API
PipedreamstdioPipedream 工作流
Supergatewayhttp/stdioMCP Server 网关
TeradatastdioTeradata 数据库

问题与规避

连接生命周期管理

问题:每次工具调用都创建新连接会带来连接开销。

对策:Flowise 的设计选择是”初始化时获取工具列表后关闭,每次调用时新建连接”。这确保了连接新鲜度(MCP Server 可能重启),但增加了延迟。对于高频调用场景,可以考虑保持连接长开。

SSE 到 HTTP 回退的隐藏问题

问题:回退到 SSE 后,tools/call 的响应方式不同,可能导致某些工具的响应格式不兼容。

对策:MCP 协议规范了统一的 JSON-RPC 响应格式,理论上两种传输方式的结果一致。但某些 MCP Server 实现可能有差异,建议在开发时优先测试目标传输方式。

原型链污染防护

问题lodash.get 在解析路径时会跟随 __proto__constructor 等属性,导致原型链污染。

对策:Flowise 在 resolveWebhookRefs 中使用正则阻断:

if (/(^|\.)(__proto__|constructor|prototype)(\.|$)/.test(subPath)) return match

设计取舍

每次调用新建连接 vs 连接池

方案优势代价
每次新建连接连接新鲜度、无状态泄漏风险连接开销
连接池低延迟、减少握手次数需要管理连接生命周期

Flowise 选择每次新建连接,原因是:

  • MCP 工具调用频率通常不高(用户级别的 Agent 交互)
  • MCP Server 可能随时重启或更新,保持长连接可能遇到断连问题
  • 无状态设计更简单,不需要管理连接池的创建和回收

stdio vs 远程传输

维度stdioSSE/HTTP
延迟最低(本地进程)受网络影响
安全性高(本地隔离)需要 hostname deny list
部署需要本地安装 MCP Server只需 URL
扩展性单实例可多实例共享

参考来源