AI앱 노트/대화의 내 MCP 서버 저장

MCP 서버로 개인 노트/대화 저장하기


한눈에 보는 전체 데이터 흐름

한국어의 구조를 보여주는 다이어그램

기본 구성 요소: Bun, Hono, SQLite

만들려는 건 데이터를 저장하고(CRUD) 꺼내보는 작은 서버다. 세 가지 재료의 역할:

  • Bun — 자바스크립트/타입스크립트 실행 런타임. 이 모든 걸 돌리는 기반. bun:sqlite라는 SQLite 드라이버가 내장돼 있어 별도 설치 없이 DB를 바로 쓸 수 있다.

  • Hono — 라우터 + 웹 프레임워크. "어떤 URL + HTTP 메서드가 들어오면 어떤 함수를 실행할지"를 정해준다.

  • SQLite — 실제 데이터(노트/일정)가 저장되는 파일 기반 데이터베이스.

API 엔드포인트의 역할

엔드포인트는 클라이언트가 요청을 보내고 응답을 받는 "창구"다. 캘린더라면 보통:

메서드 + 경로

동작

GET /events

일정 목록 조회 (날짜 범위 등으로 필터)

GET /events/:id

특정 일정 상세 조회

POST /events

새 일정 생성

PUT /events/:id

일정 수정

DELETE /events/:id

일정 삭제

노트 앱이면 eventsnotes로 바뀔 뿐 구조는 같다.

Open optionsauto

클라이언트 → [HTTP 요청] → Hono 라우터 → 핸들러 함수 → SQLite
클라이언트 ← [JSON 응답] ← Hono ← 핸들러 함수 ← 조회/저장 결과

MCP 서버로 AI 활용하기

API 위에 MCP 서버를 얹으면, Claude 같은 AI가 자연어로 그 서버를 조작할 수 있게 된다.

MCP 서버는 데이터를 직접 저장하지 않는다. AI가 쓸 수 있는 도구(tool) 를 정의해 노출하고, AI가 그 도구를 부르면 내부적으로 API를 호출하는 중계자다.

Open optionsauto

Claude  ──(MCP 프로토콜)──→  MCP 서버  ──(HTTP)──→  노트 API  ──→  SQLite

노트 앱이라면 도구 두 개로 시작:

  • save_note — 내용을 받아 저장 (POST /notes로 변환)

  • search_notes — 검색해서 꺼내옴 (GET /notes로 변환)

핵심 구분:

  • API 엔드포인트 = 기계(프로그램)가 호출하는 정형화된 창구

  • MCP 서버 = AI가 자연어 맥락에서 그 창구를 알아서 골라 쓰도록 놓는 다리


Anthropic 서버와의 연결 이해하기

오해

"Anthropic 서버에 내 대화가 저장돼 있고, MCP가 그걸 내 서버로 옮겨준다" → 틀림

실제

  • 저장은 자동이 아니라 매번 일어나는 행위다. 내가 "저장해줘" 하면, Claude가 그 순간 대화 내용을 정리해 save_note 도구 인자로 만들어 내 서버에 보낸다. 어딘가 보관돼 있던 걸 꺼내오는 게 아니다.

  • 내용도 판단(어떤 도구를 부를지)도 내 폰이 아니라 Anthropic 클라우드에 있다. Claude 모델은 폰 안이 아니라 Anthropic 서버에서 돈다. 폰/웹 창은 입출력 창일 뿐.

Open optionsauto

1. 폰/웹: "방금 대화 저장해줘"        (입력창)
        ↓ 메시지 전송
2. Anthropic 클라우드: Claude가 여기서 돎
   → "save_note를 부르자" 판단 + 도구 호출이 여기서 발생
        ↓
3. Anthropic 클라우드 → 내 서버 (커넥터 URL로 접속)
        ↓
4. 내 서버 → SQLite 저장

2번과 3번이 전부 Anthropic 클라우드에서 일어난다. 그래서 내 서버를 부르는 쪽은 내 폰이 아니라 Anthropic 클라우드다. 이 사실이 아래 Tailscale 문제로 이어진다.

클라이언트 쪽엔 "설치할 MCP"가 없다

MCP는 양 끝이 있다:

  • MCP 클라이언트 (도구 목록 읽고, 어떤 도구 부를지 정하고, 결과 받기) → 이미 claude.ai·폰 앱에 Anthropic이 내장. 내가 건드릴 것 없음.

  • MCP 서버 (도구의 실체) → 내가 만들어야 함.

