Skip to main content
Glama

emptysock-mcp

EmptySock 게임 엔진용 Model Context Protocol 서버입니다. NavMesh, Physics, Scene, Save, Actor 엔진 시스템을 Claude Desktop, AI 에이전트, Claude API에서 사용할 수 있는 MCP 도구로 노출합니다.


요구 사항

  • 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

로드된 내브메시에서 두 2D 월드 좌표 사이의 A* 경로를 찾습니다. 경로가 없으면 순서가 있는 웨이포인트 또는 []를 반환합니다.

navmesh_nearest_node

주어진 월드 좌표에 가장 가까운 이동 가능한 내브메시 노드.

예제 — 경로 찾기:

{
  "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_entities

씬에서 활성 상태인 모든 엔티티 ID.

scene_entity_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 flush 시 처라됩니다.

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. 두 항목을 모들 src/tools/index.ts에서 buildRegistry()의 register() 호출을 통해 등록합니다.

  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.

    Maintenance

    ActivitySlowing
    ResponsivenessNo recent community issues

    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