셀프 호스팅 미러
내가 가진 하드웨어에서 돌아가는 작은 서버예요. Marrow 데이터의 완전한 최신 사본을 보관하고, 휴대폰이 잠들어 있거나 주머니에 있거나 지구 반대편에 있어도 에이전트에 답해요.
앱별 설정은 연결 아래 각자의 페이지에 있어요.
Marrow 가이드 전체: MCP · 셀프 호스팅 미러 · 자동화 · 파일 · 지원
설명
내가 가진 하드웨어(Raspberry Pi, NAS, 오래된 노트북, $5짜리 VPS)에서 돌리는 작은 오픈 소스 서버예요. 휴대폰은 QR 코드를 스캔해 한 번만 페어링하면, 앱이 닫혀 있어도 백그라운드에서 모든 변경 사항을 푸시해요. 서버는 Marrow 데이터의 완전한 SQLite 사본을 보관하고 읽기용 MCP 도구 13개를 제공해요. 휴대폰의 도구 7개, sleep_log와 symptoms_and_mood, 그리고 앱 고유의 표현으로 답하는 4개(daily_brief, baselines, what_changed, data_quality)예요. 그래서 휴대폰이 서랍 속에 있는 새벽 3시에도 에이전트가 "이번 주에 잠을 어떻게 잤지?"라고 물을 수 있어요. MIT 라이선스: github.com/MarrowHealth/marrow-mcp.
설치
Python 파일 하나, 표준 라이브러리만 사용하며 Python 3.10 이상이 필요해요:
pip install marrow-mcp marrow-server # or: python3 marrow_server.py
또는 Docker로:
git clone https://github.com/MarrowHealth/marrow-mcp cd marrow-mcp docker compose up -d
처음 시작하면 페어링 URL을 출력하고, 네트워크의 아무 브라우저에서나 QR 코드를 볼 수 있어요.
휴대폰 페어링하기
- 가까이에 있는 아무 화면에서나 페어링 URL을 여세요.
- Marrow에서 내보내기, 서버 MCP, 서버와 페어링을 열고 코드를 스캔하세요.
- 끝났어요. 휴대폰이 푸시를 시작하고, 서버 페이지에 마지막 푸시 시간과 대기 중인 기록 수가 표시돼요.
페어링하면 서버의 데이터 디렉터리에 토큰 두 개가 만들어져요. 하나는 휴대폰이 푸시할 때, 하나는 에이전트가 읽을 때 써요. 토큰을 바꾸려면 토큰 파일을 삭제하세요.
에이전트를 서버에 연결하기
claude mcp add --transport http marrow http://<server-ip>:8800/mcp \ --header "Authorization: Bearer <mcp token>"
도구 13개이고 모두 읽기용이에요. 원본 도구 9개는 health_summary, list_metrics, metric_daily, metric_samples, workouts, nutrition_log, strength_log, sleep_log, symptoms_and_mood예요. 그리고 원본 도구가 끝나는 지점에서 시작하는 도구 4개는 앱 홈 페이지와 같은 계산법으로 내 최근 평소 기준과 비교해 점수를 매겨요. daily_brief(하루 단위: 주요 지표별 값과 앱 고유의 표현, 목표 대비 음식과 수분, 어젯밤 수면, 한 운동, 눈여겨볼 플래그), baselines(지표별 내 평소 기준, 최신 값의 z 점수, 90일 추세), what_changed(지난주와 그 전 4주 비교: 무엇이 달라졌고 나에게 얼마나 눈에 띄는지, 수면과 취침 시간의 변화, 시작되거나 끊긴 데이터 스트림), data_quality(최신인지, 오래됐는지, 빠졌는지를 알려 줘서 에이전트가 공백을 사실로 착각하지 않게 해요)예요. 모든 읽기 도구는 며칠 전까지, 또는 휴대폰 달력 기준의 from과 to로 기간을 지정할 수 있어요. 서버는 프롬프트 4개(how_am_i_doing, weekly_review, doctor_prep, log_from_text)와 리소스 4개도 이를 표시하는 클라이언트에 제공해요. 쓰기 도구 12개도 있고, 휴대폰이 허용하면 목록에 나타나요. Marrow 1.5부터는 내보내기, 내 연결에서 내 서버의 AI 쓰기 허용을 켜면 AI가 이 서버를 통해 식사, 수분, 체중, 운동, 수면, 증상, 기분, 목표를 무료로 기록할 수 있어요. 서버가 항목을 대기열에 쌓아 두고 Marrow가 열리거나 깨어날 때 휴대폰이 반영하며, 모두 되돌릴 수 있어요. Claude Desktop, Cursor 등의 설정은 MCP 페이지에 있어요. URL만 달라져요.
LAN 밖에서 접속하기
서버는 일반 HTTP만 쓰고 자체 TLS가 없어요. 그대로 포트 포워딩하지 마세요. 서버가 있는 기기와 휴대폰에 Tailscale을 설치하고 tailscale serve를 쓰거나, Cloudflare Tunnel이나 HTTPS를 종료하는 리버스 프록시를 앞에 두세요. 페어링 QR에는 서버가 알리는 주소가 담겨 있어요. 서버 자체의 LAN 주소이거나 --url로 지정한 주소예요. 실제로 쓸 주소를 지정해 서버를 시작하고(예: marrow-server --url https://pi.your-tailnet.ts.net) 그다음 페어링하세요.
디스크에 저장되는 것
- 모든 일일 시리즈, 샘플, 일기 항목, 근력 세트가 담긴 SQLite 데이터베이스로, 휴대폰의 푸시로 최신 상태가 유지돼요.
- 받은 푸시 원본은 모두 데이터베이스 옆에 JSONL로 쌓아 두므로, 데이터베이스가 망가져도 다시 만들 수 있어요.
- 전체 정밀도 기록은 1년에 50~150 MB 정도로 잡으세요.
단위: 건강 지표는 저장된 SI 단위와 라벨이 붙어서 도착해요. 근력 세트는 휴대폰의 표시 설정과 관계없이 "unit": "lb"와 함께 파운드로 도착하므로, 미러에서 단위가 섞이는 일은 없어요. Grafana, DuckDB, cron 작업을 데이터베이스 파일에 바로 연결하세요.
문제 해결
AI가 실행되는 컴퓨터에서 테스트 두 가지를 해 보면 문제가 어디에 있는지 알 수 있어요. 먼저 서버가 켜져 있나요? 이 테스트에는 토큰이 필요 없어요:
curl http://<server-ip>:8800/health
서버는 {"server": "marrow", "ok": true}라고 답해요. 그다음으로, 에이전트의 토큰이 작동하나요?
curl -i http://<server-ip>:8800/mcp \ -H "Authorization: Bearer <mcp token>" \ -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
| 결과 | 의미 |
|---|---|
200 OK와 도구 목록 | 서버는 정상이에요. 에이전트 설정에서 주소, 토큰, 서버 유형(HTTP)을 확인한 다음 에이전트를 다시 시작하세요. |
401과 bad bearer token | 토큰이 틀렸어요. 에이전트는 휴대폰을 페어링할 때 쓴 토큰이 아니라 mcp 토큰을 써요. 아래를 참고하세요. |
| 연결 거부 또는 시간 초과 | 서버가 실행 중이 아니거나, 포트가 틀렸거나, 서버 기기의 방화벽이 8800 포트를 막고 있어요. Docker를 쓴다면 8800:8800 포트 매핑을 확인하세요. |
- 어떤 토큰인가요? 서버는 시작할 때
agents:로 시작하는 줄에 에이전트용 토큰을 출력해요. 데이터 폴더의.mcp-token파일에도 있어요(--data를 지정하지 않으면./data, Docker에서는/data). 휴대폰은.app-token에 있는 다른 토큰을 써요. 에이전트용 토큰을 바꾸려면.mcp-token을 삭제하고 서버를 다시 시작한 다음, 모든 에이전트를 업데이트하세요. - 페어링 페이지에 토큰이 잘못됐거나 없다고 나와요. 서버가 출력한 페어링 링크를
?token=부분까지 그대로 여세요. - 페어링 페이지에 QR 코드가 아니라 텍스트가 나와요. QR에는 선택 사항인
segno패키지가 필요해요:pip install "marrow-mcp[qr]". 아니면 Marrow에서 직접 입력하기를 고르고 그 텍스트의url과token을 입력하세요. - 휴대폰에 페어링 실패라고 나와요. 휴대폰이 QR에 담긴 주소에 닿지 못했어요. Docker에서는 서버가 컨테이너 자체의 주소만 볼 수 있으니, 내 컴퓨터의 주소를 알려 주세요. 명령어에
--url http://<your-computer-ip>:8800을 추가하세요. 집 Wi-Fi 밖에서는tailscale serve나 터널에서 받은 HTTPS 주소를 쓰세요. - 로컬 네트워크 접근. 집 네트워크의 서버에 닿으려면 Marrow에 로컬 네트워크 접근이 필요해요. iOS는 처음 페어링할 때 물어봐요. 거부했다면 설정, 개인정보 보호 및 보안, 로컬 네트워크에서 Marrow를 켠 다음, Marrow를 연 채로 다시 페어링하세요.
- 그 QR 코드는 Marrow 페어링 코드가 아니에요. 카메라가 다른 코드를 읽었어요. 서버의 페어링 페이지에 있는 코드를 스캔하세요.
- 오래된 데이터이거나 Marrow에 전송 안 됨이라고 나와요. 휴대폰이 서버로 푸시하지 못하고 있어요. Marrow의 서버 MCP 페이지에 마지막 푸시와 대기 중인 기록 수가 표시돼요. 서버가 실행 중인지 확인한 다음, Marrow를 열어 대기 중인 데이터를 보내세요. 백그라운드 푸시는 iOS가 허용할 때 실행돼요.
- 기록하려면 서버를 업데이트해야 해요.
pip install -U marrow-mcp로 업데이트하고 다시 시작하세요. Docker를 쓴다면 클론한 폴더에서git pull과docker compose up -d --build를 실행하세요. - AI가 기록한 항목이 보이지 않아요. 내보내기, 내 연결에서 해당 서버의 AI 쓰기 허용을 켜세요. 쓰기 도구는 그 후에야 서버에 나타나요. 각 항목은 서버에서 대기하다가 Marrow가 다음에 열리거나 깨어날 때 반영돼요.
- 연결이 켜지지 않아요. 무료는 한 번에 연결 1개, Marrow Pro는 최대 10개까지 켤 수 있고, AI, 서버, 자동화를 모두 합친 수예요.
다른 방법 대신 이 방법을 고르면 좋은 때
에이전트가 휴대폰이 잠들어 있거나 멀리 있을 때도 데이터가 필요하거나, 파일보다 질의할 수 있는 데이터베이스를 원한다면 미러를 고르세요. 에이전트가 휴대폰 가까이에서 실행되고 따로 관리할 것을 늘리고 싶지 않다면 휴대폰 내 MCP 서버를 고르세요. 데이터가 도착할 곳이 이미 있다면 자동화를 고르세요.