CH 12 · 接入 MCP 生态
本章目标
dsh 自带的工具(读文件、跑命令、查网页)够你日常用了,但外部世界还有一大堆零散的工具——GitHub、数据库、记忆、浏览器、各种 SaaS——它们不会自己跑进你的 Agent 里。这一章把MCP 生态接进来:先讲清 MCP 是什么、dsh 为什么用"插件"来接入,然后动手把 Firecrawl 这个 MCP 服务器挂上,让模型能像调用原生工具一样调它的工具。
先搞懂:MCP 是什么
MCP(Model Context Protocol) 是一个开放协议,解决的是"AI 应用怎么连外部工具服务器"这个通用问题。你可以把 MCP 理解成工具世界的 USB-C:一个标准的接口,背后接什么设备都行。
MCP 生态里已经躺着一大批现成的 MCP 服务器(server):
| MCP 服务器 | 干什么 |
|---|---|
| 文件系统 | 读写字目录(暴露一个本地目录给 Agent) |
| GitHub | 建 issue、提 PR、查仓库 |
| 数据库 | 查询各类数据库 |
| 记忆 | 长期记忆存取(后面 CH 14 会再见到) |
| 浏览器 | 控制浏览器、抓网页 |
在 dsh 里接入 MCP 的方式,正是它一贯的风格——一个插件:@deepseek-ai/dsh-mcp-client。这个官方插件的职责很纯粹:连上你声明的每一台 MCP 服务器,把它们提供的工具注册进 ctx.tools(CH 11 说的那个工具注册表),于是模型眼里它们和原生工具没有区别。又一次印证了 CH 08 那句"一切皆插件"——MCP 接入也不例外。
几个先知道的要点:
- 工具命名是两层:先有一个 MCP 服务器(比如 Firecrawl),它下面挂着一批工具(
firecrawl_scrape抓网页、firecrawl_search搜网页、firecrawl_map列站点地图……)。接进来后,每个工具会以mcp__<服务器名>__<工具名>出现——如果服务器名取firecrawl,它的抓取工具就是mcp__firecrawl__firecrawl_scrape。这和 Claude Code、Codex 的命名形态相同。不同服务器叫同一个名字也能共存(各自带前缀)。 - 默认不启用任何服务器:插件在不在是一回事,接哪台服务器完全由你声明。没有配置,它就什么都不连。声明之后,服务器会在 dsh 启动时连上、工具注册进工具列表;至于哪一轮调哪个工具,由模型按当前任务自己挑——不是把所有工具都调一遍。
- 目前只桥接"工具":MCP 协议里除了"工具"(Tool,能调用的动作),还有两类能力——"资源"(Resource,只读的数据、文件)和"提示词模板"(Prompt)。dsh 的桥接插件现在只把"工具"接进来,资源和提示词模板暂时用不了。
- 很多服务器要鉴权:像 GitHub、Firecrawl 这类接入真实服务的 MCP 服务器,通常都要 API Key 或 token 才能用。密钥通过配置里的
headers(HTTP 方式)传进去,别硬编码进配置文件——后面配置段会展开。
动手:接第一个 MCP 服务器——Firecrawl
下面用 Firecrawl(一个真实的网页抓取 MCP 服务,Firecrawl 官网)带你走一遍。它的 MCP 服务器提供一批网页工具:firecrawl_scrape(抓单个网页)、firecrawl_search(搜索网页)、firecrawl_map(列站点地图)、firecrawl_crawl(爬整站)、firecrawl_extract(提取结构化字段)等。
第 1 步:确认 MCP 客户端插件就位
先确认 dsh-mcp-client 在不在。不用命令行,直接在 Web UI 里看插件列表:打开设置 → 插件,搜一下 mcp。下图是我这边的结果——搜索框输入 mcp 后,插件列表是空的("没有匹配的插件"),说明还没装:

