Anthropic의 Claude Code OAuth 연동 약관이 2026년 2월 19일 변경됐습니다. 정책 리스크가 명확해질 때까지 Claude Code OAuth 방식 연동을 피하고, ANTHROPIC_API_KEY 직접 입력 방식을 권장합니다. NanoClaw 공식 문서에서도 동일한 주의사항을 공지하고 있습니다.
전체 목차
NanoClaw란? — 아키텍처 & 2026 포지셔닝
NanoClaw는 ~700줄의 TypeScript로 구현된 경량 개인용 Claude AI 어시스턴트입니다. “20분 만에 전체 코드베이스를 읽고 모든 줄을 이해했다”는 사용자 후기처럼, 다른 AI 에이전트 프레임워크와 달리 투명하고 감사 가능한 코드베이스를 지향합니다. MIT 라이선스 오픈소스이며 공식 저장소는 github.com/qwibitai/nanoclaw입니다.
🏗️ 핵심 아키텍처 — Node.js 호스트 + 격리 에이전트 컨테이너
[사용자] WhatsApp / Telegram / Discord / Slack
↓ 메시지
[Node.js Host Process] ─── SQLite DB (영구 메모리)
├── WhatsApp (Baileys 라이브러리) ← 내장 기본 채널
├── Telegram / Discord / Slack ← /add-* 스킬로 추가
├── Cron 예약 작업 엔진
└── 에이전트 컨테이너 오케스트레이터
↓ 메시지 + 컨텍스트 전달
[Per-Session Agent Container] (Linux · Docker / Apple Container)
├── Claude Code (Claude Agent SDK)
├── CLAUDE.md ← 그룹별 독립 지식/메모리
├── 내장 도구: shell · 파일 읽기/쓰기 · 웹 검색 · Chromium 브라우저
└── 에이전트 위임 (Swarm 서브에이전트)
↓ 응답
[Node.js Host] → 사용자에게 메시지 전송
📊 지원 채널 전체 목록 (2026년 6월 기준)
| 채널 | 방식 | 추가 방법 | 비고 |
|---|---|---|---|
| Baileys 라이브러리 | 기본 내장 | npm run auth로 QR 페어링 | |
| Telegram | Bot API | /add-telegram 스킬 | @BotFather에서 토큰 발급 |
| Discord | Gateway API | /add-discord 스킬 | Discord Application Bot 생성 |
| Slack | Events API | /add-slack 스킬 | Slack App Manifest 설정 |
| Microsoft Teams | Bot Framework | /add-teams 스킬 | Azure Bot 등록 필요 |
| iMessage | AppleScript | /add-imessage 스킬 | macOS 전용 |
| Google Chat | Chat API | /add-googlechat 스킬 | Google Workspace 필요 |
| Resend API | /add-email 스킬 | Resend 계정 필요 | |
| Matrix · Webex · WeChat · Linear · GitHub | 각 플랫폼 API | /add-* 스킬 | 온디맨드 스킬 설치 |
🆚 NanoClaw vs OpenClaw 비교 (2026)
| 항목 | NanoClaw | OpenClaw |
|---|---|---|
| 코드베이스 | ~700줄 TypeScript | 대형 · 복잡 |
| 설치 | bash nanoclaw.sh (5분) | 복잡한 다단계 |
| 보안 | 퍼세션 컨테이너 격리 | 공유 인프라 |
| 감사 가능성 | 전체 코드 20분 독파 가능 | 제한적 |
| 멀티 LLM | Claude 전용 | 다수 LLM 지원 |
| 채널 생태계 | 스킬로 확장 | 대형 통합 생태계 |
| 라이선스 | MIT 오픈소스 | 혼합 |
사전 요구사항 & 환경 검증
이전 가이드에서 Node.js 18+로 명시됐으나 2026년 현재 공식 요구사항은 Node.js 20+, pnpm 10+입니다. Docker Compose의 node:18-alpine이미지도 node:20-alpine 이상으로 업데이트하세요. bash nanoclaw.sh 실행 시 자동으로 올바른 버전이 설치됩니다.
| 구성 요소 | 최소 버전 | 권장 | 비고 |
|---|---|---|---|
| Node.js | 20.x LTS | 22.x LTS | 18.x는 EOL 근접, 지원 종료 예정 |
| pnpm | 10.x | 최신 | npm install -g pnpm |
| Docker | 24.x | 최신 stable | Linux: Docker Engine / macOS: Docker Desktop or Apple Container |
| Claude Code | 최신 | 최신 | npm install -g @anthropic-ai/claude-code |
| RAM | 4GB | 8GB+ | Swarm 멀티에이전트 사용 시 더 필요 |
| Anthropic API Key | 필수 | – | console.anthropic.com에서 발급 |
# Node.js 버전 확인 (20+ 필요) node --version # v20.x 이상이어야 함 # pnpm 설치 확인 pnpm --version || npm install -g pnpm # Docker 확인 docker --version # 24.x 이상 docker info # Docker daemon 실행 확인 # Claude Code 설치 (없으면) npm install -g @anthropic-ai/claude-code claude --version # 설치 확인 # Anthropic API 키 환경변수 확인 echo $ANTHROPIC_API_KEY # 비어있으면 다음 단계에서 설정
설치 완전 가이드 — 2026 최신 방식
2026년 현재 NanoClaw 공식 설치 방법은 git clone 후 bash nanoclaw.sh 실행입니다. Node.js, pnpm, Docker가 없어도 설치 스크립트가 자동으로 설치합니다. 단계가 실패하면 Claude Code가 자동으로 진단하고 재개합니다.
방법 A — 자동 설치 스크립트 (권장, 5분)
# 1. github.com/qwibitai/nanoclaw 에서 Fork 클릭 (본인 계정으로 복사) # 2. 내 저장소 Clone git clone https://github.com/[내아이디]/nanoclaw.git cd nanoclaw
bash nanoclaw.sh
# 스크립트가 자동으로:
# - Node.js 20+, pnpm 10+, Docker 설치
# - ANTHROPIC_API_KEY 설정 안내
# - 에이전트 컨테이너 빌드
# - WhatsApp QR 페어링 안내방법 B — Claude Code /setup 스킬 (대화형)
cd nanoclaw claude # Claude Code 실행 # Claude Code 안에서: /setup # 대화형 설치 시작 — Claude가 각 단계를 안내 # 의존성 설치, 컨테이너 빌드, 채널 페어링까지 자동 진행
방법 C — Docker 수동 설치 (고급, R730 홈랩 권장)
version: '3.8'
services:
nanoclaw-core:
image: node:20-alpine # ⚠️ 18-alpine → 20-alpine 필수 업데이트
container_name: nanoclaw-core
restart: unless-stopped
working_dir: /app
command: sh -c "pnpm install && npm start"
volumes:
- ./:/app
- /var/run/docker.sock:/var/run/docker.sock # DooD: 에이전트 컨테이너 생성용
- nanoclaw-data:/app/data
environment:
- NODE_ENV=production
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY} # .env 파일에서 주입
- NANOCLAW_SECRET_KEY=${NANOCLAW_SECRET_KEY}
ports:
- "3000:3000" # API 포트 (내부망만 노출 권장)
networks:
- nanoclaw-net
volumes:
nanoclaw-data:
networks:
nanoclaw-net:
driver: bridgeANTHROPIC_API_KEY=sk-ant-여기에입력 NANOCLAW_SECRET_KEY=$(openssl rand -base64 32) # 웹훅 서명용 NODE_ENV=production # Telegram (선택) TELEGRAM_BOT_TOKEN= TELEGRAM_WEBHOOK_URL=https://yourdomain.com/webhooks/telegram # Discord (선택) DISCORD_BOT_TOKEN=
macOS에서 NanoClaw를 실행하면 기본적으로 Apple Container(경량, Apple Silicon 최적화)를 사용합니다. Docker로 변환하려면 Claude Code에서 /convert-to-docker 스킬을 실행하세요. Linux에서는 Docker만 지원합니다.
채널 연결 — WhatsApp QR & 추가 채널
이전 가이드에서 WhatsApp을 Chromium 브라우저 자동화(whatsapp-web.js + Puppeteer)로 설명했으나, 현재 NanoClaw의 WhatsApp은 Baileys Node.js 라이브러리를 통해 직접 WhatsApp 웹소켓 프로토콜에 연결합니다. Chromium 오버헤드가 없어 훨씬 가볍고 안정적입니다.
WhatsApp QR 페어링 상세
npm run auth
# ⚠️ 반드시 포그라운드에서 실행 — 백그라운드 실행 금지
# QR 코드는 멀티라인 ASCII 아트. 전체가 표시되어야 스캔 가능
# 120초 이상의 타임아웃 허용 (스캔 시간 충분히 확보)iPhone: 설정 → 연결된 기기 → 기기 연결 → QR 스캔
터미널의 텍스트 QR이 브라우저 QR보다 안정적 (네트워크 문제 시)
npm start
# 에이전트가 WhatsApp 메시지를 수신 대기 시작
# 세션은 ./data/whatsapp-sessions/에 저장됨 (재시작 시 자동 복원)추가 채널 설치 — Claude Code 스킬 방식
# Claude Code 실행 claude # Telegram Bot 추가 /add-telegram # → 스킬이 소스 코드에 Telegram 어댑터를 직접 추가 # → .env에 TELEGRAM_BOT_TOKEN 추가 안내 # Discord 추가 /add-discord # Slack 추가 /add-slack # ⚠️ 스킬은 소스 코드를 직접 수정하므로 git commit 권장 git add . && git commit -m "feat: add telegram channel"
Telegram 채널 설정 상세
TELEGRAM_BOT_TOKEN=7654321098:AAF_여기에입력# 개발 환경: ngrok으로 로컬 포트 외부 노출 ngrok http 3000 # Webhook 등록 curl -X POST http://localhost:3000/api/v1/integrations/telegram/register-webhook \ -H "Authorization: Bearer ${NANOCLAW_SECRET_KEY}" # 성공 응답: {"status": "success", "message": "Telegram webhook registered"}
개인 채팅(DM)은 시작 시 DB에 동기화되지 않습니다. 개인 사용자 메시지를 처리하려면 전화번호를 직접 사용해야 합니다: {"'{number}@s.whatsapp.net'".format(number="국가코드포함번호")} 형식. 그룹 채팅만 시작 시 자동 동기화됩니다.
메시징 I/O 파이프라인 아키텍처
NanoClaw의 메시지 처리는 채널 수신 → 큐잉 → 에이전트 컨테이너 스폰 → 응답 발송의 4단계로 이루어집니다. 각 메시지마다 독립된 컨테이너가 생성되어 세션 간 격리를 보장합니다.
[채널 수신] WhatsApp Baileys / Telegram Bot API / Discord Gateway
↓
[메시지 파서] 그룹 JID 추출 · 발신자 정보 · 메시지 타입
↓
[그룹 큐] 그룹별 FIFO 큐 (동일 그룹 메시지는 순서 보장)
↓
[컨테이너 스폰] Docker/Apple Container에서 에이전트 실행
- CLAUDE.md 마운트 (그룹별 독립 메모리)
- SQLite DB 마운트 (세션 영구 메모리)
- 스킬 모듈 주입
↓
[Claude Agent SDK] 도구 실행 (shell·파일·웹검색·Chromium·Swarm 위임)
↓
[응답] 원본 채널로 메시지 전송
WhatsApp 그룹 큐 구현 (Baileys 기반, 2026 수정판)
// ⚠️ 2026년 수정: whatsapp-web.js(Puppeteer) 아님 — Baileys 직접 연결 방식 // NanoClaw 공식 코드는 Baileys 라이브러리를 내부적으로 사용합니다. // npm run auth로 QR 페어링 후 ./data/whatsapp-sessions/에 세션 저장 import { makeWASocket, useMultiFileAuthState, DisconnectReason } from '@whiskeysockets/baileys'; import { Boom } from '@hapi/boom'; import { enqueueMessage } from '../group-queue'; export async function startWhatsAppClient() { const { state, saveCreds } = await useMultiFileAuthState('./data/whatsapp-sessions'); const sock = makeWASocket({ auth: state, printQRInTerminal: true, // 터미널 QR 출력 (브라우저보다 안정적) }); sock.ev.on('creds.update', saveCreds); sock.ev.on('connection.update', ({ connection, lastDisconnect }) => { if (connection === 'close') { const shouldReconnect = (lastDisconnect?.error as Boom)?.output?.statusCode !== DisconnectReason.loggedOut; if (shouldReconnect) startWhatsAppClient(); // 자동 재연결 } }); sock.ev.on('messages.upsert', async ({ messages }) => { for (const msg of messages) { if (!msg.key.fromMe && msg.message) { const jid = msg.key.remoteJid!; // 그룹 또는 개인 JID const text = msg.message.conversation || msg.message.extendedTextMessage?.text || ''; if (text) enqueueMessage({ jid, text, sock }); } } }); }
Telegram Polling Gateway (추가 채널)
import TelegramBot from 'node-telegram-bot-api';
import { enqueueMessage } from '../group-queue';
export function startTelegramGateway(): void {
const token = process.env.TELEGRAM_BOT_TOKEN;
if (!token) { console.warn('[Telegram] TELEGRAM_BOT_TOKEN 없음 — 스킵'); return; }
const bot = new TelegramBot(token, { polling: true });
bot.on('message', (msg) => {
const chatId = String(msg.chat.id);
const text = msg.text || '';
if (text) {
enqueueMessage({
jid: `tg-${chatId}`, // Telegram 채팅 ID를 NanoClaw JID로 변환
text,
sendFn: (reply: string) => bot.sendMessage(msg.chat.id, reply),
});
}
});
console.log('[Telegram] Polling 시작됨');
}CLAUDE.md & SQLite 지식 영속화
NanoClaw는 의도적으로 벡터 데이터베이스를 사용하지 않습니다. 각 에이전트 그룹마다 독립된 CLAUDE.md 파일이 있어 해당 그룹의 컨텍스트·히스토리·규칙을 담습니다. 이를 통해 그룹 간 메모리 오염이 원천 차단됩니다. 영구 데이터는 2개의 SQLite 파일로 관리됩니다.
| 구성 | 위치 | 역할 | 특징 |
|---|---|---|---|
| CLAUDE.md | ./data/groups/{jid}/CLAUDE.md | 그룹별 지식·규칙·히스토리 | 에이전트 컨테이너 시작 시 자동 마운트 |
| store/db.sqlite | ./data/store/db.sqlite | 메시지 히스토리·그룹 메타데이터 | 단일 writer · 크로스 마운트 없음 |
| session/db.sqlite | ./data/session/db.sqlite | 채널 인증·세션 상태 | 단일 writer · IPC 없음 |
CLAUDE.md 표준 템플릿 (그룹별 설정 예시)
# [에이전트 시스템 컨텍스트] - 그룹 식별자: telegram--100123456 - 마지막 동기화: 2026-06-14T09:00:00Z - 에이전트 역할: 개인 비서 및 리서치 어시스턴트 ## 운영 규칙 - 모든 응답은 한국어로 - 코드 스니펫은 마크다운 코드 블록 사용 - 불확실한 정보는 반드시 "확인 필요" 명시 - 개인정보(이름·연락처·위치)는 응답에 포함 금지 ## 영구 지식 베이스 - 사용자 선호 언어: 한국어 - 프로젝트 컨텍스트: agibop.com 블로그 운영 - 자주 쓰는 스택: Ubuntu 24.04, Docker, Ollama, n8n - 홈 서버: Dell R730 (192.168.1.250), NAS DS925+ ## 예약 작업 등록됨 - 매일 07:00 KST: 코스피 시황 브리핑 - 매주 일요일 09:00: 주간 요약 리포트 ## 히스토리 요약 [에이전트가 대화 후 자동 업데이트하는 영역]
SQLite 메모리 초기화 (데이터 손상 시)
# 백업 후 재초기화 cp ./data/store/db.sqlite ./data/store/db.sqlite.backup rm ./data/store/db.sqlite npm run init # DB 재생성 # WhatsApp 세션 초기화 (QR 재스캔 필요) rm -rf ./data/whatsapp-sessions/* npm run auth # QR 코드 재스캔
Cron 자동화 & 예약 작업 엔진
NanoClaw의 Cron 엔진은 Node.js 호스트 프로세스에서 직접 실행됩니다. 예약된 시간에 에이전트 컨테이너를 스폰하고, 실행 결과를 WhatsApp 또는 설정된 채널로 메시지를 보내줍니다.
import cron from 'node-cron';
import { EventEmitter } from 'events';
export interface AutomatedJob {
id: string;
cronExpr: string; // 표준 cron 표현식
targetJid:string; // 메시지 전송 대상 그룹/채팅
prompt: string; // 에이전트에게 전달할 명령
enabled: boolean;
}
const jobEmitter = new EventEmitter();
export function registerCronJob(job: AutomatedJob) {
if (!job.enabled) return;
cron.schedule(job.cronExpr, async () => {
console.log(`[Cron] 작업 실행: ${job.id}`);
jobEmitter.emit('trigger', { jid: job.targetJid, prompt: job.prompt });
}, {
timezone: 'Asia/Seoul' // KST 기준
});
}실전 Cron 예약 작업 예시
[
{
"id": "morning-market-brief",
"cronExpr": "0 7 * * 1-5",
"targetJid": "[email protected]",
"prompt": "오늘 코스피·코스닥 시황과 주요 뉴스 3개를 한국어로 정리해줘.",
"enabled": true
},
{
"id": "weekly-review",
"cronExpr": "0 9 * * 0",
"targetJid": "[email protected]",
"prompt": "지난 주 내가 진행한 작업들과 미완료 항목을 CLAUDE.md를 참고해서 정리해줘.",
"enabled": true
},
{
"id": "daily-server-health",
"cronExpr": "0 8 * * *",
"targetJid": "[email protected]",
"prompt": "홈서버 상태를 확인해줘. docker ps 결과와 디스크 사용량을 보고해줘.",
"enabled": true
}
]Python Custom Skill 개발 — 호스트 격리형 샌드박스
NanoClaw의 Custom Skill은 에이전트가 호출할 수 있는 외부 Python 스크립트입니다. 호스트와 격리된 환경에서 실행되며, 표준 입출력으로 에이전트와 통신합니다.
import { execFile } from 'child_process';
import * as path from 'path';
import * as fs from 'fs';
const SKILLS_DIR = path.resolve('./skills');
export function executePythonSkill(
skillName: string,
payload: Record
): Promise {
return new Promise((resolve, reject) => {
const skillPath = path.join(SKILLS_DIR, skillName, 'main.py');
if (!fs.existsSync(skillPath)) {
reject(new Error(`스킬 없음: ${skillName}`));
return;
}
const input = JSON.stringify(payload);
execFile('python3', [skillPath], {
timeout: 30_000, // 30초 타임아웃
maxBuffer: 1024 * 1024, // 1MB 출력 제한
}, (err, stdout, stderr) => {
if (err) { reject(new Error(stderr || err.message)); return; }
try { resolve(JSON.parse(stdout)); }
catch { resolve(stdout.trim()); }
}).stdin?.end(input);
});
} 실전 Python 스킬 예시 — KIS 주식 시세 조회
#!/usr/bin/env python3
"""KIS Developers API를 통한 주식 시세 조회 스킬"""
import sys, json, os, requests
def get_stock_price(ticker: str) -> dict:
"""한국투자증권 API로 실시간 시세 조회"""
app_key = os.environ.get('KIS_APP_KEY', '')
app_secret = os.environ.get('KIS_APP_SECRET', '')
# 실제 구현: 토큰 발급 → 시세 API 호출
return {
"ticker": ticker,
"price": "실시간 조회 결과",
"change": "+1.23%",
"volume": "1,234,567주",
}
if __name__ == '__main__':
payload = json.loads(sys.stdin.read() or '{}')
ticker = payload.get('ticker', '005930') # 삼성전자 기본값
result = get_stock_price(ticker)
print(json.dumps(result, ensure_ascii=False))스킬 등록 & CLAUDE.md에 선언
## 사용 가능한 Custom Skills
### stock-price
- 용도: 한국 주식 실시간 시세 조회
- 호출: execute_python_skill("stock-price", {"ticker": "005930"})
- 반환: {ticker, price, change, volume}
### youtube-summary
- 용도: YouTube 영상 자막 추출 및 요약
- 호출: execute_python_skill("youtube-summary", {"url": "https://..."})
- 반환: {title, summary, key_points}
### translate
- 용도: 다국어 번역 (DeepL API)
- 호출: execute_python_skill("translate", {"text": "...", "target": "ko"})Agent Swarm — 멀티에이전트 오케스트레이션
“하나의 질문을 던지면 서브에이전트들이 병렬로 리서치·요약·초안 작성을 처리합니다. 마치 팀을 가진 것 같습니다” — NanoClaw 공식 사용자 후기. Agent Swarm은 복잡한 태스크를 서브에이전트들에게 위임하고 결과를 통합하는 계층형 에이전트 군집입니다.
import { Anthropic } from '@anthropic-ai/sdk';
const client = new Anthropic();
interface SubAgentTask {
name: string;
prompt: string;
context: string;
}
async function runSwarm(
masterPrompt: string,
subTasks: SubAgentTask[]
): Promise {
// 1단계: 서브에이전트 병렬 실행
const subResults = await Promise.all(
subTasks.map(async (task) => {
const res = await client.messages.create({
model: 'claude-sonnet-4-6', // 서브에이전트 — 속도 최적화 모델
max_tokens: 2048,
messages: [{
role: 'user',
content: `컨텍스트: ${task.context}\n\n태스크: ${task.prompt}`
}]
});
const text = res.content[0].type === 'text' ? res.content[0].text : '';
return { name: task.name, result: text };
})
);
// 2단계: 오케스트레이터가 서브에이전트 결과 통합
const aggregated = subResults
.map(r => `## ${r.name}\n${r.result}`)
.join('\n\n');
const final = await client.messages.create({
model: 'claude-opus-4-6', // 오케스트레이터 — 최고 품질 모델
max_tokens: 4096,
messages: [{
role: 'user',
content: `${masterPrompt}\n\n서브에이전트 결과:\n${aggregated}`
}]
});
return final.content[0].type === 'text' ? final.content[0].text : '';
} 실전 Swarm 활용 예시
async function stockAnalysisSwarm(ticker: string) {
return runSwarm(
`${ticker}에 대한 종합 투자 분석 보고서를 작성해줘.`,
[
{
name: '재무분석 에이전트',
prompt: `${ticker}의 최근 4분기 재무제표를 분석해줘.`,
context: '재무 분석 전문가. PER, PBR, ROE, 영업이익률 중심 분석.'
},
{
name: '뉴스감성 에이전트',
prompt: `${ticker} 관련 최근 뉴스 감성 분석을 해줘.`,
context: '금융 뉴스 분석 전문가. 웹 검색 활용 가능.'
},
{
name: '기술분석 에이전트',
prompt: `${ticker} RSI, MACD 기술적 분석 결과를 알려줘.`,
context: '기술적 분석 전문가. 매수/매도 신호 판별.'
},
{
name: '리스크 에이전트',
prompt: `${ticker} 투자 시 주요 리스크 요인을 정리해줘.`,
context: '리스크 관리 전문가. 하방 시나리오 중심.'
}
]
);
}보안 하드닝 & 입력 가드레일
🔒 컨테이너 격리 검증
# 에이전트 컨테이너 빌드 확인 echo '{}' | docker run -i --entrypoint /bin/echo \ nanoclaw-agent:latest "Container OK" # → "Container OK" 출력되면 격리 정상 # 실행 중인 에이전트 컨테이너 확인 docker ps --filter "name=nanoclaw-agent" --format "table {{.ID}}\t{{.Status}}\t{{.Names}}" # 컨테이너 호스트 접근 제한 확인 docker inspect nanoclaw-agent:latest | grep -E "Privileged|CapAdd|NetworkMode"
🛡️ 입력 가드레일 — 프롬프트 인젝션 차단
const BLACKLIST_PATTERNS = [
/ignore\s+previous\s+instructions/i,
/forget\s+(everything|all)/i,
/you\s+are\s+now\s+(?:a|an)\s+/i,
/act\s+as\s+(?:if\s+)?(?:you\s+(?:are|were)|an?)\s+/i,
/system\s*:\s*/i,
/\[INST\]/i,
/<\|im_start\|>/i,
];
export function sanitizeInput(text: string): {
safe: boolean;
reason?: string;
} {
for (const pattern of BLACKLIST_PATTERNS) {
if (pattern.test(text)) {
return { safe: false, reason: `금지 패턴 탐지: ${pattern}` };
}
}
if (text.length > 4096) {
return { safe: false, reason: '최대 입력 길이 초과 (4096자)' };
}
return { safe: true };
}🔑 API 키 보안 — Agent Vault 패턴
- 에이전트는 원시 API 키를 보유하지 않습니다 — 아웃바운드 요청은 OneCLI Agent Vault를 통해 자격 증명이 주입됩니다.
- 에이전트별 정책 시행 — 각 에이전트 컨테이너에 사용 가능한 API 범위와 레이트 리밋이 설정됩니다.
- Docker Secrets 사용 — 프로덕션에서는 환경변수 직접 사용 대신 Docker Secrets로 API 키를 관리하세요.
- NANOCLAW_SECRET_KEY 정기 교체 — 웹훅 서명키는 90일마다 교체를 권장합니다.
systemd 서비스 등록 (Linux 프로덕션)
[Unit] Description=NanoClaw Personal AI Agent After=network.target docker.service Requires=docker.service [Service] Type=simple User=evan WorkingDirectory=/opt/nanoclaw ExecStart=/usr/bin/npm start Restart=always RestartSec=10 EnvironmentFile=/opt/nanoclaw/.env StandardOutput=journal StandardError=journal SyslogIdentifier=nanoclaw [Install] WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now nanoclaw
sudo systemctl status nanoclaw
journalctl -u nanoclaw -f # 실시간 로그 확인트러블슈팅 & 2026 운영 체크리스트
🔧 자주 발생하는 문제 & 해결책
| 문제 | 원인 | 해결책 |
|---|---|---|
| WhatsApp QR 코드가 터미널에 안 나옴 | 백그라운드 실행, 출력 잘림 | npm run auth를 포그라운드에서 실행. 타임아웃 120초 이상 설정 |
| QR 스캔 후 연결 즉시 끊김 | 동일 번호를 다른 기기에 이미 연결 | WhatsApp 앱 → 연결된 기기 → 기존 연결 모두 해제 후 재시도 |
| Container build failed | Docker 미실행 또는 버전 부족 | docker ps로 확인. Docker Desktop 시작 또는 sudo systemctl start docker |
| 에이전트가 응답 없음 | ANTHROPIC_API_KEY 미설정 또는 잘못됨 | echo $ANTHROPIC_API_KEY 확인. .env 파일 재확인 |
| 포트 충돌 (3000) | 다른 서비스가 3000 포트 사용 중 | .env에서 PORT=3001로 변경 후 재시작 |
| Telegram Webhook 등록 실패 | HTTPS URL 없음 (개발 환경) | ngrok으로 로컬 포트 노출 후 Webhook 재등록 |
| Node.js 버전 오류 | Node 18.x 이하 사용 | nvm으로 Node 20.x 설치: nvm install 20 && nvm use 20 |
✅ 2026년 6월 기준 프로덕션 운영 체크리스트
- ✓Node.js 20.x LTS 이상 사용 중 (18.x 아님)
- ✓Docker 24.x 이상,
docker ps정상 동작 - ✓ANTHROPIC_API_KEY 직접 입력 방식 사용 (OAuth 아님)
- ✓NANOCLAW_SECRET_KEY 환경변수 설정 및 .env git 제외(.gitignore)
- ✓WhatsApp 세션 파일(./data/whatsapp-sessions/) 정기 백업
- ✓컨테이너 격리 확인:
docker run nanoclaw-agent:latest echo OK - ✓HTTPS 웹훅 사용 (Cloudflare Tunnel 또는 Nginx + SSL)
- !Claude Code OAuth 연동 비활성화 (2026-02-19 정책 변경)
- !systemd 서비스 등록으로 재부팅 자동 시작
- !journalctl 또는 Grafana로 에이전트 로그 모니터링
- i스킬 추가 후
git commit으로 코드베이스 추적 - iToken 사용량 최적화: 레이어 템플릿 설정으로 최대 40% 절감 가능
🤖 마지막 한 마디: NanoClaw의 핵심 철학은 “적을수록 좋다(Less is More)”입니다. ~700줄의 투명한 코드, 20분에 전체를 읽을 수 있는 단순함, 각 세션마다 격리된 컨테이너 — 이것이 2026년에도 NanoClaw가 선택받는 이유입니다. bash nanoclaw.sh 한 줄로 지금 바로 시작해보세요.

