Skip to main content
Glama
Uncle-Peke

ui-chan

by Uncle-Peke

ui-chan-mcp

데스크톱 마스코트를 MCP(Model Context Protocol)를 통해 조작하는 서버. Claude Code나 임의의 MCP 대응 에이전트에서 마스코트의 외형(얼굴+팔)과 목소리를 함께 전환하고, 말풍선으로 대사를 말하게 할 수 있습니다.

  • 표시 계층은 Electron(투명・최상단・화면 오른쪽 아래)

  • 스탠딩 일러스트는 PSDTool 형식의 PSD(!=필수 레이어, *=라디오 전환)를 그대로 사용

  • 외형+목소리는 Cue(1파일=1개의 완성된 외형+목소리)라는 단위로 관리. 에이전트용 시각 조작 도구는 set_cue 단 하나

  • 발화 큐・복수 에이전트 동시 접속 지원

스탠딩 일러스트 PSD는 리포지토리에 포함되어 있지 않습니다(저작권 보호된 소재이기 때문). assets/에 PSDTool 호환 PSD를 넣으면 동작합니다. 없는 경우는 플레이스홀더로 시작합니다. 동봉된 ui-chan.config.json과 cues/*.json은 雨衣(うい)立ち絵素材(坂本アヒル様)의 레이어 구성용입니다. 이용은 雨衣キャラクターガイドライン의 범위에서 부탁드립니다.

셋업

→ 그림으로 보는 셋업 절차 (클론부터 화면에 나올 때까지. 사람이 읽어도 AI가 읽어도 이해할 수 있는 수준으로 쓰여 있습니다. 같은 내용이 docs/setup-page.html에도 들어 있습니다)

급한 사람을 위한 요약:

git clone https://github.com/Uncle-Peke/ui-chan-mcp.git && cd ui-chan-mcp
npm install                     # 依存の取得 + ビルド(prepare で dist/ まで作られる)
cp .env.example .env            # VoiSona Talk の資格情報(音声を使わないなら不要)
# 立ち絵 PSD を assets/ に配置
npm run doctor                  # ビルド・PSD・資格情報・エンジン起動をまとめて確認

연결

어떤 연결 방식이든, 연결한 시점에 완료입니다. 마스코트 앱과 VoiSona Talk은 연결 시 자동으로 실행되며, 인격은 MCP의 핸드셰이크(instructions)에 실려 전달됩니다. 인격 파일을 붙여 넣는 작업은 없습니다.

플러그인으로 설치(Claude Code / Claude Desktop 공통・권장)

플러그인 레지스트리는 Claude Code와 Claude Desktop에서 공유됩니다. Claude Code에서 한 번 등록하면, Desktop 쪽의 「설정 → 플러그인」에도 같은 것이 나타납니다(반대로 Desktop의 추가 UI는 GitHub에서의 추가만 가능하며, 로컬 폴더는 지정할 수 없습니다).

/plugin marketplace add /path/to/ui-chan-mcp      # ローカルのクローンから
/plugin install ui-chan@ui-chan

GitHub에서 설치할 경우 Uncle-Peke/ui-chan-mcp를 지정합니다(단, dist/는 커밋되어 있지 않으므로, 별도로 클론해서 npm install한 실제 파일이 필요합니다).

플러그인을 설치하면 커넥터(MCP 서버)도 함께 등록됩니다(.mcp.json). 수동으로 커넥터를 등록할 필요는 없으며, 둘 다 하면 같은 서버가 이중으로 실행됩니다.

MCP 서버만 사용(커넥터만)

스킬이나 훅은 필요 없고, 도구와 인격만 있으면 되는 경우. Claude Desktop이라면 **「설정 → 개발자 → 설정 편집」**에서 claude_desktop_config.json을 열고, 다음을 추가한 뒤 앱을 완전히 종료(⌘Q)하고 다시 시작합니다. command에는 which node의 결과를 넣어주세요 (Claude Desktop은 터미널과 환경이 다르므로 node라고만 쓰면 찾지 못하는 경우가 있습니다).

{
  "mcpServers": {
    "ui-chan": {
      "command": "/usr/local/bin/node",
      "args": ["/path/to/ui-chan-mcp/dist/mcp-server.js"]
    }
  }
}

같은 작업을 1개의 커맨드로 하는 경우(기존 설정은 유지하고 .bak을 남깁니다):

npm run install-desktop        # 解除は npm run install-desktop -- --remove

Claude Code에서 수동으로 등록하는 경우는 다음과 같습니다. 인증 정보는 .env에서 읽히므로 env는 필요 없습니다.

claude mcp add ui-chan -- node /path/to/ui-chan-mcp/dist/mcp-server.js

설치 방식에 따른 차이

커넥터만

플러그인

도구(set_cue 외)

○

○

인격(핸드셰이크로 주입)

○

○

앱・음성 엔진 자동 실행

○

○

/talk /mode /beam /eli14

✕

○

서브에이전트(talk / mode)

✕

○

작업에 대한 자동 리액션(EventCue)

✕

○

Claude Code와 Claude Desktop의 차이가 아니라 설치 방식의 차이입니다. 어느 앱에서든 플러그인으로 설치하면 같은 것을 사용할 수 있습니다.

Related MCP server: Persona Motion Studio

아키텍처

MCP 서버는 얇은 브리지이며, 상태는 모두 Electron 앱 쪽에 일원화되어 있습니다. 여러 에이전트가 동시에 연결해도 상태가 어긋나지 않습니다.

flowchart LR
  agent["エージェント<br/>(Claude Code 等)"]
  mcp["dist/mcp-server.js<br/>ステートレスなブリッジ"]

  subgraph app["Electron アプリ (dist/app/main.js)"]
    direction TB
    state["UiChanState<br/>発話キュー・好感度・アイドル"]
    tts["VoiSonaTalkClient<br/>音声合成"]
    renderer["レンダラ<br/>PSD合成・吹き出し・口パク"]
  end

  voisona["VoiSona Talk<br/>REST API :32766"]

  agent -- "stdio (MCP)" --> mcp
  mcp -- "WebSocket :8123" --> state
  mcp -. "未起動なら自動起動" .-> app
  mcp -. "未起動なら自動起動" .-> voisona
  state --> tts
  tts -- "WAV + 音素タイミング" --> renderer
  tts <--> voisona
  state -- "IPC (RenderCommand)" --> renderer
  • 포트 — ui-chan.config.json의 port, 또는 환경 변수 UI_CHAN_PORT

  • 자동 시작 — 앱은 세션 시작 시(SessionStart 훅)와 각 도구 호출 시, VoiSona Talk은 MCP 시작 시와 set_cue를 호출할 때마다, 꺼져 있으면 다시 깨워집니다

  • 에이전트 이름 — MCP 클라이언트 정보에서 자동 획득(UI_CHAN_AGENT_NAME로 덮어쓰기 가능)

더 자세한 구현 가이드는 CLAUDE.md를 참조하세요.

명령어 목록

MCP 도구(에이전트가 호출)

도구

인수

설명

set_cue

cue, text?, reading?, duration_ms?, pitch?, speed?, volume?, intonation?

Cue(외형+목소리)를 전환하고, 원하면 대사를 동시에 말한다. text를 생략하면 무음으로 Cue만 바뀐다. 알 수 없는 cue 이름은 default로 폴백되고 note가 붙는다. pitch/speed/volume/intonation는 그 한 줄에만 적용되는 애드리브 연기

get_state

—

현재 상태・연결 에이전트・사용 가능한 Cue・호감도・경고

adjust_affinity

direction(up/down), magnitude(low/middle/high)

호감도를 증감(세션 내에서만・재시작 시 리셋). 실제 증감량은 엔진이 결정합니다

clear

—

말풍선・Cue를 초기 상태(default)로 리셋

Cue 목록은 persona 프롬프트(및 SessionStart 훅)가 cues/*.json에서 시작할 때마다 생성하여 에이전트의 컨텍스트에 전달합니다.

슬래시 커맨드(플러그인 설치 시)

커맨드

설명

/talk <メッセージ>

우이짱과 대화한다(작업은 하지 않음)

/mode [依頼]

세션마다 빙의 모드로 한다. 이후의 작업도 대화도 우이짱 본인으로서 수행한다

/beam

우이 빔. 호감도가 임계값 미만이면 쏴주지 않는다

/eli14 [お題]

14세 시점의 도해로 설명한다(HTML 아티팩트+구두 설명)

/mcp__ui-chan__persona

인격 파일을 편집한 뒤 다시 불러오기

npm 스크립트

커맨드

설명

npm run doctor

셋업 사전 점검(빌드・PSD・자격 증명・엔진)

npm run install-desktop

Claude Desktop에 MCP 서버를 등록(-- --remove로 해제)

npm run app / stop / restart

Electron 앱 시작/종료/재시작

npm run build

src/를 dist/로 빌드(npm install 시 자동 실행)

npm run editor

Cue 에디터「우이짱의 디버그 룸」

npm run debug

대화형 디버그 콘솔(MCP 불필요・WebSocket 직접 사용)

npm run debug:launch / debug:restart

앱 실행 포함 디버그 콘솔

npm run debug:state / debug:list

상태 획득/Cue・IdlingCue・EventCue 목록

npm run dump-psd -- assets/foo.psd

PSD 레이어 구조 덤프

npm run validate-cues

cues/*.json 스키마 검증

npm run lint / lint:fix / format

Biome

node tools/mcp-test.mjs

MCP stdio 경유 E2E 테스트

Q&A

src/의 TypeScript를 수정했을 때만입니다. npm install이 prepare에서 1회 빌드하므로, 클론 직후에도 npm run build를 실행할 필요는 없습니다. Cue나 ui-chan.config.json은 JSON이므로 빌드가 필요 없습니다(Cue는 저장하면 즉시 리로드됩니다).

단, MCP 서버는 세션 시작 시의 코드를 안은 채 계속 동작합니다. 다시 빌드해도 그 세션에는 반영되지 않으므로, MCP를 다시 연결하거나 세션을 다시 열어주세요.

npm run doctor를 실행해 주세요. 흔한 원인은 VoiSona Talk이 미실행, .env에 자격 증명이 없음, VoiSona 쪽에서 REST API가 활성화되어 있지 않음, 중 하나입니다.

소리가 나오지 않아도 말풍선은 나오며, 입모양도 reading의 카나로 움직입니다. VoiSona는 set_cue 때마다 다시 깨워지고(30초에 1회까지), REST가 응답할 때까지 최대 20초 기다립니다. get_state의 warnings에 이유가 표시됩니다. 자세한 내용은 docs/TTS.md.

우선 npm run app으로 단독 실행을 시도하면 원인을 가를 수 있습니다. 플러그인 설치 시에는 SessionStart 훅이 실행을 시도하므로, 보통은 세션을 열기만 해도 나타납니다. PSD가 assets/에 없으면 플레이스홀더 표시가 됩니다.

cues/<이름>.json 파일 하나만 만들면 됩니다. 상속 없음・완전히 자기 완결적이며, 저장하면 즉시 리로드됩니다. 비주얼하게 만들려면 npm run editor. 형식과 레이어 지정은 docs/CUES_AND_CONFIG.md, PSD 레이어 이름 빠른 참조표는 docs/CUES.md.

persona/ui-chan.md(기본 인격과 도구 사용 방침)와 context/*.md(SOUL.md 가치관 / VOCABULARY.md 어휘・NG 워드 / AFFINITY.md 호감도)입니다. context/에 둔 Markdown은 파일명 순서대로 전부 에이전트로 주입됩니다. 자세한 내용은 docs/PERSONA.md.

ui-chan.config.json의 idle.idlingCues에 있는 minSec / maxSec(기본 120〜300초)로 간격을, 각 IdlingCue의 weight로 나올 빈도를 조정합니다. minAffinity / maxAffinity로 호감도에 따른 출현 구분도 할 수 있습니다.

ui-chan.config.json의 eventCues.events입니다. 이벤트 이름마다 대사 풀이 있으며, cooldownSec(같은 throttleKey를 가진 이벤트에서 공유)와 chance로 소란스러움을 조정합니다. 내용은 IdlingCue와 같은 형태이므로 weight / minAffinity / maxAffinity / hours를 사용할 수 있습니다.

제공되는 이벤트:permission(허가 대기)、idle_wait(입력 대기)、tool_failure、 turn_done、compact、agent_out(서브에이전트 내보냄)、agent_back(귀환)。

확인은 npm run debug의 event <イベント名>. 훅 쪽(hooks/)은 이벤트 이름을 던질 뿐이므로, 대사를 바꾸는 데 JavaScript를 건드릴 필요가 없습니다.

npm run dump-psd -- path/to/file.psd로 레이어 이름을 확인하고, ui-chan.config.json과 cues/*.json(기반은 cues/default.json)을 수정합니다. 인격 쪽은 persona/와 context/를 통째로 교체해 주세요. 존재하지 않는 레이어 경로는 무시되고 get_state의 warnings에 표시되므로, 교체 작업 중에도 크래시하지 않습니다.

호감도가 임계값(65)에 도달하지 못했습니다. 감사・배려・기억해 주는 것 등으로 오릅니다. 직구식 호감 표현은 오히려 떨어집니다.

문서

파일

내용

docs/CUES_AND_CONFIG.md

Cue 파일 형식과 ui-chan.config.json의 전체 설정 항목

docs/CUES.md

PSD 레이어 이름 카탈로그(신규 Cue 제작용・사람용)

docs/PERSONA.md

인격의 정의 위치와 주입 방법

docs/TTS.md

VoiSona Talk 연동 상세

docs/setup-page.html

그림으로 보는 셋업 절차(공개

Related MCP Connectors

Related MCP Servers