Skip to main content
Glama

game-bridge-mcp

让 AI 代理启动你的游戏、驱动它,并读取所发生的一切——通过 HTTP,每个实例一个端口。

你的游戏已经知道关于自身的一切:屏幕上有什么、每个实体在哪里、它接受哪些命令。game-bridge-mcp 是一个 MCP 服务器,它把这些交给代理——作为代理可以调用的工具,从运行中的游戏动态发现,而不是在这里硬编码。

agent ──MCP(stdio)──▶ game-bridge-mcp ──HTTP──▶ 127.0.0.1:7820  ← it launched this one
                                      ├───────▶ 127.0.0.1:7801  ← your IDE started this one
                                      └───────▶ 127.0.0.1:7802  ← a colleague's session

有三件事使它不仅仅是一个你花一个下午就能写出来的调试桥接脚本:

  • 它启动实例并选择端口。 调用者永远不需要选择端口或输入构建命令,因此两个代理不会冲突,桥接器会回收它启动的东西——会话结束后不会留下孤儿游戏窗口。

  • 每个工具都接受 port。 一个桥接器驱动你运行的每一个实例:一台机器上的多个代理,或者一个代理并排比较两个构建。

  • 工具列表来自游戏。 桥接器在运行时从每个实例获取 GET /tools,因此你今天早上添加的调试命令下午就可以调用——无需发布此包、无需重新连接,代理认为游戏接受的与游戏实际接受的之间也不会产生漂移。

它与引擎无关。任何语言,任何能在 localhost 上提供四个小型 HTTP 端点的东西都可以。这个契约刻意保持简短。


快速开始

npx @wildware/game-bridge-mcp --help

将其注册到 MCP 客户端——对于 Claude Code,从你的项目目录执行:

claude mcp add game-bridge -- npx -y @wildware/game-bridge-mcp

然后,从代理的角度:

launch_instance {}                                 // start a game; the bridge picks the port
list_instances  {}                                 // ...or find one already running
list_toolsets   { "port": 7820 }                   // what can this instance do?
describe_toolset { "port": 7820, "name": "play" }  // exact schemas
call_tool { "port": 7820, "name": "drop", "arguments": { "x": 1.2 } }
stop_instance { "port": 7820 }                     // clean shutdown, not a kill

launch_instance 需要一个启动声明。其他一切都可以针对任何实现了 HTTP 接口的游戏工作,无论这个桥接器是否启动了它。


Related MCP server: onyx MCP

契约

实现这个,你的游戏就可以被任何代理通过这个桥接器驱动,而这里没有任何代码需要了解它。它有三个部分,每一部分都带来特定的价值:

部分

它带来的价值

1. HTTP 接口

读取和驱动一个运行中的实例。

2. 自我注册

无需猜测端口即可找到实例。

3. 启动声明

无需人工选择端口即可启动实例。

只有第 1 部分是必需的。第 2 部分让发现变得可靠;第 3 部分让整个事情变得愉快。

1. HTTP 接口

在 127.0.0.1:<port> 上提供这些端点,端口来自一个显式的调试标志。只绑定到 loopback,并且除非游戏以该标志启动,否则保持整个接口关闭:这是一个调试接口,不是网络服务。

GET /health — 必需

存活性和身份检查。发现机制会对一个范围内的每个端口调用它,所以它必须廉价。

GET /health
{ "ok": true, "frame": 91422 }

ok: true 是将端口标记为我们的的标志。一个以其他内容响应 HTTP 的端口会被报告给代理为"其他东西占用了这个端口"——这是一个不同的问题,需要不同的修复方式,与"游戏没有运行"不同。

frame 是一个在进程生命周期内递增的计数器。桥接器监视它:frame 倒退意味着一个新进程正在这个端口上响应,缓存的工具清单会自动丢弃。这就是让重建并重新运行对代理不可见的原因。

GET /state — 必需

完整快照:代理可能想知道的一切,以 JSON 形式。没有必需的 schema——这是你的游戏——但一些约定俗成的字段可以解锁桥接器功能:

{
  "frame": 91422,
  "simFrame": 48110,
  "completedCommandId": 17,
  "paused": false,
  "ui": {
    "screen": "GameScreen",
    "elements": [ { "label": "Restart", "visible": true } ]
  },
  "events": [ { "m": "merge:cherry" }, { "m": "click:Restart" } ],
  "game": { "score": 1280, "state": "RUNNING" }
}

字段

桥接器为什么关心它

frame

重启检测;命令已运行的兜底确认。

completedCommandId

命令已运行的强确认——见下文。

ui.screen

由 list_instances 报告,因此五个实例一眼就能区分开。

ui.elements[].label / .visible

包含在紧凑的 get_state 摘要中。

events[].m

最近的事件,在每条命令之后返回,以便代理看到结果。纯字符串也被接受。

game

