
보안에 중점을 둔 AI 개인 비서

Stavrobot은 "AI 어시스턴트에게 필요한 만큼의 접근 권한만, 그 이상은 없다"는 원칙으로 만들어진 개인 AI 어시스턴트입니다.
AI 어시스턴트의 모든 유용한 기능을 갖추고 있으면서도 샌드박싱, 격리, 최소 권한에 중점을 둡니다. 가볍고 docker compose up만으로 배포됩니다.
uv를 통한 pip 의존성과 함께 임의의 Python을 호스트 환경으로부터 격리하여 실행합니다.AI 지원 설치: 코딩 AI(Claude Code, Cursor, Windsurf 등)에게 https://stavrobot.stavros.io/INSTALL.md를 가져와 따르라고 하세요. 전체 설정 과정을 대화형으로 안내해 줍니다.
수동 설치:
Telegram에서 @BotFather에게 메시지를 보내 봇을 만들고 토큰을 복사하세요. @userinfobot에게 메시지를 보내 Telegram 사용자 ID를 받으세요(이것이 채팅 ID로 사용됩니다).
env.example을 .env로 복사하고 **POSTGRES_PASSWORD**를 안전한 값으로, TZ를 여러분의 시간대로 변경하세요.
config.example.toml을 data/main/config.toml로 복사하고 필수 필드를 채우세요: apiKey, password, publicHostname, [owner].name, [owner].telegram(여러분의 채팅 ID), [telegram].botToken. 파일의 나머지 항목은 모두 선택 사항입니다.
docker compose up --build
이게 전부입니다. Telegram에서 봇에게 메시지를 보내면 응답합니다. Signal, WhatsApp, 이메일 및 기타 옵션에 대해서는 아래의 자세한 설정 섹션을 참고하세요.
config.example.toml을 data/main/config.toml로 복사하세요.authFile(또는 apiKey)과 publicHostname을 설정하세요. 나머지는 모두 선택 사항입니다.env.example을 .env로 복사하고 시간대(TZ)를 설정하세요. Postgres 자격 증명 및 기타 환경 설정도 여기에서 재정의할 수 있습니다. 항상 POSTGRES_PASSWORD를 안전한 값으로 설정하세요 — 기본값은 취약한 자리 표시자이며 프로덕션에서 사용해서는 안 됩니다.앱이 시작된 후 /settings/config를 열면 브라우저에서 config.toml을 편집할 수 있습니다. 이
페이지는 HTTP Basic Auth로 보호되며, 포함된 비밀 정보를 포함한 원시 설정을 표시합니다.
유효한 저장은 단일 <CONFIG_PATH>.bak 백업을 생성하고, 새 내용을 저장한 뒤 앱을
재시작합니다. 이 과정에서 진행 중인 에이전트 턴이 중단됩니다.
plugin-runner, coder, signal-bridge, python-runner는 시작할 때만 config.toml을
읽습니다. 비밀번호처럼 이들에 영향을 주는 변경 사항은 해당 컨테이너를 수동으로
재시작해야 합니다.
Stavrobot은 config.toml에서 baseUrl을 설정하여 모든 OpenAI 호환 엔드포인트(Ollama, LiteLLM, vLLM 등)나 사용자 정의 Anthropic 호환 프록시를 가리키도록 할 수 있습니다. 필수 필드와 예제 구성은 config.example.toml을 참고하세요.
앱은 두 가지 인증 모드를 지원합니다: API 키 또는 OAuth.
config.toml에서 apiKey를 설정하세요. 로그인이나 로그아웃이 필요 없습니다.config.toml에서 authFile을 설정하세요(자격 증명이 저장될 경로). 로그인 페이지는 Pi가 지원하는 모든 OAuth 제공자와 작동합니다.
<your-hostname>/login을 방문하세요. 페이지의 안내를 따르면 자격 증명이 인증 파일에 저장됩니다. 봇이 실행 중일 때 인증이 만료되면, 메시징 플랫폼을 통해 로그인 URL이 담긴 메시지를 보냅니다.authFile 경로의 파일을 삭제하세요. 봇은 다음 메시지에서 자격 증명 누락을 감지하고 다시 로그인하라는 메시지를 표시합니다.coder 컨테이너는 선택 사항입니다(자기 프로그래밍 기능에만 필요). 이는 메인 앱의 API 키와 별개로, 구독 인증(OAuth)을 사용하는 Claude Code를 사용합니다.
Docker Compose 프로필은 쉼표로 구분되므로 조합할 수 있습니다(예: COMPOSE_PROFILES=signal,coder).
.env 파일에서 COMPOSE_PROFILES에 coder를 포함하도록 설정하세요(예: COMPOSE_PROFILES=coder, 또는 Signal도 사용하는 경우 COMPOSE_PROFILES=signal,coder).docker compose --profile coder up --builddocker compose exec -u coder coder claude (로그인하지 않았다면 로그인하라는 메시지가 표시됩니다).[coder].model을 Claude Code 모델 별칭(sonnet, opus, haiku)으로 설정하세요.Signal은 별도의 전화번호가 필요합니다 — 개인 번호가 아닙니다. 선불 SIM이나 VoIP 번호도 작동합니다.
.env 파일에서 COMPOSE_PROFILES=signal의 주석을 해제하여 signal-bridge 컨테이너를 활성화하세요.docker compose --profile signal builddocker compose --profile signal run --rm --entrypoint bash signal-bridge -c 'signal-cli link -n "Stavrobot" | tee >(xargs -L 1 qrencode -t utf8)' — 휴대폰으로 QR 코드를 스캔하세요(Signal > 설정 > 연결된 기기).docker compose --profile signal run --rm --entrypoint bash signal-bridge -c 'signal-cli -u +YOUR_NUMBER register', 그런 다음 docker compose --profile signal run --rm --entrypoint bash signal-bridge -c 'signal-cli -u +YOUR_NUMBER verify CODE'로 인증하세요.[signal].account를 설정하세요.docker compose up --build/settings 웹 UI를 통해 허용할 번호를 추가하세요.
[telegram].botToken을 설정합니다.[owner].telegram에 채팅 ID(휴대폰 번호가 아님)를 설정합니다./settings 웹 UI를 통해 허용할 채팅 ID를 추가합니다.WhatsApp은 별도의 전화번호가 필요합니다. 그렇지 않으면 자기 자신에게 메시지를 보내게 되어 제대로 작동하지 않습니다.
WhatsApp은 Baileys를 사용합니다. 이는 WhatsApp Web처럼 companion device로 연결되는 비공식 WhatsApp Web 라이브러리입니다. 별도의 전화번호는 필요하지 않으며 기존 WhatsApp 계정에 연결됩니다.
위험: Baileys는 비공식 API를 사용합니다. WhatsApp은 이를 사용하는 계정을 차단할 수 있습니다. 사용에 따른 책임은 본인에게 있습니다.
config.toml에 [whatsapp] 섹션을 추가합니다(형식은 config.example.toml 참조).docker compose up --builddocker compose logs -f app)../data/whatsapp에 저장되어 재시작 후에도 유지됩니다./settings 웹 UI를 통해 허용할 전화번호를 추가합니다.Email은 수신 전달에 Cloudflare Email Worker를, 발신에 SMTP를 사용합니다. 전체 worker 코드와 자세한 설정 방법은 config.example.toml을 참조하세요.
config.toml에 SMTP 자격 증명과 임의의 webhookSecret을 포함한 [email] 섹션을 추가합니다.config.example.toml의 코드)를 배포하고 worker에 WEBHOOK_URL 및 WEBHOOK_SECRET 환경 변수를 설정합니다./settings 웹 UI를 통해 허용할 발신자 주소를 추가합니다.Stavrobot에 설정된 비밀번호를 사용한 HTTP Basic 인증으로 POST /pebble-index/webhook에 ring webhook을 보내도록 Pebble Index를 구성합니다. multipart 요청에는 recordedAt(epoch 밀리초)과 client가 포함되어야 하며, transcription과 audio/mp4 audio 파일을 포함할 수 있습니다. 오디오 녹음은 .m4a 첨부 파일로 에이전트의 대기열에 추가됩니다.
docker compose up --build
API는 `http://localhost:10567/chat`에서 사용할 수 있습니다. 전체 엔드포인트 목록은 [HTTP API](#http-api)를 참조하세요.
**참고:** Docker Compose는 앱을 `localhost:10567`에만 노출합니다. 외부에서 접근 가능하게 하려면(Telegram/Signal 웹훅 및 `publicHostname` 설정에 필요) `localhost:10567`을 가리키는 리버스 프록시(예: Nginx, Caddy)를 설정하세요. 포트를 직접 노출할 수도 있지만 트래픽이 암호화되지 않으므로 권장하지 않습니다.
### Docker 없이
Node.js >= 20과 실행 중인 PostgreSQL 인스턴스가 필요합니다.```bash
npm install && npm run build && npm start
참고: Python 실행과 Signal 통합은 Docker 컨테이너 내부에서만 작동합니다.
모든 엔드포인트는 아래에 public으로 표시된 것을 제외하고 config.toml의 password를 사용한 HTTP Basic 인증을 요구합니다
(사용자 이름은 무시됩니다). 오류 응답은
{"error": "..."} 형식의 JSON 객체입니다.
POST /chat