md-studio|可自定义工作台插件
通用化工作台:items(待办/笔记/任意条目)为示例领域,证明「工具面(AI 对话)与
页面 API 双通道同源」跑通。业务逻辑封装在 Workbench 类,工具 execute 与页面 mutate
都调 wb.run → 一份逻辑、三处调用。dsh 插件形态,可上架 npm。
三件套
| Workbench 类 | 业务核心 + store.json 原子写 + 审计;run(op, args, actor) 统一分发 |
| TOOLS 数组 | 声明式工具定义(3 个示例),循环注册进 ctx.tools |
| webServer 路由 | /workbench 页面 + /api/workbench state/mutate API |
能力(3 个示例工具)
| wb_create_item | 创建条目(title/content/tags/done) |
| wb_list_items | 列出条目(按关键词/标签/完成态过滤) |
| wb_get_item | 获取单个条目详情 |
数据落 $DSH_HOME/md-studio/store.json(可用 dataDir 配置覆盖),JSON 明文、原子写、
可审计。对话里登记的数据立刻出现在工作台页面,反之亦然。
加载(开发)
# 隔离 home + 临时端口(避免污染生产 dsh)
$env:DSH_HOME = '<临时隔离目录>\home'
dsh web --patch ./cordis.yml --host 127.0.0.1 --port 3199
启动后:
验证双通道同源
- 在 AI 对话里说「创建一个条目,标题:测试」→ 工具
wb_create_item 被调用
- 打开 /workbench 页面 → 该条目已出现在列表(3s 轮询)
- 在页面勾选完成 → 对话里问「列出条目」→ 该条目已是完成态
远程 MCP(零代码)
在 profile 的 cordis.patch.yml 声明 @deepseek-ai/dsh-mcp-client 实例,远程工具自动
注册进 ctx.tools,AI 对话与工作台均可调用:
- insert:
- id: mcp-remote-a
name: '@deepseek-ai/dsh-mcp-client'
config:
transport: 'streamable-http'
serverName: 'my-remote'
url: 'https://mcp.example.com/sse'
toolCallTimeoutMs: 30000
failOnStartupError: false
被外部 agent 调用
工作台 API(/api/workbench)是普通 HTTP,任何能发 HTTP 的 agent 可直连(路径 A,零
MCP,用调用方自己的 token)。需要 MCP 标准接入时,另写一个 dsh 插件用
@modelcontextprotocol/sdk 暴露 stdio/sse server(路径 B),不写在本插件里。
发布
dsh plugin --profile web add md-studio
dsh plugin --profile web add <本仓库路径>
自定义
本骨架用通用 items 示范。替换为你的领域时:
- 改领域模型(Item → 你的实体类型)
- 改 Workbench 类的方法 +
run 的 ops 映射
- 改 TOOLS 数组(加工具只改这里)
- 改 workbench.html 的 UI
三件套同源结构不变——工具与页面始终共用 wb.run。