标量字段包含在摘要中。嵌套对象和数组不包含——那是兆字节级实体列表所在的地方。

你放在这里的其他一切都会被 get_state 原样透传。

GET /command — 必需

GET /command?cmd=spawn&type=cherry&x=-1.5
{ "accepted": true, "commandId": 18, "frame": 91430 }

命令名称的键是 cmd,而不是 name——命令通常会自带一个 name 参数,重复的查询键会静默覆盖正在调用的命令。其他每个查询参数都是一个参数。

这个端点是即发即忘的,这是理解契约的最重要的一点。 它在命令被排队的那一刻就从 HTTP 线程返回;命令本身稍后在游戏线程上运行。紧接着读取 /state 的客户端读到的是命令发生之前的世界。测试看起来不稳定;游戏没问题。

桥接器处理了这一点,它处理的方式就是你的游戏应该支持的:

  1. GET /command?... → 记下返回的 commandId。

  2. 轮询 GET /state,直到 completedCommandId >= commandId。

  3. 返回那个状态——确实是在命令运行之后。

如果你的游戏不发布 completedCommandId,桥接器会降级为等待 frame 前进两次,并将结果标记为 "confirmation": "frames-advanced",这样代理就知道它得到的是较弱的保证。发布 completedCommandId 只需要几行代码,而且值得:

// game thread, once per frame
while (true) {
    val cmd = queue.poll() ?: break
    apply(cmd)
    completedCommandId = cmd.id   // published in the next /state snapshot
}

强烈建议提供一个 close 命令,通过正常的关闭流程来关闭游戏:它让代理无需杀死进程就能结束一个实例。桥接器对 close 有特殊处理——它从不等待一个不可能到达的完成信号,而是等待端口安静下来。

GET /tools — 可选,但这是最精彩的部分

清单:你的游戏可以被要求做什么,用它自己的话来说。

{
  "game": { "name": "Orbital Freight", "version": "0.9.2", "protocol": 1 },
  "toolsets": [
    {
      "name": "play",
      "description": "Drive the game the way a player does.",
      "tools": [
        {
          "name": "drop",
          "description": "Release the held crate, aiming first if x is given.",
          "args": [
            { "name": "x", "type": "number", "description": "World x, -2..2", "required": true, "default": null },
            { "name": "settle", "type": "boolean", "description": "Wait for the stack to settle", "default": "true" }
          ]
        }
      ]
    }
  ],
  "passthrough": {
    "description": "Any command the debug bridge accepts, passed straight through.",
    "examples": ["set_seed { seed }", "set_gravity { x, y }"]
  }
}

字段

含义

game.name、game.version

身份标识。由 list_instances 显示,这就是代理区分五个运行中实例的方式。

game.protocol

为文档版本化,而不是命令集。添加命令不会改变这里;重组清单才会。它让桥接器区分"我读不懂这个"和"这个游戏知道的命令和上次不同"。当前版本:1。

toolsets[]

以调用者想要做什么来命名的分组,而不是按你的代码如何组织。保持少量且直观。

tools[].name

代理调用的名称。

tools[].description

为代理编写。说明它做什么以及何时使用它——这是模型推理所依据的文本。

tools[].args[]

{ name, type, description, required, default }。type 是 JSON Schema 类型名称,因此一个转换器可以同时服务于游戏命令和桥接器工具。

tools[].command

要发送的 cmd,如果与工具名称不同的话。默认为名称。

tools[].sync

对于不能等待的命令为 false。默认为 true。

tools[].inputSchema

如果你已经有 JSON Schema,发送它而不是 args,它会按原样使用。

passthrough

自由文本加示例,描述你尚未正式发布的命令。

默认值可以是字符串("true"、"0.05")——从类型化语言序列化的清单通常会这样渲染它们。桥接器将它们折叠到描述中,而不是在 schema 中发出 default,因为 boolean 属性上的 default: "false" 可能会被严格的客户端拒绝。null 表示"无默认值"。

解析器刻意保持宽容,因为清单是用手头已有的序列化器编写的:

  • toolsets 可以是对象数组,也可以是 name → toolset 的映射。

  • 参数可以放在 args、arguments 或 params 下,可以是对象数组、裸名称数组,也可以是 name → { type, description } 的映射。

  • 格式错误的工具会被丢弃,而不是致命错误。一个坏条目不能使整个实例离线。

如果 /tools 返回 404,什么也不会坏。 桥接器回退到只包含契约级工具的内置清单,并告诉代理游戏没有发布命令列表,所以通过 raw_command 工作并读取 /state。实例相应地报告为 live 或 live-no-manifest,--manifest ./my-game.json 为无法修改的游戏从文件提供清单。

2. 自我注册

端口扫描是发现机制的弱形式:受限于某人猜测的范围,在游戏应答之前对身份保持沉默,并且在启动期间容易产生假阴性——而这正是代理最可能查看的时刻。

