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: minecraft-mcp

계약

이것을 구현하면 게임은 이 브리지를 통해 어떤 에이전트든 구동할 수 있게 되며, 여기에는 게임에 대해 아는 코드가 전혀 필요 없습니다. 세 부분으로 구성되며, 각 부분은 특정한 것을 제공합니다:

부분

제공하는 것

1. HTTP 표면

실행 중인 인스턴스를 읽고 구동하기.

2. 자체 등록

포트를 추측하지 않고 인스턴스 찾기.

3. 실행 선언

사람이 포트를 선택하지 않고 인스턴스 시작하기.

1번만 필수입니다. 2번은 발견을 안정적으로 만들고, 3번은 전체를 쾌적하게 만듭니다.

1. HTTP 표면

127.0.0.1:<port>에서 제공하세요. 포트는 명시적인 디버그 플래그에서 옵니다. 루프백에만 바인딩하고, 게임이 해당 플래그로 실행된 경우에만 전체 표면을 켜두세요: 이것은 디버그 표면이지 네트워크 서비스가 아닙니다.

GET /health — 필수

활성 및 정체성 확인입니다. 발견은 범위 내의 모든 포트에 대해 이를 호출하므로, 저렴해야 합니다.

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

ok: true가 포트를 우리 것으로 표시합니다. 다른 것으로 HTTP에 응답하는 포트는 에이전트에게 "다른 무언가가 이 포트를 차지했습니다"로 보고됩니다 — "게임이 실행 중이 아님"과는 다른 문제, 다른 해결책입니다.

frame은 프로세스 수명 동안 증가하는 카운터입니다. 브리지는 이를 감시합니다: 뒤로 가는 frame은 새 프로세스가 이 포트에 응답하고 있음을 의미하며, 캐시된 도구 매니페스트는 자동으로 삭제됩니다. 이것이 재빌드-재실행을 에이전트에게 보이지 않게 만드는 것입니다.

GET /state — 필수

전체 스냅샷: 에이전트가 알고 싶어할 모든 것을 JSON으로. 필수 스키마는 없습니다 — 그것은 당신의 게임이니까요 — 하지만 몇 가지 관례적 필드는 브리지 기능을 잠금 해제합니다:

{
  "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 인수를 가지며, 중복 쿼리 키는 호출되는 명령을 조용히 덮어쓸 수 있습니다. 다른 모든 쿼리 매개변수는 인수입니다.

이 엔드포인트는 fire-and-forget이며, 계약에서 가장 중요한 이해 사항입니다. 명령이 대기열에 들어가는 순간 HTTP 스레드에서 응답합니다; 명령 자체는 나중에 게임 스레드에서 실행됩니다. 직후에 /state를 읽는 클라이언트는 명령이 발생하기 전의 세계를 읽습니다. 테스트가 불안정해 보여도 게임은 정상입니다.

브리지는 이를 처리하며, 게임이 지원해야 할 방식은 다음과 같습니다:

  1. GET /command?... → 반환된 commandId를 기록합니다.

  2. completedCommandId >= commandId가 될 때까지 GET /state를 폴링합니다.

  3. 해당 상태를 반환합니다 — 명령이 실제로 실행된 후의 상태입니다.

게임이 completedCommandId를 게시하지 않으면, 브리지는 frame이 2만큼 진행될 때까지 기다리는 것으로 대체하고 결과에 "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") — 타입 언어에서 직렬화된 매니페스트는 보통 그렇게 렌더링합니다. 브리지는 스키마에서 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. 자체 등록

포트 스캐닝은 발견의 약한 형태입니다: 누군가 추측한 범위로 제한되고, 게임이 응답할 때까지 정체성에 대해 침묵하며, 시작 중에 오탐(false negative)이 발생하기 쉽습니다 — 에이전트가 가장 찾아볼 가능성이 높은 바로 그 순간입니다.

그래서 디버그 포트에 성공적으로 바인딩한 게임은 자신을 밝히는 작은 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, 작업 디렉터리, 시작 시간)에만 사용합니다.

  • 기본적으로 다른 프로세스의 파일을 삭제하지 마십시오. 아직 포트를 바인딩 중인 게임은 1~2초 동안은 크래시된 것과 구분할 수 없습니다. 브리지는 명시적인 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

셸 명령줄. {port}가 치환됩니다. 포트는 여기서부터 게임에 도달해야 합니다 — 이것이 전체 메커니즘입니다.

argv

command의 대안: ["./run-game", "--port", "{port}"], 셸 없이 실행됩니다.

cwd

작업 디렉터리, 이 파일 기준으로 해석됩니다 — MCP 클라이언트가 브리지를 시작한 위치 기준이 아닙니다. 그 위치는 거의 항상 프로젝트가 아닙니다.

portRange

런처가 점유할 수 있는 포트. 기본값 7820-7839, 사람들이 수동으로 나눠주는 포트인 7777과 7800-7810을 의도적으로 피합니다.

readyTimeoutMs

/health를 기다리는 시간. 콜드 빌드에 JVM까지 있으면 수십 초가 걸립니다. 기본값은 180000입니다.

env, extraArgs

추가 환경 변수와 후행 인자.

런처가 보장하는 것:

  • 포트가 두 번 검증되어 비어 있음이 확인됩니다 — 아무것도 바인딩되어 있지 않고, 헬스 체크에 응답하는 것도 없음 — 게임이 시작 중일 때는 수 밀리초 전에 바인드 테스트를 실패하면서도 중요한 방식으로 포트를 점유했기 때문입니다. 선언된 범위가 가득 차면 OS가 할당한 포트로 폴백합니다.

  • 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 스키마. 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에서 설치할 때 빌드하므로, 체크인된 dist/ 없이도 git 설치 의존성이 작동합니다.

라이선스

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 issues

Related MCP Connectors

Related MCP Servers