이 저장소가 대체 무엇인가.
Desktop Commander MCP는 AI 채팅 앱(Claude Desktop 등)이 내 컴퓨터를 실제로 조작할 수 있게 해주는 "다리(bridge)"다. AI는 원래 텍스트만 주고받을 뿐, 내 파일을 열거나 명령어를 실행할 수 없다. 이 서버를 설치하면 AI가 "이 폴더 목록을 보여줘 → 이 파일을 이렇게 고쳐 → 이 명령을 터미널에서 돌려 → 결과를 읽어와" 같은 일을 스스로 할 수 있게 된다. Anthropic이 만든 MCP(Model Context Protocol)라는 표준 위에서 동작한다.
Claude는 유능한 비서지만 기본 상태로는 말만 할 수 있는 두뇌다. 코드를 짜 줄 순 있어도 그걸 내 컴퓨터에 저장하거나 실행해 볼 수는 없다. Desktop Commander는 이 비서에게 "컴퓨터를 직접 만지는 장갑"을 끼워준다. 이제 비서는 파일 서랍을 열고(파일 읽기), 문서를 고쳐 쓰고(편집), 기계를 돌리고(명령 실행), 돌아가는 기계 옆에 서서 대화까지(프로세스 상호작용) 한다.
중요한 차이 하나: 이 장갑은 내가 이미 월정액으로 고용한 비서(Claude 구독)가 그대로 낀다. 새로 시급(API 토큰 요금)을 매기는 별도 인력을 부르는 게 아니다 — 이것이 이 프로젝트의 경제적 핵심이다.
라이선스는 관대한 MIT이고, 코드는 TypeScript로 쓰여 Node.js 위에서 단일 프로세스로 돈다(v0.2.45). Anthropic의 공식 MCP Filesystem Server 위에 검색·치환 편집 기능을 얹어 출발했고, 지금은 Excel·PDF·DOCX 읽기/쓰기, REPL 코드 실행, 원격 MCP까지 품은 종합 "컴퓨터 조작" 서버로 커졌다. TrendShift에 오늘 Daily 5위로 올라 있다.
"Claude가 파일을 고쳐준다"는 건 겉모습이다. 이 레포의 진짜 가치는 MCP 서버를 실제로 어떻게 설계하는가 · stdio 위에서 JSON-RPC 오염을 막는 트릭 · 퍼지 매칭(레벤슈타인)으로 코드를 안전하게 치환하는 법 · 장시간 프로세스를 세션으로 붙잡아 두고 REPL처럼 대화하는 구조 · 명령 블록리스트 우회를 $()까지 파고들어 막는 파서 · 워커 스레드로 무거운 검색을 이벤트 루프에서 분리하는 법을 읽을 수 있는 규모의 TypeScript 코드베이스에서 통째로 볼 수 있다는 점이다. "AI가 컴퓨터를 조작하는 에이전트는 실제로 어떻게 만들어지는가"의 표준 참고서에 가깝다.
이 도구는 편의를 위해 AI에게 실제 터미널과 파일 쓰기 권한을 준다. 잘못된 명령 하나가 파일을 지우거나 시스템을 건드릴 수 있다는 뜻이다. 그래서 프로젝트는 명령 블록리스트(rm -rf류·dd·sudo 등), 심볼릭 링크 traversal 차단, Docker 격리, 감사 로그를 기본 안전장치로 둔다. 그래도 "AI가 내 홈 디렉토리를 자유롭게 만진다"는 사실은 변하지 않으므로, 중요한 폴더는 접근을 제한하거나 Docker 샌드박스로 돌리는 것이 권장된다. 또한 기본값으로 익명 사용 통계를 수집하며(BigQuery 프록시), 설정으로 끌 수 있다.
트렌딩 이유와, Cursor·Windsurf·Claude Code 같은 경쟁 도구 대비 결정적 차이.
Cursor·Windsurf·GitHub Copilot 같은 AI 코딩 도구, 그리고 API로 붙는 대부분의 에이전트는 AI가 일할 때마다 토큰 단위로 돈을 문다. 큰 코드베이스를 다루면 월 수십 달러가 순식간이다. Desktop Commander는 Claude Desktop의 정액 구독(예: Pro/Max) 안에서 그대로 동작한다 — AI를 부르는 주체가 클라이언트 앱이라, 추가 API 비용이 붙지 않는다. "이미 내는 구독료로 자율 코딩 에이전트를 쓴다"는 가성비가 커뮤니티의 폭발적 반응을 만들었다.
대부분의 AI 코딩 도구 = 미터기 켠 택시(토큰마다 요금). Desktop Commander = 정액 지하철 정기권(구독료 안에서 무제한 승차). 목적지(작업)가 멀수록 격차가 벌어진다. 단, 정기권은 클라이언트가 정한 사용량 한도(rate limit) 안에서만 유효하다는 조건이 붙는다.
Cursor·Windsurf는 특정 IDE(에디터) 안에서만 산다. Desktop Commander는 반대로 평범한 채팅 창(Claude Desktop)을 그대로 개발·자동화 콘솔로 바꾼다. 코드뿐 아니라 파일 정리, 데이터 분석(CSV·Excel 즉석 분석), 서버 관리(SSH·DB 세션 유지), 문서 변환(PDF·DOCX 생성)까지 한 채팅에서 한다. "코딩 도구"라기보다 "컴퓨터 전반을 다루는 범용 에이전트 손"에 가깝다.
MCP는 2024년 말 등장한 뒤 AI 도구 연결의 사실상 표준이 됐다. Desktop Commander는 가장 초기부터 가장 많이 쓰인 MCP 서버 중 하나로, "MCP 서버가 실제로 무엇을 할 수 있는가"의 대표 사례로 자주 인용된다. 최근에는 Claude Desktop을 넘어 Remote MCP(웹의 ChatGPT·Claude에서 원격 접속), Docker 원클릭 설치, 파일 미리보기 UI(MCP-UI), 자체 스킬(skills) 번들까지 확장하며 계속 트렌딩에 오른다.
| 측면 | Cursor / Windsurf | Claude Code (CLI) | Desktop Commander MCP |
|---|---|---|---|
| 형태 | 전용 IDE(에디터) | 전용 터미널 CLI | MCP 서버(채팅 앱에 부착) |
| 과금 | 구독 + 토큰/한도 | API 토큰 또는 구독 | 클라이언트 구독 그대로 |
| 범위 | 주로 코드 편집 | 코드 중심 에이전트 | 터미널·파일·프로세스 전반 |
| 클라이언트 | 자체 앱만 | 자체 CLI | Claude·ChatGPT·Cursor·Cline 등 |
| 실행 | 에디터 내부 | 로컬 셸 | 로컬 셸 + REPL 메모리 실행 |
※ 세 도구는 배타적이지 않다. Desktop Commander를 Cursor·Cline 같은 클라이언트에 MCP로 함께 붙여 쓰는 경우도 많다.
무의존에 가까운 순수 C였던 colibri와 달리, 이쪽은 "여러 파일 포맷 + 프로토콜"을 다루는 실용 Node 스택이다.
| 영역 | 사용 기술 | 역할 |
|---|---|---|
| 언어 | TypeScript 5.3 → JS(ESM) | 전 코드가 TS, tsc로 빌드해 dist/로 배포 |
| 런타임 | Node.js ≥18 | 단일 프로세스, type:"module" ESM |
| 프로토콜 | @modelcontextprotocol/sdk ^1.9 | MCP 서버 구현체(도구·리소스·프롬프트 노출) |
| 전송 | stdio (커스텀 래핑) | 표준입출력으로 JSON-RPC 주고받음 |
| 스키마 | zod + zod-to-json-schema | 도구 입력값을 런타임 검증 + JSON Schema 자동 생성 |
| 기능 | 라이브러리 | 쓰임 |
|---|---|---|
| 코드/텍스트 검색 | @vscode/ripgrep | VS Code가 쓰는 그 ripgrep 바이너리로 초고속 재귀 검색 |
| 퍼지 매칭 | fastest-levenshtein | 편집 시 "거의 일치하는" 블록을 찾는 편집거리 계산 |
| Excel | exceljs | .xlsx/.xls/.xlsm 읽기·쓰기·검색(외부 도구 없이) |
| pdf-lib · unpdf · @opendocsg/pdf2md | PDF 생성/수정 + 텍스트 추출 + 마크다운 변환 | |
| DOCX | pizzip + 커스텀 XML 편집 | Word 문서를 XML 수준에서 "외과적" 편집 |
| 이미지 | sharp · file-type | 이미지 처리 · 바이너리 파일 형식 판별 |
| 마크다운 | markdown-it · remark · unified | 렌더링 · 파싱 · md↔pdf 변환(md-to-pdf) |
| 파일 미리보기 UI | @tiptap/* (ProseMirror) | Claude Desktop 안에서 마크다운 에디터·프리뷰 위젯 |
| 원격/텔레메트리 | @supabase/supabase-js · cross-fetch | Remote MCP 기기 인증 · 익명 사용 통계 전송 |
verify-ripgrep.js가 바이너리 존재를 확인한다.)배포 채널이 유난히 많다: npx 원커맨드 설치(npx @wonderwhy-er/desktop-commander setup), Smithery(MCP 마켓), MCPB 번들(@anthropic-ai/mcpb로 .mcpb 패키지 생성), Docker(Node.js 없이 샌드박스 실행 + 자동 업데이트), Remote MCP(웹 클라이언트에서 원격 접속). CI는 GitHub Actions(코드 철자 검사 등). 릴리스는 publish-release.cjs 스크립트가 npm+MCP 레지스트리에 동시 배포한다.
요청 하나가 AI 채팅에서 출발해 실제 파일/명령까지 도달하는 전 과정.
MCP의 stdio 전송은 표준출력(stdout)을 통째로 JSON-RPC 통신 채널로 쓴다. 문제는, 코드 어딘가에서 무심코 console.log("디버그") 한 줄만 찍어도 그 텍스트가 통신 채널에 섞여 프로토콜 전체가 깨진다. Desktop Commander는 StdioServerTransport를 상속해, 가로챈 콘솔 출력을 버리지 않고 정식 notifications/message JSON-RPC 구조로 감싸서 내보낸다. "디버그 가시성은 살리되 프로토콜은 안 깨지게" 하는 실전 트릭이다.
stdout = 한 줄로 이어진 컨베이어 벨트(정해진 규격의 상자만 흘러야 함). 실수로 벨트에 낙서 쪽지(console.log)를 던지면 분류기가 멈춘다. 이 클래스는 낙서 쪽지를 규격 상자에 담아 흘려보낸다 — 내용은 보존되고 라인은 안 멈춘다.
AI가 코드를 고칠 때 흔한 방식은 "이 텍스트를 찾아 저 텍스트로 바꿔라"(search/replace)다. 그런데 AI가 기억하는 원본이 공백·따옴표·들여쓰기가 살짝 어긋나면 정확히 일치(exact match)에 실패한다. Desktop Commander는 정확 일치가 안 되면 레벤슈타인 편집거리로 "가장 비슷한 블록"을 찾아 유사도가 임계값을 넘으면 편집을 제안한다. 이 퍼지 검색은 무거우므로 워커 스레드(worker thread)에서 돌려 메인 이벤트 루프를 막지 않는다.
// edit.ts (개념 요약)
1) block.search 를 파일에서 정확히 찾는다
2) 실패 → runFuzzySearchInWorker(content, search) // 워커에서 레벤슈타인
3) getSimilarityRatio() 가 임계값(예: 0.8) 이상이면
→ "이 근처가 맞나요?" 후보 제시 + 치환
4) 여러 곳 매칭 시 expected_replacements 로 안전장치
단발 명령(ls)만 지원하면 SSH·데이터베이스·개발 서버처럼 계속 살아서 입력을 기다리는 프로그램을 다룰 수 없다. Desktop Commander는 start_process로 프로세스를 띄우고 세션 ID로 붙잡아 둔 뒤, interact_with_process로 그 안에 명령을 계속 흘려보내고 read_process_output으로 출력을 페이지 단위로 읽는다. 이 구조 덕에 Python·Node·R 인터프리터를 띄워 파일을 저장하지 않고 메모리에서 코드를 실행(REPL 분석)하는 킬러 기능이 가능하다.
보안의 핵심은 command-manager.ts다. 사용자가 실행하려는 명령 문자열을 세미콜론·&&·||·파이프·& 기준으로 쪼개(extractCommands) 각 조각의 첫 단어(base command)를 블록리스트와 대조한다. 영리한 점은 따옴표 안이든 밖이든 $(...) 명령 치환까지 파고들어 검사한다는 것 — echo "$(rm -rf /)" 같은 우회를 막기 위해서다. 기본 차단 목록엔 format · mkfs · dd · sudo · su · passwd · mount 등이 들어 있다.
블록리스트 방식은 본질적으로 "알려진 나쁜 명령만 막는" 접근이라, 창의적 우회는 늘 가능하다. 그래서 프로젝트는 진짜 격리가 필요하면 Docker 컨테이너 실행을 권한다(호스트와 파일시스템·프로세스가 분리됨). "중요 데이터가 있는 계정에서 무방비로 돌리지 말 것"이 실무 원칙이다.
어디에 무엇이 있는지 — 처음 코드를 열었을 때 길을 잃지 않도록.
흐름을 따라가고 싶다면 server.ts의 switch(name) → 해당 tools/*.ts → schemas.ts의 zod 스키마 순으로 읽으면 도구 하나의 생애가 그대로 보인다. 보안이 궁금하면 command-manager.ts와 test/test-blocklist-bypass.js를 함께 열어 보라 — 테스트가 우회 시나리오를 친절히 문서화하고 있다.
이 레포를 "읽어서" 얻을 수 있는 구체적 기술 자산.
Server 인스턴스에 ListToolsRequestSchema·CallToolRequestSchema 핸들러를 등록하고, zod 스키마를 zodToJsonSchema로 변환해 도구 목록을 노출하는 MCP 서버의 정석 골격을 그대로 배울 수 있다. "도구 정의 → 검증 → 실행 → 결과 반환"의 최소 단위를 server.ts 하나로 파악 가능.
console.log 하나가 통신을 깨는 stdio 프로토콜에서, 부수효과를 어떻게 프로토콜과 분리하는가는 실무에서 반복되는 문제다. FilteredStdioServerTransport는 "출력을 버리지 말고 규격에 맞춰 감싼다"는 우아한 해법을 보여준다.
알고리즘 교과서의 편집거리가 "AI가 기억한 코드가 살짝 틀려도 안전하게 고치기"라는 실전 문제로 이어진다. 유사도 임계값·다중 매칭 방어(expected_replacements)·워커 스레드 오프로딩까지 한 세트로 볼 수 있다.
child_process를 세션으로 붙잡아 두고, 출력을 offset/length로 페이지네이션해 컨텍스트 폭주를 막는 설계는 "AI에게 무한 출력이 쏟아지는" 실전 함정의 교과서적 해법이다.
따옴표·이스케이프·$() 치환을 고려한 셸 명령 토크나이저를 직접 구현한 사례. "간단해 보이는 문자열 파싱이 왜 보안에서 어려운가"를 코드로 체감한다.
· server.ts에서 도구 하나를 골라 zod 스키마→핸들러→결과 반환을 손으로 따라 그려보기.
· test/test-blocklist-bypass.js를 읽고 "내가 아는 또 다른 우회"를 상상해 보기.
· Docker로 설치해, 호스트와 격리된 상태에서 위험 명령을 안전히 실험하기.
무엇이 있어야 돌아가고, 어떻게 붙이나.
| 항목 | 요구/권장 |
|---|---|
| OS | macOS · Windows · Linux |
| 런타임 | Node.js ≥18 (npx/npm 설치 시). Docker 방식은 Node 불필요 |
| 클라이언트 | Claude Desktop(대표) · 또는 MCP 지원 앱(ChatGPT·Cursor·Cline·Gemini 등) |
| 비용 | 서버 자체는 무료(MIT). AI 사용은 클라이언트 구독/요금에 따름 |
| 권한 | 파일시스템·터미널 접근(위험 인지 필요) · 기본 익명 통계(옵트아웃 가능) |
# Claude Desktop 설정 파일에 자동 주입 + 자동 업데이트
npx @wonderwhy-er/desktop-commander@latest setup
# 설치 후 Claude Desktop 재시작 → 채팅에서 "DC: 이 폴더 목록 보여줘"
# Node.js 없이 샌드박스 컨테이너로 실행, 호스트 폴더는 -v로 선택 마운트
# (예) ~/Projects 만 컨테이너의 /mnt/Projects 로 노출
docker run ... -v ~/Projects:/mnt/Projects desktop-commander
설치 직후 set_config_value로 AI가 접근 가능한 디렉토리를 작업 폴더로 제한하는 것이 첫 번째 안전 조치다. 홈 디렉토리 전체를 열어두지 말고, 프로젝트 폴더만 허용하면 사고 반경이 크게 줄어든다.
읽기만 하지 말고 손을 움직여 볼 것. 난이도별로.
테스트용 폴더 하나를 allowedDirectories로 지정하고, Claude에게 "이 폴더의 파일을 확장자별 하위 폴더로 정리해줘"를 시켜본다. list_directory·create_directory·move_file이 연쇄되는 걸 로그로 관찰하라.
샘플 CSV를 주고 "평균·분포를 요약하고 이상치를 찾아줘"를 요청. 내부적으로 start_process("python3 -i") → interact_with_process로 pandas가 메모리에서 돌아가는 REPL 흐름을 체감한다.
일부러 들여쓰기·따옴표가 어긋난 "찾을 텍스트"를 주고 edit_block이 어디까지 관대하게 매칭하는지 실험. 유사도 임계값을 넘나드는 경계를 관찰하면 알고리즘 감각이 붙는다.
포크한 뒤 schemas.ts에 zod 스키마를 추가하고 server.ts의 switch에 새 case를 붙여 28번째 도구(예: "특정 폴더 용량 요약")를 만들어 본다. MCP 서버 개발의 전 과정을 압축 체험.
test/test-blocklist-bypass.js를 참고해 $()·중첩 따옴표를 이용한 우회를 시도하고, command-manager.ts가 이를 어떻게 잡는지(또는 놓치는지) 추적. 보안 사고방식을 기른다.
이 레포를 발판으로 "AI 에이전트 인프라"를 4주에 걸쳐 넓히는 경로.
| 주차 | 주제 | 할 것 |
|---|---|---|
| 1주 | MCP 기초 | MCP 사양 문서 읽기 → 최소 MCP 서버(도구 1개) 직접 작성 → Claude Desktop에 연결 |
| 2주 | 프로세스·스트리밍 | Node child_process/스트림 심화 → 세션·페이지네이션 출력 구조를 미니 버전으로 재현 |
| 3주 | 텍스트 알고리즘 | 레벤슈타인·diff/patch 알고리즘 학습 → edit_block 유사 "안전 치환기" 구현 |
| 4주 | 보안·격리 | 셸 인젝션·블록리스트 한계 학습 → Docker/권한 경계 설계 → 감사 로그 붙이기 |
npx @modelcontextprotocol/inspector로 도구를 GUI로 찔러보기) · Smithery(MCP 서버 마켓) · Claude Code / Cline(MCP를 소비하는 다른 클라이언트들). Desktop Commander를 이해했다면 이들 사이의 관계가 한눈에 들어온다.문서에 나온 용어를 한 곳에.
dd·sudo 등)을 차단하는 목록. 따옴표·$() 치환까지 파싱해 우회를 막는다. 단, 원리상 완벽하진 않아 Docker 격리가 보조 수단.remote-device/에 있다.원 소스로 가는 길.