所以一个成功绑定其调试端口的游戏会写入一个小的 JSON 文件来表明自己的身份:

~/.game-bridge/instances/<pid>.json
{
  "name": "Orbital Freight",
  "version": "0.9.2",
  "protocol": 1,
  "port": 7820,
  "pid": 12345,
  "host": "127.0.0.1",
  "started": "2026-08-20T22:27:19.774Z",
  "cwd": "/home/dev/checkouts/main"
}

cwd 是刻意的:同一个游戏的多个检出同时运行,"这是哪个构建?"否则从进程外部无法回答。

写入者必须遵守的规则:

  • 在端口绑定之后再写入条目,绝不提前。为从未被占用的端口写条目比不写更糟。

  • 在干净关闭时删除条目。

  • 绝不让注册表故障破坏游戏。 目录不可写、主目录只读、沙箱环境——游戏都必须照常启动并照常提供端点服务。这是广告,不是基础设施。

  • 若设置了 GAME_BRIDGE_INSTANCES(条目目录)或 GAME_BRIDGE_HOME(其父目录),则予以遵循。

读者必须遵守的规则——这些更重要:

  • 条目仅供参考,绝不具有权威性。 崩溃或强制终止都会留下文件。这在实践中屡见不鲜。

  • 在相信任何条目之前,先用 GET /health 验证。 端口无响应的条目是过期文件,不是运行中的游戏,必须如实报告为过期文件而非实例。

  • 绝不因条目而信任超过实时游戏本身。 桥接器在游戏应答时从 /tools 获取名称和版本,条目仅用于补充线上协议无法传达的信息:pid、工作目录、启动时间。

  • 默认不删除其他进程的文件。 仍在绑定端口的游戏与已崩溃的游戏在一两秒内无法区分。桥接器仅在显式指定 prune: true 时清理,且仅在确认端口已死之后。

  • 持续扫描。 早于注册表出现的游戏仍然存在;桥接器合并注册表条目与端口扫描结果,按端口去重,并将每个实例的 discovery 报告为 registry、scan 或 both。

3. 启动声明

项目只需声明一次启动方式,调用方就永远不必输入构建命令或挑选端口。将 gamebridge.json 放在项目根目录——桥接器会从其工作目录向上查找该文件,方式与其他所有 JS 工具查找配置的方式相同,--config <file> 可覆盖此行为。

{
  "name": "Orbital Freight",
  "launch": {
    "command": "./gradlew lwjgl3:run -PdebugPort={port} --console=plain",
    "cwd": ".",
    "portRange": "7820-7839",
    "readyTimeoutMs": 180000,
    "env": { "ORBITAL_DEV": "1" }
  }
}

字段

含义

command

Shell 命令行。{port} 会被替换。端口必须从这里到达游戏——这就是整个机制的核心。

argv

command 的替代方案:["./run-game", "--port", "{port}"],不经 shell 执行。

cwd

工作目录,相对于此文件解析——而非相对于 MCP 客户端恰好启动桥接器的位置,后者几乎从不等于项目目录。

portRange

启动器可占用的端口范围。默认 7820-7839,刻意避开 7777 和 7800-7810——这些是人们手动分配的端口。

readyTimeoutMs

等待 /health 的超时时间。冷构建加 JVM 需要数十秒;默认值为 180000。

env、extraArgs

额外环境变量和尾部参数。

启动器随后保证:

  • 端口经过两次验证为空闲——既无绑定,也无健康检查应答——因为启动中的游戏可能已在关键意义上占用了端口,而毫秒前绑定测试却仍然失败。若声明的范围已满,则回退到操作系统分配的端口。

  • launch_instance 仅在 /health 应答后才返回,调用方因此永远不需要编写重试循环。

  • 启动失败会响亮地失败,并附上子进程自身的输出。 游戏启动失败时,堆栈跟踪就是全部答案:

    BridgeUsageError: Launch failed on port 7820: the process exited with code 1.
    Command: ./gradlew lwjgl3:run -PdebugPort=7820 --console=plain
    Working directory: /home/dev/orbital
    Full log: /tmp/game-bridge-logs/instance-7820-1787264781573.log
    
    Last output:
    'gradlew' is not recognized as an internal or external command,
    operable program or batch file.
  • stdout 和 stderr 被捕获到该日志文件中,贯穿实例整个生命周期,最近 200 行保存在内存中供 instance_log 使用。

  • 子进程会被回收。 在 stop_instance 时、服务器关闭时、收到 SIGINT、SIGTERM 或客户端断开连接时,每个已启动的实例都会被关闭——先执行游戏自身的 close 命令,若其不肯退出则终止整个进程树。已关闭的会话绝不会在桌面上留下游戏窗口。

超出干净关闭的升级措施仅适用于本桥接器启动且仍在跟踪的进程。对任何其他端口调用 stop_instance 会被拒绝,并提示你请游戏自行关闭。


