本版本在安装可选 Server 集成时支持 fastsim-plugin-server[kinematics]>=0.8.3,<0.9
与 fastsim[kinematics]>=0.1.0a19,<0.2。网关只使用
Server 的公开 HTTP 契约,不导入 FastSim 内部模块、不读取私有 Application 状态,
也不会绕过 Server 的权限与生命周期检查。
MCP 宿主 ── stdio ──> fastsim-mcp ── 有界 HTTP ──> fastsim-server ──> FastSimApplication
不持有仿真器 持有一个 Run 槽位
未启动时,本包完全不活动。启动 fastsim-mcp 只会创建 HTTP 客户端;在 MCP
工具被调用前不会发出任何请求。它不会自行启动 HTTP Server 或打开仿真器。如果
Server 和网关均未运行,FastSim 不会承担 MCP 回调、轮询、序列化、网络或逐物理步
开销。
三步开始
第一次使用时,在 FastSim Plugins 仓库根目录执行一次安装脚本:
./packages/fastsim-plugin-mcp/install.sh
脚本会把 MCP 安装到独立的轻量 Python 环境、创建 fastsim-mcp 命令,并在检测到
Codex CLI 时自动注册。它优先使用独立的系统 Python;若没有,则由 Conda 创建专用
前缀,不会复用 Isaac Lab 环境。使用其他 MCP 客户端时,运行以下命令输出可直接
粘贴的通用 JSON:
./packages/fastsim-plugin-mcp/install.sh --client json
以后只需正常启动 FastSim Server:
fastsim-server run.yaml
需要排查连接时运行:
fastsim-mcp doctor
然后重启 Agent,直接用自然语言要求它搭建或调整一份独立场景配置、检查场景、读取 机器人状态、截图、暂停或控制当前 Run。用户不需要填写 Server URL、generation、 幂等键、reason 或 MCP JSON。 Agent 会先读取必要的协议状态并自行生成内部字段。
需要诊断时,直接要求 Agent 检查当前 Run 即可。fastsim_debug_bundle 会并发收集有界的
Run、场景、控制、插件、操作、日志、性能指标以及可选 Geometry 和相机证据;Agent
不再需要串行调用一长串底层工具。
已经自行安装过本包时,可以只执行:
fastsim-mcp setup
MCP 进程和 FastSim Server 使用不同的 Python 环境。只有 HTTP Server 进程需要 FastSim、Isaac Lab 和仿真器依赖。
高级连接配置
默认连接本机 http://127.0.0.1:8000。连接其他 Server 时,重新执行 setup:
fastsim-mcp setup --url https://fastsim.example.com --force
只有需要从 Agent 启动不同配置或读取规划几何时,才需要给 Server 增加对应的高级参数:
fastsim-server \
--launch-root examples=/absolute/path/to/configs \
--planning-reads \
--authority operator
按 Server 默认策略,回环 HTTP 不需要 bearer token。连接受 token 保护的 Server
时,应通过 MCP 宿主的密钥设施或进程环境注入 FASTSIM_HTTP_TOKEN,不要把 token
提交到客户端配置。网关刻意不提供命令行 token 参数,避免密钥出现在进程参数中。
网关只支持 stdio 传输,不打开监听端口。
<details> <summary>高级协议与完整工具参考</summary>
底层连接参数
| 命令行参数 | 环境变量 | 默认值与边界 |
|---|---|---|
--url ORIGIN |
FASTSIM_HTTP_URL |
http://127.0.0.1:8000;只接受精确 http/https 源 |
--timeout SECONDS |
FASTSIM_MCP_TIMEOUT |
15;有限数 0.1..120 |
--max-json-bytes N |
FASTSIM_MCP_MAX_JSON_BYTES |
4194304;1 KiB..16 MiB |
--max-image-bytes N |
FASTSIM_MCP_MAX_IMAGE_BYTES |
16777216;1 KiB..64 MiB |
--audit-log ABSOLUTE_PATH |
FASTSIM_MCP_AUDIT_LOG |
stderr;父目录必须已存在 |
| 无 | FASTSIM_HTTP_TOKEN |
默认未设置;只发送到操作员配置的源 |
HTTP 源由操作员固定,工具无法提供或替换它。包含凭据、路径前缀、查询、片段、不支持 协议或无效端口的 URL 会被拒绝。网关不跟随重定向,也不继承代理环境;JSON 与 PNG 响应在流式读入内存时执行大小限制。
工具目录
所有输入都是严格 JSON 对象。未知字段与类型强制转换会被拒绝。每个输入 schema
都声明 JSON Schema draft 2020-12 与 additionalProperties: false,嵌套的 track
和 frame schema 同样严格。tools/list 直接由校验模型生成,是规范、机器可读的
schema 来源。
只读工具
| 工具 | 输入 | 公开 FastSim 结果 |
|---|---|---|
fastsim_health |
target:live、ready 或默认 both |
进程存活和/或接纳就绪状态 |
fastsim_capabilities |
无 | 感知权限的 fastsim-http/1 能力声明 |
fastsim_run_status |
无 | 当前 Run 元数据与持久启动槽位 generation |
fastsim_run_snapshot |
无 | 有界的公开 FastSimApplication 快照 |
fastsim_debug_bundle |
可选实体 ID、相机 ID、Geometry 开关和有界分页数量 | 并发收集 Agent 可直接分析的 Run、场景、控制、插件、操作、日志、指标、Geometry 与相机证据,并逐项返回错误 |
fastsim_scenario |
section:默认 summary、source、scene、behavior 或 evaluation |
不可变 Scenario 投影 |
fastsim_plugin_status |
可选 instance |
有界 plugin host 快照或一个公开插件实例 |
fastsim_plugin_events |
after_sequence 0..2^63-1(默认 0)、limit 1..100(默认 50),可选 instance、topic |
有序、有界的公开插件事件 |
fastsim_server_logs |
after_sequence 0..2^63-1、limit 1..500、wait_s 0..30 |
有界、脱敏的 Server 与插件事件 |
fastsim_process_metrics |
无 | 一次按需采集的 Server 进程 CPU、内存与可选 GPU 指标 |
fastsim_run_artifacts |
精确槽位 generation |
已提交 Run 工件的有界描述,不返回工件字节 |
fastsim_list_entities |
唯一的 entity_ids、link_ids、kinds 列表(各不超过 32),可选 enabled,offset 0..100000,limit 1..200 |
公开实体、link 与 articulation 分页 |
fastsim_inspect_entity |
精确 entity_id |
静态场景目录与已提交动态状态的组合结果 |
fastsim_robot_state |
精确 entity_id |
articulation 描述与有序关节状态 |
fastsim_camera_screenshot |
匹配 sensors.* 的 entity_id;可选有限 timeout_s (0,30] |
有界 PNG 以及 Run、generation、tick、仿真时间元数据 |
fastsim_deformable_state |
匹配 deformables.* 的 entity_id、sample_count 0..64、可选 timeout |
整体包围盒、质心、速度统计与均匀分布的节点采样 |
fastsim_frame_transform |
source、target,可选 generation 1..2^63-1 |
一个显式规划坐标系变换 |
fastsim_geometry_references |
有界的实体/运动类别/layer/purpose/representation 过滤器、include_transforms、offset 0..100000、limit 1..200 |
不含路径的几何描述与可选已提交变换 |
fastsim_solve_ik |
机器人、Base/Tip Frame、目标位姿;可选 Group、容差、超时、碰撞模式、Seed 与解数量 | 当前 Provider 的有界 IK 结果和关节解;不会执行控制 |
fastsim_control_targets |
无 | 可控 actor、资源组、轴、命令空间和控制器 |
fastsim_control_status |
可选有限 timeout_s (0,30] |
公开控制上下文 |
fastsim_list_operations |
offset 0..100000、limit 1..100,可选精确 state 与 kind |
有界异步操作分页 |
fastsim_operation_status |
小写 UUID operation_id |
一个精确生命周期/控制操作 |
实体类标识符长度为 1..256,首字符为字母或数字,其余字符只允许字母、数字、
_、.、:、/、-。短标识符最长 128 字符。过滤列表不允许重复值。
fastsim_geometry_references 接受运动类别 dynamic、kinematic、static;
用途 collision、planning_proxy、visual;以及 representation:box、
capsule、compound、convex_mesh、cylinder、heightfield、halfspace、
sdf、sphere、triangle_mesh、voxel。工具只返回公开资源引用,不返回
几何字节或主机路径。
变更类工具
每个变更都要求 confirm: true 和去除首尾空白后长度为 1..256 的 reason。
缺失、为 false、类型错误或包含多余字段时,会在任何 HTTP 请求发生前拒绝。异步
生命周期、启动和控制提交要求由 1..128 个安全字符组成的 idempotency_key,并
支持 wait_timeout_s 0..60。直接场景命令的 command_id 和 generation 则保持
可选:省略时由 Core 绑定或生成;高级调用方可在重试同一条命令时复用稳定的
command_id。
| 工具 | 额外输入与边界 | 栅栏与预检查 |
|---|---|---|
fastsim_run_lifecycle |
action:prepare、start、pause、resume、step、reset、stop、close;expected_generation;仅 step 可用的 count 1..1000 |
检查命名生命周期能力;发送幂等与槽位 generation header |
fastsim_launch_catalog_run |
启动根别名;安全相对 .yaml、.yml、.json 或 .toml 配置;target_state:open、prepared 或 running |
检查配置写能力及 /api/v1/launch 公布的别名;不允许任意主机路径 |
fastsim_launch_config |
不超过 1 MiB 的完整独立 YAML、JSON 或 TOML 文本;可移植文件名;target_state:open、prepared 或 running |
检查配置写、上传能力及 Server 公布的字节上限;仍由正常 FastSim 编译器做最终校验 |
fastsim_set_entity_pose |
已有 entity_id;世界坐标 xyz_m;默认单位四元数 quat_xyzw;可选 generation、command_id 和 deadline |
检查公开位姿能力;MCP 自动处理可替换 Server 槽位的 generation 围栏 |
fastsim_attach_entity |
刚体或铰接体 child;刚体或铰接 parent;可选 parent/child link 与相对位姿 | 创建固定物理关系并返回 attachment_id |
fastsim_detach_entity |
刚体或铰接体 child 和上一步返回的 attachment_id |
解除关系,不重置 child 铰接状态 |
fastsim_begin_entity_drag |
已有 entity_id;世界坐标抓取点;可选 generation、command_id、drag_id 和 deadline |
返回 Core drag_id;检查公开拖拽能力并自动处理所需槽位围栏 |
fastsim_update_entity_drag |
已有 entity_id;上一步返回的 drag_id;世界位姿;可选 generation、命令标识和 deadline |
向同一条 Core 拖拽事务转发一次更新 |
fastsim_end_entity_drag |
已有 entity_id;返回的 drag_id;可选 generation、命令标识和 deadline |
正常结束 Core 拖拽事务 |
fastsim_cancel_entity_drag |
已有 entity_id;返回的 drag_id;可选 generation、命令标识和 deadline |
取消 Core 拖拽事务 |
fastsim_submit_joint_path |
actor/group;1..256 个等宽帧;1..64 个轴;最多 16,384 个 +/-1e9 内的有限值;有限 dt (0,10];可选 timeout (0,300];preempt;expected_generation |
检查控制写能力和精确公开 actor/group target;发送幂等与槽位 generation header |
fastsim_submit_tracks |
1..16 个资源不重叠的 track,总帧数不超过 2,048;可选 timeout (0,300];preempt;expected_generation |
检查控制写能力及每个精确公开 entity/resource target;发送幂等与槽位 generation header |
fastsim_cancel_operation |
小写 UUID operation_id |
先读取当前状态并拒绝终态操作;是否可取消由 Server 最终判断 |
每个 physical track 包含:
entity_id、resource_group,以及类似joint.passthrough@1的带版本controller和command_space标识符;1..512个 frame,必须从0.0秒开始且时间严格递增;1..64个唯一轴、等长的有限 value 和 unit 列表;这些定义在同一 track 内必须 保持稳定,还可包含一个稳定的 frame 标识符;interpolation为默认zero_order_hold或linear;- 可选 JSON
semantics,深度不超过 8、条目不超过 1,024、key 不超过 128 字符、 每个字符串不超过 2,048 UTF-8 字节。
FastSim HTTP Server 始终是最终权威。MCP 侧的校验与预检查用于减少含糊或过期请求,
但不会替代 Server 对 schema、权限、生命周期、generation、资源和控制器的校验。
场景工具只移动已有实体,不生成资产,也不重新实现拖拽物理。IK 是独立的只读计算
工具,绝不会移动机器人。场景命令返回结果直接包含 status、run_id、generation、
scene_sequence、sim_tick,以及可选的
attachment_id、drag_id 或拒绝详情。
返回契约
每个工具都会返回 structured content 和一个 JSON 文本块,统一使用以下 envelope:
{
"ok": true,
"tool": "fastsim_run_status",
"api_version": "fastsim-http/1",
"data": {}
}
变更还会包含有界的公开审计元数据。相机截图会额外返回一个 MCP image/png 内容块。
失败会设置 MCP isError,并使用经过清理的 error envelope:
{
"ok": false,
"tool": "fastsim_run_status",
"api_version": "fastsim-http/1",
"error": {
"code": "application_not_ready",
"message": "application is not ready",
"retryable": true,
"http_status": 503,
"request_id": "request-id-if-published"
}
}
Bearer token、请求 body、本地路径、stack trace 与异常 repr 都不会写入工具错误。遇到
fastsim-http/1 以外的协议版本时,网关会按 fail-closed 原则拒绝继续。
变更审计
每次网络变更前,网关先追加一条 requested JSON Lines 记录。Server 接受请求后追加
accepted;发生已知失败后追加 rejected。如果变更前记录无法持久化,则不会发送
变更请求。
{"schema":"fastsim-mcp-audit/1","timestamp":"2026-08-26T12:00:00+00:00","audit_id":"...","tool":"fastsim_run_lifecycle","target":"run:step","reason":"advance one reviewed tick","outcome":"requested","idempotency_key_sha256":"...","expected_generation":7}
原始幂等 key 与 bearer token 永不写入审计。默认目标是 stderr,与 MCP stdio 协议流
分离。需要持久日志时,请在已存在、由操作员管理的目录中配置绝对审计路径;新文件模式
为 0600。日志保护、轮转与保留由部署策略负责。
审计结果 accepted 表示 HTTP 提交已被接受,不表示异步操作最终成功。请检查返回状态
或调用 fastsim_operation_status。
推荐操作顺序
- 调用
fastsim_health和fastsim_capabilities。 - 调用
fastsim_run_status,记录当前槽位 generation。 - 若槽位为空,操作员维护的配置使用
fastsim_launch_catalog_run;Agent 直接生成的 完整配置使用fastsim_launch_config,提交前检查场景位姿、reason 和幂等键。 - 启动或替换后重新读取
fastsim_run_status。 - 控制前调用
fastsim_control_targets以及相关状态/几何读取工具,并使用该精确 generation 提交。 - 检查返回的 operation,或使用有界
wait_timeout_s;取消时必须显式给出 UUID。
不要将同一个 idempotency key 用于不同请求。过期 generation 是安全信号:应刷新状态并 重新评估命令,不能将命令静默重试到替换后的 Run。
刻意保留的边界
本版本不公开:
- 任意 HTTP 请求、由调用方选择的 origin、Server 启停或 MCP-over-HTTP 传输;
- 多文件配置上传、任意主机路径、Run artifact 字节或本地资源定位信息;
fastsim_launch_config只接受一份可独立编译的配置; - 场景/实体变更、直接插件方法调用或插件安装;
- 深度、法线、分割、contact、粒子流体状态、几何字节或 subscription;
- 自动重试、无界轮询、后台 worker、仿真器 callback 或逐 tick hook。
这些是能力边界,而不是未记录的工具。需要新操作时,应先扩展公开 FastSim/Server 契约。
具体而言,Server 未提供 writes.entity_mutation 时会明确发布为 false,所以本网关不会虚构场景
创建或删除工具。
开发与验证
cd packages/fastsim-plugin-mcp
python -m pip install -e '.[test]'
ruff check .
mypy src tests
pytest -q
python -m build
协议测试验证精确 path、header、body、MCP schema、能力拒绝、审计顺序、响应大小限制、 认证、相机内容与无 I/O 构造;同时让每个公开工具通过当前兼容 Server 的真实 ASGI 应用和 MCP stdio 传输。确定性的 reference application 不是 GPU 仿真器,因此这些测试不声明 GPU、 GUI 或真实仿真后端已经通过。
</details>