Skip to main content
Glama

emptysock-mcp

EmptySock ゲームエンジン用の Model Context Protocol サーバー。エンジンのシステム — NavMesh、Physics、Scene、Save、Actor — を MCP ツールとして公開し、Claude Desktop、AI エージェント、Claude API から利用できます。


要件

  • Node.js 20+

  • npm 9+


Related MCP server: Hayba

インストール

git clone https://github.com/eleferrets/emptysock-mcp.git
cd emptysock-mcp
npm install
npm run build

設定

サンプルの env ファイルをコピーし、必要な値を入カしてください:

cp .env.example .env

変数

必須

説明

EMPTYSOCK_API_TOKEN

任意

認証付きエンジン API 呼び出し用の Bearer トークン

MCP_AUTH_TOKEN

任意

SSE トランスポートのリクエストに必要な Bearer トークン。空欄にすると認証が無効になります。

SAVE_BASE_DIR

任意

セーブツールが読み書きできる絶対パス。デフォルトはプロセスの作業ディレクトリです。本番環境では明示的に設定してください。

.env は決してコミットしないでください — gitignore されています。シークレットはリポジトリではなく CI/CD のシークレットマネージャーに保存してください。


サーバーの実行

stdio (ローカルでの利用と Claude Desktop に推奨)

npm run dev          # development — tsx, no build step
# or after building:
node dist/server.js

サーバーは stdin/stdout で通信します。ネッとワークポートはなく、認証インターフェースもありません。

Claude Desktop

Claude Desktop の設定ファイル (~/Library/Application Support/Claude/claude_desktop_config.json、macOS の場合) にサーバーを追加します:

{
  "mcpServers": {
    "emptysock": {
      "command": "node",
      "args": ["/absolute/path/to/emptysock-mcp/dist/server.js"],
      "env": {
        "SAVE_BASE_DIR": "/absolute/path/to/your/saves"
      }
    }
  }
}

Claude Desktop を再起動してください。EmptySock ツールがツールピッカーに表示されます。


利用可能なツール

NavMesh

ツール

説明

navmesh_find_path

読み込まれた navmesh 上の 2D ワールド座標 2 点間の A* 経路。順序付けられたウェイポイントを返し、経路が存在しない場合は [] を返します。

navmesh_nearest_node

指定されたワールドポイントに最も近い、歩行可能な navmesh ノード。

例 — 経路検索:

{
  "from": { "x": 0, "y": 0 },
  "to":   { "x": 100, "y": 50 },
  "mapId": "level1"
}

Physics

ツール

説明

physics_raycast_2d

2D 物理空間にレイを投射し、最初にヒットしたエンティティ、ヒットポイント、法線を返します。

physics_raycast_3d

3D 物理空間 (Rapier3D) にレイを投射し、最初のヒットを返します。

physics_overlap_circle

2D コライダーが円と重なるすべてのエンティティ ID。

physics_body_state

エンティティ ID で指定された物理ボディの現在の位置、速度、角速度。

例 — 円とのオーバーラップ:

{
  "center": { "x": 50, "y": 50 },
  "radius": 20,
  "layerMask": 3
}

Scene

ツール

説明

scene_list_entites

シーン内でアクティブなすべてのエンティティ ID。

scene_entiy_info

特定のエンティティのタグ、アクティブ状態、コンポーネント一覧。

scene_get_component

エンティティ上の特定コンポーネントのシリアライズ済み状態。

例 — コンポーネントの取得:

{
  "sceneId": "gameplay",
  "entityId": "player-001",
  "componentType": "Transform"
}

Save

すべてのセーブツールは SAVE_BASE_DIR 内にサンドボッス化されます。パストラバーサル (..、絶対パス) はスキーマ層と解決時の両方で拒否されます。

ツール

説明

save_read

セーブスロッとをディスから読取み、その JSON データを返します。

save_write

JSON オブジェクトを指定した名前のセーブスロットに書き込みます。

save_delete

セーブスロットを削除します。

save_list

利用可能なすべてのセーブスロットを一覧表示します。

例 — 書き込み:

{
  "slot": "autosave",
  "data": { "level": 3, "score": 4200, "checkpoint": "bridge" }
}

スロット名は英数字とダッシュ/アンダースコアのみ使用できます (例: slot1、autosave、new-game-plus)。


Actor

ツール

説明

actor_send_message

特定のアクターの受信箱にメッセージをエンキューします。次の ActorSystem フラッシュ時に処理されます。

actor_broadcast

登録済みのすべてのアクターにメッセージをブロードキャストします。

actor_inbox_size

アクターの受信箱にある保留中メッセージの数。

例 — メッセージの送信:

{
  "actorId": "enemy-spawner",
  "message": { "type": "SPAWN_WAVE", "payload": { "wave": 3 } }
}

順序に関する注記: ActorSystem は update() を呼び出す前に各アクターの受信箱を空にします。フレーム N の間に送信されたメッセージは、フレーム N の更新ロジックが実行される前に完全に処理されます。


開発

npm run lint        # TypeScript type-check (no emit)
npm test            # run Vitest suite
npm run test:watch  # watch mode

テストは src/tests/ にあります。入力検証、ツールディスパッチ、セキュリティ不変条件 (パストラバーサル、シェルメタキャラクターインジェクション、未知のツール名) をカバーしています。


ツールの追加

  1. src/tools/<domain>.ts を作成 — toolDef 配列エントリと handler 関数をエクスポートします。

  2. buildRegistry() 内の register() 呼び出しで、その両方を src/tools/index.ts に登録します。

  3. emptysock-engine の api-reference.json にエントリを追加します。

  4. eleferrets/emptysock-ai-skills にスキルファイルを追加します。