工具

工具

参数

功能

launch_instance

port?、timeoutMs?

启动游戏,挑选空闲端口,等待 /health,返回句柄。

list_instances

range?、registry?、scan?、prune?

注册表加端口扫描。名称、版本、pid、工作目录、屏幕。只读。

stop_instance

port?、graceMs?

干净关闭,然后升级处理——仅适用于本桥接器启动的实例。

instance_log

port?、lines?

已启动实例的捕获 stdout/stderr。

list_toolsets

port?

该实例的工具集,按其自身描述。

describe_toolset

port?、name

完整 JSON Schema。bridge 指桥接器自身的工具,passthrough 指未发布的命令。

call_tool

port?、name、arguments?

运行工具,等待游戏确认,返回结果摘要。

只公布这七个。游戏自身的工具通过 call_tool 访问,因为 MCP 客户端在连接时只会收到一次工具列表,之后不会再询问——固定列表对仍在开发中的游戏来说会过时,而当同一会话驱动两个不同构建时则根本是错误的。(--eager 会为无法遍历发现路径的客户端预先扁平化所有内容。)

桥接器自身的工具集

为每个合规游戏提供,无论其为何物:

工具

功能

get_state

完整的 /state 快照,或 summary: true 获取紧凑摘要。

get_health

存活状态和帧计数器。

raw_command

按名称执行任意命令,无论是否已发布。

wait_for

轮询 /state 直到字段达到某值、字段发生变化或事件出现。这就是等待启动它的命令无法报告之事的方式——排队的截图落盘、模拟到达第 N 帧。

close

干净关闭;端口静默即为确认。

call_tool 如何解析名称

  1. 桥接器的复合工具,包括宿主应用注册的任何复合工具。复合工具会遮蔽同名游戏命令,这始终是改进而非意外:复合工具之所以使用该名称,正是因为原始命令在它所请求的事情发生之前就已返回。

  2. 游戏的清单——未命中时重新获取一次,以便重建后带有新命令的游戏能在会话中途被发现。

  3. 透传——其他任何内容都作为原始命令发送。存在于游戏中但不在清单中的命令今天仍然可用。若游戏将其拒绝为未知命令,你会收到它可接受的命令列表。

port 如何解析

每个工具都接受可选的 port(在顶层或 arguments 内)。解析顺序如下:

  1. 调用中显式的 port,

  2. 命令行中的 --port,

  3. 环境变量 GAME_BRIDGE_PORT,

  4. 7777。

因此单实例设置永远不需要考虑端口,多实例会话也永远不需要第二个服务器。


同时驱动两个实例

这是本工具为之构建的场景:同一游戏的两个构建并排运行,一个代理,一个会话。

// 1. What is already running?
list_instances {}
{
  "registryDir": "/home/dev/.game-bridge/instances",
  "live": [
    { "port": 7801, "discovery": "scan", "status": "live-no-manifest",
      "frame": 2453, "manifest": "fallback", "screen": "GameScreen" },
    { "port": 7820, "discovery": "both", "status": "live", "game": "Orbital Freight",
      "version": "0.9.2", "protocol": 1, "manifest": "game", "pid": 87488,
      "cwd": "/home/dev/checkouts/main", "screen": "MenuScreen",
      "toolsets": ["play", "build", "flow", "bridge"], "launchedByThisBridge": true }
  ],
  "stale": [],
  "notAGame": [],
  "free": [7777, 7802, 7803]
}

端口 7801 是较旧的构建,没有 /tools:仍然完全可以驱动,只是不能自我描述。端口 7820 是本桥接器启动的。

// 2. Start a second one. You do not choose the port.
launch_instance {}
{ "port": 7821, "pid": 90114, "name": "Orbital Freight", "version": "0.9.3-rc1",
  "cwd": "/home/dev/checkouts/rc", "readyInMs": 4080,
  "logFile": "/tmp/game-bridge-logs/instance-7821-1787264835950.log" }
// 3. Same seed, same move, both runs.
call_tool { "port": 7820, "name": "set_seed", "arguments": { "seed": 12345 } }
call_tool { "port": 7821, "name": "set_seed", "arguments": { "seed": 12345 } }

call_tool { "port": 7820, "name": "drop", "arguments": { "x": 1.2 } }
call_tool { "port": 7821, "name": "drop", "arguments": { "x": 1.2 } }

每个都返回命令应用之后的状态,因此两者可以直接比较:

{
  "port": 7821, "tool": "drop", "via": "manifest", "command": "drop",
  "applied": true, "commandId": 18, "confirmation": "completedCommandId",
  "frame": 948, "screen": "GameScreen",
  "game": { "score": 1280, "state": "RUNNING" },
  "events": ["merge:cherry", "score:+40"]
}
// 4. Wait for something the command could not report.
call_tool { "port": 7821, "name": "wait_for",
            "arguments": { "path": "game.pendingMerges", "equals": 0, "timeoutMs": 5000 } }

