한 줄 요약 — 포토샵·인디자인을 Rust로 다시 만든 오픈소스 Craft 앱에는 MCP 서버가 들어 있다. claude mcp add 한 줄로 붙이면 Claude Code가 명함을 조판하고 사진에 효과를 입힌 뒤, 결과를 PNG로 직접 보면서 고친다.

1. 왜 디자인 툴을 MCP로 붙였나

지금까지 명함, 로고, 문패 같은 디자인 작업을 Claude와 할 때는 늘 같은 방식이었다. Claude가 SVG를 쓰고, 파이썬으로 PNG를 뽑고, 나는 그걸 열어보고 "바를 2mm 올려줘"라고 말한다. AIvance 명함을 만들 때도 그랬다. 미리캔버스 캔버스가 94×54mm(재단 90×50mm + 사방 2mm 블리드)라는 걸 뒤늦게 알고, 3mm 블리드로 만든 파일을 통째로 다시 렌더링했다.

이 방식의 한계는 분명하다. Claude는 코드로 그림을 짐작할 뿐, 디자인 툴을 쓰는 게 아니다. 레이어도 없고, 텍스트 프레임도 없고, 다음 사람이 열어서 고칠 원본 파일도 없다.

그러다 ArtCraft 팀의 Craft 앱들을 알게 됐다. 앱의 모든 메뉴와 도구가 "명령"으로 만들어져 있어서, 사람이 UI로 누르는 것과 똑같은 명령을 CLI·JSON 제어 채널·MCP 서버로 호출할 수 있다. 에이전트가 화면이 아니라 문서를 직접 다루고, 결과는 이미지로 돌려받는다. 원하던 구조였다.

2. Craft 앱이 뭔가

storytold GitHub 조직에서 공개한 앱 묶음이다. 어도비 제품군을 하나씩 클린룸 방식으로 다시 구현하고 있고, 전부 Rust로 작성됐다. 라이선스는 MIT 또는 Apache-2.0 중 선택이다. 이 글에서 쓴 건 두 개다.

  • PhotoCraft — 포토샵 대응. 레이어, 마스크, 조정 레이어, 레이어 스타일, 문자, 그리고 실제 PSD 파일을 읽고 쓴다.
  • DesignCraft — 인디자인 대응. 페이지 조판, 텍스트 프레임, 스타일, 이미지 배치.

미리 밝혀둔다. 둘 다 얼리 알파다. 제작진도 아직 실무용 포토샵 대체품이 아니라고 말한다. 릴리스 속도가 하루 단위로 빠르니 이 글의 명령어도 버전에 따라 달라질 수 있다.

3. 설치와 연결

3-1. CLI 받기

MCP 서버는 데스크톱 앱이 아니라 CLI(photocraft-cli, designcraft-cli)에 들어 있다. 운영체제마다 위치가 다르다.

  • Ubuntu — deb 패키지로 설치하면 /usr/bin/designcraft-cli에 바로 들어간다. 서버는 늘 Ubuntu를 쓰는 입장에서 가장 편했다.
  • macOS — .app에는 데스크톱 앱만 들어 있다. CLI는 릴리스의 별도 zip으로 받아서 PATH에 넣어야 한다.
  • Windows — MSI 설치 시 C:\Program Files\DesignCraft\designcraft-cli.exe. PATH에 등록되지 않는다.

로컬 맥에서는 이렇게 했다.

# CLI를 PATH 안으로, 작업 폴더는 입력/출력 분리
unzip photocraft-cli--macos-universal.zip
mkdir -p ~/.local/bin ~/craft/in ~/craft/out
cp photocraft-cli--macos-universal/photocraft-cli ~/.local/bin/
cp designcraft-cli--macos-universal/designcraft-cli ~/.local/bin/

photocraft-cli --version && designcraft-cli --version

macOS에서는 첫 실행 때 공증(notarization) 확인으로 잠깐 멈출 수 있다. CLI 바이너리 단독으로는 공증 티켓을 붙일 수 없어서 생기는 현상이라 한 번 지나가면 된다.

3-2. Claude Code에 등록

# PhotoCraft: 읽기 폴더와 쓰기 폴더를 지정
claude mcp add photocraft -- photocraft-cli mcp \
  --automation-read-root ~/craft/in \
  --automation-write-root ~/craft/out

# DesignCraft: 창 없이 엔진만 띄우는 headless 모드
claude mcp add designcraft -- designcraft-cli mcp

# 연결 확인
claude mcp list

여기서 가장 많이 틀리는 곳이 -- 구분자다. -- 뒤에 오는 건 전부 서버에 그대로 넘어간다. 이걸 빼면 Claude Code가 --automation-read-root를 자기 옵션으로 읽으려다 실패한다.

읽기·쓰기 루트는 일종의 샌드박스다. 에이전트가 건드릴 수 있는 폴더를 두 개로 묶어두니, 원본 사진은 in에, 결과물은 out에만 쌓인다. AI에게 파일 시스템을 넘길 때 이 정도 울타리는 기본으로 친다.

