Skip to main content
W

dsh-external-api

wilshi/dsh-external-api

Optional external HTTP API for DSH Desktop, off by default, bound to localhost unless widened, and authenticated with a Bearer token.

Install

dsh plugin --profile web add github:wilshi/dsh-external-api

README

DSH External API

DSH Desktop 的可选外部 HTTP API。服务默认关闭;启用后默认只监听 127.0.0.1(仅本机可访问),需要局域网/其他设备访问时把「监听地址」显式改成 0.0.0.0 或这台电脑的局域网 IPv4,并使用 Bearer Token 鉴权。

本 README 覆盖启用方式、请求与响应结构、SSE 重连、错误码和最小调用示例。

兼容性与安装

项值
DSH0.2.1-rc.5(Host protocol v4)
Cordis4.0.5
Node^22.19.0 或 ^24.0.0
插件形态Bundle(dsh.bundle.patch)+ Client inject(settings.section 槽位)
dsh plugin --profile web add dsh-external-api

安装后重启 DSH,在「设置 → API 服务」中启用。所有 @deepseek-ai/* 宿主包都声明为 peerDependencies:它们必须由 DSH 运行时提供,插件包自身不安装、也不会带出第二套 cordis 单例。

必需宿主服务(inject):sessionController、workspaceController、agentPresets、sessionSkillCatalog、webServer。运行时依赖仅 @deepseek-ai/dsh-atomic-write(原子写)与 @deepseek-ai/schemastery(配置 schema)。

快速开始

  1. 打开 DSH Desktop 的“设置 → API 服务”。
  2. 填写端口(默认 47831)并启用服务。
  3. 为调用方创建独立 Token;如需显式选择工作区或 Agent Preset,勾选对应资源授权,然后立即保存只显示一次的明文。
  4. 本机调用可直接复制状态卡片中的“本机访问 URL”;局域网设备将其中的 127.0.0.1 换成 DSH 主机的局域网 IPv4。

下面演示 DSH 主机本机访问,因此地址为 http://127.0.0.1:47831。局域网设备应把 127.0.0.1 替换为 DSH 主机的局域网 IPv4;不要使用只用于监听的 0.0.0.0。Token 已写入环境变量 DSH_API_TOKEN。

curl.exe http://127.0.0.1:47831/api/v1/capabilities `
  -H "Authorization: Bearer $env:DSH_API_TOKEN"

最省事的调用方式是创建临时会话并立即发起一次 Run:

$body = @{ input = '请概括当前项目的结构' } | ConvertTo-Json -Compress
Invoke-RestMethod `
  -Method Post `
  -Uri 'http://127.0.0.1:47831/api/v1/responses' `
  -Headers @{ Authorization = "Bearer $env:DSH_API_TOKEN" } `
  -ContentType 'application/json' `
  -Body $body

响应状态为 202,其中包含 session、run 和 eventsUrl。用返回的 Run ID 读取实时事件:

curl.exe -N http://127.0.0.1:47831/api/v1/runs/RUN_ID/events `
  -H "Authorization: Bearer $env:DSH_API_TOKEN"

API

除健康检查和 CORS 预检外,所有接口都要求 Authorization: Bearer <token>。

方法路径作用所需 Scope
GET / HEAD/api/v1/healthListener 健康检查无
GET/api/v1/capabilities能力、限制和当前 Token 权限capabilities:read
GET/api/v1/workspacesToken 可使用的工作区capabilities:read
GET/api/v1/agentsToken 可使用的 Agent Presetcapabilities:read
GET/api/v1/models?sessionId=...会话可用模型capabilities:read
GET/api/v1/skills?sessionId=...会话可用技能capabilities:read
GET/api/v1/sessions列出当前 Token 创建的会话sessions:read
POST/api/v1/sessions创建会话sessions:write
GET/api/v1/sessions/:id/messages获取脱敏后的消息历史sessions:read
POST/api/v1/sessions/:id/messages发起 Runruns:write
POST/api/v1/sessions/:id/runs发起 Run(语义等同上一项)runs:write
POST/api/v1/responses创建会话并发起 Runsessions:write、runs:write
GET/api/v1/runs/:id查询 Run 状态runs:read
GET/api/v1/runs/:id/events订阅 Run 的 SSE 事件runs:read
POST/api/v1/runs/:id/cancel取消 Runruns:write

创建会话时可选传入白名单中的 workspaceId 和 agentPreset:

{
  "workspaceId": "workspace-id",
  "agentPreset": "agent-preset-id"
}

发起 Run 的请求体:

{
  "input": "分析这个问题",
  "clientTimeZone": "Asia/Shanghai"
}

SSE 支持 Last-Event-ID 断线续传。事件类型包括 run.queued、run.started、run.cancelling、message.delta、message.completed、tool.started、tool.completed、run.completed、run.cancelled 和 run.failed。

浏览器的原生 EventSource 不能设置 Bearer Header,请改用 fetch 流。浏览器还必须位于服务允许的 Origin 白名单中;当前设置页尚未开放此配置,普通网页默认会被拒绝。下面代码只适用于已经由发行版或受控配置启用对应 Origin 的环境:

const response = await fetch(`${baseUrl}/api/v1/runs/${runId}/events`, {
  headers: { Authorization: `Bearer ${token}` },
})
if (!response.ok || !response.body) throw new Error(`HTTP ${response.status}`)

const reader = response.body.pipeThrough(new TextDecoderStream()).getReader()
for (;;) {
  const { value, done } = await reader.read()
  if (done) break
  console.log(value) // 正式客户端应按 SSE 帧解析,而不是假定一次读取就是一个事件
}

安全边界

  • Listener 默认只绑定 127.0.0.1,因此默认只有本机能访问;只有把配置项 host 显式设为 0.0.0.0(或某个局域网地址)才会对网络开放,此时启动日志会打印一条网络暴露告警。它不复用也不转发 DSH 主站的 /api 路由。
  • Token 明文只在创建时返回一次;持久化配置仅保存 SHA-256 摘要。
  • 每个 Token 只能访问自己创建的 Session、Run 和 SSE 流。
  • 工作区与 Agent Preset 默认均不允许调用方自行指定,需显式加入 Token 白名单;Token 白名单非空时,创建 Session 必须显式指定被允许的 workspaceId / agentPreset,省略即 403(避免落回一个不在白名单里的宿主默认值)。
  • Slash Command、任意内部 RPC、工具参数、工具结果正文、系统提示和推理内容均不会对外开放。
  • Host 必须与客户端实际访问的 IPv4 和端口一致;Origin、Fetch Metadata、请求体大小、请求速率、并发 Run 和 SSE 连接数也均有限制。
  • 活动 Run 默认上限为每 Token 10 个、全局 20 个;旧版精确的 2/4 默认组合会在启动时自动升级,其他自定义组合不变。
  • 设置管理接口只挂在 DSH 自身的随机回环端口,并校验同源浏览器请求;它用于防止网页跨站调用,不把同一系统账户下的恶意本机进程视为可隔离的安全边界。
  • 管理接口写入的配置保存在 $DSH_HOME/external-api/config-v1.json(目录 0700、文件 0600),与 Token 归属记录 ownership-v1.json 分开存放;加载器下发(cordis.patch.yml)的 config 作为基础层,管理页编辑覆盖其上。
  • 外部 API 是明文 HTTP。仅在受信任的专用网络中启用,并使用系统防火墙把入站来源限制到所需私网;不要把端口直接映射或暴露到公网。跨不受信任网络接入时,应使用 VPN 或受信任的 TLS 反向代理并限制来源网络。

Token 撤销会立即断开它的 SSE 连接、尝试取消活动 Run,并删除其会话归属记录。

错误格式

外部接口使用稳定的 JSON 错误结构,不回传内部异常或宿主错误详情:

{
  "error": {
    "code": "AUTH_INVALID",
    "message": "The bearer token is invalid.",
    "requestId": "..."
  }
}

客户端应以 HTTP 状态码和 error.code 作为程序判断依据。

Related plugins