// 5. Clean up what you started. 7801 is not yours - leave it alone.
stop_instance { "port": 7821 }
{ "port": 7821, "stopped": true, "how": "closed cleanly" }

当出现问题时

桥接器能区分从外部看起来完全相同的失败:

GameOffline: No game is answering on http://127.0.0.1:7809.
Start one with:
  ./gradlew lwjgl3:run -PdebugPort=7809

NotAGameSurface: Something is listening on http://127.0.0.1:7802, but it is not a
debuggable game: GET /health returned HTTP 404.
A drivable game must answer GET /health with {"ok":true,"frame":N}. Check whether
another process has taken this port.

CommandTimeout: Command 'restart' was queued on port 7801 but was not applied
within 5000ms. The game accepted it, so it is probably blocked, frozen, or on a
screen that ignores this command.

用 --launch-hint "make run PORT={port}" 设置第一条消息中指定的命令(或让 launch_instance 代为启动)。


CLI

npx @wildware/game-bridge-mcp [options]

  -p, --port <n>           Default port for tools that do not name one (default 7777)
      --scan-range <spec>  Ports list_instances sweeps (default 7777,7800-7810)
      --no-scan            Discover only via the instance registry
      --no-registry        Discover only by scanning ports
      --registry-dir <dir> Where instance entries live (default ~/.game-bridge/instances)
      --config <file>      Project launch declaration (default: nearest gamebridge.json)
      --launch-hint <cmd>  Command shown when a port is dead; {port} is substituted
      --manifest <file>    Tool manifest for games that do not serve GET /tools
      --eager              Advertise every tool flatly, for clients that cannot discover
      --timeout <ms>       HTTP and command timeout (default 5000)
  -h, --help
  -v, --version

环境变量:GAME_BRIDGE_PORT、GAME_BRIDGE_SCAN_RANGE(或 GAME_BRIDGE_SCAN)、GAME_BRIDGE_LAUNCH_HINT(或 GAME_BRIDGE_LAUNCH)、GAME_BRIDGE_MANIFEST、GAME_BRIDGE_CONFIG、GAME_BRIDGE_INSTANCES、GAME_BRIDGE_HOME。

桥接器记录的所有日志都输出到 stderr;stdout 是 MCP 传输通道,上面任何多余的一行都会破坏协议流。


在自己的项目中使用

这些组件既以 CLI 形式发布,也作为导出项提供。如果你的游戏需要串联多个命令的工具——"落子,然后等待棋盘稳定,然后报告分数差"——将它们注册为复合工具,即可继承协议、启动器、发现机制和错误消息,而无需维护第二份副本。

#!/usr/bin/env node
import { parseCli, applyProjectConfig, startStdioServer } from "@wildware/game-bridge-mcp";

const { config } = parseCli(process.argv.slice(2), process.env);
await applyProjectConfig(config);

await startStdioServer(config, {
  composites: [
    {
      name: "drop_and_settle",
      description: "Drop at world x and wait until nothing is moving. The main way to play.",
      only: "Orbital Freight",            // never offered to a game that has no crates
      args: [{ name: "x", type: "number", required: true, description: "World x" }],
      async run(ctx) {
        const before = await ctx.state();
        await ctx.commandAndSync("drop", { x: ctx.args.x });
        const settled = await ctx.call("wait_for", { path: "game.moving", equals: 0, timeoutMs: 10000 });
        const after = await ctx.state();
        return { settled: settled.matched, scoreDelta: after.game.score - before.game.score };
      },
    },
  ],
});

复合工具会获得一个限定到单个实例的上下文——state、health、command、commandAndSync、call(任何其他工具)、manifest、summarise、sleep——因此它永远不需要考虑端口。only 指定其适用的游戏,与清单中的 game.name 匹配;声称通用的桥接器绝不能向飞行模拟器提供 drop_and_settle。

复合工具的归属规则:它要么串联多个命令,要么等待 /command 无法报告的事情。任何只是一个命令加一组参数的内容都应属于游戏自身的清单,在那里它与实现它的代码保持同步。

更底层的组件——Bridge、GameClient、Launcher、readRegistry、normaliseManifest——也已导出。Bridge 和 GameClient 接受可选的 fetchImpl,这正是测试套件在无游戏、无套接字的情况下驱动整个系统的方式。


开发

npm install
npm run build     # TypeScript -> dist/
npm test          # builds, then runs node --test

81 个测试,均无需运行中的游戏:端口解析顺序、清单缓存及其三条失效路径、/tools 404 回退、命令/轮询/确认循环及其帧推进降级、读取含过期和畸形条目的注册表、启动器端口选择、启动失败与子进程回收,以及通过内存传输驱动的 MCP 表面本身。