내가 하는 일은 claude.ai 커넥터 설정에 내 서버 URL 한 줄을 등록하는 것뿐. 같은 계정이면 폰에서도 그대로 쓰인다(폰에서 새 커넥터 추가는 불가, 사용은 가능).


서버 연결 옵션과 Tailscale 활용

내 서버를 "누가 부르냐"에 따라 필요한 게 갈린다.

기기에서 직접 연결하는 경우

폰/랩탑의 앱, Claude Desktop 로컬 MCP 등이 내 기기 → 내 서버로 직접 붙는다.

  • 폰·랩탑·집 PC를 같은 Tailscale 테일넷에 넣으면, 공인 IP·포트 개방 없이 사설 주소로 안전하게 통신.

  • 컴퓨터만 켜두면 됨. 공개 노출 불필요.

claude.ai 커넥터를 통한 연결

claude.ai 커넥터는 내 기기가 아니라 Anthropic 클라우드에서 내 서버로 접속한다.

  • Tailscale 사설 주소는 테일넷 안에서만 보임 → Anthropic 클라우드는 도달 불가.

Open optionsauto

Anthropic 클라우드 ──→ 공개 인터넷 주소       ✅
Anthropic 클라우드 ──X→ Tailscale 사설 주소   ❌ (밖에서 안 보임)

→ 그래서 claude.ai 커넥터로 쓰려면 둘 중 하나:

  1. Tailscale Funnel — 특정 서비스를 공개 HTTPS 주소로 노출. 집 PC를 켜둬야 함.

  2. 클라우드 배포 — PC 안 켜둬도 항상 떠 있음. 개인 노트 규모면 무료 한도에 드는 경우 많음.

어느 쪽이든 공개로 여는 거라 인증(보호 토큰/OAuth) 필수.

연결 방식 정리

Open optionsauto

컴퓨터 켜두기 + Tailscale 사설        → 폰·랩탑 직접 연결 OK (커넥터는 X)
컴퓨터 켜두기 + Funnel(공개) + 토큰    → claude.ai 커넥터 OK
클라우드 배포 + 토큰                  → PC 안 켜둬도 + 커넥터 OK

MCP 서버 보안 설정

공개 HTTPS 주소를 내면 URL 아는 사람·봇 누구나 문 앞까지 온다.

  • 인증 없으면 = 문 활짝 열림 → 아무나 내 노트 읽고 씀 ❌

  • 인증 있으면 = 문은 보이지만 열쇠 필요 → 나만 들어감 ✅

인증 방식:

  • 토큰 방식 (간단) — 길고 추측 불가능한 비밀 문자열을 헤더로 검사. 개인용은 이걸로 충분.

  • OAuth 방식 (표준) — claude.ai 커넥터가 정식 지원. 손이 더 가지만 안전.

추가 빗장: 요청 횟수 제한(rate limit)을 같이 두면 무차별 시도 방어.


파일 전송의 제약과 해결책

두 종류의 "파일"을 구분해야 한다.

  • 이 창에서 Claude가 만들어주는 다운로드 파일 (docx, 다이어그램 등) — Anthropic 환경에서 생성해 다운로드 링크로 줌. 내 MCP 서버로 자동으로 가는 통로는 없다.

  • MCP 도구로 오가는 것 — 가능. save_file 같은 도구를 정의하면 Claude가 내용을 인자로 실어 보냄.

Open optionsauto

[이 창의 다운로드 파일]   나 → 링크 → 내가 받음        (서버로 자동연결 X)
[MCP 도구]               나 → save_file(내용) → 내 서버  ✅

제약:

  • MCP로 오가는 건 본질적으로 텍스트/구조화 데이터. 텍스트·md·json·코드는 자연스럽다.

  • 이미지·PDF 같은 바이너리는 base64로 변환하면 되지만 용량 커지면 비효율.

  • → "대화 텍스트 저장"엔 딱 맞고, "큰 파일 동기화"엔 부적합.

결론: 대화를 저장하려고 굳이 "파일"로 주고받을 필요 없다. save_note로 텍스트를 넘기면 서버가 알아서 DB든 .md 파일이든 저장하면 된다.

실행 가이드 — 결정 과정과 따라 하는 방법

01_개념정리.md에서 이해한 내용을 바탕으로, 실제로 무엇을 결정했고
어떤 순서로 만들면 되는지 정리한 문서.


개인 노트 서버 구축 결정 과정