3-3. 프로젝트 단위로 공유하려면

위 명령은 기본값인 local 스코프라 나만, 그 프로젝트에서만 보인다. --scope user를 붙이면 모든 프로젝트에서, --scope project를 붙이면 저장소에 커밋할 수 있는 .mcp.json에 기록된다.

{
  "mcpServers": {
    "designcraft": { "command": "designcraft-cli", "args": ["mcp"] },
    "photocraft": {
      "command": "photocraft-cli",
      "args": [
        "mcp",
        "--automation-read-root", "/home/martin/craft/in",
        "--automation-write-root", "/home/martin/craft/out"
      ]
    }
  }
}

3-4. 어떤 도구가 생기나

DesignCraft는 25개 도구를 노출한다. 실제로 자주 쓴 건 몇 개 안 된다.

도구 하는 일
new_document 판형, 페이지 수, 여백, 블리드 지정해 새 문서
list_commands / execute 메뉴에 있는 모든 명령 조회와 실행
batch 여러 명령을 순서대로, 앞 결과를 뒤에서 참조
inspect_document 페이지, 프레임, 스토리, 스타일, 넘침(overset) 확인
set_story_text 텍스트 프레임 내용 교체
place_image 이미지 배치
render_page 페이지를 PNG로 렌더링해 Claude에게 이미지로 반환

PhotoCraft는 Craft 앱들이 공통으로 쓰는 다섯 도구(command_list, command_run, command_batch, doc_inspect, render_preview)를 중심으로 25개를 노출한다. 뒤에 있는 명령은 800개가 넘는다.

핵심은 render_page와 render_preview다. 결과를 이미지로 돌려받기 때문에 Claude가 "만들고 → 보고 → 고치는" 루프를 혼자 돈다. SVG를 쓰던 시절에는 내가 눈 역할을 해야 했던 부분이다.

4. 사례 1 — DesignCraft로 명함 조판

예전에 SVG로 만든 AIvance 명함을 DesignCraft 문서로 다시 만들어봤다. 이번에는 처음부터 미리캔버스 규격으로 요청했다.

