Skip to content
dsh.fish
Bundle

dsh-cordis-universal-adapter

Universal bridge adapter for DeepSeek Harness: consume external MCP servers & Agent Plugins 1.0, and expose DSH native tools back as an MCP server.

Source
helibeiqi
License
MIT
Updated
Updated 5 days ago

Readme

# dsh-cordis-universal-adapter

> 面向 DeepSeek Harness 的双向桥接插件:**消费**外部 MCP 服务器与 Agent Plugins 1.0 包,并把 DSH 原生工具**反向暴露**为标准 MCP 服务器。

[![CI](https://github.com/helibeiqi/dsh-cordis-universal-adapter/actions/workflows/ci.yml/badge.svg)](https://github.com/helibeiqi/dsh-cordis-universal-adapter/actions/workflows/ci.yml)
[![npm version](https://img.shields.io/npm/v/dsh-cordis-universal-adapter.svg)](https://www.npmjs.com/package/dsh-cordis-universal-adapter)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)

## 一句话描述

在 DSH(DeepSeek Harness)的 **Host 组合层** 上,把 MCP 生态(服务器、Agent Plugins 1.0 包)接入 `ctx.tools`,
同时把 `ctx.tools` 导出为 MCP 服务器,让同一批工具同时以 DSH 原生与 MCP 两种形态暴露。

```
外部 MCP 服务器 ──▶ McpClientBridge ──▶ ctx.tools(DSH 工具)
Agent Plugins 1.0 ─▶ PluginLoader ─────┘        │
                                                ▼
外部 MCP 客户端 ◀── McpServerBridge ◀── ctx.tools.schemas()
```

## 安装

三条安装命令(按场景选择):

```bash
# 从 GitHub 仓库安装
dsh plugin --profile web add github:helibeiqi/dsh-cordis-universal-adapter

# 从 npm 安装
dsh plugin --profile web add dsh-cordis-universal-adapter

# 从本地目录安装(开发调试)
dsh plugin --profile web add "file:./dsh-cordis-universal-adapter"
```

## 平面说明:Host 组合层

本插件**不是** Agent(不参与对话主循环),也不是工具本身——它是一个 **Host 组合层的连接器**:

- **Inbound(正向)**:连接外部 MCP 服务器(stdio / Streamable HTTP),`listTools()` 后把每个 MCP 工具
  注册为 `ctx.tools` 中的 DSH 工具(命名 `mcp:<serverId>:<toolName>`);加载 Agent Plugins 1.0 包时,
  解析 `plugin.json` + `skills/*/SKILL.md` + `mcp.json`,把 Skill 描述注入系统提示词扩展点。
- **Outbound(反向)**:通过 `ctx.tools.schemas()` 枚举已注册工具,注册到 `McpServer`,
  经 `serveStdio`(或 HTTP)暴露给任意 MCP 客户端(命名 `dsh:<toolName>`)。
- **路由(可选)**:语义路由通过 `ctx.llm` 的带 tools 参数的 chat 接口(function calling)为任务排序工具,
  失败退化为 prompt-based 选择;**默认关闭**,开启后每次路由产生一次 LLM 调用。
- **生命周期**:所有连接由状态机(start / stop / update)管理,`update` 时"断开旧 → listTools → 注销旧 → 注册新",
  与 DSH HMR 协同;卸载时经 `ctx.effect` 全部回收。

## 支持的 DSH 版本区间

| 依赖 | 版本区间 |
|---|---|
| `@deepseek-ai/cordis` | `>=0.1.0`(peerDependency) |
| `@deepseek-ai/dsh-tools` | `>=0.1.0`(peerDependency) |
| Node.js | `>=22.19` |

> ⚠️ **Developer Preview 破坏性变更警告**:`@deepseek-ai/dsh-tools` 与 MCP 均处于 Developer Preview 阶段,
> 接口可能破坏性变更。本插件在 `0.1.x` 内锁定已验证的 API 形态(见 `docs/DESIGN.md` §14 真实 API 对齐修正与
> §15 真实运行时验证发现);依赖升级导致签名变化时,请关注 CHANGELOG 中的迁移说明。
>
> ℹ️ **已在 dsh 0.1.0-rc.6 实测通过**:插件挂载进配置树、真实连接 filesystem MCP 服务器(注册 14 个工具)、
> Agent 调用其工具返回真实结果、单服务器故障隔离。注意 dsh bundle 要求 `package.json` 中
> `dsh.bundle` 为**对象形式**(`{ "patch": "./cordis.patch.yml" }`),且 patch 文件为**顶层 YAML 数组**语法。

## 配置字段表

`cordis.patch.yml` 插件段(完整示例见仓库内 `cordis.patch.yml`):

| 字段 | 类型 | 默认值 | 必填 | 说明 |
|---|---|---|---|---|
| `servers[]` | array | `[]` | 否 | 外部 MCP 服务器列表 |
| `servers[].id` | string | — | 是 | 唯一标识(`[A-Za-z0-9_-]`),用于工具命名空间与状态跟踪 |
| `servers[].transport` | `'stdio' \| 'http'` | — | 是 | 传输类型 |
| `servers[].command` | string | — | stdio 时必填 | 子进程命令(如 `npx`) |
| `servers[].args` | string[] | `[]` | 否 | 子进程参数 |
| `servers[].env` | record | — | 否 | 附加环境变量(凭据不落日志) |
| `servers[].url` | string | — | http 时必填 | Streamable HTTP 端点 |
| `servers[].headers` | record | — | 否 | 静态请求头(支持 `${ENV_VAR}` 插值) |
| `servers[].requestTimeoutMs` | number | `30000` | 否 | callTool/listTools 超时 |
| `servers[].connectTimeoutMs` | number | `10000` | 否 | 连接握手超时 |
| `pluginDirs[]` | array | `[]` | 否 | Agent Plugins 1.0 包目录 |
| `export.enabled` | boolean | `false` | 否 | 是否反向导出 DSH 工具 |
| `export.transport` | `'stdio' \| 'http'` | `'stdio'` | 否 | 导出传输 |
| `export.name` | string | `'dsh-export'` | 否 | 导出服务器名 |
| `export.namespace` | string | `'dsh'` | 否 | Outbound 工具前缀 |
| `export.httpPort` | number | `0` | 否 | HTTP 端口(0=随机) |
| `export.tools` | string[] | — | 否 | 显式导出清单(仅当 `schemas()` 为空时生效的退化选项) |
| `router.enabled` | boolean | `false` | 否 | 语义路由开关(开启产生 LLM 开销) |
| `router.mode` | `'auto' \| 'tools' \| 'prompt'` | `'auto'` | 否 | `auto`=优先 tools 失败退 prompt |
| `router.maxTools` | number | `10` | 否 | 返回工具数上限 |
| `router.minScore` | number | `0` | 否 | 分数下限过滤 |
| `router.provider` / `router.model` | string | env `DSH_ROUTER_PROVIDER` / `DSH_ROUTER_MODEL` | 否 | 路由 LLM 路由 |
| `naming.conflictStrategy` | `'error' \| 'prefix'` | `'prefix'` | 否 | 工具名冲突策略 |
| `naming.prefixSeparator` | string | `':'` | 否 | 命名空间分隔符 |
| `schema.strict` | boolean | `false` | 否 | `true`=无法转换的 JSON Schema 拒绝注册;`false`=降级宽松校验 |
| `logging.level` | `'silent' \| 'error' \| 'warn' \| 'info' \| 'debug'` | `'info'` | 否 | 日志级别 |

## 端到端示例:加载社区 filesystem MCP 服务器

```yaml
# cordis.patch.yml
plugins:
  dsh-cordis-universal-adapter:
    servers:
      - id: filesystem
        transport: stdio
        command: npx
        args: ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
```

启动后,DSH 中将出现 `mcp:filesystem:read_directory`、`mcp:filesystem:write_file` 等工具,
Agent 可以直接调用:

```
用户:读取 /tmp 目录下有哪些文件
Agent → 调用 mcp:filesystem:read_directory({ path: "/tmp" }) → 返回目录列表
```

```bash
dsh --profile web --dump-config   # 确认插件正确挂载进配置树
```

## 反向导出示例:把 DSH 原生工具导出为 MCP 服务器

```yaml
plugins:
  dsh-cordis-universal-adapter:
    export:
      enabled: true
      transport: stdio
      namespace: dsh
```

DSH 中所有已注册工具(`ctx.tools.schemas()`)将以 `dsh:<toolName>` 暴露。任意 MCP 客户端
(Claude Desktop、其他 Harness、`@modelcontextprotocol/inspector`)连接该 stdio 端点后即可调用:

```bash
# 在 DSH 进程内加载本插件(export.enabled=true),然后在外部:
npx @modelcontextprotocol/inspector   # 选择 stdio 模式连接 DSH 进程
```

独立调试可用仓库自带脚本(不依赖 DSH 运行时,演示转换链路):

```bash
npx tsx scripts/export-mcp.ts   # 启动 stdio 演示服务器(dsh:echo / dsh:add / dsh:fail)
```

## 开发调试

```bash
npm install
npm run typecheck   # tsc --noEmit(含 tests/scripts)
npm run lint        # ESLint(零警告)
npm run test        # Vitest(核心模块覆盖率 ≥ 80%)
npm run build       # 产出 lib/
npm pack --dry-run  # 检查 tarball 只含 lib/ + README + LICENSE
```

调试要点:

- **日志脱敏**:`env` / `headers` / URL 凭据永不写入日志;`Authorization` 用 `${ENV_VAR}` 插值。
- **状态查看**:监听 `universal-adapter/status` 事件(`ctx.on`)可跟踪每个 server 的连接状态机。
- **单服务器故障隔离**:一个外部 MCP 服务器连接失败只影响自身(状态 `error`),不阻断其他服务器与导出。
- **HMR**:插件 `apply` 重跑时旧 `ctx.effect` cleanup 自动执行;配置热更优先走 `update()`。

## 已知限制

1. **JSON Schema → DSH DSL 仅支持常用子集**:`$ref` / 循环引用 / 复杂 `oneOf` 降级为宽松校验
   (`schema.strict: false` 时工具仍注册,入参不校验)。
2. **Streamable HTTP 认证**:仅支持静态头(Bearer token),OAuth 动态流程不在 0.1 范围。
3. **反向导出返回值**:DSH 工具返回值必须是 JSON 可序列化值;二进制 / 流式输出不支持。
4. **路由开销**:`router.enabled: false` 时零 LLM 开销;开启后每次路由一次 LLM 调用,且不缓存。
5. **跨 server 工具名唯一性**:依赖 `serverId` 前缀保证;`serverId` 冲突会导致注册报错
   (按 `naming.conflictStrategy` 处理)。
6. **不实现沙箱**:外部 MCP 服务器的隔离依赖其宿主进程边界(stdio 子进程 / 远程 HTTP 服务)。

## GitHub 仓库发布步骤

1. 推送公开 GitHub 仓库(helibeiqi/dsh-cordis-universal-adapter)
2. 添加 topic:`dsh-plugin`、`deepseek-harness`、`agent-plugin`、`mcp`、`cordis`
3. `npm login && npm publish`
4. 在 DSH 社区 Discussions 宣布发布

## License

[MIT](LICENSE) © dsh-cordis-universal-adapter contributors

Install

dsh plugin --profile web add github:helibeiqi/dsh-cordis-universal-adapter

Profile: web

  • This package builds from source on install. pnpm will ask you to allow its build script — that is permission to run the package’s code on your machine, outside the agent sandbox. Only allow sources you trust.
  • This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.
Source