대화하며 좁혀온 선택들:

  1. 무엇을 만드나 → 캘린더가 아니라 개인 노트/대화 저장 서버.
    같은 bun+hono+sqlite 패턴, 데이터만 notes로.

  2. 도구는save_note(저장), search_notes(검색) 두 개로 시작.

  3. 검색 방식 → 우선 SQL 키워드 검색으로 무료 시작.
    부족하면 나중에 로컬 임베딩 의미 검색을 얹는다. (둘 다 비용 0)

  4. 어디서 돌리나(미정 — 아래 분기에서 택1)

    • 집 PC(WSL) + Tailscale 사설 → 폰·랩탑 직접 연결용

    • 집 PC(WSL) + Tailscale Funnel + 보호 토큰 → claude.ai 커넥터용

    • 클라우드 배포 + 보호 토큰 → PC 안 켜둬도 + 커넥터용

  5. 인증 → 공개로 열면 보호 토큰(헤더 검사) 필수. 개인용은 토큰 방식으로 충분.

  6. 비용 → 위 구성만이면 0원.
    (Console API 키/외부 임베딩 API를 안 넣는 한)

  7. 파일 → 대화는 "파일"이 아니라 텍스트로 save_note 하면 됨.
    서버가 원하면 .md로 떨어뜨리게 만들 수 있음.

추가 결정 사항

  • Telegram을 붙인다면: "노트 저장/검색만"(무료) vs "AI가 답하는 챗봇"(Console API 키 필요, 과금).

  • claude.ai 커넥터만 쓸 거면 Telegram은 나중 문제.


MCP 서버 구축 작업 과정

아래는 "집 PC + Funnel + 보호 토큰 → claude.ai 커넥터" 기준의 큰 흐름.
클라우드 배포를 택했다면 5단계만 배포로 바뀐다.

준비물 확인

  • Bun 설치 (WSL 안에)

  • Tailscale 계정 (Funnel 쓸 경우)

  • claude.ai 계정 (커넥터 등록용)

프로젝트 뼈대 구성

Open optionsauto

notes-mcp/
  ├─ db.ts          # SQLite 연결 + 테이블 생성
  ├─ api.ts         # hono로 /notes CRUD 엔드포인트
  ├─ mcp.ts         # MCP 서버: save_note / search_notes 도구 정의
  ├─ auth.ts        # 보호 토큰 검사 미들웨어
  └─ index.ts       # 전부 묶어서 서버 실행

DB와 테이블 설정

노트 한 건 = id, body(본문), created_at(저장 시각), tags(키워드).
bun:sqlite로 파일 하나(notes.db) 만들고 테이블 생성.

API 엔드포인트 설정

  • POST /notes → 본문 받아 INSERT

  • GET /notes?q=키워드WHERE body LIKE '%키워드%'로 검색

  • (나중에) GET /notes/:id, DELETE /notes/:id 등 추가

보호 토큰 인증 설정

  • 길고 추측 불가능한 문자열 하나 생성 (예: openssl rand -hex 32)

  • 모든 요청에서 Authorization 헤더의 토큰이 일치할 때만 통과, 아니면 401

  • 이 토큰은 내가 만든 비밀 — 어디 등록·결제 대상 아님

공개 주소로 노출하기

  • 서버를 로컬 포트(예: 3000)에서 실행

  • Tailscale Funnel로 그 포트를 공개 HTTPS 주소로 노출
    https://내기기.테일넷.ts.net 형태 주소가 생김

  • (클라우드 배포 택했으면: 이 단계 대신 클라우드에 올림 → 자동으로 공개 HTTPS)

MCP 도구 정의

  • save_note(body, tags?) → 내부에서 POST /notes 호출

  • search_notes(query) → 내부에서 GET /notes?q=... 호출

  • MCP 서버 엔드포인트를 위 공개 주소 아래 경로로 노출 (예: /mcp)

claude.ai 커넥터 등록

  • claude.ai → 설정 → 커넥터 → 커스텀 커넥터 추가

  • 공개 MCP 주소 입력 (예: https://내기기.테일넷.ts.net/mcp)

  • 보호 토큰은 커넥터 인증 설정에 넣음

  • 연결되면 폰 앱에서도 같은 계정으로 사용 가능

테스트

  • 이 창에서 "방금 대화 요약해서 내 노트에 저장해줘" → save_note 호출 확인

  • 새 대화에서 "지난번 MCP 얘기 찾아줘" → search_notes 호출 확인

밀어주고 끌어주는

온·오프라인 AI 스터디

AI로 어디까지 할 수 있는지
직접 확인하실 분만 신청하세요.