关于 connect-tools-and-mcp
面向使用 CrewAI 构建 Agent 的开发者,介绍如何配置自定义工具、crewai_tools 和 MCP 连接。内容基于 CrewAI 1.15.x 验证,重点说明易被忽略的 API 差异与运行陷阱。
主要功能
- 01选择自定义工具与 MCP 接入方式
- 02配置 stdio、HTTP 和 SSE 连接
- 03说明工具命名与筛选规则
- 04梳理缓存及工具失败处理
- 05核对 crewai_tools 可用名称
适用场景
- 01为 CrewAI Agent 接入本地或远程 MCP 服务
- 02排查工具导入或调用失败
- 03配置工具缓存和失败策略
MCP 相关
该技能指导 CrewAI Agent 连接 MCP 服务,包括原生配置与 MCPServerAdapter 的用法,并说明传输方式和工具筛选。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ crewaiinc/ skills --skill connect-tools-and-mcp安装后在 Claude Code 中输入/connect-tools-and-mcp确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/crewai-tools-names.mdcustom-tools.mdmcp-connections.md详细介绍
将工具和 MCP 服务连接到 CrewAI Agent
为 Agent 提供可用的工具——自定义 Python、预构建的 crewai_tools 或 MCP 服务——避免 0.x 时代那些会静默失败的错误。
已于 2026-10-01 对照 crewai 1.15.22 和 1.15.23 验证。
已于 2026-10-01 在 CrewAI AMP 和真实大模型上进行实测。
先运行 crewai version;如果主版本或次版本与 1.15 不同,请先使用 ask-docs 技能重新验证受版本影响的行,再采信这些内容。
1. 选择机制
| 需求 | 使用方式 | 章节 |
|---|---|---|
| 快速将 Python 函数用作工具 | crewai.tools 中的 @tool | 3 |
| 需要配置、状态或文档化输入架构的工具 | 使用 args_schema 的 BaseTool 子类 | 3 |
| 预构建的搜索、抓取或文件工具 | crewai_tools——但先导入一次以确认名称存在 | 5 |
| 远程 MCP 服务 | Agent(mcps=[MCPServerHTTP(...)])——如果 Crew 已部署或使用 akickoff(),不要使用 https:// 字符串 | 6、8 |
| 随代码一起提供的 MCP 服务 | Agent(mcps=[MCPServerStdio(...)])——当服务包含在包中时,也可在 CrewAI AMP 上使用 | 6、10 |
| 在 CrewAI AMP 账户中连接的集成 | mcps=["<slug>"] 或 "<slug>#<tool>" | 6 |
| 裸 MCP 工具名称或手动启动/停止生命周期 | MCPServerAdapter(需要 crewai-tools[mcp]) | 9 |
mcp 已是 crewai 1.15.x 的核心依赖项——原生 mcps= 无需额外安装。
2. 导入
| 你可能写了 | 当前写法 | 旧写法会发生什么 |
|---|---|---|
from crewai_tools import BaseTool | from crewai.tools import BaseTool | ImportError: cannot import name 'BaseTool' from 'crewai_tools' |
from crewai_tools import tool | from crewai.tools import tool | ImportError: cannot import name 'tool' from 'crewai_tools' |
from crewai_tools import CodeInterpreterTool | 沙箱工具:E2BPythonTool、DaytonaPythonTool | ImportError——已移除 |
from crewai_tools import ZapierActionsAdapter | from crewai_tools.adapters.zapier_adapter import ZapierActionsAdapter(或顶层的 ZapierActionTools) | 顶层导入时发生 ImportError |
使用适配器时写 from crewai.mcp import ... | from crewai_tools import MCPServerAdapter | 适配器位于 crewai_tools;原生配置位于 crewai.mcp |
from crewai.tools import BaseTool, tool, ToolFailure, ToolExecutionFailedError
from crewai.mcp import (
MCPServerStdio, MCPServerHTTP, MCPServerSSE,
create_static_tool_filter, create_dynamic_tool_filter,
)
from crewai.mcp.exceptions import MCPConnectionError
3. 自定义工具
from pydantic import BaseModel, Field
from crewai.tools import BaseTool, tool
class PriceInput(BaseModel):
sku: str = Field(..., description="Product SKU, e.g. 'A-100'")
currency: str = Field("EUR", description="ISO currency code")
class PriceTool(BaseTool):
name: str = "price_lookup"
description: str = "Return the unit price for a SKU. Use before quoting a price."
args_schema: type[BaseModel] = PriceInput
def _run(self, sku: str, currency: str = "EUR") -> str:
return f"{sku} costs 9.99 {currency}"
@tool("Unit Converter")
def convert(km: float) -> str:
"""Convert kilometres to miles."""
return f"{km * 0.621371:.1f} mi"
print(PriceTool().run(sku="A-100")) # args are validated against PriceInput first
print(convert.run(km=10))
可避免实际故障的规则:
| 规则 | 可避免的故障 |
|---|---|
始终定义 _run,即使是异步工具也不例外 | _run 是抽象方法:TypeError: Can't instantiate abstract class ... without an implementation for abstract method '_run' |
将异步代码写在 async def _run(...) 中 | Agent 在 kickoff() 和 akickoff() 中都会通过 _run 执行工具;只有在你自行调用 tool.arun() 时,才会使用 _arun 重写方法 |
为 @tool 函数编写文档字符串 | 装饰时出现 ValueError: Function must have a docstring |
| 面向大模型编写描述:说明工具的作用以及适用场景 | Agent 根据描述选择工具;MCP 工具尤其如此,因为它们的名称含义不明(第 7 节) |
| 预期显示的名称会经过规范化处理 | @tool("Unit Converter") 会以 unit_converter 的名称提供给大模型(在使用 claude-haiku-4-5 的一次实际运行中观察到) |
返回 ToolFailure,而不是错误字符串 | 错误字符串看起来像数据;ToolFailure 会记录在 TaskOutput.tool_failures 中,并可中止运行(见下文) |
每个工具的选项(均位于 BaseTool 中,并可在注明处传给 @tool(...)):
| 字段 | 效果(已验证) |
|---|---|
max_usage_count=N(也可用 @tool("x", max_usage_count=N)) | 在单个任务内运行 N 次后,Agent 会收到 Tool '...' has reached its usage limit of N times and cannot be used anymore.。下一个任务或 kickoff 会获得新的使用额度,因此请自行确保副作用“每次运行仅发生一次”。0 或负数会触发 ValidationError |
result_as_answer=True(也可用于 @tool) | 工具的返回值会成为任务输出;不会再调用大模型 |
cache_function=lambda args, result: bool | 按次决定结果是否可以缓存(第 4 节) |
tool_failure_policy="ignore" | "warn" | "raise" | 也适用于 Agent、Task 和 Crew;默认值为 warn。raise 会中止运行并抛出 ToolExecutionFailedError |
故障:工具引发异常不会导致 crew 失败。异常文本会反馈给 Agent 并记录为工具故障,而 crew 最终会“成功”完成。当下游代码必须获知故障时,请返回 ToolFailure(...) 并设置 tool_failure_policy="raise",或检查 result.tasks_output[i].tool_failures。完整示例:references/custom-tools.md。
Task(tools=[...]) 会替换该任务的 Agent 工具,而不是在原有工具上添加。
4. 工具结果缓存
| 设置 | 1.15.22-1.15.23 中的默认值 | 效果 |
|---|---|---|
Crew(cache=...) | False | 需显式启用。设为 True 后,使用相同参数重复调用会直接返回首次结果,而不运行工具 |
Agent(cache=...) | True | 仅表示允许参与缓存;即使 crew 启用了缓存,设为 False 也会让该 Agent 退出缓存 |
BaseTool(cache_function=...) | 始终缓存 | 返回 False 可避免将结果写入缓存 |
在 crewai 1.15.2 及之前的版本中,crew 默认会缓存工具结果;从 1.15.3 开始,缓存需显式启用。如果你依赖旧行为,请明确设置 Crew(cache=True)。对于实时数据工具或会改变状态的工具,除非其 cache_function 返回 False,否则切勿启用缓存。
另有一种保护机制并非缓存:如果 Agent 连续两次重复完全相同的调用,crewai 会拒绝第二次调用(“我尝试重复使用相同输入……”),无论是否启用了缓存。
5. crewai_tools:实际存在的名称
crewai-tools 1.15.22-1.15.23 导出 118 个名称。围绕某个工具编写代码前,请先导入该工具。模型经常会编造以下名称:
| 幻觉名称(ImportError) | 1.15.22-1.15.23 中的实际名称 |
|---|---|
CodeInterpreterTool | 已移除——请使用 E2BPythonTool / DaytonaPythonTool |
BedrockKBRetriever | BedrockKBRetrieverTool |
GitHubSearchTool、GithubTool | GithubSearchTool |
ArxivTool | ArxivPaperTool |
ComposioToolSet | ComposioTool |
GoogleSearchTool、WebSearchTool、DuckDuckGoSearchTool | SerperDevTool、BraveSearchTool、TavilySearchTool、EXASearchTool |
PDFTextWritingTool、PGSearchTool | 无 |
WikipediaTool、PythonREPLTool、ShellTool、CalculatorTool、HumanTool、LangChainTool、SeleniumTool | 无(存在 SeleniumScrapingTool)——请编写自定义工具 |
许多工具需要第三方软件包。缺少依赖时,构造工具会询问 You are missing the '<pkg>' package. Would you like to install it? [y/N](已针对 EXASearchTool、TavilySearchTool、FirecrawlSearchTool、SeleniumScrapingTool 验证)。连接终端时,这会一直阻塞;关闭 stdin 时,则会引发 click.exceptions.Abort。请提前安装额外依赖,例如 uv add "crewai-tools[exa-py]"。向 LLM 提供预构建工具时,使用的是经过清理的显示名称,而非类名:DirectoryReadTool 会显示为 list_files_in_directory,FileReadTool 会显示为 read_a_files_content。RAG 工具(WebsiteSearchTool、PDFSearchTool 等)在构造时如果没有嵌入器密钥就会失败。完整列表及额外依赖见:references/crewai-tools-names.md。
6. 原生 Agent(mcps=[...])
from crewai import Agent
from crewai.mcp import MCPServerHTTP, MCPServerSSE, MCPServerStdio, create_static_tool_filter
agent = Agent(
role="Inventory analyst",
goal="Answer stock questions",
backstory="Careful with numbers.",
mcps=[
MCPServerHTTP(url="https://mcp.example.com/mcp",
headers={"Authorization": "Bearer <your-key>"}),
MCPServerSSE(url="https://legacy.example.com/sse"),
MCPServerStdio(command="uvx", args=["mcp-server-time"],
tool_filter=create_static_tool_filter(allowed_tool_names=["get_current_time"])),
"https://docs.example.com/mcp#search_docs", # https string, one tool (sync kickoff only - section 8)
"acme#lookup_stock", # AMP-connected integration, one tool
"acme#list_warehouses", # second tool = second ref
],
)
字符串引用会在构造时验证;只有在任务运行时才会建立连接。
| 形式 | 规则(均已验证) |
|---|---|
MCPServerStdio(command, args, env, tool_filter, cache_tools_list) | 在 Crew 运行的地方启动子进程。服务不会继承你的环境变量:它只会获得 HOME, LOGNAME, PATH, SHELL, TERM, USER 以及 env= 中传入的变量,因此请通过 env 显式传递其 API 密钥。没有 cwd 或超时字段 |
MCPServerHTTP(url, headers, streamable=True, tool_filter, cache_tools_list) | 可流式传输的 HTTP;http:// 和 https:// 均可用。请使用主机名,而非 IP:http://127.0.0.1:8765/mcp 会导致工具名称以数字开头,Anthropic 模型会拒绝它们(ValueError: Anthropic function name '127_0_0_1_8765_mcp_lookup_stock' must start with a letter or underscore);http://localhost:8765/mcp 可用 |
MCPServerSSE(url, headers, tool_filter, cache_tools_list) | 旧版 SSE 服务(通常使用 /sse 路径) |
"https://host/path" 字符串 | 必须以 https:// 开头。可选的 #tool 用于保留一个工具。在运行中的事件循环中(await crew.akickoff()),以及部署到 CrewAI AMP 的 Crew(第 8 节)中,会静默解析为零个工具 |
"slug" / "slug#tool" 字符串 | CrewAI AMP 账户中已连接的集成;旧版 "crewai-amp:slug" 也可用。账户尚未连接的 slug 会导致工具数为零,但运行仍会继续(在 AMP 上观察到) |
"http://localhost:8000/mcp" 或任何既不是 https:// 也不是 slug 的字符串 | 构造 Agent 时会出现 ValidationError: ... Invalid MCP reference: 'http://...'. String references must be an 'https://' URL or a valid slug。对于 http://,请使用 MCPServerHTTP |
"slug#a,b" | 同样会引发 Invalid MCP reference 验证错误。每个工具使用一个引用 |
"https://...#a,b" | 可接受,但会选中零个工具(# 只接受一个名称)。每个工具使用一个引用 |
tool_filter 名称 | 与经过清理的工具名称匹配:服务端工具 getForecast 必须列为 get_forecast |
各传输方式、动态筛选器和 AMP 形式的完整示例见:references/mcp-connections.md。
7. MCP 工具名称会被改写——切勿硬编码
原生 MCP 工具会以 <server name>_<tool name> 的形式提供给大模型,然后经过规范化处理:转为小写、非字母数字字符替换为 _、拆分驼峰命名,最长 64 个字符。
| 来源 | 大模型看到的工具 lookup_stock 名称 |
|---|---|
MCPServerStdio(command="python", args=["servers/inventory.py"]) | python_servers_inventory_py_lookup_stock |
使用绝对路径的 MCPServerStdio,例如 /opt/app/.venv/bin/python + /opt/app/servers/inventory_server.py | opt_app_venv_bin_python_opt_app_servers_inventory_serve_a87662e9——超过 64 个字符,因此会被截断并进行哈希处理,工具名称也会消失。command=sys.executable 在本地和 AMP 上也会产生相同结果 |
MCPServerHTTP(url="http://localhost:8765/mcp") | localhost_8765_mcp_lookup_stock(主机为 IP 时,名称会以数字开头——见第 6 节) |
MCPServerHTTP(url="https://mcp.example.com/mcp") 或相同的 https:// 字符串 | mcp_example_com_mcp_lookup_stock |
"acme#lookup_stock"(AMP) | 根据账户返回的服务 URL 生成,而非根据 acme 生成——只有 _lookup_stock 后缀是稳定的 |
MCPServerAdapter | lookup_stock(裸名称) |
后果:
- 不要在任务描述或背景说明中写“调用
lookup_stock工具”。应描述其能力(“使用库存工具检查库存水平”),或在运行时获取确切名称。原生函数调用模型通常能够应对(告诉 claude-haiku-4-5“调用 lookup_stock 工具”后,它调用了python_mcp_server_py_lookup_stock),但采用文本 ReAct 路径的模型会因Action 'lookup_stock' don't exist而失败;如果名称经过哈希处理,就只能依靠描述。 - 保持 stdio
command/args简短(如"uvx"、"npx"、相对脚本路径),这样名称才易读且不超过 64 个字符。绝对路径还会让你的文件系统布局出现在每条提示词中。带作用域的 npx 包本身就会占用约 45 个字符:npx -y @modelcontextprotocol/server-filesystem ./data会将list_allowed_directories哈希为..._data_list_4ab656ee;需要裸名称时,请使用MCPServerAdapter。 - 在代码中,通过
tool.original_tool_name而非tool.name来识别已解析的原生 MCP 工具。
8. 超时、重试和故障行为
| 路径 | 连接 | 每次工具调用 | 重试 | 服务端宕机时 |
|---|---|---|---|---|
MCPServerStdio/HTTP/SSE 配置和 AMP slug | 30 s | 30 s | 超时时尝试 3 次——每次都会重新运行工具。实际运行中:一个耗时 35 s 的工具运行了 3 次(约 99 s);Agent 收到 Error executing tool: Error executing MCP tool slow_report: Operation timed out after 30 seconds 作为其观察结果,记录了一次工具故障,Crew 随后结束。直接调用 tool.run() 则会引发 RuntimeError | 启动时引发 MCPConnectionError |
"https://..." 字符串 | 10 s,发现工具时 15 s | 60 s | 尝试 3 次(一个耗时 65 s 的工具运行了 3 次,约 198 s),然后将错误作为字符串返回 | Agent 在没有 MCP 工具的情况下运行,不报错 |
MCPServerAdapter | connect_timeout=(默认值为 30) | 没有 crewai 超时(一个耗时 35 s 的调用成功完成) | 无 | 构造函数引发 RuntimeError: Failed to initialize MCP Adapter |
在 1.15.22-1.15.23 中,原生超时是模块常量。MCPServerStdio、MCPServerHTTP、MCPServerSSE 或 Agent 上都没有字段可以更改这些超时。因此:
- 确保 MCP 工具调用远低于 30 s。让它们具备幂等性,因为超时的调用会重新发送。对于长时间运行的任务,让一个工具返回任务 ID,再用另一个工具轮询。
- 在生产环境中优先使用配置对象,而不是
https://字符串:配置对象会在启动时明确报错,而不是静默丢弃工具。 https://字符串使用asyncio.run()发现工具。在正在运行的事件循环中,这会失败,Agent 会在没有任何工具且不报错的情况下运行(只出现RuntimeWarning: coroutine 'MCPToolResolver._get_mcp_tool_schemas_async' was never awaited)。在实际运行中,await crew.akickoff()和 CrewAI AMP 部署都出现过这种情况——Agent 会在没有工具的情况下运行,其回答可能会描述它从未执行过的工具调用。同一个服务端使用MCPServerHTTP(url=...)时,在这两种情况下都能正常工作。同步的crew.kickoff()(包括从同步 Flow 步骤中调用)可以正常解析字符串。- 带有
isError: true的 MCP 结果会以文本形式传给 Agent。该结果会被记录为mcp_error工具故障,而tool_failure_policy="raise"会将其转为ToolExecutionFailedError。
9. MCPServerAdapter 和 @CrewBase mcp_server_params
MCPServerAdapter 需要额外安装:uv add "crewai-tools[mcp]"(它会安装 mcpadapt;mcp 本身已经存在)。如果没有安装这个额外依赖,构造它时会询问 You are missing the 'mcp' package. Would you like to install it? [y/N]。在会无限期阻塞的终端中运行时,程序会一直等待;如果标准输入已关闭(CI 中很常见),则会引发 click.exceptions.Abort。请明确安装这个额外依赖。
from mcp import StdioServerParameters
from crewai_tools import MCPServerAdapter
params = StdioServerParameters(command="python", args=["mcp_server.py"])
with MCPServerAdapter(params, "lookup_stock", connect_timeout=60) as tools:
print([t.name for t in tools]) # ['lookup_stock'] - bare names, filtered by name
# build agents with tools=tools and kick off INSIDE the with-block
服务端会在构造函数中启动,并在 with 块退出时停止。之后再使用工具会失败。对于远程服务,请传入字典并指定传输方式:{"url": "https://<host>/mcp", "transport": "streamable-http"}。如果不提供 "transport",适配器会使用 SSE;若连接的是 streamable-HTTP /mcp 端点,则会因 Couldn't connect to the MCP server after <connect_timeout> seconds 而失败。
在 @CrewBase 类中,设置 mcp_server_params(也可以设置 mcp_connect_timeout,默认值为 30),并在 @agent 方法中调用 self.get_mcp_tools("name", ...)。crewai 会在每次 kickoff 后停止该适配器。在同一个实例上第二次调用 .crew().kickoff() 时,所有 MCP 调用都返回 Event loop is closed,但 Crew 仍然显示“成功”。每次运行都创建一个新实例:InventoryCrew().crew().kickoff()。
10. 托管部署:在 CrewAI AMP 上可行的方式
在 CrewAI AMP 部署(ZIP 部署、crewai 1.15.23、anthropic/claude-haiku-4-5)中测得,每种配置都启动了一次:
| 已部署 crew 中的配置 | 结果 |
|---|---|
MCPServerHTTP(url="https://<public host>/mcp") | 可行——模型调用了 <host>_mcp_<tool> |
"https://<public host>/mcp#tool" 字符串 | 没有可用工具,运行状态为 SUCCESS——模型在回答中编造了工具调用(第 8 节) |
MCPServerStdio(command="python", args=["-m", "<pkg>.inv_server"]),服务模块位于 src/<pkg>/ 中 | 可行——打包在项目中的 stdio 服务可在部署环境中运行 |
同上,但使用 command=sys.executable | 可行(工具名称经过哈希处理,见第 7 节) |
MCPServerStdio(..., env={"X": os.environ["X"]}),其中 X 是部署环境变量 | 服务可以读取 X;不设置 env= 则无法读取 |
MCPServerAdapter(StdioServerParameters(...)),且 pyproject.toml 中包含 crewai-tools[mcp] | 可行,工具名称不带前缀 |
MCPServerStdio 指向部署中不存在的文件(例如笔记本电脑上的路径) | 运行失败,报错 MCPConnectionError |
MCPServerStdio(command="npx", ...) | 同样运行失败——部署环境中只有 Python 项目安装的内容 |
MCPServerHTTP 指向错误路径(HTTP 404) | 同样运行失败 |
账户中未连接的 "<slug>#tool" | 没有可用工具,运行状态为 SUCCESS |
从 API 看 MCP 连接失败时的情况:对于上文每个 MCPConnectionError 运行,轮询 GET /status/{kickoff_id} 时都会得到纯文本 HTTP 500 Internal Server Error,即使几分钟后仍然如此,而不是 JSON 格式的 FAILED 状态。同一 crew 中的普通异常则会返回文档中说明的格式:{"state": "FAILED", "status": "ValueError: ..."}。如果 /status 持续返回 500,应将其视为“运行失败”,并首先检查 MCP 连接。
规则:
- 无论 crew 在哪里运行,stdio 服务都会作为子进程运行。将服务打包在项目中(
src/<pkg>/server.py,通过python -m <pkg>.server启动),并在pyproject.toml/uv.lock中声明其 Python 依赖;笔记本电脑上的路径或 Node/npx 服务不会包含在部署中。 - 远程服务请使用
MCPServerHTTP(url="https://<host>/mcp")(或MCPServerSSE),切勿使用https://字符串。部署时应使用由你控制的稳定主机名,并在该主机名上要求身份验证,不要让临时隧道一直运行。 - 健康检查:对健康的可流式 HTTP MCP 端点执行
curl -s -o /dev/null -w "%{http_code}" https://<host>/mcp,会返回 406(在公共服务和本地环境中均有观察到)。404 表示路径错误;000/连接被拒绝表示服务已停止。 - 将令牌放在
headers中,并从环境变量读取(os.environ["ACME_MCP_TOKEN"]),切勿将令牌放在 URL 字符串或代码中。stdio 服务只能通过env=获取部署环境变量。
常见错误
| 症状 | 原因 | 修复方法 |
|---|---|---|
cannot import name 'BaseTool' from 'crewai_tools' | 0.x 导入路径 | from crewai.tools import BaseTool, tool |
Can't instantiate abstract class ... '_run' | 只定义了 _arun | 定义 _run(可以是 async def) |
Action 'lookup_stock' don't exist, these are the only available Actions: ...,或 Agent 从未使用 MCP 工具 | 提示词使用了裸工具名(lookup_stock),但大模型看到的是 python_..._lookup_stock | 描述工具能力;在运行时推导名称 |
ValidationError ... Invalid MCP reference: 'github#a,b' | # 后只能跟一个工具名 | ["github#a", "github#b"] |
mcps=["https://...#a,b"] 没有可用工具 | 原因相同,但不会验证 https 字符串 | 每个工具使用一个引用 |
ValidationError ... Invalid MCP reference: 'http://localhost:8000/mcp' | 字符串必须是 https:// 或 slug | MCPServerHTTP(url="http://localhost:8000/mcp") |
Anthropic function name '127_0_0_1_...' must start with a letter or underscore | MCP 服务 URL 使用了 IP 地址 | 使用主机名(localhost) |
https:// 字符串形式的 MCP 在 akickoff() 下或 AMP 上没有可用工具;答案会虚构工具调用 | 字符串引用无法在运行中的事件循环内解析 | MCPServerHTTP(url=...) |
GET /status 持续失败,或运行始终无法完成 | 运行可能遇到了 MCPConnectionError(stdio 命令或文件缺失、URL 错误) | 在本地运行 Crew 以查看错误;修复 MCP 连接 |
tool_filter 未保留任何工具 | 过滤器使用了服务端的 camelCase 名称 | 使用规范化后的名称(get_forecast) |
| 运行卡在 "Would you like to install it? [y/N]" | 缺少可选包(crewai-tools[mcp]、exa-py 等) | 运行前安装额外依赖 |
| 工具运行了 3 次/副作用重复发生 | 原生 MCP 调用超过 30 s,因而被重试 | 保持调用简短且幂等 |
| Crew “成功”,但答案称工具出错 | 工具异常会传递给 Agent,而不会抛出 | 返回 ToolFailure;设置 tool_failure_policy="raise";检查 tool_failures |
启用 Crew(cache=True) 后结果过时 | 实时数据工具被缓存 | 使用 cache_function=lambda a, r: False 或 Agent(cache=False) |
| 相同的重复调用现在每次都会访问 API | Crew 缓存在 1.15.x 中需显式启用 | Crew(cache=True) |
对同一个 @CrewBase 实例进行第二次 kickoff:Event loop is closed | 适配器在第一次 kickoff 后已停止 | 每次 kickoff 创建新的 Crew 实例 |
stdio MCP 服务提示缺少 API 密钥,尽管密钥已在 .env 中 | stdio 服务获取的是最小化环境,而非你的环境 | MCPServerStdio(..., env={"X_API_KEY": os.environ["X_API_KEY"]}) |
| 本地运行正常,部署后失败 | 部署环境中没有 stdio 服务文件或命令(npx、笔记本电脑上的路径) | 将服务打包到软件包中,或通过稳定的 URL 使用 HTTP 提供服务 |
检查清单
- 从
crewai.tools导入BaseTool/tool;每个crewai_tools名称只导入一次,以确认其存在 - 自定义工具定义
_run,具有args_schema(或带类型注解的@tool签名)和面向大模型的描述 - 将失败作为
ToolFailure返回;有意选择tool_failure_policy - 显式设置
Crew(cache=...);不缓存实时数据工具 - 提前安装可选软件包和
crewai-tools[mcp],避免交互式提示阻塞 - 每个工具使用一个
"slug#tool"引用;http://服务使用MCPServerHTTP,而非字符串;使用主机名,而非 IP 地址 - 已部署的 Crew 或使用
akickoff()时,不使用https://字符串引用;改用MCPServerHTTP - 提示词或代码不依赖裸 MCP 工具名称;保持 stdio 命令简短
- stdio 服务通过
env=获取密钥(它们不会继承 Crew 的环境变量) - MCP 工具调用在远低于 30 s 的时间内完成,且具备幂等性
- 已部署的 Crew 使用稳定 URL 上的 HTTP/SSE MCP 服务(对裸 GET 请求返回 406),或使用随软件包一同发布的 stdio 服务
- 使用
mcp_server_params时,每次 kickoff 都创建一个全新的@CrewBase实例
参考资料
- 自定义工具 - BaseTool、
@tool、异步、ToolFailure 和失败策略、缓存、使用限制,以及可运行示例 - MCP 连接 - 所有
mcps=形式、筛选器、名称派生、超时、MCPServerAdapter、@CrewBase、部署 - crewai_tools 名称 - 完整的 1.15.22-1.15.23 导出列表、幻觉生成的名称、额外项和构造行为
- 公开文档:https://docs.crewai.com/en/concepts/tools 和 https://docs.crewai.com/en/mcp/overview
相关技能:
- check-crewai-api - 当前 Agent/Task/Crew API 和工具之外的导入项
- design-agent - 选择为 Agent 配置多少个工具,以及编写角色/目标/背景故事
- test-crewai-project - 使用存根 LLM 离线驱动工具调用
- deploy-to-amp - 将带有 MCP 连接的项目部署到 CrewAI AMP
- ask-docs - 当已安装版本不同时,查询实时文档