列表里找不到它,就回命令行把它装成 web profile 的依赖:
dsh plugin --profile web add @deepseek-ai/dsh-mcp-client注意:这条命令只是把包装进 profile(dsh plugin list --profile web 能看到依赖),它不会自己跑起来——插件真正被加载要靠第 3 步在 cordis.patch.yml 里 insert 它并配好服务器。这里有个实测踩过的坑:如果只 insert 插件、不带服务器配置,dsh 启动会直接报 Cannot read properties of undefined (reading 'serverName'),因为 serverName 是必填项。
配置完成、重开 dsh 后,再回到设置 → 插件,就能看到 mcp-client 了,状态是"已启用"(下图就是装好后的样子,搜索框还是 mcp,插件列表 1 条、状态已启用):

第 2 步:拿到 Firecrawl 的 API Key
Firecrawl 需要鉴权。登录 Firecrawl 官网 注册并创建一个 API Key——官方用法是把它作为 Bearer 令牌发给 https://mcp.firecrawl.dev/v2/mcp。免费版每月有 1000 积分调用额度。
下图就是我创建好的页面:左侧能看到剩余积分,中间列出了默认密钥(fc- 开头、中间打码),右上角 + Create 可以新建:

拿到密钥后,先把它设成系统环境变量(下面第 3 步配置会引用它)。先说清楚一件事:环境变量不是写在某个文本文件里,它是 Windows 系统界面里统一维护的一份"名单",设置界面就是往这份名单里加一项。Windows 上用图形界面设置,不用敲命令:
- 按
Win键,输入"环境变量",打开编辑系统环境变量 - 点右下角环境变量按钮

- 在用户变量一栏点新建:变量名填
FIRECRAWL_API_KEY,变量值填fc-你的完整key

- 一路确定关掉窗口
注意:设置完要新开一个终端再启动 dsh——已开的窗口不会自动读到新设的环境变量。
第 3 步:在 profile 配置里声明 Firecrawl
MCP 服务器的配置写在 web profile 的补丁文件里(就是 CH 08 说的 cordis.patch.yml):
- Windows:
C:\Users\<你的用户名>\.dsh\profiles\web\cordis.patch.yml - macOS / Linux:
~/.dsh/profiles/web/cordis.patch.yml
往 insert 列表里加一台服务器,用官方推荐的 streamable-http 方式(连远程端点):
每个 insert 条目里
serverName是必填的(第 1 步那个启动报错就是因为它为空)——它就是工具名的命名空间,也决定了mcp__<这里>__工具长什么样。
Firecrawl 官方提供远程端点 https://mcp.firecrawl.dev/v2/mcp,用 Bearer 令牌鉴权:
- insert:
- id: mcp-firecrawl
name: '@deepseek-ai/dsh-mcp-client'
config:
serverName: firecrawl
transport: streamable-http
url: https://mcp.firecrawl.dev/v2/mcp
headers:
Authorization: !!js '`Bearer ${process.env.FIRECRAWL_API_KEY}`'密钥通过环境变量引用(process.env.FIRECRAWL_API_KEY),不直接写死在文件里(环境变量怎么设见第 2 步)——文件一提交到 Git 就可能泄露。以后想接其他 MCP 服务器,照这个格式再加一条 insert 就行。
几个常用字段说明:
| 字段 | 含义 |
|---|---|
serverName | 工具名的命名空间(mcp__<这里>__工具),1–32 位字母数字下划线,一个作用域内唯一 |
transport | stdio(本地程序)或 streamable-http(远程服务) |
command / args / env | stdio 方式的可执行文件、参数、额外环境变量 |
url / headers | HTTP 方式的端点地址与额外请求头(鉴权令牌就放这) |
toolCallTimeoutMs | 单次工具调用超时(默认 60 秒) |
reconnect | 断线自动重连策略(默认开启,500ms 起翻倍退避、上限 30s、连续失败 10 次放弃) |
编辑完保存,文件就长这样——新增的 insert 段已标出:
第 4 步:重启,让模型调用
重开 dsh,等它完成启动。Firecrawl 的工具不会有个专门的"工具列表页"给你看,最直接的确认方式就是让模型用一次:
- 在会话里发一句:
用 Firecrawl 抓一下 deepseek.com 这个网页的正文 - 看模型的回复和轨迹:连接成功的话,模型会调用
mcp__firecrawl__firecrawl_scrape,轨迹里出现一条 TOOL 行,右侧面板能看到它传的url参数和抓回的 markdown 结果


