ethanplusai/jarvis
요약
JARVIS는 Claude Code를 위한 음성 인터페이스로, 사용자와의 대화를 통해 프로젝트 브레인스토밍부터 설계 및 실행까지 전 과정을 지원하는 도구입니다. 이 시스템은 사용자 컴퓨터의 모든 Claude Code 세션을 모니터링하며, 계획(plan) → 검토(review) → 실행(execute) 단계를 거쳐 개발을 진행합니다. 특히 Anthropic API 키를 환경 변수에서 제거하여 보안성을 높이고, 음성 출력에는 Fish Audio 사용이 필수적입니다.
핵심 포인트
- Claude Code 기반의 대화형 프로젝트 관리 시스템.
- 대화 과정에서 계획-검토-실행(plan→review→execute) 사이클을 거침.
- Anthropic API 키를 환경 변수에서 제거하여 보안성을 강화함.
- 음성 출력은 Fish Audio 사용이 필수적이며, 텍스트로 대체 가능.
클로드 코드(Claude Code)를 위한 음성 인터페이스, JARVIS.
JARVIS는 이미 비용을 지불하고 사용하는 Claude Code 위에 존재하는 영국식 집사입니다. 사용자가 그와 대화하면 됩니다. 그는 질문 하나하나씩 사용자에게 프로젝트에 대해 브레인스토밍하며, 사용자가 무언가에 결정하면 그것을 프로젝트 파일로 설계하여 기록합니다. 그런 다음 실제로 Claude Code 세션을 시작하고 계획(plan) → 검토(review) → 실행(execute) 과정을 거치게 합니다. 작동하는 동안 그는 사용자 컴퓨터의 모든 Claude Code 세션을 모니터링하며, 그중 하나가 사람의 응답을 기다리느라 멈춰 있으면, 사용자가 볼 필요 없이 어떤 세션인지 소리로 알려줍니다.
"알겠습니다, 주인님."
사용자가 그와 대화하는 동안 실제로 보는 것은 frontend/src/orb.ts 파일이 실시간으로 렌더링되는 화면입니다. 맥박을 구동하는 오디오는 녹음된 목소리가 아니라 실제 분석기 측정값에 맞춘 음성 형태의 엔벨로프(envelope)인 합성음이지만, 모든 픽셀은 이 파일이 실행되고 있는 것입니다. scripts/make_orb_loop.py를 사용하여 재생성하세요.
전체 대시보드는 클릭하여 볼 수 있습니다. 프로젝트, 프롬프트, 사람, 수치 등 이 페이지의 모든 스크린샷에 있는 데이터는 가상의 샘플 데이터입니다.
AI API 사용은 없으며, 불가능합니다. JARVIS의 두뇌는 사용자의 Claude 구독에서 실행되는 Claude Code 프로세스이며, 터미널에서 사용하는 것과 동일한 로그인으로 작동합니다. 음성 경로 어디에도 Anthropic API 키가 존재하지 않으며, 실수로 넣을 수도 없습니다:
# claude_env.py
SCRUBBED_ENV_PREFIXES = ("CLAUDE_CODE_", "ANTHROPIC_")
SCRUBBED_ENV_KEYS = {"CLAUDECODE"}
JARVIS가 생성하는 모든 Claude Code 프로세스—두뇌와 모든 빌드—는 claude_env.child_env()를 통해 시작됩니다.
이 함수는 환경 변수에서 모든 ANTHROPIC_* 변수를 먼저 제거합니다. 이는 의도적인 것이며 사소한 배려가 아닙니다. CLI는 사용자의 로그인보다 상속된 ANTHROPIC_API_KEY를 조용히 선호하며, claude auth status는 계속 loggedIn: true를 보고하는 동안 청구 시스템은 조용히 키로 이동합니다. 따라서 JARVIS는 자신에게 키를 전달하지 않을 것이라고 신뢰하기보다는 아예 키를 제거합니다. .env 파일에 남겨두지 마세요.
만약 당신이 — 스타트업 점검을 좋아한다면 경고할 것이며, 뇌는 여전히 그것을 볼 수 없을 것입니다.
따라서 중요한 숫자는 달러 금액이 아니라 구독의 두 창 중 얼마나 많은 부분이 사라졌는지입니다. 가상의 샘플 데이터입니다.
당신이 비용을 지불하는 유일한 것은 Fish Audio이며, 이것이 JARVIS에게 목소리를 제공합니다. FISH_API_KEY 없이는 tts.py가 아무것도 반환하지 않으므로, JARVIS는 침묵하고 그의 답변은 대신 브라우저의 텍스트로 나타납니다. 다른 TTS를 사용하고 싶다면, 교체할 수 있는 작고 잘 분리된 파일이 있으니 아래 나만의 것으로 만들기를 참고하세요.
생각을 소리 내어 합니다. 대화가 디자인 단계입니다. 그는 한 번에 하나의 질문을 하고, 두세 가지 접근 방식을 제시하며, 당신이 하나에 동의하기 전까지는 아무것도 시작하지 않습니다.디자인을 기록합니다. 합의된 내용은 docs/superpowers/specs/YYYY-MM-DD-<주제>-design.md로 디스크에 저장됩니다.
빌드되는 프로젝트 내부에서 — 단 하나의 프로세스도 실행되기 전에요. 번호가 매겨진 섹션별로 다시 읽거나 음성으로 승인할 수 있으며, 대시보드에서 열 수도 있습니다.빌드를 진행합니다. 빌드는 실제 claude -p
세션은 자신에게 단계별 계획을 작성하고, 그 계획을 사양(spec)과 비교 검토한 다음, 테스트 주도 개발(test-driven development) 방식에 따라 과제별로 실행하며 진행하는 체크박스들을 표시하도록 지시받습니다. '얼마나 진행했는가'라는 질문은 추측이 아니라 이 체크박스들을 읽음으로써 답변됩니다.기계의 모든 Claude Code 세션을 감시합니다— 자신만의 것뿐만 아니라 다른 사람의 것도요. "내 세션 중 나를 기다리는 것이 무엇인가?"라고 물으면 실시간으로 확인해 줍니다. 하나의 세션에 메시지를 게시할 수도 있고, Terminal.app에서 실행되는 세션에 대한 권한 프롬프트에 단일 키 입력을 통해 답변할 수 있습니다.필요할 때 방해합니다. 인간의 도움이 필요한 세션은 즉시 소리 내어 알려주고, 단순히 완료된 세션들은 다음 일시 정지 시 하나의 문장으로 묶입니다. 브라우저 탭이 열려 있는 사람이 아무도 없다면 macOS 알림으로 표시됩니다.기억합니다. 장기 기억(long-term memory)은 평문 Markdown 파일 폴더이며, 파일당 하나의 사실을 담고 있고, 이 인덱스는 두뇌가 항상 볼 수 있도록 되어 있습니다. 어떤 텍스트 편집기에서든 읽고 수정할 수 있습니다.모든 것을 기록합니다. JARVIS가 시작하는 모든 Claude Code 프로세스는 *실행(run)*입니다. 이는 프롬프트, 프로젝트, 상태, 토큰 사용량 및 전체 이벤트 스트림을 포함하는 SQLite의 한 행으로 저장됩니다. /dashboard에서 실시간으로 확인하세요.
실행(Runs) 보기. JARVIS가 시작하는 모든 Claude Code 프로세스는 여기에 하나의 행으로 표시되며, 그것을 시작한 프롬프트와 함께 합니다. 가상의 샘플 데이터입니다.
대시보드는 Runs, Sessions, Memory, Specs, Projects, Usage의 여섯 개 탭으로 구성되어 있습니다. Usage는 구독권의 5시간 및 7일 사용 가능 시간과 누가 이를 사용했는지 보여줍니다.
세션(Sessions) 보기. 목록 옆에 막힌 세션이 열려 있습니다. 세션이 멈춘 이유는 추측이 아니라 CLI 자체의 문구로 표시됩니다. 가상의 샘플 데이터입니다.
macOS. Terminal 제어, 창 목록, 스크린샷 및 알림 모두 AppleScript를 통해 이루어집니다. 오늘날 Linux나 Windows 경로는 없습니다.**Google Chrome.**선호 사항이 아닌 제약 조건입니다. 마이크는 Web Speech API (SpeechRecognition / webkitSpeechRecognition, frontend/src/voice.ts 참고)을 사용합니다.
)), which Firefox has never implemented. 백업할 서버 측 전사(transcription) 기능이 없습니다.Claude Code가 설치 및 로그인됨. npm install -g @anthropic-ai/claude-code<br><br>(2.1.224 이상) 버전인 경우, 한 번 claude를 실행하여 로그인합니다. 이것이 JARVIS가 작동하는 방식입니다.Python 3.11 이상 및 Node.js 18 이상이 필요하며, Fish Audio API 키가 필수적입니다. 대체 음성이 없습니다.<br><br><br>git clone <your fork of this repo> jarvis<br>cd jarvis<br>cp .env.example .env<br>...<br><br><br>.env 파일 채우기.<br><br>.env.example에는 많은 내용이 문서화되어 있으며, 간단히 말해 필수 키 1개와 선택 키 3개가 있습니다:<br><br>FISH_API_KEY=... # 필수, 대체 불가<br># JARVIS_BRAIN_MODEL=sonnet # 선택: 두뇌 모델<br># FISH_VOICE_ID=... # 선택: 다른 음성<br>...<br><br><br>인증서 생성. 이것들은 선택 사항이 아닙니다:<br><br>openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -nodes -subj '/CN=localhost'<br><br>server.py는 cert.pem과 key.pem이 옆에 놓여 있으면 항상 HTTPS를 제공하고,<br>frontend/vite.config.ts는 /api와 /ws를 <br>https://localhost:8340로 프록시합니다.<br><br>이 두 파일(pair) 없이는 백엔드가 일반 HTTP를 제공하며, 개발 서버의 프록시는 이를 도달할 수 없고, 프런트 엔드를 통한 모든 API 및 WebSocket 호출은 500 오류와 함께 실패하지만 페이지 자체는 여전히 로드되어 매우 혼란스러운 저녁 시간을 보내게 됩니다. 이 인증서들을 한 번 생성하고 잊어버리세요.<br><br>그런 다음 두 개의 터미널에서:<br><br><br>python server.py --host 127.0.0.1 # 터미널 1<br>cd frontend && npm run dev # 터미널 2<br><br><br>Chrome을 http://localhost:5173에서 열고, 오디오를 허용하기 위해 페이지를 한 번 클릭한 다음 말합니다. 대시보드는 http://localhost:5173/dashboard.html에 있습니다.<br><br>누가 접근할 수 있나요?--host는 기본적으로 127.0.0.1— 즉 이 컴퓨터에서만 작동합니다. JARVIS가 제공하는 모든 것은 사용자의 전체 권한으로 작동합니다:POST /api/runs은 claude --dangerously-skip-permissions를 실행하고, /api/sessions는 사용자가 가진 모든 Claude Code 대화를 읽습니다. 엄격한 Origin
모든 WebSocket과 상태 변경 라우트 앞에 검사(check)를 두어, 우연히 방문하는 웹 페이지가 /ws/voice를 열 수는 없습니다.
그리고 당신처럼 말하게 합니다. 설정할 것이 아무것도 없습니다: 페이지는 동일 출처(same-origin)이므로 브라우저가 Origin을 전송합니다.
페이지는 위조할 수 없습니다. 하지만, Origin은 브라우저가 설정했을 때만 위조 불가능합니다. 따라서 원시 HTTP를 다루는 어떤 것도 대시보드라고 주장할 수 있으므로, Origin이 없는 클라이언트 — 즉 스크립트, 뇌 자체의 MCP 자식(child) — 는 대신 토큰을 <data-dir>/jarvis/tool-token에 제시해야 하며, 네트워크 상에서 루프백 바인딩은 나머지 답입니다. --host 0.0.0.0
의미하는 바라면 여전히 작동합니다. JARVIS_ALLOWED_ORIGINS를 실제로 페이지를 열 주소로 설정하세요. 그렇지 않으면 브라우저가 거부될 것입니다. 이것은 이 디자인에서 의도된 다섯 가지 신뢰 결정 중 하나입니다 — 실행하기 전에 What this trusts, and why를 참조하십시오.
Chrome에 대한 또 다른 점: 마이크 권한은 **포트를 포함한 출처(origin)**에 한정됩니다. Vite를 재시작하여 5174로 떨어지면, 승인 정보가 따라가지 않으며 Chrome은 다시 프롬프트를 표시하지 않습니다 — 그저 침묵하며 거부된 상태를 유지합니다. 모든 것이 제대로 작동하는 것 같지만 마이크가 작동하지 않는다면, 포트가 이동했는지 확인하십시오.
JARVIS는 아무것도 연결되지 않은 상태로 배포됩니다. 유용한 것은 우리가 무엇을 사용할지 추측하는 것이 아니라 — 바로 문(door)입니다. 어떤 MCP 서버든 작동합니다. mcpServers 블록을 data/jarvis/connections.json에 넣으세요:
{
"mcpServers": {
"notion": {
...
이것은 서버 자체의 README에서 가져온 변경되지 않은 블록입니다. JARVIS를 재시작하고 **"무엇에 연결되어 있니?"**라고 물어보세요 — 그는 실제로 시작된 것부터 답변하며, 시작하지 않을 것이 무엇인지 그리고 그 이유를 명시하고, 그것이 자신에게 어떤 비용을 지불하게 하는지 알려줍니다. (턴마다 도구당 컨텍스트 250 토큰 정도입니다 — 측정된 수치이며, 의도한 도구가 아닌 실제로 로드된 도구를 기준으로 계산됩니다. 대화에서 그가 기억하는 양에 대해서는 청구되지 않습니다.)
다른 MCP 서버들은 의도적으로 무시됩니다. JARVIS는 --strict-mcp-config 옵션으로 실행되므로, ~/.claude.json이나 Claude Desktop에 설정하지 않는 한 그 어떤 것도 접근할 수 없습니다. JARVIS에 연결하는 것은 당신이 직접 수행한 작업이어야지, 물려받은 것이어서는 안 됩니다.
연결된 서버가 무엇을 반환하든 웹 페이지와 동일하게 취급됩니다: 보고될 뿐, 절대 따르지는 않습니다. 서버를 설치할 때 그 코드에 대해 보증했으므로, 그것이 돌려주는 티켓이나 이메일, 공유 페이지까지는 책임지지 않습니다.
더 자세한 단계별 안내(서버가 시작되지 않을 때 무엇을 해야 하는지 포함)는 skills/jarvis-setup/SKILL.md를 참고하세요.
JARVIS의 이전 버전들은 Apple Calendar, Mail 및 Notes에 연결되어 있었습니다. 그런 기능들은 사라졌습니다. 그것들은 그가 어떤 말을 하기 전에 첫 실행 시 세 번의 AppleScript 권한 프롬프트를 필요로 했는데, 소프트웨어 구축이 임무인 비서에게는 과도한 요구였습니다. 우리가 선택하는 문 하나가 우리가 고른 세 개의 문보다 가치가 있습니다.
마이크 → Chrome Web Speech API → WebSocket → FastAPI (server.py)
│
▼
...
두뇌(brain)는 턴당 요청이 아니라 하나의 지속적인 프로세스입니다. 당신의 녹취록은 그 표준 입력(stdin)으로 작성되며, 응답은 도착하는 대로 스트리밍되어 문장 단위로 분할됩니다. 따라서 나머지 부분이 아직 작성되는 동안 첫 단어들은 이미 발화되고 있습니다. 이는 MCP 도구로서 JARVIS 자체 기능에 접근하며, POST /internal/tool로 전달되는 stdio 채널을 통해 이루어집니다. 정확한 목록은 brain.py 상단의 허용 목록(allowlist)이며, 여기에서 인용할 숫자가 아니라 읽어야 할 목록입니다.
웹에서 방금 읽은 것에 대해 행동하는 기능은 얻지 못합니다. WebSearch, WebFetch, read_page, 또는 look_at_page를 사용한 턴은 해당 턴의 나머지 모든 실행 도구에 의해 거부되며, 턴이 당신의 발화로 시작하지 않는 한 어떤 행동 도구도 실행되지 않습니다. 웹 페이지, 스크린샷 또는 다른 세션의 녹취록에서 도착하는 텍스트는 신뢰할 수 없는 것으로 간주되어 그렇게 취급됩니다.
실제 작업으로 생성되는 모든 것은 하나의 기록된 파이프라인을 거치며, 이 과정 전반에 걸쳐 두 가지 불변(invariant)이 유지됩니다:
실행은 항상 최종 상태에 도달합니다—succeeded, failed, timed_out, 또는 cancelled 중 하나입니다. 절대로 running 상태에 갇히지 않습니다.
모든 상태 전환은 알림(notification)이 되기 전에 데이터베이스 쓰기 작업입니다. WebSocket은 캐시 무효화 힌트일 뿐, 진실의 원천(source of truth)이 아닙니다. 대시보드는 /api/runs를 기준으로 조정됩니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 GitHub AI Tools의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기