이 페이지의 목차
문서 AI로 Bot 만들기

LLM이 도구를 직접 호출(MCP)

tools/war3_mcp.py는 MCP 서버입니다. Claude Code, Claude Desktop 또는 MCP를 지원하는 어떤 클라이언트든 이 서버를 연결하면, LLM이 코드를 먼저 쓰지 않고도 게임 상황을 보고, 명령을 내리고, 화면에서 플레이어에게 말하고, 카드를 띄워 플레이어에게 묻고, 스크린숏으로 화면을 볼 수 있습니다.

tools/war3_mcp.py는 MCP 서버(stdio)입니다. Claude Code, Claude Desktop, 로컬 모델의 Agent 프레임워크 — MCP를 지원하는 어떤 클라이언트든 이 서버를 연결하면, LLM이 코드를 먼저 쓰지 않고도 직접 게임 상황을 보고, 명령을 내리고, 게임 화면에서 플레이어에게 말하고, 플레이어에게 묻고, 스크린숏으로 화면을 볼 수 있습니다.

Bot 작성, 참모, 유닛 대사에 이은 또 하나의 연결 방식입니다. LLM이 스스로 도구의 사용자가 됩니다.

연결하기

claude mcp add war3 -- python <저장소>\tools\war3_mcp.py --inst 9      # Claude Code. <저장소>는 자신의 openwar3 폴더로 바꾸세요

다른 클라이언트는 이 형식으로 설정을 씁니다.

{"mcpServers": {"war3": {"command": "python", "args": ["<저장소>\\tools\\war3_mcp.py", "--inst", "9"]}}}

처음 도구를 호출할 때 게임에 연결하므로, 게임은 나중에 켜도 됩니다. 게임을 껐다가 다시 켜면 다음 호출 때 자동으로 다시 연결합니다. --role을 붙여 LLM이 할 수 있는 일을 제한합니다.

역할쓸 수 있는 것
dev(기본값)war3_jass를 포함한 모든 도구
player --player NN번 플레이어의 유닛만 지휘하고, 그 시야만 볼 수 있음(공정 모드). JASS 없음
observer읽기 전용, 화면에 그릴 수 없고 유닛이 말하게 할 수도 없음. 내린 명령은 런타임이 바로 거부

player 역할의 제한은 게이트웨이와 같습니다. 게임 종료, 속도 변경, 일시 정지를 쓸 수 없고, 다른 플레이어의 패를 볼 수 있는 API도 쓸 수 없으며, 플레이어 번호를 받는 조회는 자기 자신만 조회할 수 있습니다.

몇 가지 상한: 도구 결과 하나는 최대 20만 자이며, 넘으면 잘라 내고 범위를 좁히는 방법을 알려 줍니다. war3_ask_player는 최대 120초까지 기다립니다. 스크린숏의 scale은 0.1에서 1 사이입니다.

도구

도구하는 일
war3_overview게임 상황 한 페이지: 시간, 자원, 식량, 아군 유닛 종류별 수, 영웅(체력, 마나, 레벨, 쿨다운), 보이는 적 유닛 종류, 생산. 이것부터 호출하세요
war3_units유닛 목록(owner는 me / enemy / creep / all, types로 필터링). addr로 명령을 내림
war3_events지난 호출 이후 일어난 일: 사망, 레벨 업, 시전, 생산 완료, 채팅, 플레이어가 버튼을 클릭함……(기본적으로 너무 자주 발생하는 몇 종류는 제외)
war3_call아무 공개 API나 호출(move, attack_move, train, build, cast, learn, ui.button, canvas.text……). 유닛은 {"unit": addr}로 씀
war3_apiAPI 조회: 키워드로 이름과 설명을 검색
war3_toast / war3_say화면 위쪽에 한 줄 표시 / 유닛 머리 위에 한 마디
war3_ask_player화면 가운데에 선택 카드 몇 장을 띄우고, 플레이어가 클릭하기를 기다렸다가 무엇을 골랐는지 반환(게임 일시 정지 가능)
war3_screenshot게임 화면 스크린숏(PNG. 창이 가려져 있어도 찍을 수 있고, 포커스를 빼앗지 않음)
war3_jassJASS 코드 실행(dev 전용. 월드 변경은 싱글플레이 게임에서만)

이런 것을 할 수 있습니다.

  • 같이 플레이 / 코치: war3_overview로 게임 상황을 보고, war3_toast로 화면에 조언을 띄움
  • 플레이하면서 플레이어에게 묻기: war3_ask_player로 카드 세 장을 띄우고, 플레이어가 고른 대로 진행
  • 해설: war3_events로 무슨 일이 있었는지 읽고, war3_say로 유닛이 직접 말하게 함
  • 부대 하나를 직접 지휘: player 역할 + war3_call. 자기 유닛만 움직일 수 있음
  • 화면을 보며 UI 조정: war3_screenshot으로 한 장 찍어, 직접 그린 버튼이 제자리에 있는지 확인

대화는 대략 이렇게 흘러갑니다

나: 지금 게임 상황을 보고, 화면에서 나한테 물어봐 줘. 다음은 멀티, 병력 생산, 본진 업그레이드 중 뭘로 할까?

→ war3_overview      {}
← 게임 상황 한 페이지: 게임 시간, 금 500, 식량 10/12, 아군 htow 1 · hpea 5 · Hpal 1, 보이는 적 없음, 생산 중인 것 없음
→ war3_ask_player    {"question": "다음은?", "options": ["병력 생산", "멀티", "본진 업그레이드"], "pause": true}
← {"picked": 1, "option": "멀티"}

모델: 멀티를 고르셨네요. 먼저 war3_units로 놀고 있는 일꾼을 하나 찾고, 가장 가까운 금광이 어디인지 볼게요……

실측

2026-09-25:

  • 자체 MCP 클라이언트로 실제 게임에 연결, 7/7: 핸드셰이크 → 도구 나열(10개) → war3_overview(htow 1, hpea 5) → war3_units → war3_toast → war3_screenshot(PNG 약 20만 바이트) → war3_ask_player(카드 세 장, 두 번째 카드 클릭을 시뮬레이션 → {"picked": 1, "option": "멀티"}).
  • Claude Code 2.1에 실제로 연결: Claude Code가 직접 서버를 띄우고 핸드셰이크했으며, 상태는 connected, 도구 10개가 모두 mcp__war3__*로 도구 목록에 나타났습니다.

구현

  • 줄바꿈으로 구분한 JSON-RPC 2.0(initialize / tools/list / tools/call / ping), 프로토콜 버전 2025-06-18, 2025-03-26과 2024-11-05도 호환.
  • 도구 오류는 MCP 규칙에 따라 결과 안에 담으며(isError: true), 연결을 끊지 않습니다.
  • 게이트웨이와 같은 역할 화이트리스트, 유닛 인자 형식, “게임 상황 한 페이지”를 공유합니다.
  • 로그는 stderr로 보내고, stdout에는 프로토콜만 씁니다.