src/lib/ の共有ヘルパーを使用します:

  • parse(schema, raw) — 失敗時に McpError(InvalidParams) をスローする Zod パース

  • SafeRelPath, SafeId, Vec2, Vec3, GameNum — 再利用可能な Zod スキーマ

  • textResponse(data) — 標準の MCP テキストコンテンツレスポンスを構築する

  • wrapError(err) — stderr にログを記録し、McpError(InternalError) として再スローする


セキュリティモデル

懸念事項

対策

不正な引数

すべての入力で Zod safeParse を実行。失敗時は McpError(InvalidParams) を返す

パストラバーサル

SafeRelPath スキーマ + セーブハンドラーでの path.resolve 包含チェック

シェルインジェクション

テンプレート文字列による exec() は不使用。サブプロセスが必要な場合は argv 配列で execFile を使用

認証情報の漏えい

シークレットは process.env からのみ取得。スタックトレースは stderr に記録され、クライアントには送信されない

過大な入力

すべてのスキーマフィールドで文字列長を制限

未知のツール

McpError(MethodNotFound) — 意図しないハンドラーへのフォールスルーなし

Available Tools

21 tools
actor_broadcastB

Broadcast a message to all registered actors in the current ActorSystem.

Inputs: message (required).

actor_inbox_sizeB

Return the number of pending messages in an actor's inbox.

Inputs: actorId (required).

actor_send_messageA

Enqueue a message in a specific actor's inbox. The actor processes it on the next flush pass.

Inputs: actorId (required), message (required).

emptysock_layer_infoA

Return reference documentation for the EmptySock LayerSystem API: defineLayer, addToLayer, setVisible, setParallax, and RenderSystem integration.

Inputs: no named parameters.

gms2_inspect_projectA

Read a GameMaker Studio 2 .yyp project file and return a JSON summary: project name, asset counts by type, and lists of object and script names. Read-only — does not modify any files.

Inputs: yypPath (required).

particle_emitter_configA

Get or set a ParticleSystem emitter configuration by emitter ID. Omit config to read; provide config to write.

Inputs: emitterId (required), config.

physics_body_stateA

Return the current position, velocity, and angular velocity of a physics body by entity ID.

Inputs: entityId (required).

physics_overlap_circleB

Return all entity IDs whose 2D colliders overlap a circle.

Inputs: center (required), radius (required), layerMask.

physics_raycast_2dB

Cast a ray in 2D physics space and return the first hit entity, hit point, and normal.

Inputs: origin (required), direction (required), maxDistance (required), layerMask.

physics_raycast_3dC

Cast a ray in 3D physics space (Rapier3D) and return the first hit.

Inputs: origin (required), direction (required), maxDistance (required), layerMask.

save_deleteA

Delete a save slot from disk.

Inputs: slot (required).

save_listA

List all available save slots.

Inputs: subdir.

save_readA

Read a save slot from disk and return its JSON data.

Inputs: slot (required).

save_writeA

Write JSON data to a save slot on disk.

Inputs: data (required), slot (required).

scene_create_entityC

Add a new entity to a scene. Returns the new entity's ID.

Inputs: sceneId (required), tag, components.

scene_entity_infoC

Return the tag, active state, and component list for a specific entity.

Inputs: sceneId (required), entityId (required).

scene_get_componentB

Retrieve the serialised state of a specific component on an entity.

Inputs: sceneId (required), entityId (required), componentType (required).

scene_list_entitiesB

List all entity IDs currently active in a scene.

Inputs: sceneId (required).

story_graph_exportA

Export the Story Graph (VNSystem) for a named scene as a JSON object containing nodes and edges.

Inputs: sceneId (required), graphId.

Tool Schema Changelog

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

Loading tool schema changelog…

    TDQS

    B3.4/5.0

    Scored across 21 tools

    Disambiguation5/5

    Tools are clearly separated by domain (navmesh, physics, scene, save, actor, etc.) and each tool targets a distinct action or query. Even within physics, 2D and 3D raycasts are explicitly differentiated. No two tools appear to do the same thing.

    Naming Consistency5/5

    All tools follow a consistent domain_verb_noun pattern (e.g., scene_create_entity, save_list, actor_send_message). Suffixes like _2d and _3d are uniform, and the one odd name (emptysock_layer_info) still adheres to the same style. Naming is predictable and coherent.

    Tool Count3/5

    With 21 tools, the count falls in the 16-25 range, which is borderline heavy. However, the server covers many distinct subsystems, so each tool arguably earns its place, but the overall number feels slightly excessive for a single MCP server.

    Completeness3/5

    The set covers core read/query operations across multiple domains, but there are notable gaps: scene entities can be created and inspected but not updated or deleted, physics only offers queries (no manipulation), and particle control is limited to configuration. This leaves some lifecycle operations incomplete.

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      D
      maintenance
      Enables LLM-driven text game state management by exposing MCP tools for managing players, locations, items, entities, and abstract concepts.
      MIT
    • A
      license
      Not graded
      quality
      B
      maintenance
      An MCP server enabling AI agents to author Unreal Engine 5 scenes directly, with tools for spawning actors, building PCG graphs, validating physics, generating terrain, and more through a single MCP connection.
      13
      MIT
    • A
      license
      Not graded
      quality
      D
      maintenance
      Connects Claude Code to the Unity Editor via MCP, enabling AI-driven control of scenes, assets, components, UI, animations, and more through 91 tools.
      2
      MIT
    • A
      license
      C
      quality
      C
      maintenance
      Enables AI-driven game development by providing MCP tools to interact with the Godot editor, including scene editing, node manipulation, script attachment, and scene execution.
      28
      14 npm
      MIT