跳转到内容

MCP 工作流:将 Flow 发布为 MCP Server

学习目标

  • 理解 Langflow 中 MCP Server 的两种部署模式(独立 vs 内嵌)
  • 掌握将组件标记为 MCP 工具的方法(tool_mode=True / component_as_tool
  • 学会通过 MCP 协议从外部 Agent 调用 Langflow Flow

前置知识

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

下文假设你已理解 MCP 的基本协议和传输层,直接聚焦 Langflow 将 Flow 暴露为 MCP 工具的具体实现。


项目实践

1. 两种 MCP 部署模式

Langflow 提供两种 MCP Server 部署方式:

模式一:独立 MCP Server(stdio 传输)

Terminal window
# 作为独立进程运行,连接已启动的 Langflow 实例
lfx-mcp --url http://localhost:7860 --api-key your-key

独立 MCP Server 通过 REST API 与 Langflow 通信,提供以下工具集:

工具类别工具示例功能
组件搜索list_components按名称、类型、描述搜索可用组件
Flow 构建add_component向 Flow 添加组件节点
Flow 构建configure_component修改组件的输入参数
Flow 构建add_connection在两个组件间建立连线
Flow 执行run_flow执行指定 Flow 并返回结果
组件描述describe_component获取组件的详细文档

模式二:内嵌 MCP 端点(SSE 传输)

内嵌 MCP 直接挂载在 Langflow 的 FastAPI 路由上(/api/v1/mcp),将启用了 tool_mode=True 的组件输出自动注册为 MCP 工具。

选择策略

维度独立模式内嵌模式
用途Agent 构建和修改 FlowAgent 调用已部署的 Flow
传输stdio(进程间通信)SSE(HTTP 流式)
工具集Flow 构建工具(增删改组件)Flow 执行工具(运行工作流)
认证需要 API Key复用 Langflow 的认证体系

2. 将组件输出暴露为 MCP 工具

在 Langflow 中,任何组件的输出都可以通过 tool_mode 标记变为 MCP 工具:

class VectorStoreComponent:
outputs = [
Output(
name="as_tool",
display_name="作为工具使用",
method="retrieve_as_tool", # 执行方法
tool_mode=True, # 标记为 MCP 工具
types=["Tool"],
),
]
def retrieve_as_tool(self, query: str) -> str:
"""根据查询文本,从向量数据库中检索相关文档并返回。"""
results = self.vector_store.similarity_search(query, k=self.top_k)
return "\n".join(doc.page_content for doc in results)

自动注册流程

工具的名称和描述自动从组件推导:

  • 工具名{component_display_name}_{output_display_name}
  • 描述Outputdescription 或组件的 description
  • 参数:执行方法的函数签名推导为 JSON Schema

3. 零缓存策略

独立 MCP Server 采用零缓存策略:每次 mutating 操作(添加组件、修改连线)都执行 GET → modify → PATCH,不在本地缓存 Flow 状态。

为什么不用缓存

  • Flow 可能被多个 Agent 或用户同时修改,缓存会导致状态不一致
  • 每次 GET 保证获取最新状态,避免”基于过期状态修改”的冲突
  • 代价是每次操作多一次网络往返,但保证了强一致性

4. 多 Agent 并发隔离

在 SSE 模式下,多个 Agent 可能同时连接同一个 Langflow MCP 端点。Langflow 使用 contextvars 实现 per-session 隔离:

# 每个 SSE 连接有独立的 contextvar
_client_var: contextvars.ContextVar[LangflowClient | None] = contextvars.ContextVar("_client", default=None)
_registry_var: contextvars.ContextVar[dict | None] = contextvars.ContextVar("_registry", default=None)
# stdio 模式(单 Agent)使用模块级共享变量
_shared_client: LangflowClient | None = None
_shared_registry: dict | None = None

关键设计

  • stdio 模式:单一 Agent 连接,模块级共享变量简单高效
  • SSE 模式:多 Agent 并发连接,contextvars 确保每个连接的组件注册表和客户端实例独立

问题与规避

陷阱现象对策
工具名冲突两个 Flow 导出同名 MCP 工具为 Flow 设置唯一的 endpoint_name,工具名自动带上端点前缀
Flow 状态不一致多个 Agent 同时修改同一 Flow独立模式天然一致(GET-PATCH);内嵌模式建议每个 Flow 独立部署
工具描述过短Agent 无法理解工具的用途Output(description="...") 中编写清晰的工具描述,这是 Agent 的唯一参考
MCP Server 连接失败Langflow 未启动或 API Key 错误确保 uv run langflow run 已启动,MCP Server 的 --url--api-key 匹配

设计取舍

Flow-as-MCP vs Flow-as-REST-API

维度Flow-as-MCPFlow-as-REST-API
调用方支持 MCP 的 Agent(Claude、Codex)任意 HTTP 客户端
工具发现Agent 自动发现可用工具需要手动查阅 API 文档
参数传递结构化 JSON,由 Agent 推导需要手动构建请求体
组合能力Agent 可组合多个 MCP 工具需要外部编排

推荐策略:对内(开发调试)使用 REST API;对外(Agent 集成)使用 MCP。


参考来源

  • 源码:src/lfx/src/lfx/mcp/server.py
  • 源码:src/backend/base/langflow/api/v1/mcp.py
  • 源码:src/backend/base/langflow/agentic/mcp/server.py