发布

尚未发布到 npm。发布时:

npm version minor          # keep SERVER_VERSION in src/server.ts in step
npm test                   # prepublishOnly runs build + test again
npm pack --dry-run         # confirm dist/, README.md and LICENSE are the payload
npm publish                # publishConfig.access is already "public"

package.json 中的 files 将 tarball 限制为 dist/、README.md 和 LICENSE;prepare 在从 git 安装时构建,因此通过 git 安装的依赖无需签入 dist/ 即可工作。

许可证

MIT — 参见 LICENSE。

Available Tools

7 tools
call_toolA

Run a tool on one instance and return the result. Accepts any tool from any of that instance's toolsets, and any raw debug command it understands even if unpublished. Commands are waited on until the game reports them applied, so the state returned is the state after the command ran.

NameRequiredDescriptionDefault
nameYesTool or command name
portNoDebug port of the game instance to talk to. Defaults to the bridge's --port, then GAME_BRIDGE_PORT, then 7777. launch_instance returns one; list_instances finds the rest.
argumentsNoArguments for the tool

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full behavioral burden. It discloses that it accepts unpublished raw debug commands, runs on one instance, waits until the game reports the command applied, and returns the state after execution. This gives an agent crucial insight into side effects and synchronization behavior beyond the schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two focused sentences with no filler. The primary purpose is front-loaded, and the important behavioral qualifiers about command applicability and waiting semantics are delivered compactly.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description is largely complete for a generic dynamic executor, especially given the schema documents parameters. It covers purpose, target scope, command breadth, and post-command state. It does not enumerate return-value shapes or possible errors, but that is difficult for arbitrary tools and is not a major gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds meaningful semantics to the 'name' parameter by explaining it can be any tool from the instance's toolsets or any raw debug command, even unpublished. It also implicitly ties 'port' to 'one instance' and clarifies that arguments are forwarded to the selected tool or command.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: 'Run a tool on one instance and return the result.' It clearly distinguishes call_tool from the lifecycle/discovery siblings (launch_instance, list_instances, stop_instance, instance_log) by framing it as the generic executor for any tool or command.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage context instead of stating it explicitly: use this tool when you need to run any tool or raw debug command against a single instance. However, it never mentions alternatives or calls out when not to use it, such as preferring instance_log for log retrieval or launch_instance for starting a game.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

describe_toolsetA

Full schemas for the tools in one toolset on one instance. 'bridge' is the toolset this bridge adds itself; 'passthrough' explains how to send commands the game has not published.

NameRequiredDescriptionDefault
nameYesToolset name, 'bridge', or 'passthrough'
portNoDebug port of the game instance to talk to. Defaults to the bridge's --port, then GAME_BRIDGE_PORT, then 7777. launch_instance returns one; list_instances finds the rest.

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description must carry behavioral disclosure. It implies a read-only introspection operation by saying it provides 'full schemas' and 'explains' commands, which is reasonably transparent. It does not mention error behavior, whether a running instance is required, or that it makes no modifications, but the read-only nature is strongly implied.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact, with the core purpose front-loaded in the first sentence and essential special-case terminology in the second. Every sentence contributes useful information and there is no filler or repetition of schema content.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple introspection tool with two parameters and full schema coverage, the description covers the essential semantics including special name values and instance scoping. It does not describe the exact return structure, but 'full schemas' sufficiently conveys the expected output for this tool type. Missing explicit usage guidance vs siblings is the main gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The tool description adds genuine value beyond the schema by explaining what 'bridge' and 'passthrough' mean for the name parameter, which the schema only lists as allowed values. Port semantics are already fully covered in the parameter description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states that the tool returns full schemas for all tools in a toolset on a single instance, which is a specific, recognizable purpose. It also distinguishes itself from siblings like list_toolsets by emphasizing schema detail and instance scoping. The special values 'bridge' and 'passthrough' add useful differentiation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The intended use is implied: if an agent needs full tool schemas, this is the tool. However, it does not explicitly contrast with list_toolsets, call_tool, or other siblings, nor state when not to use it. The explanation of 'bridge' and 'passthrough' gives usage context but not alternative-based selection guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

instance_logA

The captured stdout/stderr of an instance this bridge launched. When a game fails to boot, or dies mid-session, the stack trace is here and nowhere else.

