
如果你正在做 AI Agent 相关开发最近一定绕不开两个词MCP 和 AI Agent。而 MCP Server 的数量正在以肉眼可见的速度膨胀每个团队都在封装自己的工具、数据源、业务能力。工具变多之后一个新的问题开始浮现Agent 怎么知道该用哪个工具开发者怎么从海量 Agent 里找到自己需要的那一个这时候“搜索 Agent”本身就成了一个值得被解决的问题。今天要聊的项目叫Buy My Agent MCP Server它想做的事情很直接把一个 AI Agent 搜索引擎封装成 MCP Server让任何支持 MCP 协议的客户端都能直接搜索可用的 Agent。这个思路看起来不复杂但它背后其实藏着一个很重要的判断——Agent 的发现机制正在从“平台内置市场 私有 SDK”走向“开放协议 统一搜索”。这篇文章不会只停在介绍项目本身。我会从 MCP 的核心概念讲起拆解 Agent 搜索 MCP Server 的架构然后给出一个完整的 Python 示例代码带你从零实现一个可运行的 Agent 搜索服务并且用 MCP Inspector 和常见客户端做验证。最后还会补充常见问题、排查思路和工程化建议。读完这篇文章你能搞明白三件事MCP Server 到底解决了什么问题为什么它适合做 Agent 搜索。一个“搜索 Agent 的 MCP Server”需要哪些核心设计。如何自己写一个最小可用版本并接到真实客户端上测试。1. 这篇文章真正要解决的问题先别急着写代码我们先回答一个更本质的问题为什么需要“搜索 AI Agent”这件事现在的 Agent 生态有两个很明显的趋势。第一个趋势是 Agent 数量快速增加企业内部可能同时存在客服 Agent、数据分析 Agent、运维 Agent、知识库 Agent每个 Agent 都有自己的描述、能力边界、调用地址和认证方式。第二个趋势是 MCP 正在成为主流接入方式无论是 Claude Desktop、Dify、Cursor还是自研的 Agent 框架都在支持 MCP 协议。这两个趋势撞在一起就产生了一个新痛点工具和服务越来越多但发现和路由机制非常原始。传统做法是各家做一个“插件市场”或“工具广场”。例如某些 Agent 平台内置了工具商店开发者只能在该平台上架用户只能在该平台内搜索。这种模式的缺点是生态绑定太强工具作者发布一次就只能覆盖一个平台用户换个客户端又得重新找工具。而基于 MCP 的 Agent 搜索方案把“搜索”本身做成了一个 MCP Server。客户端只需要知道这个 Server 的地址不需要关心 Agent 存到哪里、用什么语言写的、底层是什么数据源。这就像你不需要知道网站的数据库是哪家只要知道 URL 就能访问一样。Buy My Agent MCP Server这个项目标题里的关键词正是“Search AI Agents from Any MCP Client”。从项目定位来看它就是想做 Agent 搜索的“基础设施层”。什么样的读者最应该关注这类方案正在搭建企业内部 Agent 平台的开发者需要统一管理多个 Agent。做 MCP 工具生态的人想把自己的 Agent 暴露给更多客户端。AI 应用开发新手想知道 MCP Server 除了“暴露工具”还能怎么玩。技术选型阶段的团队在比较“自研工具注册中心”和“MCP 协议层方案”。说白了这是一篇以 MCP 为骨架、以 Agent 发现为场景的实战型文章。我们不仅要理解项目还要能自己复现出一个类似的 Server。2. MCP 与 AI Agent 搜索的核心概念在进入代码之前我们需要把 MCP 涉及的基本概念理清楚。很多新手看到 MCP 这个词就以为是某个新框架其实它更接近一套“AI 应用的外部能力接入标准”。2.1 MCP 到底是什么MCP 的全称是 Model Context Protocol即模型上下文协议。它定义了 AI 应用比如聊天机器人、IDE 插件、Agent 框架如何通过标准接口访问外部工具、数据源和资源。一个很流行的类比是 USB-C过去你连接不同的设备要用不同的线现在协议统一了插口一致就能互联互通。MCP 解决的正是“每接入一个工具就要写一套集成代码”的问题。MCP 架构里有三个角色角色职责示例MCP Client发起请求通常是 AI 应用Claude Desktop、Dify、自研 AgentMCP Server提供工具、数据、指令文件服务器、数据库服务器、Agent 搜索服务器协议层定义通信方式和消息格式JSON-RPC 2.0 over stdio / HTTPMCP Server 可以暴露三类能力Tool工具、Resource资源和 Prompt提示模板。其中 Tool 最常用因为 Agent 需要通过 Tool 去执行具体动作比如查天气、发邮件、调数据库。2.2 Agent Skill 和 MCP 有什么区别在讨论 Agent 搜索时经常会看到另一个词Agent Skill。有人会问Skill 和 MCP 是不是同一个东西这里需要做一个区分。MCP 定义的是“客户端请求外部能力”的协议重点在接口传输。Agent Skill 更偏上层它描述的往往是 Agent 具备的某种能力封装比如“数据分析技能”“代码审查技能”。一个 Skill 内部可以通过调用多个 MCP 工具来完成目标也可以只是一套提示词加决策逻辑。更简洁的理解MCP 解决的是“怎么调用外部能力”。Skill 解决的是“Agent 以什么方式组织能力”。如果你做一个 Agent 搜索 MCP Server你返回“找到哪些 Agent”属于数据层客户端找到 Agent 后怎么调用它仍然可以通过 MCP 完成。搜索和调用可以分开这也是这个项目设计上比较聪明的地方。2.3 Agent 搜索 MCP Server 的核心价值传统的 Agent 发现方式通常是这样的平台内置目录开发者人工审核用户通过界面搜索。而 Agent 搜索 MCP Server 的价值在于把“发现能力”直接嵌入到 Agent 的运行链路里。举个例子传统方式开发者在浏览器里打开某个平台页面搜索“客服 Agent”找到后复制 API 地址再回到自己的 Agent 配置里填写。MCP 方式Agent 在处理用户问题前自己调用一个search_agents工具输入“客服”得到结构化结果再决定是否调用对应的 Agent 服务。两种方式相比后者更适合自动化流程因为它让搜索和调用之间不再需要人工搬运。当然这个方案也有边界。MCP Server 本身只是提供了搜索接口它并不负责让搜索出来的 Agent 能直接工作。真正远程调用其他 Agent还需要额外的协议、鉴权和运维支持。后面我们在最佳实践里会展开。3. 环境准备与前置条件现在进入实操。我们要实现一个最小可用的“Agent 搜索 MCP Server”整体技术栈比较简单主要是 Python 和 MCP 库。3.1 环境要求以下环境不是硬性版本要求但建议尽量满足操作系统Windows 10/11、macOS 或 Linux 都可以。MCP 与操作系统关系不大。Python3.10 及以上推荐 3.11 或 3.12。包管理工具建议使用uv或pip。MCP SDKmcp包。示例中使用mcp官方 Python SDK 和FastMCP便利封装具体版本以安装时为准。支持 MCP 的客户端MCP Inspector官方自带的调试工具、Claude Desktop、Dify 等均可。建议不要直接使用最新版 Python 的夜间版本避免第三方包兼容问题。3.2 安装依赖我们先创建一个项目目录并初始化虚拟环境。mkdir agent-search-mcp cd agent-search-mcp python -m venv .venv source .venv/bin/activate # Windows 下使用 .venv\Scripts\activate然后安装依赖。pip install mcp[cli] fastmcp如果安装速度慢可以改用国内镜像源。pip install mcp[cli] fastmcp -i https://pypi.tuna.tsinghua.edu.cn/simple安装完成后验证mcp命令是否可用。mcp --version3.3 准备一个支持 MCP 调试的客户端本地开发时强烈建议先用 MCP Inspector 测试。MCP Inspector 是官方提供的可视化调试工具可以加载本地 Python 脚本查看 Server 暴露的工具列表并直接调用工具。mcp inspector python server.py这个命令会在浏览器中打开一个调试界面后面第 6 节会详细介绍怎么验证。4. 架构设计与核心流程在写代码之前我们先想清楚整个 Agent 搜索 MCP Server 的架构。这个设计并不复杂但有几个关键决策会影响后续扩展。4.1 整体架构Agent 搜索 MCP Server 的核心流程是MCP Client 启动时调用 Server 的list_tools发现search_agents工具。Agent 收到用户请求后决定调用search_agents传入查询词。MCP Server 收到参数后去本地的 Agent 注册表中搜索。注册表返回结构化结果。MCP Server 把结果转成 MCP 协议要求的格式返回给客户端。这里最核心的部分是“Agent 注册表”。它可以是一个 JSON 文件适合初期演示。SQLite 数据库适合中小规模。一个内部 API适合企业级动态注册。向量数据库适合做语义搜索。从最小实现角度我们先用 JSON 文件做数据源后面可以替换成数据库。4.2 Agent 元数据应该包含什么所谓“搜索 Agent”搜索的实际上是 Agent 的元数据而不是 Agent 的运行时数据。一条合理的 Agent 记录建议包含这些字段字段含义示例id唯一标识agent-cs-support-v1name展示名称客服助手description功能描述处理售前咨询和售后问题category分类customer-serviceendpoint调用地址https://agent.example.com/cscapabilities能力标签chat, ticket, refundauth_type鉴权类型none / api_key / oauth2health_status健康状态online / offlineprice调用价格free / paid这里有个设计重点搜索阶段不要返回敏感的鉴权信息。即使 Server 内部存储了 API Key返回给客户端时也应该去掉或者用 token 占位符替代。很多安全漏洞就是因为搜索接口把内部密钥也返回出去了。4.3 搜索方式最简单的是关键词匹配对 name、description、capabilities 等字段做子串匹配。但实际项目中更推荐使用“关键词过滤 相关性排序”。如果是企业内部使用可以先用 SQLite 的 FTS全文搜索或者直接LIKE查询。如果是开放生态可以考虑引入向量数据库做语义搜索。下面的示例先用 SQLite 做精确与模糊搜索逻辑清晰且容易替换。5. 完整示例代码实现现在开始写代码。我们的目标是最小可运行目录结构如下agent-search-mcp/ ├── server.py ├── agents.db # SQLite 数据库首次运行时自动创建 └── seed_data.py # 初始化演示数据5.1 初始化演示数据先创建一个seed_data.py用来初始化数据库写入几条示例 Agent。# seed_data.py import sqlite3 DB_PATH agents.db AGENTS [ { name: 客服助手, description: 负责售前咨询、售后问题处理支持退款流程, category: customer-service, endpoint: https://agent.example.com/customer-service, capabilities: chat,ticket,refund, auth_type: api_key, health_status: online, }, { name: 数据分析师, description: 帮助用户查询业务报表、生成数据摘要, category: data-analysis, endpoint: https://agent.example.com/data-analyst, capabilities: query,sql,report, auth_type: none, health_status: online, }, { name: 运维告警助手, description: 对接监控系统查询服务器状态和告警事件, category: devops, endpoint: https://agent.example.com/ops-alert, capabilities: monitor,alert,status, auth_type: oauth2, health_status: offline, }, ] def init_db() - None: conn sqlite3.connect(DB_PATH) conn.execute(DROP TABLE IF EXISTS agents) conn.execute( CREATE TABLE agents ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, description TEXT, category TEXT, endpoint TEXT, capabilities TEXT, auth_type TEXT, health_status TEXT ) ) for agent in AGENTS: conn.execute( INSERT INTO agents (name, description, category, endpoint, capabilities, auth_type, health_status) VALUES (:name, :description, :category, :endpoint, :capabilities, :auth_type, :health_status) , agent, ) conn.commit() conn.close() if __name__ __main__: init_db() print(seed data initialized)执行初始化python seed_data.py5.2 实现搜索逻辑接下来写独立的搜索函数后续在 MCP 工具中直接调用。这样可以保持 MCP 层和业务层分离。# agent_search.py import sqlite3 DB_PATH agents.db def search_agents(query: str, category: str | None None, health: str | None None) - list[dict]: conn sqlite3.connect(DB_PATH) conn.row_factory sqlite3.Row sql SELECT id, name, description, category, endpoint, capabilities, auth_type, health_status FROM agents WHERE (name LIKE ? OR description LIKE ? OR capabilities LIKE ?) params [f%{query}%, f%{query}%, f%{query}%] if category: sql AND category ? params.append(category) if health: sql AND health_status ? params.append(health) sql ORDER BY id DESC LIMIT 20 rows conn.execute(sql, params).fetchall() conn.close() return [dict(row) for row in rows]这里有几个细节值得注意使用LIKE做模糊搜索满足最小演示场景。支持 category 和 health 过滤方便客户端做精细查询。使用参数化查询避免 SQL 注入。结果限制 20 条防止返回数据量过大。5.3 实现 MCP Server现在写 MCP Server 本体。# server.py from typing import Any from mcp.server.fastmcp import FastMCP from agent_search import search_agents mcp FastMCP(agent-search) mcp.tool() def search_agents_tool(query: str, category: str | None None, health: str | None None) - list[dict[str, Any]]: 搜索可用的 AI Agent返回包含 name、description、endpoint 等信息的列表。 Args: query: 查询关键词例如“客服”“数据分析”。 category: 按分类过滤可选值为 customer-service、data-analysis、devops。 health: 按健康状态过滤可选值为 online、offline。 results search_agents(query, category, health) return results if __name__ __main__: mcp.run()这段代码的逻辑很简单用FastMCP创建一个名为agent-search的 Server然后通过mcp.tool()注册一个search_agents_tool工具。MCP 客户端会自动发现这个工具并根据函数签名生成参数 schema。mcp.run()默认使用 stdio 传输方式适合本地客户端。如果需要远程暴露给多台机器可以改成 streamable HTTP 传输后面会提到。5.4 完整示例的注意事项上面的代码里函数名叫search_agents_tool但 MCP 客户端看到的是工具名search_agents_tool。如果你希望客户端看到的名称更简洁可以给mcp.tool()传 name 参数。mcp.tool(namesearch_agents) def search_agents_tool(query: str, category: str | None None, health: str | None None) - list[dict[str, Any]]: ...这个细节很常见但容易被忽略。很多文档示例直接拿函数名当工具名实际项目里还是应该显式指定一个稳定的工具名因为改名会导致客户端工具路由失效。6. 运行结果与效果验证代码写完后需要实际验证 Server 是否正常。验证分为两步先用 MCP Inspector 做协议层测试再接入真实客户端看端到端效果。6.1 用 MCP Inspector 验证启动 Servermcp inspector python server.py如果一切正常终端会显示Starting MCP inspector...然后浏览器会自动打开调试页面。在 Inspector 页面里你应该能看到以下内容一个新连接已经创建。agent-search这个 Server 已连接。工具列表里出现了search_agents或search_agents_tool。点开工具后界面会显示参数字段query、category、health。我们在 Inspector 中直接调用工具在 query 输入“客服”得到返回结果应该类似于[ { id: 1, name: 客服助手, description: 负责售前咨询、售后问题处理支持退款流程, category: customer-service, endpoint: https://agent.example.com/customer-service, capabilities: chat,ticket,refund, auth_type: api_key, health_status: online } ]如果能看到这段 JSON说明 MCP Server 的工具链路已经打通。6.2 配置到支持的客户端以 Dify 为例在“工具”配置中选择“添加 MCP 服务”传输方式选择 stdio然后填写启动命令。python /absolute/path/to/server.py注意Dify 在运行时启动 MCP Server 的目录可能和你的项目目录不同建议在命令中写绝对路径并且在 server.py 中不要依赖相对路径读取数据库。更稳妥的做法是提前把agents.db放在项目目录并在代码中通过环境变量指定路径。如果使用 Claude Desktop配置文件通常是claude_desktop_config.json添加一个 MCP Server 条目{ mcpServers: { agent-search: { command: python, args: [/absolute/path/to/server.py] } } }保存后重启客户端然后发送一条包含“帮我找个客服 Agent”的提示观察是否调用search_agents工具。6.3 如何判断结果是成功判断标准有三点客户端能列出工具说明 MCP Server 连接正常。调用工具能返回结构化 JSON说明搜索逻辑正常。Agent 模型能根据工具结果给出自然语言回答说明上下文传递正常。如果第 3 步失败问题通常不在 MCP Server而是提示词设计。模型没有收到足够强的指令就不会主动调用工具。7. 常见问题与排查思路MCP Server 的调试并不复杂但新手经常会在几个地方卡住。下面是常见问题列表。问题现象可能原因排查方式解决方案启动报错 ModuleNotFoundError虚拟环境未激活或依赖未安装检查pip list激活虚拟环境并重新安装依赖连接失败stdio 命令配置错误在终端直接运行启动命令修改为绝对路径检查 Python 环境工具列表不显示 search_agentsMCP Server 注册失败查看 Inspector 的日志输出确认mcp.tool()装饰器已生效检查代码缩进调用工具超时数据库查询慢或死锁在数据库循环查询外打印耗时优化索引限制返回条数返回结果为空查询词拼写或数据未初始化用 SQLite 客户端查看 agents 表重新执行python seed_data.py中文字段乱码客户端编码或终端编码问题检查 JSON 输出编码Python 3 默认 UTF-8确认终端为 UTF-8SQLite 数据库锁定多进程同时写操作查看错误日志生产环境改为数据库服务或开启 WAL 模式其中最常见的问题是路径问题。MCP 客户端启动服务器时工作目录可能和你的项目目录不一致导致代码里的相对路径找不到数据库。解决方法是统一使用环境变量或者配置项。import os DB_PATH os.getenv(AGENT_SEARCH_DB, agents.db)这样至少可以先用环境变量覆盖默认值避免在配置中到处改硬编码路径。8. 最佳实践与工程建议打通最小示例之后我们有必要把视野拉到生产环境看看 Agent 搜索 MCP Server 在工程化过程中应该注意什么。8.1 搜索能力分层搜索 Agent 不是简单的数据库查询。生产环境里我建议把搜索分成三层第一层是关键词搜索用于精确匹配名称、ID、精确标签。第二层是全文搜索或模糊匹配用于描述、能力标签。第三层是语义搜索用于用户用自然语言描述“需要一个自动处理退款问题的代理”这类场景。最小实现只需要第一层但架构上要预留后面的扩展点。推荐把search_agents函数的返回结构保持稳定内部实现可以随时替换。8.2 只读与调用分离这个 MCP Server 的核心是“搜索”所以它应该是只读的。不要在一个搜索工具里顺手接上“调用 Agent”的功能否则会带来安全和职责混乱问题。更合理的设计是search_agents负责发现 Agent返回元数据。invoke_agent另一个 MCP Server 或另一个工具负责真正调用 Agent。这样搜索服务可以开放给团队所有人使用而调用服务需要更严格的权限控制。8.3 不要暴露敏感元数据Agent 注册表里可能记录内部 endpoint、owner、token 等敏感信息。搜索接口返回给客户端时应该只暴露客户端需要的字段比如 name、description、category、capabilities、health_status。对于 endpoint如果是公网可访问的可以考虑返回如果是内网地址不应该直接暴露给外部客户端。更稳妥的做法是返回“调用方式指引”而不是直接给内网地址。8.4 缓存与限流如果 Agent 搜索服务要被多个客户端高频调用建议引入缓存。Agent 元数据变化频率低可以设置 30 秒到 5 分钟的缓存。而在 Python 代码里直接加一个简单的字典缓存就够用在中小规模场景。from functools import lru_cache lru_cache(maxsize128) def search_cached(query: str, category: str | None, health: str | None) - list[dict]: return search_agents(query, category, health)但要注意缓存会带来数据滞后。如果 Agent 下线或新增缓存过期时间决定了可用性。建议搜索接口返回结果时带上 server 侧的时间戳方便客户端判断数据的新鲜度。8.5 多进程与线程安全SQLite 在多线程同时写入时容易报错“database is locked”。搜索场景是只读操作通常问题不大但如果你的 Server 同时处理多个请求建议使用连接池。开启 WAL 模式。每次请求使用独立的数据库连接。开启 WAL 可以在初始化时执行PRAGMA journal_modeWAL;8.6 版本兼容与升级MCP 协议仍在快速演进mcpPython SDK 的接口也可能会变。在实际项目中建议固定依赖版本不要使用latest。升级 SDK 前查看 changelog。做好本地回归测试。如果你的 Server 暴露给多个客户端还要注意不同客户端对 MCP 协议的兼容程度。Dify 和 Claude Desktop 对工具参数的 schema 支持可能有细微差异写参数描述时要尽量详尽减少模型误填参数的概率。8.7 商业化与付费设计回到项目标题里的Buy My Agent。如果要做商业化可以考虑这几个方向免费提供搜索服务按 Agent 调用量向 Agent 提供方收费。提供高级搜索能力比如语义搜索、全局搜索、跨注册表搜索。为 Agent 提供商做“认证标识”提高搜索结果中的信任度。当然商业化不是本文的重点但它提醒了我们一件事MCP Server 不只是技术工具也可以是商业模式里的一环。把 Agent 搜索做成协议层服务意味着上游可以连接大量 Agent 提供方下游可以连接大量客户端这是传统“工具商店”做不到的。9. 总结与后续学习方向从项目标题出发我们聊透了 Agent 搜索 MCP Server 的技术栈MCP 协议负责“接口标准化”Agent 注册表负责“数据沉淀”搜索函数负责“能力输出”。这三者合在一起就是一个最小可用的 Agent 发现基础设施。你在实际操作时先不用追求把所有 Agent 都接进来。建议按这个路径推进跑通示例代码用 Inspector 验证工具调用。把数据源从 SQLite 换成团队内部已有的 Agent 管理平台 API。增加搜索字段过滤和排序逻辑。接入一个真实客户端比如 Dify 或自研 Agent 框架。再考虑语义搜索、缓存、监控和商业化功能。如果继续深入 MCP可以重点研究三块内容一是 MCP 的 Streamable HTTP 传输方式它决定了远程 Server 如何部署二是客户端侧 Agent 如何自动路由到正确的工具这涉及到 Tool Use 的提示工程三是 MCP 生态里和 Agent 发现相关的其他开放标准比如 Agent Card、Agent Directory 类方案它们和 MCP 搜索 Server 实际上是互补而非替代关系。最后提醒一句不要被工具表象迷惑。Buy My Agent MCP Server不只是“又一个 MCP Server”它背后代表的是 Agent 生态从“平台封闭发现”走向“协议开放发现”的一次尝试。这种方向不一定最终胜出但对做 Agent 工程的人来说值得多花一点时间去验证和投入。