whale_craft
Verifiedwhale_craft · v0.1.2 · MIT · Web UI
DSH 原生 Minecraft Agent 插件:每会话独立机器人 + mc_* / mc_kit_* / mc_admin_* 工具 + 单对话看门狗 + 浏览器 UI + 工作区 .whale-craft 记忆
Install
dsh plugin add whale_craft Confirm the layer applied with dsh --profile default --dump-config — see the install guide.
Source
Tags
Creators
Readme
Whale Craft
English ↓ · 中文 ·
让 AI Agent 真的进 Minecraft 里玩 —— 一个 DSH(DeepSeek Harness)原生插件:
把一台无头 Minecraft 机器人(mineflayer)跑在 DSH 进程里,给模型一套 mc_* 工具去走路、挖建、说话、
看图、记事,并在"值得你注意"的时候把它叫醒。
- 🎮 每会话一个独立机器人:不同对话可以连不同服务器、用不同账号,互不干扰
- 👀 能看世界:字符地形图(省 token、坐标精确)与真图像(
mc_map{format:"image"})双通道 - 🔔 单脑看门狗:事件只走
mc_watch一条通道 —— 空闲时唤醒、生成中插话(提示词注入,不模拟用户发言)。 玩家说话不论走签名聊天、未签名聊天,还是被服务端塞进 system 位置都认得出来 - 🧠 长期记忆:
<工作区>/.whale-craft/文档树,索引由 AI 维护,会话开始时自动带进上下文 - 🖥️ 自带浏览器 UI:状态条(显示连的哪个服)+「强制停止」+「MC设置」(账户 / 指令白名单 / 提示词)
- 🔒 密码不进模型上下文:凭据只写宿主凭据库;账户在「MC设置」里维护
- 📢 版本硬提示词:随插件版本发布的固定提示("本版本哪些工具还不成熟、怎么把文件给用户看"), 不可编辑、也不用配 —— 在「MC设置 → 提示词」里可以展开看原文
使用
- 创建新对话,选中「MC模式」。
- 选中或新建一个工作区(记忆与提示词都放在它的
.whale-craft/里)。 - 如有必要,进入「MC设置」修改玩家名称,或使用第三方皮肤站登录。
- 对你的 AI 说「进 xx 服务器」。
- 在对话窗口下命令,或直接在游戏里聊天。
想让 AI 进局域网房间?直接说"找个局域网服务器"——它用
mc_lan听广播 + 扫本机网段, 拿到地址后用mc_connect进去(对方要先在游戏里「对局域网开放」)。
🔴 必须选工作区:每个会话都要在工作区里跑 ——
.whale-craft/(记忆 + 提示词)就建在那儿。 插件只在两个时刻去备好它:首次进入 MC 模式会话、或点开「MC设置」(不会在你没玩 MC 的普通会话里乱建目录)。 没有选中工作区的会话会被拒绝:不进入 MC 模式(没有按钮、没有隔离、没有专属提示词), 「MC设置」的接口也一律拒绝并说明原因。
要求
| 项 | 要求 |
|---|---|
| DSH | 已发布在 npm(@deepseek-ai/dsh);本插件只用公开契约(dsh.bundle.patch + exports["./client"]) |
| Node | ≥ 22(跟 DSH 一致) |
| Minecraft 机器人 | mineflayer,插件的直接依赖 —— 跟着一起装好,不用你动手 |
| 可选 | sharp(SVG→PNG 光栅化)—— 装不上只影响 mc_kit_image 的渲染,其它功能照常 |
安装
对你的 AI 说:
帮我安装插件 https://github.com/yzi1b/whale-craft
手动安装
whale_craft 是标准 DSH 插件:包自带 cordis.patch.yml(package.json 里声明了 dsh.bundle.patch),
只要把包名列进 profile 的 dsh.profile.bundles 即生效,不需要手改 profile 的补丁文件。
# 从 GitHub 装(npm 上的包名是 whale_craft,仓库名是 whale-craft)
dsh plugin --profile web add github:yzi1b/whale-craft
dsh plugin --profile web add whale_craft # 发布到 npm 之后
# 或从本地目录装
dsh plugin --profile web add link:/path/to/whale-craft
这条命令把包装进 profile,并把 whale_craft 加进 dsh.profile.bundles。
然后重启 DSH(服务端插件不热重载;浏览器端 bundle 是热重载的)。
落盘位置
| 东西 | 位置 |
|---|---|
| 全局配置 | $DSH_HOME/whale_craft/config.json |
| 账户元数据 | $DSH_HOME/whale_craft/accounts.json |
| 插件日志 | $DSH_HOME/whale_craft/logs/whale-craft.log(可用 MC_LOG 覆盖) |
| 会话锁(连服期间) | $DSH_HOME/whale_craft/.instance.<会话>.json |
| 记忆 / 提示词 | <会话工作区>/.whale-craft/:README.md(AI 维护的总索引)+ RULES.md(行事准则)+ 任意文档/图片 |
| 出图与发布 | <会话工作区>/.whale-craft/.out/(不对外)· <会话工作区>/.whale-craft/.express/(可访问,见下) |
记忆是按会话工作区的,与插件装在哪、DSH 装在哪都无关。
.whale-craft/里的东西只读写文件,不执行任何东西。
配置
「MC设置」入口有两个,按会话状态互斥(任何时刻只出现一个):新会话页上贴在模式芯片的右边;
已有会话时落在对话标题条的操作区。点开就是账户 / 指令白名单 / 提示词 / 文件分享四个标签页。
配置落在 $DSH_HOME/whale_craft/config.json,改完立即生效。
非 MC 模式下的 AI 可以用 mc_admin_config 工具改这些键(MC 模式会话看不见、也调不动它):
| 键 | 含义 | 默认 |
|---|---|---|
commandWhitelist |
mc_command 放行的服务器指令。支持精确名 "tp"、正则 "/^gi.+/"、"*" 全放行 |
tp/give/time/… |
allowAllCommands |
指令白名单页那个总开关 | false |
mcModePresets |
哪些 preset 算"MC 模式"(权限隔离的判据) | ["minecraft","whale_craft"] |
mcMode.allowOtherTools |
MC 模式白名单里额外放行的其它工具(默认只给 mc_* / mc_kit_* / 文件工具 / present) |
[] |
mcMode.hideAdminTools |
是否把 mc_admin_* 也放进白名单(默认隐藏,另有 guard 硬拒) |
true |
injectWhaleCraftAgentsMd |
是否把 .whale-craft/RULES.md(行事准则)注入 MC 模式会话 |
true |
injectWorkspaceAgentsMd |
是否额外注入工作区根上的 AGENTS.md |
false |
rulesFollowVersion |
「提示词」页的「随版本更新」:插件版本一变,就用新版本默认准则替换 .whale-craft/RULES.md |
true |
expressMode |
文件分享:「文件分享」页选的模式:off 关闭 / online 在线 |
"off" |
expressBase |
在线模式的 base(你访问这台 DSH 的地址,可带路径前缀) | "" |
memoryDir |
记忆根目录(null = 用会话工作区的 .whale-craft/) |
null |
ensureMcPreset |
启动时若 mcModePresets 里一个 preset 都不存在,就复制官方 minimal 建一个「MC模式」(已存在则绝不动) |
true |
账户与凭据
「MC设置 → 账户」支持三种类型,新建/编辑各是独立界面:
| 类型 | 登录方式 | 说明 |
|---|---|---|
| 离线 | 无 | 名字即身份;可自定义 UUID(留空按 OfflinePlayer:<名字> 派生) |
| 第三方(皮肤站) | Yggdrasil 外置登录 | 先填认证服务器(已缓存的服务器是可点选、可 × 删除的标签),再填账号密码;服务器名字留空就用域名 |
| Mojang 官方(微软账号) | —— | 未实现 |
列表每行是类型气泡 + 游戏 ID(皮肤站账户登录成功后回写的档案名),下面一行小灰字是
你输入的账号(服务器名) —— 输入的是邮箱、游戏里叫角色名,两者不一样时都看得见。
🔒 边界:密码/token 只写进宿主凭据服务($DSH_HOME/.credentials.yaml,目录 owner-only);
密码和 token 不会出现在工具返回值、HTTP 响应或模型上下文里;凭据服务不可用时不会降级写明文。
工具(28 个,三层命名空间)
| 层 | 数量 | 工具 |
|---|---|---|
游戏内 mc_* |
24 | mc_status mc_connect mc_lan mc_accounts mc_capabilities mc_disconnect mc_stop mc_config mc_sessions mc_diag mc_say mc_events mc_watch mc_map mc_scan mc_entities mc_inventory mc_move mc_act mc_dig mc_build mc_give mc_sequence mc_command |
游戏外辅助 mc_kit_* |
3 | mc_kit_memory(记忆树:按服/主题定位、key 覆盖、搜索、删除、把文件与图片存进记忆)· mc_kit_image(SVG→PNG / 引图 / 拼网格)· mc_kit_express(把发布区里的文件按「文件分享」模式换成路径 / URL / 一句提示) |
管理 mc_admin_* |
1 | mc_admin_config(读写全局配置;MC 模式看不见、也调不动) |
几个设计点:
mc_give走协议级set_creative_slot(创造模式即可,不需要 OP);mc_sequence给"连串动作"(最多 64 步),比让模型写脚本稳;mc_command是最后手段(要 OP,且受白名单限制);mc_map的format:"image"会渲染一张真地形图:作为图片附件回给模型,同时落盘到.whale-craft/.out/;mc_lan找局域网房间:听224.0.2.60:4445的"对局域网开放"广播,再扫本机所在网段 (自己手写的 STATUS ping,拿版本 / MOTD / 人数)。🔴 只允许内网网段,公网直接拒;- 记忆是语义层不是文件别名:
topic/server自动定位路径、append带key覆盖同 key 那条、 跨文件search、删除、把任意文件(含图片)put进记忆再当图片附件读回来。
MC 模式与权限隔离
不止是权限隔离,有限的工具暴露可以让 AI 更专注于 MC 交互。
把会话的 preset 设成 mcModePresets 里的一员(默认 minecraft / whale_craft),该会话就会:
- 只看得见白名单里的工具(
tools.restrict({allow}),无条件生效):mc_*/mc_kit_*+ 文件工具(read/write/edit/glob/grep/read_image)present(宿主有就放行)+ 你在mcMode.allowOtherTools里额外点名的。 宿主的pwsh/subagent/workflow/serve_*之类一个都看不见。
- 文件工具被关进记忆文件夹:它们的路径由全局
guard硬限在<工作区>/.whale-craft/内 (不给路径也算越界 = 拒绝;.dsh凭据、secrets/、行事准则另有硬拒)。 - 管理工具看不见也调不动(白名单 +
guard双保险)。 - 收到几条插件提示行(在对话里看得见、可折叠,不是用户发言):见下一节。
- 系统提示词 = preset 自己的 persona(宿主按 preset 自动注入,插件不插手)。
提示词是怎么进去的
本插件不往系统提示词里塞任何东西(那样既冗余、又会被 preset 的 persona 压制)。
注入只有一条通道 —— 学 DSH 原生注入 AGENTS.md 的做法,把内容当插件提示行投进会话:
| 顺序 | 内容 | 开关 |
|---|---|---|
| 1 | 工作区根上的 AGENTS.md(DSH 原生那份文件) |
injectWorkspaceAgentsMd(默认关) |
| 2 | .whale-craft/RULES.md:本模式的行事准则(称呼 / 记忆 / 看门狗 / 登服 / 聊天 / 硬规矩) |
injectWhaleCraftAgentsMd(默认开) |
| 3 | 版本硬提示词:硬编码、随插件版本发布,说明"本版本哪些工具还不成熟、优先用什么、怎么把文件给用户看" | 无开关(版本的一部分) |
| 4 | 记忆总索引:.whale-craft/README.md 的正文 + 一份自动目录树 |
无开关 |
- 每条都写明出自哪个文件(首行
Instructions from: …),在对话里是可折叠的一行提示; - 为什么行事准则叫
RULES.md而不是AGENTS.md:DSH 会把AGENTS.md/CLAUDE.md当"工作区指令"自动注入 —— 任何会话只要读过/写过.whale-craft/下的文件,宿主就会把那份注入该会话(包括非 MC 会话), 而且不受本插件的开关控制。改成不在候选名单里的名字,注入就只剩我们这一条、且只对 MC 模式生效。 老工作区里若已有.whale-craft/AGENTS.md,插件会自动搬进RULES.md并把老文件改名备份 (AGENTS.md.bak-<时间>)。 - 行事准则只有你能改:AI 不能读写它(工具与记忆工具两条路都挡),要改就在「MC设置 → 提示词」里编辑, 那里也能一键恢复默认。
- 「随版本更新」(默认开):插件升级后,用新版本的默认准则替换当前内容(会覆盖你的修改);
判定靠记忆目录里的
.rules-version标记。想长期维持自己那份就把它关掉 —— 关掉后插件永不动它, 且关着期间不会"攒着":以后再打开也不会突然覆盖。
把文件给用户看(发布区 + 「文件分享」开关)
让 AI「画了图给你看」这件事,插件自带一条最小通道:目录即白名单,不依赖任何外部图床/文件服务。 分享方式由你在「MC设置 → 文件分享」里选(默认关闭)。
| 目录 | 谁能拿到 | 用途 |
|---|---|---|
<工作区>/.whale-craft/.out/ |
谁都拿不到 | 默认输出(草稿、中间产物) |
<工作区>/.whale-craft/.express/ |
取决于分享模式 | 发布区:要给你看的图/文件(支持子目录) |
两种模式(expressMode):
| 模式 | mc_kit_express 返回什么 |
那条访问服务 |
|---|---|---|
| 关闭(默认) | 恒回一句「文件分享已关闭,请告知用户文件绝对路径,让用户自行打开」——AI 把文件的绝对路径给你,你自己打开 | 不开(访问即 404) |
| 在线 | base + /api/whale-craft/express/<工作区 uuid>/<相对路径> 的完整 URL(图片能直接在对话里内联显示) |
只在这个模式开 |
在线模式要填 base = 你访问这台 DSH 用的地址(如 https://dsh.example.com,可带路径前缀);
设置页有「获取当前」,也可以直接切到在线 —— base 为空时会自动用当前访问地址填上。
(精度:浏览器把自己正在用的 location.origin 报给服务端 → 否则看 Origin 头 → 同源 Referer
→ X-Forwarded-Proto + Host → Host。注意 location.origin 不含路径,所以反代额外加的
路径前缀得你自己补 —— DSH 本身没有"挂载前缀"概念。)
两种模式都只认发布区:文件得先放进 .express/ 或其子目录(出图时把 out 写成那里,
或用 mc_kit_memory {action:"put"} 复制过去),再让 AI 调 mc_kit_express 取那一行。
- 服务端地址:
GET|HEAD /api/whale-craft/express/<工作区 uuid>/<剩余路径>(自己的顶层前缀路由, 自带同一道信任栅栏)。uuid 是 DSH 工作区注册表里那个稳定 id —— 不同父目录下的同名工作区不会撞, 目录改名链接也不失效;查不到对应工作区就 404(不退回目录名)。 - 安全:只用纯文件名逐段拼接(
..、.、空段、段内分隔符、盘符、~一律拒),拼完再realpath复查 "真实路径仍在发布区里" ⇒ 路径穿越与符号链接都出不去;不列目录;单文件上限 32 MB; 所有扩展名放行,只给 svg/html 这类"被当文档打开会执行脚本"的加一个Content-Security-Policy: sandbox头。 - 设置页还有 「清除分享数据」:与模式无关、随时可点(二次确认后删掉当前工作区
.express/里的 所有文件,目录本身重建)。 - ⚠️ 前端渲染只认绝对 http(s) 图片地址 ⇒ 只有在线模式的 URL 能内联显示;关闭模式本来就是"给你路径自己开"。
「MC模式」preset 会自己长出来
第一次装好没有「MC模式」? 插件会自己建一个:启动时发现 mcModePresets(默认 minecraft / whale_craft)
里一个都不存在,就调用 DSH 官方接口 agentPresets.copy('minimal', 'minecraft', 'MC模式')
—— 整目录复制官方极简模式(DSH 的 authoring 只允许这样建),然后:
- persona 换成一句:"你在一台真实的 Minecraft Java 版服务器里扮演一名玩家:你的"身体"是一台无头机器人,
能观察世界、移动、挖掘和建造。"(官方
minimal那句"helpful software engineer assistant"、以及它的complete: true/includeRuntimeContext: false都会被去掉 —— 后者会压掉所有其它提示段); - 关掉持久 shell(本模式没有 shell,别让模型看见
pwsh); - 补齐本模式需要的工具组:
tool-fs(文件工具)·tool-jobs(后台任务控制器,看门狗要挂 job)·present(显式文件交付)—— 官方minimal里一个都没有。🔴 加之前会先探"这个部署里到底有没有那个包" (看随附 preset 有没有人引用它),探不到就绝不加,免得把 preset 弄挂。 - 已经有一个就绝不动它;不想要这个行为就把
ensureMcPreset关掉。 - 每次启动还会自检那个自建的 preset(插件升级 / DSH 升级后它可能过期):显示名/简介/排序不对 → 只修显示文本;
组成还是"我们当初复制的那份"而官方源变了(或自建规格变了)→ 重新复制一遍(旧目录先备份成
<id>.bak-<时间>)。只要你动过组成,就一律不碰 —— 它靠一个.whale-craft.json自建标记判断 "这份是不是我建的、有没有被改过"。
安全边界
- HTTP 接口(
/api/mc/*:状态、强制停止、账户、配置、提示词、发布区文件)有信任栅栏: 非回环且不在webRuntime.trustedHosts的 Host 一律 403;Sec-Fetch-Site: cross-site403;外来 Origin 403。 - AI 拿不到密码(见上)。
- AI 不能改行事准则,也不能用文件工具或记忆工具读写它。
mc_command默认只放行一份白名单,且需要 OP;allowAllCommands才全放开(自己负责)。- 归档保护:归档一个正在玩 MC 的会话时,先踢下线 + 关看门狗 + 清后台任务,再放行归档。 它接替了宿主的一个内部方法(不是公开扩展点),DSH 升级后可能需要跟着调整。
- 不碰别人的建筑:这是给 Agent 的准则,不是技术限制 —— 请在自己的服 / 授权范围内玩。
开发与自检
node tools/check-core.mjs # 全树语法 + 动态 import + 私有字段一致性(改 core.mjs 必跑)
node selfcheck.mjs # 617 条离线断言(假 ctx,不需要 MC 服务器、不连网)
# 起一个隔离 DSH 实例验证"整树加载"(需要一份 DSH checkout):
DSH_ROOT=/path/to/deepseek-harness node tools/isolate.mjs start
selfcheck.mjs 覆盖:工具面与参数、每会话实例隔离、超时/中断、放置判据(与 minecraft-data 真值表比对)、
看门狗唤醒投递与 job 结算、未签名/系统位置聊天的识别、记忆树读写与路径穿越防护、发布区的防穿透与真路由、
「文件分享」两种模式与 base 推导(含反代 Referer 一档)、账户库与凭据隔离、配置校验、
提示词注入去重与版本提示、preset 自检与重建、强制停止的四步顺序、
依赖面(含"vec3 与 mineflayer 必须是同一份"这类运行时断言),以及客户端 bundle 的静态检查。
CI 跑的就是这两条(.github/workflows/ci.yml):ubuntu(Node 22 / 24)+ windows(Node 22);
另有一个「打包产物」job,npm pack 之后核对 tarball 里该有的文件都在、且没混进 node_modules / 日志 / 账户。
发布走 tag(.github/workflows/release.yml):git tag v0.1.1 && git push --tags →
先跑上面两条 + 校验 tag 与 package.json 版本一致,再 npm pack 并把 tarball 挂到 GitHub Release;
仓库里配了 NPM_TOKEN secret 的话顺带发 npm(没配就只发 Release,不会失败)。
npm publish 前还会自动跑一遍这两条(prepublishOnly)—— 坏树发不出去。
已知限制
- 微软正版登录未实现(只有离线 / Yggdrasil 皮肤站)。
- 文件分享默认是关的(
expressMode: "off"):AI 画了图只会把绝对路径给你,要让它直接在对话里显示, 得在「MC设置 → 文件分享」里切到在线并填好base。前端只认绝对 http(s) 图片地址,所以关闭模式下的 本地路径不会内联成图(这是设计如此,不是 bug)。 - 在线模式的
base不做连通性自检:填错了只有你自己能发现(AI 拿到的 URL 打不开)。 - 🔴 行事准则为什么叫
RULES.md(见上):AGENTS.md会被 DSH 当工作区指令自动注入到任何碰过该目录的会话, 与 MC 模式无关 —— 所以这个名字是刻意的。 - 工具描述与文档目前是中文。
- 能连的 MC 版本取决于依赖里的
mineflayer;想连官方还没支持的新版本,可以自行替换 profile 里的那一份。 - 归档保护依赖宿主内部方法,DSH 升级后可能需要跟进。
AI 使用
本项目代码由 AI 生成,可能存在未知风险,请谨慎使用。
- 工具:DeepSeek Harness
- 模型:DeepSeek V4 Flash
许可
MIT(见 LICENSE)。第三方组件与许可见 THIRD_PARTY_NOTICES.md。
English
Whale Craft is a native DSH (DeepSeek Harness) plugin that runs a headless Minecraft bot (mineflayer) inside the harness process, so an agent can actually play: walk, mine, build, chat, read the world and keep notes — and wake itself up when something worth noticing happens.
- One bot per conversation — different chats can play on different servers with different accounts.
- It can see — exact ASCII terrain maps (cheap in tokens) and real rendered images.
- A single-channel watchdog — events reach the model through one tool (
mc_watch) only: it wakes the agent when idle and injects a note mid-generation when busy. It never fakes a user message. Player chat is recognised whether the server sends it signed, unsigned, or in the system slot. - Long-term memory — a plain document tree under
<workspace>/.whale-craft/, indexed by the agent and injected as a plugin notice when the session starts. - A per-release built-in prompt — a hard-coded, non-editable note that ships with each version ("which tools are still immature, how to hand files to the user").
- File sharing switch — per-workspace publish area (
.whale-craft/.express/, "the directory is the allow-list"), two modes: off (default — the agent just hands you an absolute path) or online (the agent hands back a full URL built from yourbase, and images render inline in the chat). The HTTP route that serves those files exists only in online mode. - Passwords never reach the model — credentials live in the host credential store; accounts are managed from the in-app MC Settings dialog.
- Offline regression suite — 617 assertions, no Minecraft server required.
Install
The easy way: tell your agent "install the plugin from https://github.com/yzi1b/whale-craft".
Or manually:
# from GitHub (or npm, once published — package name is whale_craft)
dsh plugin --profile web add github:yzi1b/whale-craft
dsh plugin --profile web add whale_craft
# or from a local checkout
dsh plugin --profile web add link:/path/to/whale-craft
# then restart DSH (host plugins are not hot-reloaded; the browser bundle is)
This installs the package and appends whale_craft to dsh.profile.bundles.
mineflayer ships as a regular dependency — you do not need to install it yourself.
Use
- Start a new conversation and pick the MC mode preset.
- Pick or create a workspace — memory and the prompt live in its
.whale-craft/. - Optionally set the player name in MC Settings, or sign in with a third-party (Yggdrasil) account.
- Tell your agent which server to join.
- Give orders in the chat, or talk to the bot directly in game.
Where things live
| What | Where |
|---|---|
| Config · accounts · logs · lock | $DSH_HOME/whale_craft/ |
| Memory · prompt · output · published files | <workspace>/.whale-craft/ (README.md · RULES.md · .out/ · .express/) |
Passwords and tokens go to the host credential store only — they never show up in tool output, HTTP responses, or the model context.
Verify offline
node tools/check-core.mjs && node selfcheck.mjs # 617 assertions, no MC server needed
CI runs exactly this on Linux (Node 22 and 24) and Windows (Node 22), and packs the tarball on every push.
Push a v* tag to get a GitHub Release with the tarball (and an npm publish too, if you configure NPM_TOKEN).
MIT licensed. Third-party notices in THIRD_PARTY_NOTICES.md.