NameRequiredDescriptionDefault
portNoDebug port of the game instance to talk to. Defaults to the bridge's --port, then GAME_BRIDGE_PORT, then 7777. launch_instance returns one; list_instances finds the rest.
linesNoHow many trailing lines (default 50)

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the behavioral burden. It clearly states this is a read-only view of captured stdout/stderr from bridge-launched instances and that the interesting failure information is 'here and nowhere else', giving a strong execution-time mental model. It doesn't mention output formatting or truncation, but the captured-log framing covers the main behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences: the first defines what the tool returns, the second says when to use it. No filler, no repetition of schema details, and the key use case is front-loaded early.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read-only log tool with two optional parameters and schema-covered parameter semantics, this description plus the schema is nearly complete. It tells the agent what the tool does, which scenarios call for it, and how parameters work. A minor gap is the exact return format, but with no output schema this is not critical.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the parameters port and lines already have clear meaning, defaults, and port resolution order. The description adds no extra parameter-level detail, but the baseline is 3 when schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description identifies the tool's resource: captured stdout/stderr for an instance launched by this bridge, and ties it to boot failures and mid-session crashes. It lacks an explicit verb like 'get' or 'read', but the meaning is unmistakable and it is clearly distinct from the launch/list/stop siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives direct usage context: when a game fails to boot or dies mid-session, the stack trace is here. It doesn't name alternative tools, but among lifecycle/toolset siblings this one is obviously the log-reader, so the guidance is sufficient.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

launch_instanceA

Start a game instance and wait until it answers. The bridge picks a free port itself, so you never choose one and never collide with someone else's instance, and it owns the process: it is reaped when this server shuts down. Uses the project's launch declaration (gamebridge.json). Returns the port to pass to every other tool. Prefer this over starting the game yourself.

NameRequiredDescriptionDefault
portNoForce a specific port instead of letting the bridge choose. Rarely needed.
timeoutMsNoHow long to wait for the game to answer. A cold build plus a JVM can take minutes.

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries full behavioral burden, and it largely succeeds. It discloses that launch is synchronous ('wait until it answers'), that ports are auto-selected to avoid collisions, that the bridge owns the process and reaps it on shutdown, that it reads the project's gamebridge.json, and that the tool returns a port. These are exactly the behavioral details an agent needs beyond the schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Every sentence earns its place. The description is front-loaded with the core action and wait behavior, then explains port auto-selection, process ownership, config source, return value, and provides a usage recommendation. It is compact, well-organized, and free of filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with two optional parameters and no output schema, the description explains the key runtime contract: the launched process lifecycle, how the port is chosen, what the return value is for, and why the tool should be preferred over manual startup. An agent has enough context to select and call the tool correctly, including what to do with the returned port.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema already documents both parameters (port and timeoutMs), so baseline is 3. The description adds meaningful context beyond the schema: the bridge automatically picks a free port, so forcing one is rarely needed, and the returned port must be passed to all other tools. This helps an agent understand when and why to use or omit the optional port parameter. Timeout semantics are left mostly to the schema, but the description's 'wait until it answers' supports the intent.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description starts with a clear, specific verb and resource: 'Start a game instance and wait until it answers.' It also distinguishes itself from starting the game manually and, by mentioning the returned port that every other tool needs, it implicitly differentiates from listing/stopping/logging tools. This is unambiguous and not a tautology.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear usage context: it is the preferred way to launch the game, the bridge handles port allocation, and the tool waits until the game responds. It explicitly says 'Prefer this over starting the game yourself,' which is strong guidance. It does not enumerate exact when-not-to-use conditions for each sibling, but the context is sufficient for an agent to choose it appropriately.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_instancesA

What is running: instances that self-registered, plus a sweep of the configured port range for games that predate the registry. Reports name, version, pid, working directory, current screen and whether each was found via the registry or the scan. Read-only, so it is safe to point at instances someone else owns. Use it to attach to a game you did not launch.

NameRequiredDescriptionDefault
scanNoSweep the port range (default true)
pruneNoDelete registry entries whose port has been verified dead. Off by default: a game still binding its port looks identical to a crashed one.
rangeNoPorts to sweep, e.g. '7777,7800-7810'. Defaults to --scan-range.
registryNoRead the instance registry (default true)

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden of behavioral disclosure. It explicitly discloses the read-only safety property ('Read-only, so it is safe to point at instances someone else owns'), which is the key behavioral trait an agent needs. It does not contradict any annotations since none exist.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, front-loaded with the core purpose ('What is running'), followed by reported fields, then safety and use case. Zero wasted words; every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description usefully enumerates the returned fields and that coverage is complete for a read-only enumeration tool. The only mild gap is that the output format/ordering is unspecified, which is a minor omission for a listing tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline 3 applies even without param detail in the description. The description adds conceptual framing (the port sweep relation to 'games that predate the registry') but the schema already documents scan, prune, range, and registry thoroughly, including the dangerous prune default behavior.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Leads with a specific verb and object — 'What is running: instances that self-registered, plus a sweep of the configured port range'. It names the exact fields reported (name, version, pid, working directory, current screen) and the two discovery sources (registry vs scan), and the read-only framing plus the 'attach to a game you did not launch' use case clearly separates it from the launch/stop/log siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives an explicit purpose statement — 'Use it to attach to a game you did not launch' — and explains the two data sources, which signals when a scan is needed (old instances) vs the registry alone. It does not explicitly name when NOT to use it or point to an alternative (e.g. instance_log for logs), but the context is clear enough for an agent to select it for enumeration.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_toolsetsA

