关于 Dwarf Fortress (DFHack)
dfhack-mcp 将运行中的 Dwarf Fortress 堡垒状态与游戏资料提供给 AI Agent,作为观察和预警工具,而非自动驾驶。默认只读,改变堡垒的工具需显式启用,并通过预览、确认与撤销流程执行。
主要功能
- 01读取堡垒状态、威胁与资源
- 02查询居民、工作、军队和健康
- 03读取地图与地质信息
- 04结合世界资料和 Wiki 识别威胁
- 05可选启用堡垒操作工具
适用场景
- 01检查粮食储备与居民需求
- 02发现威胁、伤病及防御薄弱处
- 03查询生物特性和应对资料
MCP 相关
这是一个通过 MCP 向客户端提供 Dwarf Fortress 实时状态、空间信息和参考查询工具的服务。修改堡垒的操作工具默认隐藏,设置 DFHACK_MCP_ACTUATORS 后才可使用。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
npx -y dfhack-mcpDFHACK_HOSTHost running DFHack's remote RPC server. Defaults to 127.0.0.1.DFHACK_PORTPort for DFHack's remote RPC server. Defaults to 5000.DFHACK_MCP_ACTUATORSSet to any value to expose the write tools. Unset, the server is read-only.本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
工具
37收录的工具列表 · 更新于 2 周前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| limit | integer | 否 | 每页艺术品数量(默认 25,最多 100)。雕刻始终完整汇总。 |
| scope | enum | 否 | 要返回的艺术品范围。"site"(默认)= 仅此堡垒的艺术品。"world" = 世界中的所有艺术品,每件均带有 site_local 标记。site | world |
| cursor | string | 否 | 上一次调用返回的 next_cursor 分页游标;第一页时省略。 |
详细介绍
dfhack-mcp
一个 MCP 服务,让 AI Agent 能实时了解你的 Dwarf Fortress 要塞——它是副驾驶和预警顾问,而不是自动驾驶系统。让 Claude(或任何 MCP 客户端)连接到它,然后问 “我的要塞情况怎么样?”——它会直接从正在运行的游戏中读取幸福度、威胁、库存、工作、健康状况和防御情况,并用通俗语言作答。
默认只读。 37 个传感器和参考工具只会观察游戏。少数会_改变_要塞的执行器——队列管理器命令、应用 quickfort 蓝图、分配劳动力、发出平民警报、拉动杠杆——需要明确选择启用,在启用前会保持隐藏(参见执行操作)。
两类工具:
- 传感器回答_我的要塞现在在做什么?_——
fort_status、threats、stocks、jobs_and_labor、military、injuries_and_health、defenses等。 - 参考工具回答_Dwarf Fortress 是如何运作的?——
game_data提供你 的世界的真实数据(已加载的 raws),wiki_*工具提供一般说明,而identify会结合两者,回答“这是什么生物,我该如何应对它。”_
它返回的是事实,而非建议——经过汇总的 JSON,读起来就像快速浏览屏幕,让 Agent 自行判断。
每个工具都有参考页面,介绍参数、返回结构、真实输出示例和注意事项,详见 docs/tools。
快速开始
此软件包已发布到 npm,并附带预构建包——无需构建。使用 npx 让 MCP 客户端连接到它:
{
"mcpServers": {
"dfhack": {
"command": "npx",
"args": ["-y", "dfhack-mcp"]
}
}
}
Claude Desktop、Claude Code 或任何 stdio MCP 客户端只需这些配置即可。npx -y dfhack-mcp 会获取并运行最新版本;它的运行时依赖——MCP SDK、zod 和
dfhack-remote-node RPC
传输层——会自动从 npm 获取。
可以浏览官方 MCP Registry
的客户端能在其中找到此服务,名称为 io.github.alexanderolvera/dfhack-mcp;其
列表根据 server.json 生成,并指向同一个 npm
软件包,因此无论通过哪种方式安装,得到的构建版本都相同。
然后,只需运行你的要塞(见下一节),再向 Agent 提出类似这样的问题: “检查一下我的要塞,并标记所有紧急情况。”
更喜欢固定版本的全局安装?
npm install -g dfhack-mcp # then set "command": "dfhack-mcp", "args": []
要求
- 运行中的 Dwarf Fortress 和 DFHack,并且已加载要塞。工具会读取 正在运行的游戏;如果未加载要塞,它们会说明情况。
- DFHack Remote RPC 运行在
localhost:5000。只要 DF 在 DFHack 下运行,它就会默认启用——无需编辑配置文件。(allow_remote设置仅控制来自_其他_机器的连接,可以保持为false;本地 MCP 服务无论该设置为何值都能连接。)如需连接到其他地址,请设置DFHACK_HOST/DFHACK_PORT。 - 运行已发布软件包需要 Node 20+。(只有从源码开发时才需要 Node 24+——参见开发。)
可以询问它什么
Agent 会自行选择工具;你只需描述需求。以下是它可以使用的工具。
传感器——要塞状态
无需参数;每个工具都会报告已加载要塞的情况。
fort_status()— 名称、日期/季节、人口、财富、幸福度明细、预先分类的警报。stocks()— 食物/饮品的可供应天数,以及关键材料数量和显著的库存偏低/偏高列表。threats()— 按类型分组的危险单位;区分活跃与已控制目标,标记重大威胁/入侵者/不死生物,并列出各组的决定性特征(避陷阱、飞行、火焰、结网、摧毁建筑、远程攻击)。unmet_needs()— 汇总需求系统:按受影响而分心的矮人数对未满足需求排序,并显示各项需求的匮乏程度。jobs_and_labor()— 劳动力利用情况:忙碌与空闲的成年人数(不包括儿童)、空闲比例,以及按数量排序的进行中工作明细。military()— 小队、入伍士兵、已填补职位、针对地图上敌对目标的战备情况,以及各小队名册中的装备缺口(缺失的制服部件)、弹药和当前训练命令。injuries_and_health()— 受伤者/患者/卧床者/昏迷者人数,以及所需护理(诊断、手术、缝合等)。defenses()— 活跃敌对目标的地图位置,以及其到堡垒核心和最近吊桥的距离/方向/z 轴高度差;另提供可控结构清单(桥、杠杆、闸门、活板门、笼式陷阱、门)。burrows()— 每个地洞的大小和成员,以及平民警报安全地洞集合(已配置/已启用/已关联的地洞)——这是civilian_alert的读取部分。mechanisms()— 每个杠杆的位置、状态和关联目标(桥/门/闸门/活板门/支撑结构/武器陷阱);压力板的触发条件;未关联的杠杆和桥。moods()— 当前活跃的任何奇异心境(仙灵/孤僻/附身/阴郁/邪恶):对应矮人、驱动技能、工坊状态,以及与堡垒库存交叉核对的每种所需材料——这是“需要骨头,堡垒库存为零”的早期预警。mandates_and_justice()— 贵族的管理负担:当前生产指令和出口禁令、尚未满足的贵族房间需求,以及司法状况(未结案件、等待处罚的定罪案件、拘禁能力)。rooms_and_zones()— 设施清单,每项数量都配有需求侧数字:卧室、餐厅、医院、水井、神殿、酒馆、图书馆、行会大厅,以及可用棺材数量与等待安葬的死者数量。它是unmet_needs()的供应侧补充。trade()— 商队生命周期和贸易站:贸易站是否存在/是否完备及马车能否通行、已到场商队及其状态、贸易代理的指派/到场情况,以及存放在贸易站的货物数量和估算价值。environment()— 当前环境条件:季节和天气、地表温度及裸露水面是否结冰、拓荒地点的生物群系属性(邪恶/善良/复生),以及堡垒已经开辟的每个洞穴是否开放或封闭。对战争迷雾保持诚实。find_unit(query)— 按姓名片段或职业查找居民;为每个匹配项提供简明档案(职业、年龄、压力、工作、小队、健康标记)。可进一步调用citizen查看详情。citizen(unit_id)— 单个矮人的完整人物档案:社交关系图(配偶/父母/子女/朋友/仇敌,每人都有可供继续查询的unit_id)、崇拜的神祇、显著的性格极端、重要技能、喜好/厌恶,以及与当前压力相关的近期想法。site_history()— 世界史诗中关于该堡垒的记录:建立过程、堡垒的矮文名和英文名及其词源、此地曾发生的围攻/战斗,以及在此地逝世的重要人物。artifacts_and_engravings()— 堡垒的杰作和重要雕刻。chronicle()— 便于快速浏览的堡垒近期事件动态。
空间(对战争迷雾保持诚实——绝不泄露未发现的地块):
-
map_overview()—— 在读取任何单个地图块之前调用,低成本了解概况:地图范围、堡垒核心坐标、地表 z 层、包含玩家活动(挖掘/建造)的 z 层,以及作为垂直柱体的楼梯。无论堡垒大小如何,结果大小固定。 -
tile_region(z?, x0?, y0?, x1?, y1?)—— 以 ASCII 网格和自描述图例显示单个 z 层的有限区域。尚未发现的地图块显示为?。所有参数均为可选:不传参数 → 以堡垒核心为中心的 60×40 区域;仅传z→ 该层的质心;否则使用指定的角点。硬性上限为 100×100(超出范围的请求会被截断,不会报错)。只渲染地图;不会进行设计。符号 含义 符号 含义 ?尚未发现(战争迷雾) +建造的地板 #未挖掘的石头/墙壁 ~水/溪流 ,未挖掘的土壤(沙/黏土/壤土) %岩浆 .已挖掘的地板/可行走地面 W工坊/熔炉 F防御工事 S仓库 r斜坡 M机械(齿轮/轴/水泵/水车/风车) v斜坡顶端 n家具(床/椅子/桌子/门等) <>x向上/向下/上下楼梯 (space) 开放空间 T树 -
geology(reveal_hidden?)—— 一次调用即可完成地质勘测(默认仅显示已揭示的信息):地表 z 层、已暴露的地层及其材料名称、含水层(轻型或重型及其 z 范围)、已发现的洞穴、是否已到达岩浆海,以及地表水。reveal_hidden: true会绕过战争迷雾(调试/剧透开关,默认关闭)。
参考 — DF 的运作方式
wiki_* 是纯 HTTP 工具,无需游戏即可使用;game_data / identify 会读取已加载的世界。
game_data(query, kind?)—— 返回你的世界中六种类型(creature、material、plant、reaction、item、building;默认为creature)的 raws。对于从未出现在 wiki 上的程序生成生物(恶魔、被遗忘的野兽、泰坦),这是权威信息来源。query可以是标记(DEMON_4、INORGANIC:IRON)、名称("plump helmet"),也可以是生物对应的实时unit_id。匹配到一个强匹配项 → 完整档案;匹配到多个 → 消歧列表;没有匹配项 →{"match_count":0,"matches":[]}。identify(query)—— 一次调用即可回答 “这是什么生物,该如何应对”:将game_data(你的世界中的 raws)与wiki_lookup(策略)结合。返回档案(其中的flags[]/interactions[]包含诸如 TRAPAVOID → 机械陷阱不起作用 之类的信息),以及 1–2 段精简的 wiki 摘录。出现威胁时可使用。wiki_search(query)—— 在 DF wiki 中搜索候选标题和清理后的摘要(优先搜索DF2014命名空间)。wiki_lookup(title, section?, refresh?)—— 获取 wiki 文章的纯文本版本,固定使用DF2014;支持跟随重定向、识别章节片段,并缓存约 30 天。
采取行动(执行工具)
默认情况下,上述所有工具都只读取游戏数据。执行工具会_改变_堡垒,因此需要通过显式开关启用——设置 DFHACK_MCP_ACTUATORS 后,它们才会出现在工具列表中;若不设置,服务将严格保持只读。
{
"mcpServers": {
"dfhack": {
"command": "npx",
"args": ["-y", "dfhack-mcp"],
"env": { "DFHACK_MCP_ACTUATORS": "1" }
}
}
}
每个执行工具都采用相同的 预览 → 确认 → 应用 → 撤销 安全流程,因此变更绝不会令人措手不及:
- 预览(试运行)。 Agent 在完整指定操作后调用工具,但不提供确认令牌。它会收到一份
preview,准确说明将会发生哪些变化——只陈述事实,绝不给出建议——以及一个一次性confirm_token。不会写入任何内容。如果操作无法按要求执行(例如蓝图格式错误),预览会说明原因,且不会签发令牌。 - 应用。 Agent 使用相同参数并附上该令牌再次调用。服务端会重新检查_操作对象_自预览以来是否发生变化;如果发生了变化,令牌就会失效,Agent 需要重新预览。成功后,它会收到一个
undo句柄,以及来自匹配传感器、用于确认变更的readback。
令牌只能使用一次,且仅针对特定目标:堡垒其他地方发生无关变更不会使令牌失效,但目标发生变更则会。每个执行器都会指定自己的撤销路径。
管理者工作订单
work_order_list(after_id?)— _只读,始终可用。_以事实形式列出堡垒管理者的订单:id、工作类型、产出物品/材料、总量/剩余量、重复频率、绑定的工坊,以及每个订单的验证状态。采用分页(上限 256),并提供游标。work_order_create(job_type, amount, frequency?, material?, item_type?)— 创建新订单并加入队列;预览会标记would_duplicate和manager_present。撤销方式:work_order_cancel。work_order_cancel(order_id)— 按 id 移除一个订单;撤销句柄为重建规格(若无法完整恢复工坊绑定或条件,则会带有faithful标记)。
Quickfort 蓝图 — 根据 Agent 起草的 quickfort CSV 指定挖掘/区域。没有单独的读取传感器:不带令牌调用 blueprint_apply 本身就是预览。
blueprint_apply(csv, anchor_x, anchor_y, anchor_z, mode)— 根据#dig或#zone蓝图指定区域;左上角单元格映射到锚点。试运行会解析 quickfort 自身的统计数据,并预览受影响的图块、占用范围,以及其下方的战争迷雾图块(只陈述事实,不会因此阻止操作)。蓝图格式错误时会阻止操作且不签发令牌(quickfort 会部分应用)。v1 范围:仅限 dig + zone — 会拒绝build/place。撤销方式:blueprint_undo。blueprint_undo(csv, anchor_x, anchor_y, anchor_z, mode)— 通过 quickfort 原生撤销功能还原挖掘/区域指定(使用相同的 csv/锚点/模式)。令牌会对每个单元格的摘要进行签名,因此任一单元格发生偏移都会使令牌失效。
通过工作详情分配劳役
work_details()— _只读,始终可用。_列出每项工作详情(游戏中的劳役组):名称、模式、启用的劳役令牌,以及分配到该详情的居民(按 id 排序,上限为 200,并提供完整的member_count)。assign_work_detail(unit_id, detail, enabled)— 将一名居民添加到某项详情,或从中移除。预览会报告currently_member、resulting_members_count和only_member;若请求的状态已经满足,预览会显示为无操作。撤销方式:使用相同调用并反转enabled。
紧急响应
burrows()— _只读,始终可用。_列出每个洞穴的大小和成员,以及平民警报自身的状态:configured(堡垒是否曾设置过警报)、active(当前是否正在鸣响)和关联的洞穴 id。civilian_alert(burrow, enabled)— 将一个洞穴加入平民警报安全集合或从中移除。enabled=true还会在警报尚未响起时拉响警报;enabled=false仅当该集合完全清空后才会解除警报。撤销方式:使用相同调用并反转enabled。mechanisms()— _只读,始终可用。_列出每个杠杆/压力板的位置及关联目标(桥/门/水闸/舱口/支撑物/武器陷阱),以及未关联的杠杆和桥。pull_lever(lever_id, urgent?)— 为矮人排入一项任务,让其拉动指定杠杆(urgent默认为立即执行优先级)。此操作只会将任务加入队列;矮人完成任务后才会实际切换装置,而不是在应用时切换。撤销方式:再次拉动同一杠杆。
保存游戏
game_save()— 在进行大规模或高风险更改前,快速保存要塞作为检查点,以便出错时可通过加载存档回滚。不接受参数;试运行会预览将要冻结的要塞和游戏日期。需要了解两点:写入是异步的(DF 会在接下来的几帧中提交;回读只能确认快速保存已_发出_,不能确认文件已写入),并且会通过 DF 的自动保存进行,因此存档会写入 DF 设置中的轮换“自动保存”文件夹,而不是覆盖当前加载的存档。此操作不可逆:要回滚,请在 DF 中加载相应的存档/自动存档。仅限堡垒模式。
配置
以下均为可选项,在 MCP 客户端的服务器 env 中设置:
| 变量 | 默认值 | 作用 |
|---|---|---|
DFHACK_HOST | 127.0.0.1 | DFHack 的 Remote RPC 监听所在主机。 |
DFHACK_PORT | 5000 | DFHack Remote RPC 的端口。 |
DFHACK_MCP_ACTUATORS | (未设置) | 设为 1 以启用写入执行器(关闭时严格只读)。 |
DFHACK_MCP_DEV | (未设置) | 设为 1 以启用 run_lua,这是一个原始 DFHack Lua 逃生口(可读取并写入游戏状态;仅供工具作者使用)。 |
故障排除
{"error":"no fort loaded"}— DFHack 可访问,但你正处于标题画面或菜单中。请在堡垒模式下加载一个要塞。- 无法连接到 DFHack 的错误 — Dwarf Fortress 未在 DFHack 环境下运行,或 RPC 端口不同。确认 DF 已在 DFHack 环境下启动,并且
DFHACK_HOST/DFHACK_PORT与实际设置相符(默认值为127.0.0.1:5000)。 - 客户端中没有显示这些工具 — 重启 MCP 客户端,使其重新启动服务器;正在运行的服务器不会加载配置更改。
- 缺少写入工具 — 这是默认设置。请设置
DFHACK_MCP_ACTUATORS=1(参见执行操作)。 - 加载要塞后第一次调用报错,但之后正常 — 刚启动的 DFHack 在完成查询脚本注册前,可能会拒绝第一次工具调用;请重试一次。
开发
如需修改服务器本身,请克隆项目并直接运行 TypeScript 入口文件(需要 Node 24+——它通过类型剥离运行源文件,无需构建步骤):
git clone https://github.com/alexanderolvera/dfhack-mcp.git
cd dfhack-mcp
npm install # or: npm run bootstrap (installs + runs the T0 contract check)
node src/index.ts
将 MCP 客户端指向此项目目录,并设置 "command": "node", "args": ["/absolute/path/to/dfhack-mcp/src/index.ts"]。
所有易受版本变化影响的 DFHack 字段访问都位于 src/dfhack-queries/ 下的真实 .lua 脚本中(每个工具对应一个脚本),通过名称和原生 argv 调用——因此,DF/DFHack 版本升级只需局部修复,而且查询参数从设计上就能防止注入。每个工具都是 src/tools/ 中的轻量 TypeScript 封装。
提供事实,而非建议。 工具负责_感知_——它们会返回要塞和世界的实际情况,就像玩家读取屏幕一样。它们不会告诉你该建造什么或如何战斗;这些判断由 Agent 负责。描述_该怎么做_的字段属于建议,应予以省略。
每个工具都通过分级测试框架(npm run verify:t0 … t2)在实时要塞中验证——绝不使用模拟。工具编写规范和验证工作流请参阅 CONTRIBUTING.md,测试框架的分级说明请参阅 docs/VERIFY.md。
许可证
ISC——详见 LICENSE.md。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。