- 如果工具没进来,模型会明说"我这边没有这个抓取工具",或者干脆退回用内置的网页搜索——这两种都说明服务器没连上,回上一节排障
想省事?装两个社区插件
官方内置既没有"工具列表"页,也没有"逛插件"的入口,社区补齐了这两块,都只需要一条命令:
① 插件市场 dsh-market(987 star):装完设置里多出"插件市场",能按分类浏览、搜索、一键安装社区插件。市场里装的插件大多装完刷新页面即生效,不用重启 dsh:
dsh plugin --profile web add dshmarket
② MCP 可视化面板 DSH Skill & MCP Panel(108 star):装完设置里多出"MCP 管理",每台服务器的状态和工具数直接可见,增删改、启停都在界面里点,不用再手改 cordis.patch.yml。它不用敲命令——直接在①的插件市场里搜索 dsh-skill-mcp-panel 就能找到,一键安装,装完刷新页面即生效(个别 host 级插件会提示"待重启",按提示操作即可):

这两个插件恰好是本章开头那句话的注脚——一切皆插件:官方没做的界面能力,社区插件补上,装上就成了 dsh 的一部分。
插件怎么装、怎么管还有很多门道——命令行安装、bundle 自动挂载、全局与 Profile 的区别。这一章只是在 MCP 场景下开了个口,后面会专门有一章系统地讲插件安装,再讲到插件开发,一路接上场景实操。
常见问题
| 问题 | 怎么处理 |
|---|---|
| 接进来没看到工具? | 先看日志里有没有连接/发现错误;确认服务器本身能连(先用浏览器或 curl 直接访问端点看通不通);确认 serverName 没和其他服务器撞名;鉴权类服务器再查一下密钥有没有传对(401/403 多半是这问题) |
| Firecrawl 这类服务密钥放哪? | 通过配置里的 headers 传(HTTP 方式),启动前把密钥设成环境变量(第 2 步),别写死在 cordis.patch.yml 里——文件一提交到 Git 就可能泄露 |
| 服务器崩了会怎样? | 插件会自动重连(500ms 起翻倍退避),重连期间工具仍列出但调用会失败;连续失败 10 次后工具被移除,直到重载配置或重启。编辑配置会原地重载服务器连接,没变的名字保持不变 |
| 会不会太耗 token? | 每台服务器的工具描述和输入 schema 都会进入每次请求。接你真正用得到的,别囤一堆 |
这一章你学到了什么
能自己完成下面几条,就算过关:
- [ ] 能说清 MCP 是干什么的,以及 dsh 接入它的方式(一个插件
dsh-mcp-client) - [ ] 知道工具命名是两层:一个 MCP 服务器下挂多个工具,接进来后是
mcp__服务器名__工具名 - [ ] 知道鉴权类 MCP 服务器(如 Firecrawl)密钥怎么传、为什么不写死在配置文件里
- [ ] 能在
cordis.patch.yml里声明一台 MCP 服务器(stdio 或 streamable-http 至少会一种) - [ ] 能让模型实际调用一个 MCP 工具,并在轨迹里看到
mcp__开头的调用 - [ ] 服务器连不上或崩了时,知道去哪看错误、怎么排查
- [ ] 知道想省事可以装两个社区插件:dsh-market(插件市场)和 DSH Skill & MCP Panel(MCP 可视化)