List the toolsets one instance publishes, as that instance describes itself. Different ports can legitimately return different lists. Start here, then describe_toolset, then call_tool.

NameRequiredDescriptionDefault
portNoDebug port of the game instance to talk to. Defaults to the bridge's --port, then GAME_BRIDGE_PORT, then 7777. launch_instance returns one; list_instances finds the rest.

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the burden of behavioral disclosure. It reveals that the response reflects the instance's self-description and can vary by port, which is meaningful behavioral context. It also implies a read-only listing operation, though it doesn't go deeper into failure cases or return format.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences deliver the purpose, a critical caveat, and the recommended workflow. Every sentence earns its place, and the key distinction is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers the essential workflow, port variability, and the self-describing nature of the response. It doesn't describe the exact return structure, but for a simple list operation without an output schema this is a minor gap given the clear intent and provided next steps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The single 'port' parameter is fully documented in the schema, including defaults and how to obtain a port from sibling tools. The description adds only the note that different ports may return different lists, which supplements but does not significantly expand on the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states a specific verb ('List') and resource ('toolsets one instance publishes') and adds the important qualifier 'as that instance describes itself.' It is immediately distinguishable from sibling tools like launch_instance, list_instances, describe_toolset, and call_tool.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly instructs the agent to start here and then proceed to describe_toolset and call_tool, giving a clear workflow. It also warns that different ports can return different lists, which is essential context for choosing which instance/port to query.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

stop_instanceA

Shut down an instance this bridge launched: the game's own close command first, then termination of the process tree if it will not go. Only ever applies to a process this bridge started. To ask a game you did not launch to exit, use call_tool { name: 'close' }.

NameRequiredDescriptionDefault
portNoDebug port of the game instance to talk to. Defaults to the bridge's --port, then GAME_BRIDGE_PORT, then 7777. launch_instance returns one; list_instances finds the rest.
graceMsNoHow long to wait for a clean exit

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden, and it delivers: it discloses the two-stage shutdown behavior, the escalation to process-tree termination, and the boundary that only bridge-launched processes are affected. This is exactly the kind of hidden destructive behavior an agent needs to know before invoking.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three compact sentences, with the core action and escalation front-loaded and no filler. Every sentence earns its place; nothing restates the tool name or repeats schema content.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a shutdown tool with two optional parameters, clear destructive behavior, explicit scope boundaries, and a named sibling alternative, everything needed to select and invoke it correctly is present. The absence of an output schema is not a practical gap since the agent does not need return-value details to call it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Both parameters are already fully described in the input schema, including port resolution order and graceMs purpose. The description adds no additional parameter-level detail, but with 100% schema coverage the baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Shut down') and resource ('an instance this bridge launched'), and explicitly contrasts it with call_tool's 'close' command. An agent can immediately tell this tool is for shutdown of bridge-launched instances only.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly scopes the tool to processes this bridge started and gives the exact alternative for games not launched by the bridge: use call_tool { name: 'close' }. This gives the agent both a clear when-to-use and when-not-to-use rule.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 7 tool updatesv0.1.0
    • First observedcall_tool
    • First observeddescribe_toolset
    • First observedinstance_log
    • First observedlaunch_instance
    • First observedlist_instances
    • First observedlist_toolsets
    • First observedstop_instance

TDQS

A4.4/5.0

Scored across 7 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: launch, list, stop, get log, list toolsets, describe toolset, and call tool. No overlapping functionality.

Naming Consistency4/5

Most tools follow the verb_noun pattern (launch_instance, list_instances, stop_instance, list_toolsets, describe_toolset, call_tool), but 'instance_log' is a noun phrase rather than a verb action, which is a minor inconsistency.

Tool Count5/5

Seven tools is well-scoped for a game bridge server, covering management and introspection without being excessive or insufficient.

Completeness5/5

The tool set covers the full lifecycle of game instances (launch, list, stop, log) and toolset interaction (list, describe, call), leaving no obvious gaps for the stated purpose.

Maintenance

ActivityStale
ResponsivenessNo recent community issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    An educational MCP server that exposes system tools (like IP, hostname, file operations, ping) for AI agents to execute via HTTP.
    453 npm
    MIT
  • A
    license
    A
    quality
    C
    maintenance
    An MCP server that empowers AI coding agents to work effectively with Minecraft mod development, providing static analysis of decompiled source code and runtime interaction with a running Minecraft instance.
    31
    53 npm
    18
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    An MCP server that gives coding agents IDE-like access to JVM classpaths by querying the actual build tool, providing precise source code, signatures, and structure without cache-walking or version guesswork.
    187 npm
    4
    MIT