블로그에 자동으로 공부한 내용을 기록하는 자바 프로젝트
MCP Blog Assistant
노션에 정리한 글을 1차 정리(AI/룰) 후 타입별 템플릿을 적용해 **GitHub Pages(github.io)**에 자동 발행하는 MCP 서버입니다.
포스트 타입
- 토이프로젝트 (toy)
- 알고리즘 (algo)
- CS공부 (cs)
- 일상 (daily)
노션 데이터베이스의 Type Select 속성에 toy, algo, cs, daily 중 하나를 지정하면 해당 템플릿이 적용됩니다.
YAML / 환경변수 설정
application.yaml에 아래 항목이 정의되어 있습니다. 민감한 값은 환경변수로 넣는 것을 권장합니다.
Notion
| 키 | 환경변수 | 설명 |
|----|----------|------|
| notion.secret | NOTION_SECRET | 노션 연동 시크릿 (필수) |
| notion.database-id.blog | NOTION_DATABASE_ID_BLOG | 블로그용 노션 DB ID (선택) |
노션 연동 토큰: Notion Developers에서 Integration 생성 후 시크릿 복사. 페이지/DB에 해당 Integration을 연결해야 합니다.
GitHub Pages (github.io)
| 키 | 환경변수 | 설명 |
|----|----------|------|
| github-pages.repo | GITHUB_PAGES_REPO | 저장소 owner/repo (예: myname/myname.github.io) |
| github-pages.branch | GITHUB_PAGES_BRANCH | 푸시할 브랜치 (기본 main) |
| github-pages.token | GITHUB_PAGES_TOKEN | GitHub Personal Access Token (repo 권한) |
| github-pages.posts-path | GITHUB_PAGES_POSTS_PATH | Jekyll 포스트 경로 (기본 _posts) |
저장소는 Jekyll 기준입니다. 타입별 하위 폴더에 마크다운이 커밋됩니다: _posts/Daily/, _posts/CS/, _posts/Algorithm/, _posts/Project/ (각각 YYYY-MM-DD-슬러그.md). GitHub 저장소에 해당 폴더 구조가 있어야 합니다.
Blog 공통
| 키 | 환경변수 | 설명 |
|----|----------|------|
| blog.dry-run | BLOG_DRY_RUN | true면 실제 발행 없이 내용만 생성 |
로컬에서 서버 켜고 테스트하기
1. 필요한 것
- 노션: Integration 시크릿 + 블로그용 페이지 하나 (페이지 ID 필요)
- Preview만 볼 때: 위만 있으면 됨 (발행 안 함)
- 실제 GitHub 발행:
GITHUB_PAGES_REPO,GITHUB_PAGES_TOKEN추가
2. 설정
application.yaml에 노션 시크릿이 이미 있으면 그대로 둬도 됨. 환경변수로 덮어쓰려면:
export NOTION_SECRET=ntn_xxxx # 노션 Integration 시크릿
# GitHub 실제 발행할 때만
export GITHUB_PAGES_REPO=your-username/your-username.github.io
export GITHUB_PAGES_TOKEN=ghp_xxxx
3. 서버 실행
./gradlew bootRun
기본 포트 8080. 콘솔에 Started McpBlogAssistantApplication 나오면 준비된 것.
4. 편하게 쓰는 방법
- 웹 폼: 서버 띄운 뒤 브라우저에서 http://localhost:8080/publish.html 접속. 페이지 ID 입력 후 "미리보기" / "GitHub 발행" 버튼만 누르면 됨. (별도 프론트 개발 없이 사용 가능)
- 노션에서: 발행할 페이지 URL을 복사해 두고, 주소창에서 페이지 ID 부분만 복사해 위 폼에 붙여넣기. 노션 자체에는 "버튼으로 API 호출" 기능이 없어서, 링크로
http://localhost:8080/publish.html?pageId=복사한ID처럼 걸어 두고 클릭해서 열어 쓰는 식으로 쓰면 편함. - Cursor에서: 서버가 떠 있는 상태에서 채팅으로 "페이지 ID 30a5977fe8e480259b8bc9475aceccca 로 GitHub 발행해줘"라고 하면, AI가
curl로 publish API를 호출해 줄 수 있음.
5. Cursor MCP로 사용하기 (도구로 연결)
채팅에서 "페이지 ID xxx 발행해줘"라고만 하면 AI가 MCP 도구를 호출해 발행하도록 하려면, 이 저장소에 포함된 MCP 어댑터를 Cursor에 등록하면 됩니다.
조건
- Spring Boot API 서버가 먼저 실행 중이어야 합니다 (
./gradlew bootRun). MCP 어댑터는 이 API를 HTTP로 호출할 뿐, 서버를 대신 띄우지 않습니다.
설정 절차
- MCP 어댑터 빌드 (최초 1회):
cd mcp-server && npm install && npm run build && cd .. - 프로젝트에
.cursor/mcp.json이 이미 있습니다. Cursor를 이 프로젝트로 연 상태에서 Cursor 설정 > Features > MCP에서blog-assistant서버가 켜져 있는지 확인합니다. (프로젝트 MCP 설정을 쓰면 자동으로 로드될 수 있음.) - API base URL을 바꾸려면
.cursor/mcp.json의env.BLOG_API_URL을 수정합니다. 기본값은http://localhost:8080입니다.
사용 예
- "노션 페이지 ID 30a5977fe8e480259b8bc9475aceccca 미리보기 해줘" → AI가
notion_blog_preview도구 호출. - "페이지 ID 30a5977fe8e480259b8bc9475aceccca 로 GitHub 발행해줘" → AI가
notion_blog_publish도구 호출.
MCP 어댑터는 mcp-server/ 디렉터리의 Node.js 프로젝트이며, Cursor가 stdio로 기동한 뒤 도구 호출 시에만 http://localhost:8080/mcp/notion-to-blog/... 를 호출합니다.
6. API로 테스트 (curl)
노션 페이지 ID는 노션 URL에서 복사:
- 예:
https://www.notion.so/My-Page-abc123def456...→abc123def456...(하이픈 있든 없든 됨)
Preview (발행 없이 결과만 확인)
curl -s -X POST http://localhost:8080/mcp/notion-to-blog/preview \
-H "Content-Type: application/json" \
-d '{"pageId": "여기에_노션_페이지_ID"}' | jq .
title, content(HTML), postType 이 나오면 정상.
Publish - dry run (실제 푸시 없이 내용만 확인)
curl -s -X POST http://localhost:8080/mcp/notion-to-blog/publish \
-H "Content-Type: application/json" \
-d '{"pageId": "여기에_노션_페이지_ID", "dryRun": true, "publishTarget": "github"}' | jq .
Publish - 실제 GitHub Pages 발행
GITHUB_PAGES_REPO, GITHUB_PAGES_TOKEN 설정한 뒤:
curl -s -X POST http://localhost:8080/mcp/notion-to-blog/publish \
-H "Content-Type: application/json" \
-d '{"pageId": "여기에_노션_페이지_ID", "dryRun": false, "publishTarget": "github"}' | jq .
응답에 url(예: https://username.github.io/repo/2025-02-18-slug/) 나오면 발행된 것.
jq없으면| jq .빼고 실행해도 됨. Windows에서는 PowerShell이나 Postman으로 같은 URL·body 호출하면 됨.
커밋 메시지
GitHub에 푸시할 때 커밋 메시지는 Post: {글 제목} 형식으로 들어가도록 되어 있음. 노션 DB에서 제목 속성 이름이 "Title"이 아니어도, 타입이 title인 속성을 찾아서 제목을 넣음.
MCP REST API 요약
- Preview (발행 없이 HTML만 생성)
POST /mcp/notion-to-blog/preview Content-Type: application/json { "pageId": "노션_페이지_ID" } - Publish (정리 후 GitHub Pages 또는 티스토리 발행,
dryRun: true면 발행 생략)POST /mcp/notion-to-blog/publish Content-Type: application/json { "pageId": "노션_페이지_ID", "dryRun": false, "publishTarget": "github" }publishTarget:"github"(현재만 지원)
노션 페이지 ID는 URL의 한 부분(하이픈 제거 여부 무관)입니다.
테스트
./gradlew test
노션 DB 스키마 가정
- Title (title 타입): 글 제목
- Type (select):
toy|algo|cs|daily
본문은 해당 페이지의 블록을 가져와 Markdown 형태로 변환합니다.