DesignCraft로 명함 앞면을 만들어줘.
- 재단 90×50mm, 사방 블리드 2mm (전체 94×54mm)
- 다크 배경은 블리드 끝까지, 하단에 파란(#2563EB) 바. 바는 재단선을 걸쳐서 블리드까지
- 텍스트: AIvance / 변종원 / Advisor / AI 개발 · 컨설팅 · 교육
- 글자는 안전영역 안쪽에만
- render_page로 결과를 보고 어긋난 데가 있으면 고친 뒤 ~/craft/out/card-front.png로 저장

Claude Code가 호출한 순서를 정리하면 대략 이렇다. 단위는 포인트(1/72인치)라 mm를 환산해야 한다. 90mm는 255.12pt, 50mm는 141.73pt, 2mm는 5.67pt다.

new_document    {"width": 255.12, "height": 141.73, "bleed": 5.67, "margins": 14.17}
inspect_document                       → 페이지 경계 확인
execute         {"command": "frame.create",
                 "params": {"rect": [14.17, 20, 240.95, 48], "content": "text", "text": "AIvance"}}
                                       → {"id": 8, "story": 9}
set_story_text  {"story": 9, "text": "AIvance"}
... 이름·직함·서비스 문구 프레임 반복
render_page     {"page": 0}            → PNG 확인, 수정
render_page     {"page": 0, "path": "~/craft/out/card-front.png"}

DesignCraft MCP로 조판한 명함 

SVG 방식과 비교해 좋았던 점은 세 가지다.

  1. 블리드가 문서 속성이다. SVG 때는 캔버스 크기에 블리드를 직접 더하다 3mm와 2mm를 헷갈렸다. 여기서는 bleed 값 하나로 끝나고, 재단선과 블리드 영역을 앱이 안다.
  2. 넘친 글자를 도구가 알려준다. inspect_document가 스토리의 overset을 보고하니, 서비스 문구가 프레임을 넘치면 Claude가 렌더링 전에 먼저 안다.
  3. 원본이 남는다. .designcraft 파일로 저장해두면, 다음에 직함이 바뀌어도 텍스트 프레임 하나만 바꾸면 된다.

한글 텍스트에서 걸린 함정

문서를 읽다가 발견한 부분이다. DesignCraft에서 텍스트 위치는 글자 수가 아니라 UTF-8 바이트 오프셋이다. 한글은 한 글자가 3바이트라 "변종원"의 길이는 3이 아니라 9다. 텍스트 일부만 골라 크기나 굵기를 바꾸는 명령(text.select, story.replaceRange 등)을 쓸 때 Claude가 글자 수로 계산하면 엉뚱한 곳이 선택된다. 오프셋이 글자 중간에 걸리면 앞 글자 시작으로 당겨지므로 오류도 안 나고 조용히 틀린다.

그래서 CLAUDE.md에 한 줄을 넣어두는 게 좋다. "DesignCraft 텍스트 오프셋은 UTF-8 바이트 기준. 한글은 글자당 3바이트로 계산할 것." PHP 개발자라면 strlen()과 mb_strlen()의 차이를 떠올리면 바로 이해된다.

5. 사례 2 — PhotoCraft로 카툰 효과

두 번째는 사진 한 장을 만화풍으로 바꾸는 작업이다. 원본은 ~/craft/in에 넣고 이렇게만 말했다.

PhotoCraft로 ~/craft/in/photo.jpg를 카툰 스타일로 바꿔줘.
- 색은 단계를 줄여 평평하게, 윤곽선은 굵고 검게
- 원본 레이어는 남기고 효과는 위 레이어로
- 중간중간 render_preview로 확인하고, 최종본은 PSD와 PNG 둘 다 ~/craft/out에 저장

재미있는 건 Claude가 일하는 방식이다. "카툰 필터" 같은 명령은 없다. Claude는 먼저 command_list로 필터·조정 계열 명령을 훑고, 색 단계 줄이기와 윤곽선 추출을 조합하는 계획을 세운 다음 command_batch로 실행했다. 단계마다 render_preview로 결과를 보면서 윤곽선이 너무 지저분하면 값을 조정했다. 포토샵 숙련자가 액션을 짜는 과정과 거의 같다.

결과물을 PSD로 받은 게 생각보다 쓸모 있었다. 원본 레이어와 효과 레이어가 분리되어 있어서, 포토샵(나는 중급 정도 다룬다)으로 열어 윤곽선 레이어 불투명도만 내리는 식으로 마무리할 수 있다. 다만 PhotoCraft가 다시 저장한 PSD는 원본과 바이트 단위로 같지 않다. 원본 PSD를 덮어쓰지 말고 항상 out에 새로 저장하게 한 이유다.

6. 써보며 정리한 주의점

  • 알파 버전이다. 렌더링 백엔드 문제로 캔버스가 비는 사례가 보고돼 있다. 결과는 반드시 PNG로 직접 확인한다.
  • headless와 connected 모드를 구분한다. 기본 mcp는 창 없이 엔진만 돈다. 에이전트가 하는 일을 앱 화면에서 실시간으로 보고 싶으면 앱을 --control 7979로 띄우고 mcp --connect 7979로 연결한다. screenshot, click, 대화상자 조작은 connected 모드에서만 된다.
  • 폰트는 서버에 있어야 한다. Ubuntu에서 headless로 돌릴 때 한글 폰트가 없으면 대체 폰트로 렌더링된다. 명함처럼 폰트가 중요한 작업은 Noto Sans KR 같은 폰트를 먼저 설치한다.
  • 루트 폴더를 좁게 잡는다. 홈 디렉터리 전체를 루트로 주지 않는다. 작업 폴더 두 개면 충분하다.
  • 인쇄용 색은 따로 확인한다. PNG는 RGB다. 인쇄소가 CMYK를 요구하면 별도 변환이 필요하고, #2563EB 같은 선명한 파랑은 변환 후 톤이 달라진다.

7. CI4 서비스에 붙인다면

MCP는 대화형으로 쓸 때 편하지만, 같은 엔진을 CLI로 바로 부를 수도 있다. PhotoCraft는 액션 JSON을 폴더 단위로 일괄 적용하는 batch 명령을 제공한다. Claude와 대화하며 다듬은 효과를 액션 파일로 굳혀두면, 서비스에서 업로드 이미지에 같은 효과를 입히는 기능으로 옮길 수 있다. 아직 구상 단계지만 CI4라면 이런 모양이 될 것이다.

&1',
            escapeshellarg($this->actionsFile),
            escapeshellarg($inDir),
            escapeshellarg($outDir)
        );

        exec($cmd, $output, $code);

        if ($code !== 0) {
            throw new RuntimeException('PhotoCraft batch failed: ' . implode("\n", $output));
        }
    }
}

실제로 붙인다면 요청 안에서 동기 실행하지 않는다. 이미지 처리는 시간이 들쭉날쭉하니 큐에 넣고 202 Accepted로 응답한 뒤 워커에서 돌리는 게 맞다. 알파 버전 바이너리를 운영에 넣는 것도 아직은 이르다. 지금은 내부 도구나 관리자 기능 정도가 적당하다.

정리

그동안 Claude와 디자인을 한다는 건, Claude가 코드로 그림을 짐작하고 내가 눈이 되어주는 일이었다. Craft MCP를 붙이고 나서 처음으로 Claude가 디자인 툴을 쓰고, 결과를 스스로 보고, 고친다. 결과물도 PNG 한 장이 아니라 레이어가 살아 있는 원본 파일로 남는다.

아직 알파라 실무 전체를 맡기긴 어렵다. 하지만 명함, 배너, 썸네일처럼 규격이 정해진 반복 작업이라면 지금도 충분히 쓸 만하다. 다음에는 VectorCraft로 로고 작업을 해볼 생각이다.

참고