CrewAI Tools 实战指南:内置工具、自定义工具与 MCP 服务器接入
CrewAI Tools(crewai-tools 包)是 CrewAI 框架的官方工具集,负责为 Agent 提供读写文件、爬取网页、查询数据库/向量库以及调用第三方 API 等扩展能力。本文基于仓库中的 lib/crewai-tools/README.md 展开,覆盖其内置工具清单、两种自定义工具的写法(继承 BaseTool 与 @tool 装饰器)、MCP(Model Context Protocol)服务器的两种接入方式,并结合源码剖析 MCPServerAdapter、BaseTool 的参数结构与 MCP 工具适配机制,读完你可以直接在自己的 CrewAI 项目中组装、定制工具并把社区 MCP 服务器的工具 1:1 映射为 CrewAI 工具。
一、CrewAI Tools 的定位
crewai-tools 是一个独立的 Python 包,元数据定义在 lib/crewai-tools/pyproject.toml:
- 包名
crewai-tools,描述为 "Set of tools for the crewAI framework"; - Python 版本要求
>=3.10, <3.14; - 核心依赖锁定了
crewai==1.15.18,并内置requests、beautifulsoup4、python-docx、pymupdf、youtube-transcript-api、tiktoken、pytube等基础库; - 其余能力(Selenium、Tavily、Snowflake、Qdrant、MCP、Stagehand、MySQL、MongoDB 等)全部以 optional-dependencies(extras) 形式提供,按需安装、互不干扰。
这意味着你只需安装与所用工具匹配的 extra,即可避免引入大量无关依赖,例如 pip install crewai-tools[mcp] 只装 MCP 相关依赖。
二、内置工具清单
官方 README 将内置工具分为六大类(见 README 的 Available Tools 一节):
| 类别 | 代表工具 |
|---|---|
| 文件管理(File Management) | FileReadTool、FileWriteTool |
| 网页抓取(Web Scraping) | ScrapeWebsiteTool、SeleniumScrapingTool |
| 数据库集成(Database Integrations) | MySQLSearchTool |
| 向量数据库集成(Vector Database Integrations) | MongoDBVectorSearchTool、QdrantVectorSearchTool、WeaviateVectorSearchTool |
| API 集成(API Integrations) | SerperApiTool、ExaSearchTool |
| AI 能力工具(AI-powered Tools) | DallETool、VisionTool、StagehandTool |
从源码目录 lib/crewai-tools/src/crewai_tools/tools/ 的实际结构看,工具规模远超上述清单:每个工具都是一个独立子目录(如 scrape_website_tool/、mysql_search_tool/、exa_tools/、brave_search_tool/、snowflake_search_tool/、youtube_channel_search_tool/、e2b_sandbox_tool/ 等),统一由 lib/crewai-tools/src/crewai_tools/init.py 导出——其中 MCPServerAdapter、FileReadTool、ScrapeWebsiteTool 均在该文件的 __all__ 中显式列出,因此可以直接 from crewai_tools import ScrapeWebsiteTool 使用。
一个内置工具的源码细节:ScrapeWebsiteTool
以 README 中列出的 ScrapeWebsiteTool 为例,其完整实现在 scrape_website_tool.py,可以看清内置工具的典型结构:
- 输入参数通过 Pydantic 模型
ScrapeWebsiteToolSchema声明,其中website_url为必填字段; - 工具本身还暴露
website_url(可固定某个站点)、cookies(支持从环境变量取 cookie 值)、headers(默认携带浏览器 User-Agent 等请求头)三个可配置项; - 若构造时传入了固定
website_url,工具会自动改写description并把参数模式切换为无参的FixedScrapeWebsiteToolSchema——即"工具化固定行为 + 自动更新对 LLM 的说明"这一模式; - 网络请求经由
crewai_tools.security.safe_requests.safe_get(见 safe_requests.py)发出,并附带 15 秒超时;同目录下还有safe_path.py、ssrf_adapter.py,说明内置文件/网络类工具带有统一的安全防护层(如 SSRF 防护)。
理解这一结构后,你可以按同样的方式阅读 FileReadTool、MySQLSearchTool 等任意内置工具的参数定义与默认值。
三、创建自定义工具:两种方式
官方 README 给出了两条创建自定义工具的路径,两者最终都落在 CrewAI 核心的 BaseTool 抽象上(实现见 lib/crewai/src/crewai/tools/base_tool.py)。
方式 1:子类化 BaseTool
适合需要复杂状态、多参数、环境变量声明或结果 schema 的场景:
from crewai.tools import BaseTool
class MyCustomTool(BaseTool):
name: str = "Tool Name"
description: str = "Detailed description here."
def _run(self, *args, **kwargs):
# Your tool logic here
结合 BaseTool 的字段定义(base_tool.py#L139-L158),你在子类中可用到的核心声明项有:
name:工具唯一名称,应清晰传达用途,Agent 据此选择工具;description:告诉模型"何时/为何/如何"使用该工具的说明,直接影响工具被选中的概率;args_schema: type[BaseModel]:工具入参的 Pydantic 模型,用于生成暴露给 LLM 的参数 schema;result_schema: type[BaseModel] | None:可选的输出 schema,声明后框架会将其序列化信息附加进工具描述,帮助模型理解返回结构;env_vars: list[EnvVar]:声明工具所需环境变量(名称、描述、是否必填、默认值)。
_run 是工具执行入口,返回字符串结果;此外 BaseTool 还提供 cache_function(控制缓存策略)、max_usage_count(使用次数上限)等能力,并在 _generate_description 中自动把 args_schema 转成 JSON Schema 拼入最终 description——这也是 MCP 适配工具所复用的同一机制。
方式 2:@tool 装饰器
轻量函数式工具推荐直接用装饰器:
from crewai import tool
@tool("Tool Name")
def my_custom_function(input):
# Tool logic here
return output
从源码 base_tool.py#L677-L730 可以看到 tool() 支持三种调用形态:
@tool:无参使用,自动以函数名作为工具名;@tool("name"):指定自定义工具名(内部会用"".join(name.split()).title()生成参数模型类名);@tool(result_as_answer=True)/@tool(result_schema=MyModel, max_usage_count=5):声明式选项——result_as_answer=True表示该工具的返回值直接作为 Agent 的最终回答;result_schema指定输出模型;max_usage_count限制工具最大调用次数(None为不限)。
有两个硬性约束值得注意(源码中显式抛 ValueError):被装饰函数必须有 docstring(用作工具描述)和必须有类型注解(用于生成参数 schema)。装饰器会自动遍历函数签名构建 args_schema,因此参数命名和注解质量直接决定 LLM 能否正确填参。
四、CrewAI Tools 与 MCP:接入社区 MCP 服务器
这是 README 篇幅最重的部分:CrewAI Tools 支持 Model Context Protocol(MCP),可以把社区构建的成百上千个 MCP 服务器中的工具直接接入 CrewAI Agent。
前置安装
使用前必须先安装 mcp extra 依赖:
pip install crewai-tools[mcp]
# or
uv add crewai-tools --extra mcp
对照 pyproject.toml 的 mcp extra,其依赖为 mcp>=1.28.1,<2 与 mcpadapt>=0.1.9。另外,源码中还有一个兜底逻辑:若忘记安装而直接构造 MCPServerAdapter,会交互式提示是否立即安装(uv add mcp crewai-tools'[mcp]'),否则抛出带提示信息的 ImportError(见 mcp_adapter.py#L159-L175)。
选项 1:全托管连接(上下文管理器)
用 with 语句管理连接生命周期,MCP 服务器在后台自动启动/停止,你只需使用映射出来的 CrewAI 工具:
STDIO 服务器:
from mcp import StdioServerParameters
from crewai_tools import MCPServerAdapter
serverparams = StdioServerParameters(
command="uvx",
args=["--quiet", "pubmedmcp@0.1.3"],
env={"UV_PYTHON": "3.12", **os.environ},
)
with MCPServerAdapter(serverparams) as tools:
# tools is now a list of CrewAI Tools matching 1:1 with the MCP server's tools
agent = Agent(..., tools=tools)
task = Task(...)
crew = Crew(..., agents=[agent], tasks=[task])
crew.kickoff(...)
SSE 服务器:
serverparams = {"url": "http://localhost:8000/sse"}
with MCPServerAdapter(serverparams) as tools:
# tools is now a list of CrewAI Tools matching 1:1 with the MCP server's tools
agent = Agent(..., tools=tools)
task = Task(...)
crew = Crew(..., agents=[agent], tasks=[task])
crew.kickoff(...)
选项 2:手动管理连接(更多控制权)
需要精细控制时,显式实例化 MCPServerAdapter,并在 try ... finally 中调用 stop() 确保连接即使出错也能被正确关闭:
from mcp import StdioServerParameters
from crewai_tools import MCPServerAdapter
serverparams = StdioServerParameters(
command="uvx",
args=["--quiet", "pubmedmcp@0.1.3"],
env={"UV_PYTHON": "3.12", **os.environ},
)
try:
mcp_server_adapter = MCPServerAdapter(serverparams)
tools = mcp_server_adapter.tools
# tools is now a list of CrewAI Tools matching 1:1 with the MCP server's tools
agent = Agent(..., tools=tools)
task = Task(...)
crew = Crew(..., agents=[agent], tasks=[task])
crew.kickoff(...)
# ** important ** don't forget to stop the connection
finally:
mcp_server_adapter.stop()
SSE 版本同理,将 serverparams 换成 {"url": "http://localhost:8000/sse"} 即可。
源码级机制剖析
结合 mcp_adapter.py 的完整实现,README 未展开的几个要点值得了解:
- 构造签名:
MCPServerAdapter(serverparams, *tool_names, connect_timeout=30)。除 STDIO(StdioServerParameters)或 SSE(dict)参数外,还支持按名称过滤工具(MCPServerAdapter(..., "tool1", "tool2")只暴露指定工具),以及自定义连接超时(默认 30 秒); - 生命周期:
__init__内部即调用start()(通过mcpadapt的MCPAdapt.__enter__建立连接),若启动失败会自动执行stop()清理并抛出RuntimeError;__enter__直接返回tools,__exit__负责断开连接——这解释了为什么"上下文管理器"模式下with语句里工具已立即可用; - 工具映射:每个 MCP 工具由
CrewAIToolAdapter.adapt()(mcp_adapter.py#L31-L85)转换成一个动态生成的BaseTool子类:工具名经sanitize_tool_name规范化,inputSchema经create_model_from_schema转成 Pydantic 参数模型,并由_generate_description()把参数 JSON Schema 拼进 description——即 MCP 工具与 CrewAI 工具的"1:1 映射"在 schema 层面是完整的; - 返回值处理:
_run调用 MCP 工具后,从结果content中提取文本; tools属性:若服务器未启动就访问会抛ValueError;返回类型为ToolCollection[BaseTool](tool_collection.py)——它是list的子类,额外支持按名称下标访问(tools["search"],大小写不敏感)和filter_by_names/filter_where过滤。
测试佐证
上述两种接入方式均有真实端到端测试:lib/crewai-tools/tests/adapters/mcp_adapter_test.py 用 FastMCP 动态生成了带 echo_tool/calc_tool 的 STDIO 与 SSE 回声服务器,分别验证了 with 上下文管理器语法和 try ... finally 手动停止语法下工具数量、工具名与调用结果(如 tools[0].run(text="hello") == "Echo: hello")。
安全考量与当前限制
README 明确列出了以下注意事项,生产使用前务必阅读:
- 信任问题:STDIO 服务器会在本机执行代码,务必只接入你信任的 MCP 服务器;SSE 并非绝对安全,恶意 MCP 服务器仍可能向你的应用注入内容;
- 功能范围:目前只支持 MCP 服务器的 tools 原语,不支持 prompts、resources 等其他 MCP 原语;
- 输出限制:按官方文档说明,调用结果只返回 MCP 服务器工具的第一个文本输出(
.content[0].text);从源码结构看,适配层在结果为单个TextContent时直接返回其text,为多个内容项时将所有TextContent文本汇总为一个列表字符串返回,因此多输出场景的呈现形式以实际适配代码为准。
五、开发者环境:安装、测试与静态检查
README 的 Developer Quickstart 部分给出的官方流程如下:
pip install crewai[tools]
开发环境下(针对 lib/crewai-tools/ 目录):
- 安装依赖:
uv sync - 运行测试:
uv run pytest - 运行静态类型检查:
uv run pyright - 安装提交前钩子:
pre-commit install
测试资产位于 lib/crewai-tools/tests/(含 60+ 个测试脚本与 YAML 数据),每个内置工具通常都有对应的独立测试文件,可作为参数用法的第一手参考。构建系统为 hatchling,版本号取自 src/crewai_tools/init.py。
六、何时选择 CrewAI Tools
官方 README 给出的三点选型理由可以归纳为:
- 简单且灵活:内置工具开箱即用,
BaseTool/@tool又保留了足够的自定义空间; - 快速集成:通过 extras 机制可即插即用地接入外部服务、API 与数据库;
- 面向生产:核心依赖版本锁定、安全模块(
safe_path、safe_requests、SSRF 防护)内置、类型注解完整(带py.typed标记),配合 pyright 静态检查保证一致性。
贡献流程遵循标准开源协作方式:Fork 并克隆仓库、创建功能分支(git checkout -b feature/my-feature)、提交(git commit -m 'Add my feature')、推送分支后发起 Pull Request;问题反馈可通过社区论坛或仓库 Issue 渠道进行。
七、小结
crewai-tools 包的价值在于三点闭环:内置工具覆盖文件、网页、数据库、向量库与第三方 API 等常见场景;自定义机制(BaseTool 子类 + @tool 装饰器)让你以最小成本扩展专属能力,且两者共享同一套 schema/description 机制;MCP 适配层(MCPServerAdapter + ToolCollection)则把社区 MCP 生态的工具以 1:1 方式安全地纳入 CrewAI Agent。掌握本文的两种自定义写法和两种 MCP 接入模式后,即可在当前仓库的 README、mcp_adapter.py、base_tool.py 与 MCP 测试用例 之间对照源码,深入任何你关心的工具实现细节。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0624
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00