📚 教程概述
本教程将详细介绍如何在Agno框架中将MCP(Model Context Protocol)作为工具集成到Agent中。通过MCP Tools,你的AI Agent可以无缝连接到各种外部MCP服务器,使用它们提供的工具和资源。我们将使用DeepSeek和Qwen模型进行演示,提供完整可运行的代码示例。
📖 目录
1. MCP Tools简介
1.1 什么是MCP Tools?
MCP Tools 是Agno框架中用于连接外部MCP服务器的工具类。通过MCP Tools,你可以让Agent访问任何符合MCP协议的服务器提供的工具和资源。
核心概念:
- 🔌 Agno作为MCP Client:Agent通过MCPTools连接外部MCP服务器
- 🛠️ 工具自动发现:自动发现MCP服务器提供的所有工具
- 📦 统一接口:使用标准化的方式调用各种外部服务
- 🔗 多服务器支持:一个Agent可以连接多个MCP服务器
1.2 MCP Tools在Agno中的角色
┌─────────────────────────────────────────────┐
│ Agno Agent (MCP Client) │
│ │
│ ┌────────────────────────────────────┐ │
│ │ Agent Configuration │ │
│ │ - Model: DeepSeek/Qwen │ │
│ │ - Tools: [fs_tools] │ │
│ └────────────────────────────────────┘ │
│ ↓ │
│ ┌────────────────────────────────────┐ │
│ │ MCPTools (async context) │ │
│ │ - 启动MCP服务器 │ │
│ │ - 发现可用工具 │ │
│ │ - 调用工具并返回结果 │ │
│ └────────────────────────────────────┘ │
└─────────────────┬───────────────────────────┘
│ MCP Protocol (stdio)
┌─────────┴──────────┐
↓ ↓
┌────────────────┐ ┌────────────────┐
│ MCP Server 1 │ │ MCP Server 2 │
│ (文件系统) │ │ (GitHub API) │
└────────────────┘ └────────────────┘
1.3 为什么使用异步上下文管理器?
使用 async with 的优势:
- ✅ 自动资源管理:自动启动和关闭MCP服务器连接
- ✅ 异常安全:即使出现异常也能正确清理资源
- ✅ 异步支持:完全支持Python异步编程模式
- ✅ 代码简洁:无需手动管理连接生命周期
2. 环境配置和依赖安装
2.1 前置要求
- Python 3.11+
- Node.js 18+ (用于运行MCP服务器)
- DeepSeek API密钥 或 Qwen API密钥
2.2 安装依赖
# 安装Agno框架及相关依赖
pip install agno python-dotenv
# 安装常用MCP服务器
npm install -g @modelcontextprotocol/server-filesystem
npm install -g @modelcontextprotocol/server-github
npm install -g @modelcontextprotocol/server-brave-search
npm install -g dingtalk-mcp@latest
2.3 设置API密钥
创建 .env 文件:
# DeepSeek API密钥
DEEPSEEK_API_KEY=your_deepseek_api_key_here
# Qwen API密钥
DASHSCOPE_API_KEY=your_dashscope_api_key_here
# GitHub Token (用于GitHub MCP Server)
GITHUB_TOKEN=your_github_token_here
# Brave Search API Key
BRAVE_API_KEY=your_brave_api_key_here
# Slack Bot Token
DINGTALK_Client_ID=your dingtalk app client id
DINGTALK_Client_Secret=your dingtalk app cliengt secret
在Python中加载环境变量:
from dotenv import load_dotenv
load_dotenv()
3. MCP Tools基础配置
3.1 MCPTools类的基本用法
import asyncio
from agno.tools.mcp import MCPTools
from agno.agent import Agent
from agno.models.deepseek import DeepSeek
async def basic_example():
# 使用async with上下文管理器
async with MCPTools(
# MCP服务器启动命令(使用npx运行)
"npx -y @modelcontextprotocol/server-filesystem /path/to/directory",
# 可选:指定要使用的工具
include_tools=["read_file", "list_directory"]
) as mcp_tools:
# 创建Agent并添加MCP工具
agent = Agent(
name="Assistant",
model=DeepSeek(),
tools=[mcp_tools], # 🔑 关键:将MCP工具传递给Agent
markdown=True
)
# 使用Agent
await agent.aprint_response("列出目录中的文件")
# 运行异步函数
asyncio.run(basic_example())
3.2 配置参数详解
| 参数 | 类型 | 说明 | 必需 |
|---|---|---|---|
command | str | npx命令启动MCP服务器(第一个位置参数) | 是 |
include_tools | List[str] | 要包含的工具列表,留空则包含所有 | 否 |
exclude_tools | List[str] | 要排除的工具列表 | 否 |
env | Dict[str, str] | 环境变量 | 否 |
3.3 命令格式说明
标准格式:
MCPTools("npx -y @modelcontextprotocol/server-name [参数]")
参数说明:
npx: Node.js包执行器-y: 自动确认安装(如果服务器未安装)@modelcontextprotocol/server-name: MCP服务器包名[参数]: 服务器特定参数(如文件路径、API密钥等)
3.4 最小化示例
"""
最简单的MCP Tools使用示例
"""
import asyncio
from agno.agent import Agent
from agno.models.deepseek import DeepSeek
from agno.tools.mcp import MCPTools
from dotenv import load_dotenv
load_dotenv()
async def run_agent(message: str, file_path: str) -> None:
async with (
# 配置文件系统MCP工具
MCPTools(
f"npx -y @modelcontextprotocol/server-filesystem {file_path}",
include_tools=[
"list_allowed_directories",
"list_directory",
"read_file",
],
) as fs_tools,
):
# 创建Agent
agent = Agent(
name="File Assistant",
model=DeepSeek(),
tools=[fs_tools],
instructions=["你是一个文件管理助手"],
markdown=True,
read_tool_call_history=True
)
# 执行任务
await agent.aprint_response(message)
if __name__ == "__main__":
asyncio.run(run_agent(
"列出目录中的所有文件",
"你的文件夹"
))
4. 实际代码示例
4.1 示例1:文件系统操作Agent(DeepSeek)
完整的文件管理助手,支持读取、写入、搜索文件。
文件名:file_agent_deepseek.py
"""
Agno MCP Tools示例:文件系统操作Agent
使用DeepSeek模型和MCP文件系统服务器
"""
import asyncio
import os
from dotenv import load_dotenv
from agno.agent import Agent
from agno.models.deepseek import DeepSeek
from agno.tools.mcp import MCPTools
load_dotenv()
async def file_operations_demo():
"""文件操作演示"""
# 设置允许访问的目录
workspace_path = "/Users/yourname/Documents/test_folder"
async with MCPTools(
f"npx -y @modelcontextprotocol/server-filesystem {workspace_path}",
include_tools=[
"list_allowed_directories", # 列出允许访问的目录
"list_directory", # 列出目录内容
"read_file", # 读取文件
"write_file", # 写入文件
"create_directory", # 创建目录
"move_file", # 移动文件
"search_files", # 搜索文件
"get_file_info", # 获取文件信息
]
) as fs_tools:
# 创建文件管理Agent
agent = Agent(
name="DeepSeek File Manager",
model=DeepSeek(),
tools=[fs_tools],
instructions=[
"你是一个专业的文件管理助手",
"你可以帮助用户:",
"- 列出目录内容",
"- 读取和写入文件",
"- 创建和管理目录",
"- 搜索文件",
"- 移动和重命名文件",
"在执行危险操作(如删除)前,先向用户确认",
"用清晰的格式展示文件信息"
],
markdown=True,
read_tool_call_history=True
)
print("=" * 60)
print("📁 DeepSeek文件管理Agent启动")
print("=" * 60)
# 测试场景1:列出目录内容
print("\n🔍 测试1:列出目录内容")
await agent.aprint_response("列出当前目录中的所有文件和文件夹")
# 测试场景2:创建文件
print("\n✏️ 测试2:创建新文件")
await agent.aprint_response(
"创建一个名为'hello_mcp.txt'的文件,内容为'Hello from MCP Tools!'"
)
# 测试场景3:读取文件
print("\n📖 测试3:读取文件内容")
await agent.aprint_response("读取hello_mcp.txt的内容")
# 测试场景4:搜索文件
print("\n🔎 测试4:搜索文件")
await agent.aprint_response("搜索所有.txt文件并显示它们的路径")
# 测试场景5:文件信息
print("\n📊 测试5:获取文件详细信息")
await agent.aprint_response("获取hello_mcp.txt的详细信息,包括大小、创建时间等")
async def main():
await file_operations_demo()
if __name__ == "__main__":
asyncio.run(main())
运行效果:
📁 DeepSeek文件管理Agent启动
============================================================
🔍 测试1:列出目录内容
当前目录包含以下文件和文件夹:
- 📁 projects/
- 📄 hello_mcp.txt (125 bytes)
- 📄 notes.md (2.3 KB)
✏️ 测试2:创建新文件
✅ 已成功创建文件 hello_mcp.txt
内容:Hello from MCP Tools!
📖 测试3:读取文件内容
文件内容:Hello from MCP Tools!
4.2 示例2:GitHub操作Agent(Qwen)
通过MCP连接GitHub,管理仓库、Issues、PRs等。
文件名:github_agent_qwen.py
"""
Agno MCP Tools示例:GitHub操作Agent
使用Qwen模型和MCP GitHub服务器
"""
import asyncio
import os
from dotenv import load_dotenv
from agno.agent import Agent
from agno.models.openai import OpenAIChat
from agno.tools.mcp import MCPTools
load_dotenv()
async def github_operations_demo():
"""GitHub操作演示"""
# 设置GitHub Token环境变量
github_token = os.getenv("GITHUB_TOKEN")
if not github_token:
print("❌ 错误:请设置GITHUB_TOKEN环境变量")
return
async with MCPTools(
"npx -y @modelcontextprotocol/server-github",
include_tools=[
"search_repositories", # 搜索仓库
"get_file_contents", # 获取文件内容
"list_commits", # 列出提交记录
"create_issue", # 创建Issue
"create_pull_request", # 创建PR
"list_issues", # 列出Issues
"fork_repository", # Fork仓库
"create_branch", # 创建分支
],
env={"GITHUB_PERSONAL_ACCESS_TOKEN": github_token}
) as github_tools:
# 创建GitHub管理Agent
agent = Agent(
name="Qwen GitHub Manager",
model=OpenAIChat(
id="qwen-max-latest",
api_key=os.getenv("DASHSCOPE_API_KEY"),
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1"
),
tools=[github_tools],
instructions=[
"你是一个GitHub管理助手",
"你可以帮助用户:",
"- 搜索和浏览GitHub仓库",
"- 查看文件内容和提交历史",
"- 创建和管理Issues",
"- 创建和审查Pull Requests",
"- Fork仓库和创建分支",
"使用专业的技术语言,提供清晰的反馈",
"在创建资源(如Issue、PR)前,向用户确认详情"
],
markdown=True,
read_tool_call_history=True
)
print("=" * 60)
print("🐙 Qwen GitHub管理Agent启动")
print("=" * 60)
# 测试场景1:搜索仓库
print("\n🔍 测试1:搜索仓库")
await agent.aprint_response("搜索关于'agno framework'的仓库,显示前3个结果")
# 测试场景2:查看仓库文件
print("\n📂 测试2:查看仓库文件")
await agent.aprint_response(
"查看phidatahq/agno仓库的README.md文件,总结主要内容"
)
# 测试场景3:列出Issues
print("\n📋 测试3:列出Issues")
await agent.aprint_response(
"列出phidatahq/agno仓库中最近的5个open状态的issues,"
"显示标题、创建者和创建时间"
)
# 测试场景4:查看提交历史
print("\n📜 测试4:查看提交历史")
await agent.aprint_response(
"查看phidatahq/agno仓库最近10次提交,总结主要改动"
)
async def main():
await github_operations_demo()
if __name__ == "__main__":
asyncio.run(main())
GitHub工具说明:
| 工具名称 | 功能 | 示例用法 |
|---|---|---|
search_repositories | 搜索GitHub仓库 | 搜索Python AI框架 |
get_file_contents | 获取文件内容 | 读取README.md |
list_commits | 列出提交记录 | 查看最近的提交 |
create_issue | 创建Issue | 报告bug或提建议 |
create_pull_request | 创建PR | 提交代码修改 |
list_issues | 列出Issues | 查看待解决问题 |
fork_repository | Fork仓库 | 创建仓库副本 |
create_branch | 创建分支 | 开始新功能开发 |
4.3 示例3:多MCP服务器集成
同时使用多个MCP服务器,实现复杂的工作流。
文件名:multi_mcp_agent.py
"""
Agno MCP Tools示例:多MCP服务器集成
同时使用文件系统、GitHub和搜索工具
"""
import asyncio
import os
from dotenv import load_dotenv
from agno.agent import Agent
from agno.models.deepseek import DeepSeek
from agno.tools.mcp import MCPTools
load_dotenv()
async def multi_server_demo():
"""多服务器集成演示"""
workspace_path = "/Users/yourname/projects"
# 🔑 关键:使用逗号分隔多个async with语句
async with (
# MCP Server 1: 文件系统
MCPTools(
f"npx -y @modelcontextprotocol/server-filesystem {workspace_path}",
include_tools=["read_file", "write_file", "list_directory", "search_files"]
) as fs_tools,
# MCP Server 2: GitHub
MCPTools(
"npx -y @modelcontextprotocol/server-github",
include_tools=["get_file_contents", "search_repositories", "create_issue"],
env={"GITHUB_PERSONAL_ACCESS_TOKEN": os.getenv("GITHUB_TOKEN")}
) as github_tools,
# MCP Server 3: Brave搜索(可选)
# MCPTools(
# "npx -y @modelcontextprotocol/server-brave-search",
# include_tools=["brave_web_search"],
# env={"BRAVE_API_KEY": os.getenv("BRAVE_API_KEY")}
# ) as search_tools,
):
# 创建多功能开发助手
agent = Agent(
name="DeepSeek Dev Assistant",
model=DeepSeek(),
tools=[fs_tools, github_tools], # 🔑 传递多个工具
instructions=[
"你是一个全能的开发助手",
"你可以:",
"1. 操作本地文件系统(读写文件、管理目录)",
"2. 管理GitHub仓库(查看代码、创建Issues)",
"3. 协调本地开发和远程仓库的工作流",
"根据任务自动选择合适的工具",
"提供详细的操作反馈"
],
markdown=True,
read_tool_call_history=True
)
print("=" * 60)
print("🚀 多MCP工具开发助手启动")
print("=" * 60)
# 复杂任务1:从GitHub下载文件到本地
print("\n📥 任务1:协调GitHub和本地文件系统")
await agent.aprint_response("""
请执行以下任务:
1. 从phidatahq/agno仓库获取README.md的内容
2. 在本地创建一个文件保存该内容,命名为agno_readme_backup.md
3. 确认文件已成功创建
""")
# 复杂任务2:代码分析和问题报告
print("\n🔍 任务2:代码审查和问题跟踪")
await agent.aprint_response("""
请执行以下任务:
1. 读取本地的main.py文件
2. 分析代码,识别潜在的问题或改进点
3. 如果发现重要问题,起草一个GitHub Issue的内容
(标题和详细描述,但不要实际创建)
""")
# 复杂任务3:项目同步
print("\n🔄 任务3:项目文件比对")
await agent.aprint_response("""
请执行以下任务:
1. 列出本地项目目录的文件结构
2. 对比一个GitHub仓库的文件结构
3. 报告差异(哪些文件只在本地,哪些只在远程)
""")
async def main():
await multi_server_demo()
if __name__ == "__main__":
asyncio.run(main())
多服务器集成的优势:
- ✅ 一个Agent可以跨多个数据源工作
- ✅ 自动协调不同工具完成复杂任务
- ✅ 统一的接口,无缝切换工具
- ✅ 提高Agent的能力和灵活性
4.4 示例4:Brave搜索Agent
使用Brave搜索MCP服务器进行网络研究。
文件名:brave_search_agent.py
"""
Agno MCP Tools示例:Brave搜索Agent
使用Brave Search MCP服务器进行网络研究
"""
import asyncio
import os
from dotenv import load_dotenv
from agno.agent import Agent
from agno.models.openai import OpenAIChat
from agno.tools.mcp import MCPTools
load_dotenv()
async def search_research_demo():
"""搜索研究演示"""
brave_api_key = os.getenv("BRAVE_API_KEY")
if not brave_api_key:
print("❌ 错误:请设置BRAVE_API_KEY环境变量")
print("获取API密钥: https://brave.com/search/api/")
return
async with MCPTools(
"npx -y @modelcontextprotocol/server-brave-search",
include_tools=[
"brave_web_search", # 网页搜索
"brave_local_search", # 本地搜索
],
env={"BRAVE_API_KEY": brave_api_key}
) as search_tools:
# 创建搜索研究Agent
agent = Agent(
name="Qwen Search Researcher",
model=OpenAIChat(
id="qwen-max-latest",
api_key=os.getenv("DASHSCOPE_API_KEY"),
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1"
),
tools=[search_tools],
instructions=[
"你是一个专业的网络研究助手",
"使用Brave搜索获取最新、准确的信息",
"对搜索结果进行深度分析和总结",
"提供信息来源链接",
"用清晰的Markdown结构呈现研究结果",
"区分事实和观点",
"标注信息的时效性"
],
markdown=True,
read_tool_call_history=True
)
print("=" * 60)
print("🔎 Brave搜索研究Agent启动")
print("=" * 60)
# 研究任务1:技术主题深度研究
print("\n📚 研究任务1:技术主题深度研究")
await agent.aprint_response("""
研究'Model Context Protocol (MCP)':
1. 搜索MCP的最新发展和特性
2. 总结核心功能和应用场景
3. 列出主要的实现和工具
4. 提供相关资源链接
""")
# 研究任务2:对比分析
print("\n⚖️ 研究任务2:技术对比分析")
await agent.aprint_response("""
对比DeepSeek和Qwen模型:
1. 搜索两个模型的官方信息
2. 比较它们的参数规模、能力和特点
3. 分析各自的优势和适用场景
4. 总结选择建议
""")
# 研究任务3:实时资讯
print("\n📰 研究任务3:实时资讯收集")
await agent.aprint_response("""
搜索2024年AI领域的重要进展:
1. 查找最近3个月的重大AI新闻
2. 按时间顺序整理
3. 突出最具影响力的突破
4. 提供新闻来源
""")
# 研究任务4:特定问题解决
print("\n💡 研究任务4:问题解决方案")
await agent.aprint_response("""
搜索'如何优化Python异步性能':
1. 查找最佳实践和技巧
2. 收集代码示例
3. 总结常见陷阱
4. 推荐学习资源
""")
async def main():
await search_research_demo()
if __name__ == "__main__":
asyncio.run(main())
Brave搜索工具特性:
- 🌐 实时网络搜索
- 🔍 高质量搜索结果
- 📊 结构化数据返回(标题、摘要、URL)
- 🚫 无广告干扰
- 🔒 隐私保护
5. 常见MCP Server集成
5.1 文件系统 (Filesystem)
安装:
npm install -g @modelcontextprotocol/server-filesystem
使用示例:
async with MCPTools(
f"npx -y @modelcontextprotocol/server-filesystem {directory_path}",
include_tools=[
"read_file", # 读取文件
"read_multiple_files", # 批量读取
"write_file", # 写入文件
"create_directory", # 创建目录
"list_directory", # 列出目录
"move_file", # 移动文件
"search_files", # 搜索文件
"get_file_info", # 文件信息
]
) as fs_tools:
agent = Agent(model=DeepSeek(), tools=[fs_tools])
5.2 GitHub
安装:
npm install -g @modelcontextprotocol/server-github
使用示例:
async with MCPTools(
"npx -y @modelcontextprotocol/server-github",
include_tools=[
"create_or_update_file", # 创建/更新文件
"search_repositories", # 搜索仓库
"create_repository", # 创建仓库
"get_file_contents", # 获取文件内容
"create_issue", # 创建Issue
"create_pull_request", # 创建PR
"fork_repository", # Fork仓库
"create_branch", # 创建分支
],
env={"GITHUB_PERSONAL_ACCESS_TOKEN": os.getenv("GITHUB_TOKEN")}
) as github_tools:
agent = Agent(model=DeepSeek(), tools=[github_tools])
5.3 Brave搜索
安装:
npm install -g @modelcontextprotocol/server-brave-search
使用示例:
async with MCPTools(
"npx -y @modelcontextprotocol/server-brave-search",
include_tools=["brave_web_search", "brave_local_search"],
env={"BRAVE_API_KEY": os.getenv("BRAVE_API_KEY")}
) as search_tools:
agent = Agent(model=DeepSeek(), tools=[search_tools])
5.4 Google Maps
安装:
npm install -g @modelcontextprotocol/server-google-maps
使用示例:
async with MCPTools(
"npx -y @modelcontextprotocol/server-google-maps",
include_tools=[
"geocode", # 地址转坐标
"reverse_geocode", # 坐标转地址
"search_places", # 搜索地点
"get_directions", # 获取路线
"get_distance_matrix", # 计算距离矩阵
],
env={"GOOGLE_MAPS_API_KEY": os.getenv("GOOGLE_MAPS_API_KEY")}
) as maps_tools:
agent = Agent(model=DeepSeek(), tools=[maps_tools])
await agent.aprint_response("从北京天安门到故宫的步行路线")
5.5 PostgreSQL数据库
安装:
npm install -g @modelcontextprotocol/server-postgres
使用示例:
async with MCPTools(
"npx -y @modelcontextprotocol/server-postgres",
include_tools=[
"query", # 执行SQL查询
"list_tables", # 列出所有表
"describe_table", # 查看表结构
"execute", # 执行SQL语句
],
env={"POSTGRES_CONNECTION_STRING": os.getenv("DATABASE_URL")}
) as db_tools:
agent = Agent(model=DeepSeek(), tools=[db_tools])
await agent.aprint_response("查询users表中注册时间最近的10个用户")
5.6 Puppeteer(浏览器自动化)
安装:
npm install -g @modelcontextprotocol/server-puppeteer
使用示例:
async with MCPTools(
"npx -y @modelcontextprotocol/server-puppeteer",
include_tools=[
"puppeteer_navigate", # 访问网页
"puppeteer_screenshot", # 截图
"puppeteer_click", # 点击元素
"puppeteer_fill", # 填写表单
"puppeteer_evaluate", # 执行JS
]
) as web_tools:
agent = Agent(model=DeepSeek(), tools=[web_tools])
await agent.aprint_response("访问example.com并截图保存")
5.7 Memory(知识库)
安装:
npm install -g @modelcontextprotocol/server-memory
使用示例:
async with MCPTools(
"npx -y @modelcontextprotocol/server-memory",
include_tools=[
"store_memory", # 存储知识
"search_memory", # 搜索知识
"delete_memory", # 删除知识
"list_memories", # 列出所有知识
]
) as memory_tools:
agent = Agent(model=DeepSeek(), tools=[memory_tools])
await agent.aprint_response("记住:我喜欢Python编程")
6. 高级使用场景
6.1 场景1:全栈开发助手
集成文件系统、GitHub、搜索和数据库。
"""
全栈开发助手:多工具协作
"""
import asyncio
import os
from dotenv import load_dotenv
from agno.agent import Agent
from agno.models.deepseek import DeepSeek
from agno.tools.mcp import MCPTools
load_dotenv()
async def fullstack_dev_assistant():
workspace = "/Users/yourname/projects/my_app"
async with (
# 本地文件系统
MCPTools(
f"npx -y @modelcontextprotocol/server-filesystem {workspace}",
include_tools=["read_file", "write_file", "list_directory", "search_files"]
) as fs_tools,
# GitHub管理
MCPTools(
"npx -y @modelcontextprotocol/server-github",
include_tools=["get_file_contents", "create_issue", "create_pull_request"],
env={"GITHUB_PERSONAL_ACCESS_TOKEN": os.getenv("GITHUB_TOKEN")}
) as github_tools,
# 网络搜索
MCPTools(
"npx -y @modelcontextprotocol/server-brave-search",
include_tools=["brave_web_search"],
env={"BRAVE_API_KEY": os.getenv("BRAVE_API_KEY")}
) as search_tools,
# 数据库管理
MCPTools(
"npx -y @modelcontextprotocol/server-postgres",
include_tools=["query", "list_tables", "describe_table"],
env={"POSTGRES_CONNECTION_STRING": os.getenv("DATABASE_URL")}
) as db_tools,
):
agent = Agent(
name="Fullstack Dev Assistant",
model=DeepSeek(),
tools=[fs_tools, github_tools, search_tools, db_tools],
instructions=[
"你是一个全栈开发专家助手",
"你可以:",
"1. 管理本地项目文件和代码",
"2. 与GitHub仓库交互(查看、创建Issue/PR)",
"3. 搜索技术文档和解决方案",
"4. 查询和分析数据库",
"5. 协调完整的开发工作流",
"根据任务智能选择工具组合",
"提供详细的技术建议和最佳实践"
],
markdown=True,
read_tool_call_history=True
)
print("🚀 全栈开发助手已启动\n")
# 复杂开发任务
await agent.aprint_response("""
我正在开发一个用户认证功能,请帮我:
1. 搜索JWT认证的Python最佳实践
2. 检查数据库中users表的结构
3. 在本地创建auth.py文件,实现JWT认证逻辑
4. 从GitHub上类似项目学习实现方式
5. 如果发现本地代码有问题,起草改进建议
""")
if __name__ == "__main__":
asyncio.run(fullstack_dev_assistant())
6.2 场景2:数据分析管道
数据库查询 → 分析 → 报告 → 通知。
"""
数据分析管道:自动化数据分析和报告
"""
import asyncio
import os
from datetime import datetime
from dotenv import load_dotenv
from agno.agent import Agent
from agno.models.openai import OpenAIChat
from agno.tools.mcp import MCPTools
load_dotenv()
async def data_analysis_pipeline():
report_dir = "/Users/yourname/reports"
async with (
# 数据库连接
MCPTools(
"npx -y @modelcontextprotocol/server-postgres",
include_tools=["query", "list_tables"],
env={"POSTGRES_CONNECTION_STRING": os.getenv("DATABASE_URL")}
) as db_tools,
# 文件系统(保存报告)
MCPTools(
f"npx -y @modelcontextprotocol/server-filesystem {report_dir}",
include_tools=["write_file", "list_directory"]
) as fs_tools,
# 钉钉通知
MCPTools(
"npx -y dingtalk-mcp@latest",
include_tools=["post_message"],
env={
"DINGTALK_Client_ID": os.getenv("DINGTALK_Client_ID"),
"DINGTALK_Client_Secret": os.getenv("DINGTALK_Client_Secret")
}
) as dingding_tools,
):
agent = Agent(
name="Data Analyst",
model=OpenAIChat(
id="qwen-max-latest",
api_key=os.getenv("DASHSCOPE_API_KEY"),
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1"
),
tools=[db_tools, fs_tools, dingding_tools],
instructions=[
"你是一个专业的数据分析师",
"工作流程:",
"1. 从数据库查询数据",
"2. 进行统计分析和可视化描述",
"3. 生成Markdown格式的分析报告",
"4. 将报告保存到本地文件",
"5. 在钉钉发送报告摘要和链接",
"使用清晰的数据呈现格式",
"提供洞察和建议"
],
markdown=True,
read_tool_call_history=True
)
print("📊 数据分析管道已启动\n")
# 自动化分析任务
current_date = datetime.now().strftime("%Y年%m月")
await agent.aprint_response(f"""
执行{current_date}的销售数据分析:
1. 从sales表查询本月的所有销售数据
2. 计算以下指标:
- 总销售额
- 平均订单金额
- 订单数量
- Top 10畅销产品
- 销售趋势(周同比)
3. 生成详细的分析报告(Markdown格式)
4. 将报告保存为 monthly_sales_report_{datetime.now().strftime('%Y%m')}.md
5. 使用钉钉发送报告摘要到群消息中
""")
if __name__ == "__main__":
asyncio.run(data_analysis_pipeline())
6.3 场景3:智能运维助手
监控 + 日志分析 + 自动修复 + 告警。
"""
智能运维助手:自动化监控和问题处理
"""
import asyncio
import os
from dotenv import load_dotenv
from agno.agent import Agent
from agno.models.deepseek import DeepSeek
from agno.tools.mcp import MCPTools
load_dotenv()
async def devops_assistant():
log_dir = "/var/log/myapp"
async with (
# 数据库监控
MCPTools(
"npx -y @modelcontextprotocol/server-postgres",
include_tools=["query"],
env={"POSTGRES_CONNECTION_STRING": os.getenv("DATABASE_URL")}
) as db_tools,
# 日志文件访问
MCPTools(
f"npx -y @modelcontextprotocol/server-filesystem {log_dir}",
include_tools=["read_file", "search_files", "list_directory"]
) as fs_tools,
# 钉钉通知
MCPTools(
"npx -y dingtalk-mcp@latest",
include_tools=["post_message"],
env={
"DINGTALK_Client_ID": os.getenv("DINGTALK_Client_ID"),
"DINGTALK_Client_Secret": os.getenv("DINGTALK_Client_Secret")
}
) as dingding_tools,
# GitHub Issue跟踪
MCPTools(
"npx -y @modelcontextprotocol/server-github",
include_tools=["create_issue", "list_issues"],
env={"GITHUB_PERSONAL_ACCESS_TOKEN": os.getenv("GITHUB_TOKEN")}
) as github_tools,
):
agent = Agent(
name="DevOps Assistant",
model=DeepSeek(),
tools=[db_tools, fs_tools, dingding_tools, github_tools],
instructions=[
"你是一个智能运维助手",
"你的职责:",
"1. 监控系统健康状态",
"2. 分析日志识别问题",
"3. 提供问题诊断和修复建议",
"4. 发送告警通知",
"5. 创建Issue跟踪问题",
"按问题严重程度分类:",
"- 🔴 Critical: 立即通知并创建Issue",
"- 🟡 Warning: 记录并建议检查",
"- 🟢 Info: 仅记录",
"提供清晰的问题描述和解决步骤"
],
markdown=True,
show_tool_calls=True,
read_tool_call_history=True
)
print("🔧 智能运维助手已启动\n")
# 健康检查任务
await agent.aprint_response("""
执行系统健康检查:
1. 查询数据库性能指标(慢查询、连接数、表大小)
2. 分析最近1小时的应用日志,识别ERROR和WARNING
3. 检查是否有异常模式或频繁错误
4. 如果发现Critical问题:
- 在钉钉群发送告警消息
- 在GitHub创建Issue记录问题详情
5. 生成健康检查报告摘要
""")
if __name__ == "__main__":
asyncio.run(devops_assistant())
6.4 场景4:内容创作工作流
研究 → 写作 → 审核 → 发布。
"""
内容创作工作流:自动化内容生产
"""
import asyncio
import os
from datetime import datetime
from agno.models.dashscope import DashScope
from dotenv import load_dotenv
from agno.agent import Agent
from agno.models.openai import OpenAIChat
from agno.tools.mcp import MCPTools
load_dotenv()
async def content_creation_workflow():
content_dir = "/Users/yourname/blog"
async with (
# 网络研究
MCPTools(
"npx -y @modelcontextprotocol/server-brave-search",
include_tools=["brave_web_search"],
env={"BRAVE_API_KEY": os.getenv("BRAVE_API_KEY")}
) as search_tools,
# 本地写作
MCPTools(
f"npx -y @modelcontextprotocol/server-filesystem {content_dir}",
include_tools=["write_file", "read_file", "list_directory"]
) as fs_tools,
# GitHub发布
MCPTools(
"npx -y @modelcontextprotocol/server-github",
include_tools=["create_or_update_file", "get_file_contents"],
env={"GITHUB_PERSONAL_ACCESS_TOKEN": os.getenv("GITHUB_TOKEN")}
) as github_tools,
):
agent = Agent(
name="Content Creator",
model=DashScope(
id="qwen3-max",
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1"
),
tools=[search_tools, fs_tools, github_tools],
instructions=[
"你是一个专业的技术内容创作者",
"创作流程:",
"1. 研究主题:使用搜索收集资料",
"2. 撰写文章:创建高质量的技术文章",
"3. 本地保存:保存为Markdown文件",
"4. 发布:推送到GitHub博客仓库",
"写作风格:",
"- 清晰易懂,适合技术读者",
"- 包含代码示例和实践建议",
"- 结构化组织,使用标题和列表",
"- 添加元数据(日期、标签、分类)"
],
markdown=True,
read_tool_call_history=True
)
print("✍️ 内容创作工作流已启动\n")
# 完整创作任务
topic = "Python异步编程最佳实践"
date_str = datetime.now().strftime("%Y-%m-%d")
await agent.aprint_response(f"""
创作一篇关于'{topic}'的技术博文:
1. 研究阶段:
- 搜索最新的Python异步编程资料
- 收集最佳实践和常见陷阱
- 查找代码示例
2. 写作阶段:
- 撰写一篇2000字左右的文章
- 包含至少3个代码示例
- 添加实用建议和注意事项
- 包含文章元数据:
```yaml
---
title: {topic}
date: {date_str}
tags: [Python, 异步编程, asyncio]
category: 编程技术
---
3. 保存阶段:
- 保存为 posts/{date_str}-python-async-best-practices.md
4. 发布阶段:
- 推送到GitHub仓库 username/tech-blog
- 路径: content/posts/{date_str}-python-async-best-practices.md
请完成整个创作和发布流程。
""")
if __name__ == "__main__":
asyncio.run(content_creation_workflow())
7. 最佳实践和注意事项
7.1 资源管理
✅ 使用异步上下文管理器
# ✅ 推荐:自动管理资源
async with MCPTools("npx -y @modelcontextprotocol/server-filesystem /path") as tools:
agent = Agent(tools=[tools], ...)
await agent.aprint_response("任务")
# MCP服务器自动关闭
# ❌ 不推荐:手动管理(容易忘记清理)
tools = MCPTools("npx -y @modelcontextprotocol/server-filesystem /path")
agent = Agent(tools=[tools], ...)
# 需要手动调用 await tools.close()
✅ 多服务器管理
# ✅ 推荐:使用逗号分隔多个上下文
async with (
MCPTools("command1") as tools1,
MCPTools("command2") as tools2,
MCPTools("command3") as tools3,
):
agent = Agent(tools=[tools1, tools2, tools3], ...)
7.2 工具选择策略
使用 include_tools 精确控制
# ✅ 推荐:只包含需要的工具
async with MCPTools(
"npx -y @modelcontextprotocol/server-filesystem /path",
include_tools=["read_file", "write_file", "list_directory"] # 明确列出
) as tools:
pass
# ⚠️ 谨慎:包含所有工具(可能导致工具过多,影响选择效率)
async with MCPTools(
"npx -y @modelcontextprotocol/server-filesystem /path"
# 不设置include_tools,将包含所有工具
) as tools:
pass
使用 exclude_tools 排除不需要的
async with MCPTools(
"npx -y @modelcontextprotocol/server-filesystem /path",
exclude_tools=["delete_file", "move_file"] # 排除危险操作
) as tools:
pass
7.3 错误处理
处理MCP服务器启动失败
import asyncio
from agno.tools.mcp import MCPTools
async def safe_mcp_init():
try:
async with MCPTools(
"npx -y @modelcontextprotocol/server-filesystem /path",
include_tools=["read_file"]
) as tools:
agent = Agent(tools=[tools], ...)
await agent.aprint_response("任务")
except Exception as e:
print(f"❌ MCP服务器启动失败: {e}")
print("请检查:")
print("1. Node.js是否已安装")
print("2. MCP服务器包是否已安装")
print("3. 路径和权限是否正确")
# 回退方案
agent = Agent(model=DeepSeek(), ...) # 不使用MCP工具
处理工具调用失败
agent = Agent(
name="Robust Agent",
model=DeepSeek(),
tools=[mcp_tools],
instructions=[
"如果工具调用失败,尝试以下策略:",
"1. 检查参数是否正确",
"2. 尝试使用替代工具",
"3. 向用户说明无法完成并解释原因",
"4. 提供手动操作的建议"
]
)
7.4 性能优化
1. 减少工具调用次数
# ✅ 优化:批量操作
agent = Agent(
instructions=[
"尽可能使用批量操作工具",
"例如:read_multiple_files而不是多次read_file"
]
)
# 示例任务
await agent.aprint_response("""
读取以下文件的内容:
- file1.txt
- file2.txt
- file3.txt
请使用批量读取功能一次性获取
""")
2. 限制工具调用深度
agent = Agent(
model=DeepSeek(),
tools=[mcp_tools],
max_tool_calls=5, # 限制最多调用5次工具
instructions=["在最少的工具调用次数内完成任务"]
)
3. 缓存常用查询
from functools import lru_cache
@lru_cache(maxsize=100)
async def cached_query(query_string):
"""缓存数据库查询结果"""
# 实现缓存逻辑
pass
7.5 安全性
✅ 使用环境变量存储敏感信息
# ✅ 推荐
from dotenv import load_dotenv
load_dotenv()
async with MCPTools(
"npx -y @modelcontextprotocol/server-github",
env={"GITHUB_PERSONAL_ACCESS_TOKEN": os.getenv("GITHUB_TOKEN")}
) as tools:
pass
# ❌ 不要硬编码
async with MCPTools(
"npx -y @modelcontextprotocol/server-github",
env={"GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_xxxxx"} # 危险!
) as tools:
pass
✅ 限制文件系统访问范围
# ✅ 推荐:限制在特定目录
safe_dir = "/Users/yourname/safe_workspace"
async with MCPTools(
f"npx -y @modelcontextprotocol/server-filesystem {safe_dir}"
) as tools:
pass
# ❌ 危险:允许访问根目录
async with MCPTools(
"npx -y @modelcontextprotocol/server-filesystem /" # 危险!
) as tools:
pass
✅ 审核工具权限
agent = Agent(
tools=[mcp_tools],
instructions=[
"在执行以下操作前需要用户确认:",
"- 删除文件或目录",
"- 修改重要配置",
"- 发送外部消息",
"- 执行数据库写入操作"
]
)
7.6 调试技巧
启用详细日志
agent = Agent(
name="Debug Agent",
model=DeepSeek(),
tools=[mcp_tools],
markdown=True, # Markdown格式输出
read_tool_call_history=True # 读取工具调用历史
)
查看MCP服务器输出
import subprocess
# 手动测试MCP服务器
result = subprocess.run(
["npx", "-y", "@modelcontextprotocol/server-filesystem", "/tmp"],
capture_output=True,
text=True
)
print("stdout:", result.stdout)
print("stderr:", result.stderr)
使用测试模式
async def test_mcp_tools():
"""测试MCP工具是否正常工作"""
async with MCPTools(
"npx -y @modelcontextprotocol/server-filesystem /tmp",
include_tools=["list_directory"]
) as tools:
agent = Agent(model=DeepSeek(), tools=[tools])
# 简单测试任务
response = await agent.run("列出目录中的文件")
print(response.content)
assert response.content, "应该返回内容"
print("✅ MCP工具测试通过")
asyncio.run(test_mcp_tools())
7.7 测试策略
单元测试
import pytest
@pytest.mark.asyncio
async def test_filesystem_mcp():
"""测试文件系统MCP工具"""
async with MCPTools(
"npx -y @modelcontextprotocol/server-filesystem /tmp/test",
include_tools=["list_directory", "read_file"]
) as fs_tools:
agent = Agent(
model=DeepSeek(),
tools=[fs_tools]
)
response = await agent.run("列出目录中的文件")
assert response.content is not None
assert len(response.content) > 0
@pytest.mark.asyncio
async def test_multiple_mcp_servers():
"""测试多MCP服务器集成"""
async with (
MCPTools("npx -y @modelcontextprotocol/server-filesystem /tmp") as fs,
MCPTools("npx -y @modelcontextprotocol/server-github") as gh,
):
agent = Agent(model=DeepSeek(), tools=[fs, gh])
response = await agent.run("测试任务")
assert response is not None
集成测试
@pytest.mark.asyncio
async def test_fullstack_workflow():
"""完整工作流测试"""
async with (
MCPTools(f"npx -y @modelcontextprotocol/server-filesystem /tmp") as fs,
MCPTools("npx -y @modelcontextprotocol/server-github") as gh,
):
agent = Agent(
model=DeepSeek(),
tools=[fs, gh],
instructions=["执行完整的工作流测试"]
)
# 测试复杂任务
response = await agent.run("""
1. 从GitHub读取文件
2. 保存到本地
3. 确认文件已创建
""")
assert "成功" in response.content or "完成" in response.content
7.8 部署建议
Docker部署
Dockerfile:
FROM node:18-slim
# 安装Python
RUN apt-get update && apt-get install -y \
python3.11 \
python3-pip \
&& rm -rf /var/lib/apt/lists/*
# 安装MCP服务器
RUN npm install -g \
@modelcontextprotocol/server-filesystem \
@modelcontextprotocol/server-github \
@modelcontextprotocol/server-brave-search \
@modelcontextprotocol/server-slack
# 设置工作目录
WORKDIR /app
# 安装Python依赖
COPY requirements.txt .
RUN pip3 install --no-cache-dir -r requirements.txt
# 复制应用代码
COPY . .
# 设置环境变量
ENV PYTHONUNBUFFERED=1
# 运行应用
CMD ["python3", "app.py"]
docker-compose.yml:
version: '3.8'
services:
agno-app:
build: .
environment:
- DEEPSEEK_API_KEY=${DEEPSEEK_API_KEY}
- GITHUB_TOKEN=${GITHUB_TOKEN}
- BRAVE_API_KEY=${BRAVE_API_KEY}
volumes:
- ./workspace:/app/workspace:ro
- ./output:/app/output
restart: unless-stopped
生产环境配置
"""
生产环境配置示例
"""
import asyncio
import logging
from agno.agent import Agent
from agno.models.deepseek import DeepSeek
from agno.tools.mcp import MCPTools
# 配置日志
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)
async def production_agent():
try:
async with (
MCPTools(
"npx -y @modelcontextprotocol/server-filesystem /app/workspace",
include_tools=["read_file", "list_directory"]
) as fs_tools,
):
agent = Agent(
name="Production Agent",
model=DeepSeek(),
tools=[fs_tools],
# 生产环境优化
max_tool_calls=10,
read_tool_call_history=False, # 不显示详细调用
markdown=False
)
logger.info("Agent started successfully")
# 执行任务
result = await agent.run("处理任务")
logger.info(f"Task completed: {result.content[:100]}...")
return result
except Exception as e:
logger.error(f"Agent error: {e}", exc_info=True)
raise
if __name__ == "__main__":
asyncio.run(production_agent())
📝 总结
在本教程中,我们深入学习了:
- ✅ MCP Tools基础:使用async with上下文管理器
- ✅ 标准调用方式:npx命令启动MCP服务器
- ✅ 工具精确控制:include_tools参数指定需要的工具
- ✅ 丰富示例:文件系统、GitHub、Slack、搜索等
- ✅ 多工具集成:同时使用多个MCP服务器
- ✅ 高级场景:全栈开发、数据分析、运维、内容创作
- ✅ 最佳实践:安全性、性能优化、错误处理、部署
核心要点
- 🎯 使用 async with:自动管理MCP服务器生命周期
- 🎯 npx启动服务器:
npx -y @modelcontextprotocol/server-name [参数] - 🎯 精确控制工具:使用include_tools只包含需要的工具
- 🎯 多工具协作:一个Agent可以同时使用多个MCP服务器
- 🎯 异步编程:所有操作都是异步的,使用await
下一步学习
- 📚 探索更多MCP服务器:mcp.so/zh
- 🔧 开发自定义MCP服务器
- 🌐 将MCP Tools与Agno的Team、Workflow结合
- 🚀 在生产环境部署MCP驱动的AI应用