给 AI,尤其是 Codex,一个能真正操作 Minecraft 客户端的本地接口。
Codex Client Control 的出发点其实很明确:现在很多 AI 已经能写 Minecraft 相关代码、分析问题、规划流程,但一旦到了“真的去操作客户端”这一步,通常就断掉了。
所以这个 mod 做的事情,就是把本地正在运行的 Minecraft 客户端接成一个可调用的控制端。游戏启动后,它会在本机 127.0.0.1 打开一个带 token 的 HTTP / WebSocket 接口,让外部程序能读取客户端状态,也能把真实输入重新送回客户端。
这里说的“外部程序”,我最开始就是按 Codex 来想的,所以名字前面直接用了 Codex。这个项目本质上就是想给 Codex 一只手,让它不只是停留在文本层面,而是真的能去看、去点、去移动、去执行。
我选 HTTP 也是同样的思路:简单、直观、容易调试,而且对 AI 很友好。只要一个代理能发本地请求,它就能开始控制这个客户端,不需要额外塞一套复杂脚本运行时进去。
简单一点说,你可以从外部脚本里让客户端前后左右移动、发送聊天、切快捷栏、操作 GUI、读取容器、查看准星目标,或者执行一段编排好的动作序列。
如果你要的是更长时间、更高频的连续操作,仓库里还有一个独立的 lan-bot 子项目。它适合另一类场景;这个模组更偏向把“当前客户端”开放成一个稳定、可观察、可控制的本地接口。详见 lan-bot/README.md。
因为这个项目一开始就不是在做一个泛泛的“客户端控制 mod”。
我的目标更具体:我想给 Codex 一个真正能落到 Minecraft 客户端上的控制桥,让它可以通过本地 HTTP 接口去访问状态、发送动作、执行测试,而不是只停留在“告诉你下一步该怎么做”。
现在这套接口当然也能被别的脚本、桌面工具或者 AI 使用,但它的起点确实就是 Codex,这也是名字保留下来的原因。
config/codex-client-control.propertiestokenX-Auth-Token 的请求访问 http://127.0.0.1:47862/status,确认接口已经可用PowerShell 简例:
$token = (Get-Content .\config\codex-client-control.properties | Select-String '^token=').ToString().Split('=')[1]
Invoke-RestMethod 'http://127.0.0.1:47862/status' -Headers @{ 'X-Auth-Token' = $token }
默认会构建 gradle.properties 里 default_minecraft_version 指向的版本,产物文件名会自动附带对应的 Minecraft 版本号。
常用构建方式:
gradlew build1.21.11:gradlew buildMods1_21_111.21.8:gradlew buildMods1_21_8gradlew buildAllSupportedModsgradlew collectCurrentMods如果你确实想手动覆盖版本属性,在 Windows PowerShell 里请给 minecraft_version 加引号,或者直接用上面的版本任务名。
产物目录:
fabric/build/<minecraft_version>/libs/neoforge/build/<minecraft_version>/libs/plugin/build/<minecraft_version>/libs/build/release/<minecraft_version>/服务端插件模块可单独构建:gradlew :plugin:build -Ptarget_loader=plugin。插件适用于 Spigot / Paper / Purpur / Folia,默认监听 127.0.0.1:47864。
如果你准备上传 Modrinth,可直接参考根目录里的 MODRINTH_DESCRIPTION.md。
GET / - 根路径,返回基本信息GET /status - 获取客户端状态GET /full-state - 获取完整状态(状态 + 聊天 + 屏幕 + 目标 + 容器 + 玩家列表)GET /chat - 读取聊天缓存GET /screen - 读取当前 GUI 信息和可见控件GET /target - 读取准星目标GET /container - 读取当前容器内容GET /players - 读取玩家列表GET /debug/fake-player - 读取本地调试假人列表GET /action/status - 读取托管动作状态POST /chat - 发送聊天消息POST /command - 执行命令POST /look - 转动视角POST /key - 按住/松开按键POST /input - 应用综合控制状态(按键 + 视角 + 快捷栏)POST /tap - 轻点按键POST /hotbar - 切换快捷栏POST /release-all - 松开所有常用控制键POST /gui/close - 关闭当前 GUIPOST /gui/click - 点击 GUI 坐标POST /gui/release - 松开 GUI 鼠标按键POST /gui/scroll - 滚动 GUIPOST /gui/key - 向 GUI 发送按键POST /gui/type - 向 GUI 输入文本POST /gui/click-widget - 按控件索引点击按钮POST /screenshot - 截图POST /sequence - 执行动作序列POST /action/run - 运行托管动作POST /action/cancel - 取消托管动作POST /debug/fake-player/spawn - 生成本地调试假人POST /debug/fake-player/move - 移动本地调试假人POST /debug/fake-player/remove - 移除本地调试假人POST /debug/fake-player/clear - 清空本地调试假人连接到 ws://127.0.0.1:47862/ws,需要携带 X-Auth-Token 请求头。
支持的动作(action):
ping - 心跳检测status - 获取状态full-state - 获取完整状态chat / chat.read - 读取/发送聊天subscribe / unsubscribe / subscriptions - 订阅管理screen - 获取屏幕快照target - 获取准星目标container - 获取容器内容players - 获取玩家列表action.status / action.run / action.cancel - 托管动作command - 执行命令look - 转动视角key - 按键控制input - 综合输入控制tap - 轻点按键hotbar - 切换快捷栏release-all - 松开所有按键gui.close / gui.click / gui.release / gui.scroll / gui.key / gui.type / gui.click-widget - GUI 操作screenshot - 截图sequence - 动作序列debug.fake-player / debug.fake-player.spawn / debug.fake-player.move / debug.fake-player.remove / debug.fake-player.clear - 调试假人所有请求都需要带 X-Auth-Token 请求头。
服务端插件提供与客户端控制端相近的 HTTP/WebSocket 风格接口,默认地址为 http://127.0.0.1:47864,配置文件为 plugins/CodexClientControlPlugin/config.yml。
常用接口:
GET /status - 读取插件桥状态、服务端类型、在线模式和 Folia 检测结果GET /server - 读取服务端元信息GET /players - 读取在线玩家GET /worlds - 读取已加载世界GET /fake-player - 读取插件假人记录GET /action/catalog - 读取 200+ 动作目录GET /action/status - 读取动作状态POST /chat - 广播聊天POST /command - 以控制台身份执行命令POST /action/run - 运行插件端动作POST /action/cancel - 取消动作POST /fake-player/spawn / remove / clear - 管理插件假人记录GET /ws - 插件端 WebSocket 接口插件假人模式默认关闭,且默认只允许在 online-mode=false 的离线服务器中使用。在线模式服务器需要真实 Microsoft 登录客户端;插件不会伪造正版登录,也不会在服务端内保存或代管 Microsoft 凭据。
配置文件首次启动后会生成在:
config/codex-client-control.properties默认配置:
host=127.0.0.1port=47862token=<自动生成>配置会在模组首次启动时自动生成,如果文件已存在则读取现有配置。
先读取 token:
$token = (Get-Content .\versions\1.21.11far\config\codex-client-control.properties | Select-String '^token=').ToString().Split('=')[1]
查看状态:
Invoke-RestMethod 'http://127.0.0.1:47862/status' -Headers @{ 'X-Auth-Token' = $token }
获取完整状态:
Invoke-RestMethod 'http://127.0.0.1:47862/full-state' -Headers @{ 'X-Auth-Token' = $token }
读取聊天缓存:
Invoke-RestMethod 'http://127.0.0.1:47862/chat?limit=20&since=0' -Headers @{ 'X-Auth-Token' = $token }
读取当前 GUI 信息和可见控件:
Invoke-RestMethod 'http://127.0.0.1:47862/screen' -Headers @{ 'X-Auth-Token' = $token }
读取准星目标:
Invoke-RestMethod 'http://127.0.0.1:47862/target' -Headers @{ 'X-Auth-Token' = $token }
读取当前容器内容:
Invoke-RestMethod 'http://127.0.0.1:47862/container' -Headers @{ 'X-Auth-Token' = $token }
读取玩家列表:
Invoke-RestMethod 'http://127.0.0.1:47862/players' -Headers @{ 'X-Auth-Token' = $token }
读取托管动作状态:
Invoke-RestMethod 'http://127.0.0.1:47862/action/status' -Headers @{ 'X-Auth-Token' = $token }
发送聊天:
Invoke-RestMethod 'http://127.0.0.1:47862/chat' `
-Method Post `
-Headers @{ 'X-Auth-Token' = $token } `
-ContentType 'application/json' `
-Body '{"message":"你好,这条消息来自 Codex。"}'
执行命令:
Invoke-RestMethod 'http://127.0.0.1:47862/command' `
-Method Post `
-Headers @{ 'X-Auth-Token' = $token } `
-ContentType 'application/json' `
-Body '{"command":"spawn"}'
应用综合控制状态:
Invoke-RestMethod 'http://127.0.0.1:47862/input' `
-Method Post `
-Headers @{ 'X-Auth-Token' = $token } `
-ContentType 'application/json' `
-Body '{
"keys": {"forward": true, "sprint": true},
"yaw": 90.0,
"pitch": 10.0,
"hotbar": 3
}'
转动视角:
Invoke-RestMethod 'http://127.0.0.1:47862/look' `
-Method Post `
-Headers @{ 'X-Auth-Token' = $token } `
-ContentType 'application/json' `
-Body '{"deltaYaw":30,"pitch":15}'
按住前进:
Invoke-RestMethod 'http://127.0.0.1:47862/key' `
-Method Post `
-Headers @{ 'X-Auth-Token' = $token } `
-ContentType 'application/json' `
-Body '{"key":"forward","state":true}'
轻点跳跃:
Invoke-RestMethod 'http://127.0.0.1:47862/tap' `
-Method Post `
-Headers @{ 'X-Auth-Token' = $token } `
-ContentType 'application/json' `
-Body '{"key":"jump","durationMs":120}'
切到 3 号快捷栏:
Invoke-RestMethod 'http://127.0.0.1:47862/hotbar' `
-Method Post `
-Headers @{ 'X-Auth-Token' = $token } `
-ContentType 'application/json' `
-Body '{"slot":3}'
松开所有常用控制键:
Invoke-RestMethod 'http://127.0.0.1:47862/release-all' `
-Method Post `
-Headers @{ 'X-Auth-Token' = $token }
点击 GUI 坐标:
Invoke-RestMethod 'http://127.0.0.1:47862/gui/click' `
-Method Post `
-Headers @{ 'X-Auth-Token' = $token } `
-ContentType 'application/json' `
-Body '{"x":320,"y":180,"button":0}'
滚动 GUI:
Invoke-RestMethod 'http://127.0.0.1:47862/gui/scroll' `
-Method Post `
-Headers @{ 'X-Auth-Token' = $token } `
-ContentType 'application/json' `
-Body '{"x":320,"y":180,"deltaY":-1}'
向当前 GUI 输入文本:
Invoke-RestMethod 'http://127.0.0.1:47862/gui/type' `
-Method Post `
-Headers @{ 'X-Auth-Token' = $token } `
-ContentType 'application/json' `
-Body '{"text":"hello codex"}'
向当前 GUI 发送按键:
Invoke-RestMethod 'http://127.0.0.1:47862/gui/key' `
-Method Post `
-Headers @{ 'X-Auth-Token' = $token } `
-ContentType 'application/json' `
-Body '{"key":257,"scancode":28,"modifiers":0}'
按 GET /screen 返回的控件索引点击按钮:
Invoke-RestMethod 'http://127.0.0.1:47862/gui/click-widget' `
-Method Post `
-Headers @{ 'X-Auth-Token' = $token } `
-ContentType 'application/json' `
-Body '{"index":0,"button":0}'
截图:
Invoke-RestMethod 'http://127.0.0.1:47862/screenshot' `
-Method Post `
-Headers @{ 'X-Auth-Token' = $token } `
-ContentType 'application/json' `
-Body '{"name":"codex-shot"}'
动作序列:
Invoke-RestMethod 'http://127.0.0.1:47862/sequence' `
-Method Post `
-Headers @{ 'X-Auth-Token' = $token } `
-ContentType 'application/json' `
-Body '{"steps":[{"action":"look","deltaYaw":45},{"action":"move","forward":true,"sprint":true,"durationMs":800},{"action":"wait","durationMs":200},{"action":"tap","key":"jump","durationMs":120}]}'
运行托管动作:
Invoke-RestMethod 'http://127.0.0.1:47862/action/run' `
-Method Post `
-Headers @{ 'X-Auth-Token' = $token } `
-ContentType 'application/json' `
-Body '{"action":"move_to","x":100,"y":64,"z":200}'
取消托管动作:
Invoke-RestMethod 'http://127.0.0.1:47862/action/cancel' `
-Method Post `
-Headers @{ 'X-Auth-Token' = $token } `
-ContentType 'application/json' `
-Body '{"id":1}'
生成一个本地调试假人:
Invoke-RestMethod 'http://127.0.0.1:47862/debug/fake-player/spawn' `
-Method Post `
-Headers @{ 'X-Auth-Token' = $token } `
-ContentType 'application/json' `
-Body '{"name":"CodexDummy","x":0,"y":80,"z":0,"nameVisible":true}'
移动本地调试假人:
Invoke-RestMethod 'http://127.0.0.1:47862/debug/fake-player/move' `
-Method Post `
-Headers @{ 'X-Auth-Token' = $token } `
-ContentType 'application/json' `
-Body '{"name":"CodexDummy","x":2,"y":80,"z":2,"yaw":180}'
读取本地调试假人:
Invoke-RestMethod 'http://127.0.0.1:47862/debug/fake-player' -Headers @{ 'X-Auth-Token' = $token }
清空本地调试假人:
Invoke-RestMethod 'http://127.0.0.1:47862/debug/fake-player/clear' `
-Method Post `
-Headers @{ 'X-Auth-Token' = $token }
关闭当前 GUI:
Invoke-RestMethod 'http://127.0.0.1:47862/gui/close' `
-Method Post `
-Headers @{ 'X-Auth-Token' = $token }
使用 PowerShell 连接 WebSocket(需要 PowerShell 7+ 或使用其他 WebSocket 客户端):
# 使用 System.Net.WebSockets 连接
$ws = New-Object System.Net.WebSockets.ClientWebSocket
$ws.Options.SetRequestHeader('X-Auth-Token', $token)
$tokenBytes = [System.Text.Encoding]::UTF8.GetBytes($token)
$ws.ConnectAsync('ws://127.0.0.1:47862/ws', [System.Threading.CancellationToken]::None).Wait()
# 发送消息
$message = @{
action = 'ping'
id = 1
} | ConvertTo-Json
$sendBytes = [System.Text.Encoding]::UTF8.GetBytes($message)
$ws.SendAsync($sendBytes, [System.Net.WebSockets.WebSocketMessageType]::Text, $true, [System.Threading.CancellationToken]::None).Wait()
# 接收消息
$buffer = New-Object byte[] 1024
$receive = $ws.ReceiveAsync($buffer, [System.Threading.CancellationToken]::None).Result
$response = [System.Text.Encoding]::UTF8.GetString($buffer, 0, $receive.Count)
Write-Host $response
$ws.CloseAsync([System.Net.WebSockets.WebSocketCloseStatus]::NormalClosure, 'Close', [System.Threading.CancellationToken]::None).Wait()
订阅实时推送:
{
"action": "subscribe",
"topics": ["status", "screen", "target", "container", "players", "chat", "full-state", "action"]
}
订阅后会每 25ms 推送一次订阅的 topic 数据。
取消订阅:
{
"action": "unsubscribe",
"topics": ["status", "screen"]
}
查看当前订阅:
{
"action": "subscriptions"
}
POST /sequence 是动作序列接口,适合脚本化移动/等待/GUI 组合,不是完整寻路算法。POST /action/run 是托管动作接口,会异步执行预定义的动作(如 move_to、place_blocks 等),可以通过 POST /action/cancel 取消。POST /input 是综合输入接口,可以同时设置按键状态、视角和快捷栏,适合需要精确同步的操作。POST /debug/fake-player/* 创建的是客户端本地调试实体,只在你自己的客户端里可见,服务器和其他玩家不会把它当成真实玩家。POST /gui/click-widget 使用 GET /screen 返回的控件索引,索引从 0 开始。所有接口失败时会返回如下格式的错误响应:
{
"error": "错误信息"
}
HTTP 状态码:
200 - 成功400 - 请求参数错误401 - 缺少或错误的 X-Auth-Token404 - 接口不存在500 - 服务器内部错误0.18.41.21.11 / 1.21.8引用的是发表于论文的《Collaborating Action by Action: A Multi-agent LLM Framework for Embodied Reasoning》 https://arxiv.org/abs/2504.17950
27 commits
8 commits
JavaScript
54.9%
Java
45.1%
给 AI,尤其是 Codex,一个能真正操作 Minecraft 客户端的本地接口。
Codex Client Control 的出发点其实很明确:现在很多 AI 已经能写 Minecraft 相关代码、分析问题、规划流程,但一旦到了“真的去操作客户端”这一步,通常就断掉了。
所以这个 mod 做的事情,就是把本地正在运行的 Minecraft 客户端接成一个可调用的控制端。游戏启动后,它会在本机 127.0.0.1 打开一个带 token 的 HTTP / WebSocket 接口,让外部程序能读取客户端状态,也能把真实输入重新送回客户端。
这里说的“外部程序”,我最开始就是按 Codex 来想的,所以名字前面直接用了 Codex。这个项目本质上就是想给 Codex 一只手,让它不只是停留在文本层面,而是真的能去看、去点、去移动、去执行。
我选 HTTP 也是同样的思路:简单、直观、容易调试,而且对 AI 很友好。只要一个代理能发本地请求,它就能开始控制这个客户端,不需要额外塞一套复杂脚本运行时进去。
简单一点说,你可以从外部脚本里让客户端前后左右移动、发送聊天、切快捷栏、操作 GUI、读取容器、查看准星目标,或者执行一段编排好的动作序列。
如果你要的是更长时间、更高频的连续操作,仓库里还有一个独立的 lan-bot 子项目。它适合另一类场景;这个模组更偏向把“当前客户端”开放成一个稳定、可观察、可控制的本地接口。详见 lan-bot/README.md。
因为这个项目一开始就不是在做一个泛泛的“客户端控制 mod”。
我的目标更具体:我想给 Codex 一个真正能落到 Minecraft 客户端上的控制桥,让它可以通过本地 HTTP 接口去访问状态、发送动作、执行测试,而不是只停留在“告诉你下一步该怎么做”。
现在这套接口当然也能被别的脚本、桌面工具或者 AI 使用,但它的起点确实就是 Codex,这也是名字保留下来的原因。
config/codex-client-control.propertiestokenX-Auth-Token 的请求访问 http://127.0.0.1:47862/status,确认接口已经可用PowerShell 简例:
$token = (Get-Content .\config\codex-client-control.properties | Select-String '^token=').ToString().Split('=')[1]
Invoke-RestMethod 'http://127.0.0.1:47862/status' -Headers @{ 'X-Auth-Token' = $token }
默认会构建 gradle.properties 里 default_minecraft_version 指向的版本,产物文件名会自动附带对应的 Minecraft 版本号。
常用构建方式:
gradlew build1.21.11:gradlew buildMods1_21_111.21.8:gradlew buildMods1_21_8gradlew buildAllSupportedModsgradlew collectCurrentMods如果你确实想手动覆盖版本属性,在 Windows PowerShell 里请给 minecraft_version 加引号,或者直接用上面的版本任务名。
产物目录:
fabric/build/<minecraft_version>/libs/neoforge/build/<minecraft_version>/libs/plugin/build/<minecraft_version>/libs/build/release/<minecraft_version>/服务端插件模块可单独构建:gradlew :plugin:build -Ptarget_loader=plugin。插件适用于 Spigot / Paper / Purpur / Folia,默认监听 127.0.0.1:47864。
如果你准备上传 Modrinth,可直接参考根目录里的 MODRINTH_DESCRIPTION.md。
GET / - 根路径,返回基本信息GET /status - 获取客户端状态GET /full-state - 获取完整状态(状态 + 聊天 + 屏幕 + 目标 + 容器 + 玩家列表)GET /chat - 读取聊天缓存GET /screen - 读取当前 GUI 信息和可见控件GET /target - 读取准星目标GET /container - 读取当前容器内容GET /players - 读取玩家列表GET /debug/fake-player - 读取本地调试假人列表GET /action/status - 读取托管动作状态POST /chat - 发送聊天消息POST /command - 执行命令POST /look - 转动视角POST /key - 按住/松开按键POST /input - 应用综合控制状态(按键 + 视角 + 快捷栏)POST /tap - 轻点按键POST /hotbar - 切换快捷栏POST /release-all - 松开所有常用控制键POST /gui/close - 关闭当前 GUIPOST /gui/click - 点击 GUI 坐标POST /gui/release - 松开 GUI 鼠标按键POST /gui/scroll - 滚动 GUIPOST /gui/key - 向 GUI 发送按键POST /gui/type - 向 GUI 输入文本POST /gui/click-widget - 按控件索引点击按钮POST /screenshot - 截图POST /sequence - 执行动作序列POST /action/run - 运行托管动作POST /action/cancel - 取消托管动作POST /debug/fake-player/spawn - 生成本地调试假人POST /debug/fake-player/move - 移动本地调试假人POST /debug/fake-player/remove - 移除本地调试假人POST /debug/fake-player/clear - 清空本地调试假人连接到 ws://127.0.0.1:47862/ws,需要携带 X-Auth-Token 请求头。
支持的动作(action):
ping - 心跳检测status - 获取状态full-state - 获取完整状态chat / chat.read - 读取/发送聊天subscribe / unsubscribe / subscriptions - 订阅管理screen - 获取屏幕快照target - 获取准星目标container - 获取容器内容players - 获取玩家列表action.status / action.run / action.cancel - 托管动作command - 执行命令look - 转动视角key - 按键控制input - 综合输入控制tap - 轻点按键hotbar - 切换快捷栏release-all - 松开所有按键gui.close / gui.click / gui.release / gui.scroll / gui.key / gui.type / gui.click-widget - GUI 操作screenshot - 截图sequence - 动作序列debug.fake-player / debug.fake-player.spawn / debug.fake-player.move / debug.fake-player.remove / debug.fake-player.clear - 调试假人所有请求都需要带 X-Auth-Token 请求头。
服务端插件提供与客户端控制端相近的 HTTP/WebSocket 风格接口,默认地址为 http://127.0.0.1:47864,配置文件为 plugins/CodexClientControlPlugin/config.yml。
常用接口:
GET /status - 读取插件桥状态、服务端类型、在线模式和 Folia 检测结果GET /server - 读取服务端元信息GET /players - 读取在线玩家GET /worlds - 读取已加载世界GET /fake-player - 读取插件假人记录GET /action/catalog - 读取 200+ 动作目录GET /action/status - 读取动作状态POST /chat - 广播聊天POST /command - 以控制台身份执行命令POST /action/run - 运行插件端动作POST /action/cancel - 取消动作POST /fake-player/spawn / remove / clear - 管理插件假人记录GET /ws - 插件端 WebSocket 接口插件假人模式默认关闭,且默认只允许在 online-mode=false 的离线服务器中使用。在线模式服务器需要真实 Microsoft 登录客户端;插件不会伪造正版登录,也不会在服务端内保存或代管 Microsoft 凭据。
配置文件首次启动后会生成在:
config/codex-client-control.properties默认配置:
host=127.0.0.1port=47862token=<自动生成>配置会在模组首次启动时自动生成,如果文件已存在则读取现有配置。
先读取 token:
$token = (Get-Content .\versions\1.21.11far\config\codex-client-control.properties | Select-String '^token=').ToString().Split('=')[1]
查看状态:
Invoke-RestMethod 'http://127.0.0.1:47862/status' -Headers @{ 'X-Auth-Token' = $token }
获取完整状态:
Invoke-RestMethod 'http://127.0.0.1:47862/full-state' -Headers @{ 'X-Auth-Token' = $token }
读取聊天缓存:
Invoke-RestMethod 'http://127.0.0.1:47862/chat?limit=20&since=0' -Headers @{ 'X-Auth-Token' = $token }
读取当前 GUI 信息和可见控件:
Invoke-RestMethod 'http://127.0.0.1:47862/screen' -Headers @{ 'X-Auth-Token' = $token }
读取准星目标:
Invoke-RestMethod 'http://127.0.0.1:47862/target' -Headers @{ 'X-Auth-Token' = $token }
读取当前容器内容:
Invoke-RestMethod 'http://127.0.0.1:47862/container' -Headers @{ 'X-Auth-Token' = $token }
读取玩家列表:
Invoke-RestMethod 'http://127.0.0.1:47862/players' -Headers @{ 'X-Auth-Token' = $token }
读取托管动作状态:
Invoke-RestMethod 'http://127.0.0.1:47862/action/status' -Headers @{ 'X-Auth-Token' = $token }
发送聊天:
Invoke-RestMethod 'http://127.0.0.1:47862/chat' `
-Method Post `
-Headers @{ 'X-Auth-Token' = $token } `
-ContentType 'application/json' `
-Body '{"message":"你好,这条消息来自 Codex。"}'
执行命令:
Invoke-RestMethod 'http://127.0.0.1:47862/command' `
-Method Post `
-Headers @{ 'X-Auth-Token' = $token } `
-ContentType 'application/json' `
-Body '{"command":"spawn"}'
应用综合控制状态:
Invoke-RestMethod 'http://127.0.0.1:47862/input' `
-Method Post `
-Headers @{ 'X-Auth-Token' = $token } `
-ContentType 'application/json' `
-Body '{
"keys": {"forward": true, "sprint": true},
"yaw": 90.0,
"pitch": 10.0,
"hotbar": 3
}'
转动视角:
Invoke-RestMethod 'http://127.0.0.1:47862/look' `
-Method Post `
-Headers @{ 'X-Auth-Token' = $token } `
-ContentType 'application/json' `
-Body '{"deltaYaw":30,"pitch":15}'
按住前进:
Invoke-RestMethod 'http://127.0.0.1:47862/key' `
-Method Post `
-Headers @{ 'X-Auth-Token' = $token } `
-ContentType 'application/json' `
-Body '{"key":"forward","state":true}'
轻点跳跃:
Invoke-RestMethod 'http://127.0.0.1:47862/tap' `
-Method Post `
-Headers @{ 'X-Auth-Token' = $token } `
-ContentType 'application/json' `
-Body '{"key":"jump","durationMs":120}'
切到 3 号快捷栏:
Invoke-RestMethod 'http://127.0.0.1:47862/hotbar' `
-Method Post `
-Headers @{ 'X-Auth-Token' = $token } `
-ContentType 'application/json' `
-Body '{"slot":3}'
松开所有常用控制键:
Invoke-RestMethod 'http://127.0.0.1:47862/release-all' `
-Method Post `
-Headers @{ 'X-Auth-Token' = $token }
点击 GUI 坐标:
Invoke-RestMethod 'http://127.0.0.1:47862/gui/click' `
-Method Post `
-Headers @{ 'X-Auth-Token' = $token } `
-ContentType 'application/json' `
-Body '{"x":320,"y":180,"button":0}'
滚动 GUI:
Invoke-RestMethod 'http://127.0.0.1:47862/gui/scroll' `
-Method Post `
-Headers @{ 'X-Auth-Token' = $token } `
-ContentType 'application/json' `
-Body '{"x":320,"y":180,"deltaY":-1}'
向当前 GUI 输入文本:
Invoke-RestMethod 'http://127.0.0.1:47862/gui/type' `
-Method Post `
-Headers @{ 'X-Auth-Token' = $token } `
-ContentType 'application/json' `
-Body '{"text":"hello codex"}'
向当前 GUI 发送按键:
Invoke-RestMethod 'http://127.0.0.1:47862/gui/key' `
-Method Post `
-Headers @{ 'X-Auth-Token' = $token } `
-ContentType 'application/json' `
-Body '{"key":257,"scancode":28,"modifiers":0}'
按 GET /screen 返回的控件索引点击按钮:
Invoke-RestMethod 'http://127.0.0.1:47862/gui/click-widget' `
-Method Post `
-Headers @{ 'X-Auth-Token' = $token } `
-ContentType 'application/json' `
-Body '{"index":0,"button":0}'
截图:
Invoke-RestMethod 'http://127.0.0.1:47862/screenshot' `
-Method Post `
-Headers @{ 'X-Auth-Token' = $token } `
-ContentType 'application/json' `
-Body '{"name":"codex-shot"}'
动作序列:
Invoke-RestMethod 'http://127.0.0.1:47862/sequence' `
-Method Post `
-Headers @{ 'X-Auth-Token' = $token } `
-ContentType 'application/json' `
-Body '{"steps":[{"action":"look","deltaYaw":45},{"action":"move","forward":true,"sprint":true,"durationMs":800},{"action":"wait","durationMs":200},{"action":"tap","key":"jump","durationMs":120}]}'
运行托管动作:
Invoke-RestMethod 'http://127.0.0.1:47862/action/run' `
-Method Post `
-Headers @{ 'X-Auth-Token' = $token } `
-ContentType 'application/json' `
-Body '{"action":"move_to","x":100,"y":64,"z":200}'
取消托管动作:
Invoke-RestMethod 'http://127.0.0.1:47862/action/cancel' `
-Method Post `
-Headers @{ 'X-Auth-Token' = $token } `
-ContentType 'application/json' `
-Body '{"id":1}'
生成一个本地调试假人:
Invoke-RestMethod 'http://127.0.0.1:47862/debug/fake-player/spawn' `
-Method Post `
-Headers @{ 'X-Auth-Token' = $token } `
-ContentType 'application/json' `
-Body '{"name":"CodexDummy","x":0,"y":80,"z":0,"nameVisible":true}'
移动本地调试假人:
Invoke-RestMethod 'http://127.0.0.1:47862/debug/fake-player/move' `
-Method Post `
-Headers @{ 'X-Auth-Token' = $token } `
-ContentType 'application/json' `
-Body '{"name":"CodexDummy","x":2,"y":80,"z":2,"yaw":180}'
读取本地调试假人:
Invoke-RestMethod 'http://127.0.0.1:47862/debug/fake-player' -Headers @{ 'X-Auth-Token' = $token }
清空本地调试假人:
Invoke-RestMethod 'http://127.0.0.1:47862/debug/fake-player/clear' `
-Method Post `
-Headers @{ 'X-Auth-Token' = $token }
关闭当前 GUI:
Invoke-RestMethod 'http://127.0.0.1:47862/gui/close' `
-Method Post `
-Headers @{ 'X-Auth-Token' = $token }
使用 PowerShell 连接 WebSocket(需要 PowerShell 7+ 或使用其他 WebSocket 客户端):
# 使用 System.Net.WebSockets 连接
$ws = New-Object System.Net.WebSockets.ClientWebSocket
$ws.Options.SetRequestHeader('X-Auth-Token', $token)
$tokenBytes = [System.Text.Encoding]::UTF8.GetBytes($token)
$ws.ConnectAsync('ws://127.0.0.1:47862/ws', [System.Threading.CancellationToken]::None).Wait()
# 发送消息
$message = @{
action = 'ping'
id = 1
} | ConvertTo-Json
$sendBytes = [System.Text.Encoding]::UTF8.GetBytes($message)
$ws.SendAsync($sendBytes, [System.Net.WebSockets.WebSocketMessageType]::Text, $true, [System.Threading.CancellationToken]::None).Wait()
# 接收消息
$buffer = New-Object byte[] 1024
$receive = $ws.ReceiveAsync($buffer, [System.Threading.CancellationToken]::None).Result
$response = [System.Text.Encoding]::UTF8.GetString($buffer, 0, $receive.Count)
Write-Host $response
$ws.CloseAsync([System.Net.WebSockets.WebSocketCloseStatus]::NormalClosure, 'Close', [System.Threading.CancellationToken]::None).Wait()
订阅实时推送:
{
"action": "subscribe",
"topics": ["status", "screen", "target", "container", "players", "chat", "full-state", "action"]
}
订阅后会每 25ms 推送一次订阅的 topic 数据。
取消订阅:
{
"action": "unsubscribe",
"topics": ["status", "screen"]
}
查看当前订阅:
{
"action": "subscriptions"
}
POST /sequence 是动作序列接口,适合脚本化移动/等待/GUI 组合,不是完整寻路算法。POST /action/run 是托管动作接口,会异步执行预定义的动作(如 move_to、place_blocks 等),可以通过 POST /action/cancel 取消。POST /input 是综合输入接口,可以同时设置按键状态、视角和快捷栏,适合需要精确同步的操作。POST /debug/fake-player/* 创建的是客户端本地调试实体,只在你自己的客户端里可见,服务器和其他玩家不会把它当成真实玩家。POST /gui/click-widget 使用 GET /screen 返回的控件索引,索引从 0 开始。所有接口失败时会返回如下格式的错误响应:
{
"error": "错误信息"
}
HTTP 状态码:
200 - 成功400 - 请求参数错误401 - 缺少或错误的 X-Auth-Token404 - 接口不存在500 - 服务器内部错误0.18.41.21.11 / 1.21.8引用的是发表于论文的《Collaborating Action by Action: A Multi-agent LLM Framework for Embodied Reasoning》 https://arxiv.org/abs/2504.17950
27 commits
8 commits
JavaScript
54.9%
Java
45.1%