name: notion-pilot description: "Notion API 통합 스킬. DB/페이지/블록 CRUD, 마크다운 읽기/쓰기, 파일 업로드, 이미지 커버 설정, upsert, 코멘트, 페이지 이동 등 모든 Notion 작업을 notion-api.mjs 모듈로 처리합니다. Use when: (1) 노션에 추가/수정/조회, (2) 노션 DB 생성, (3) 노션 이미지 업로드, (4) 노션 커버 설정, (5) 노션 파일 업로드, (6) Notion API 작업. 트리거: '노션', 'Notion', '노션에', '노션 DB', '노션 페이지', '노션 업로드'." allowed-tools: Bash(node *), Read, Write, Glob, Grep
Notion Pilot 스킬
Notion API를 notion-api.mjs 모듈로 직접 호출하여 DB, 페이지, 블록, 파일 업로드 등 모든 작업을 처리하는 스킬.
Workflow
모든 노션 작업은 아래 순서를 반드시 따른다.
Step 1. config.json 확인
이 스킬 디렉토리 내 config.json을 Read 도구로 확인한다.
config.json이 없는 경우 (최초 실행):
먼저 이 스킬 디렉토리에 빈 토큰으로 config.json을 즉시 생성한다:
{
"token": ""
}
그 다음 사용자에게 아래와 같이 안내한다:
Notion 토큰 설정이 필요합니다. 두 가지 방법 중 선택하세요:
1️⃣ 여기에 토큰을 붙여넣기 (ntn_으로 시작하는 값)
2️⃣ 직접 파일에 입력: ~/.claude/skills/notion-pilot/config.json
토큰 발급: https://www.notion.so/profile/integrations → '새 API 통합' → 토큰 복사
- 사용자가 토큰을 붙여넣으면 → config.json의
token값을 채워준다. - 사용자가 "직접 입력할게" 등으로 응답하면 → config.json 경로를 다시 알려주고 작업을 중단한다.
config.json이 있지만 token이 빈 문자열인 경우:
위와 동일하게 토큰 입력을 안내한다.
config.json이 있고 token이 채워져 있으면 바로 Step 2로 진행한다.
Step 2. 작업 실행
notion-api.mjs 모듈을 import하여 작업을 수행한다.
API 호출 방법
notion-api.mjs 모듈 (유일한 방법)
모든 Notion API 작업에 이 모듈을 사용한다. mcp__notion-mcp__* 도구는 절대 사용하지 않는다. OAuth MCP 토큰 만료 등의 문제가 발생해도 notion-api.mjs로만 작업한다.
import { notion } from 'file:///<이 스킬의 scripts 디렉토리>/notion-api.mjs';
// 검색
const results = await notion.search('키워드', { filter: 'database' });
// DB 생성
const db = await notion.createDatabase(parentPageId, '새 DB', '📋', {
'이름': { title: {} },
'상태': { select: { options: [{ name: '진행중', color: 'blue' }] } },
});
// 페이지 생성 (DB 내) - prop 헬퍼 사용
const page = await notion.createPage(dbId, {
'이름': notion.prop.title('홍길동'),
'상태': notion.prop.select('진행중'),
'점수': notion.prop.number(95),
});
// ── 페이지 본문 읽기/쓰기 (마크다운 우선) ──
// 읽기: 특수 블록도 <callout>, <database> 등 확장 태그로 반환됨 (누락 없음)
const content = await notion.getPageMarkdown(pageId);
// 쓰기: 마크다운 문자열로 본문 전체 교체 (블록 API 대비 토큰 6배 절약)
await notion.updatePageMarkdown(pageId, '## 섹션 제목\n\n본문 내용\n\n- 항목 1\n- 항목 2');
// 블록 API는 마크다운으로 불가능한 세밀한 조작이 필요할 때만 사용
await notion.appendBlocks(pageId, [notion.block.callout('안내', '📝', 'blue_background')]);
// ── 마크다운 쓰기 시 특수 블록 레퍼런스 ──
// ✅ 읽기/쓰기 모두 지원:
// <callout icon="📌">기본 콜아웃 (color 없음)</callout>
// <callout icon="📌" color="blue_bg">컬러 콜아웃 (blue_bg, green_bg, orange_bg 등)</callout>
// <details><summary>토글 제목</summary>토글 내부 내용</details>
// > 인용문 (quote)
// --- (divider)
// - [ ] 미완료 / - [x] 완료 (to_do)
// | 헤더 | ... | (table)
// ```lang ... ``` (code)
// $`E=mc^2`$ (인라인 수식)
// $$\nE=mc^2\n$$ (수식 블록)
//
// ⚠️ 읽기전용 (쓰기 불가, 블록 API로 대체):
// bookmark → 읽으면 <unknown alt="bookmark"/> 로 표시
// embed → 읽으면 <unknown alt="embed"/> 로 표시
// synced_block → 블록 API 필수
// DB 전체 조회 (자동 페이지네이션)
const allPages = await notion.queryAll(dbId);
// ── 저수준 API 호출 (call) ──
// 시그니처: notion.call(method, path, body?)
// - method: 'GET' | 'POST' | 'PATCH' | 'DELETE'
// - path: 슬래시(/)로 시작하는 API 경로 (예: '/pages/PAGE_ID')
// - body: POST/PATCH 시 요청 본문 (선택)
// ⚠️ queryAll/createPage 등 고수준 함수는 DB ID → DS ID 자동 변환을 하지만,
// call()은 자동 변환하지 않으므로 DS ID가 필요한 엔드포인트에서는 직접 DS ID를 사용해야 한다.
const page = await notion.call('GET', '/pages/PAGE_ID');
const children = await notion.call('GET', '/blocks/BLOCK_ID/children?page_size=100');
await notion.call('PATCH', '/pages/PAGE_ID', { in_trash: true });
// 블록을 특정 위치에 삽입: `after` 파라미터는 폐기됨(2026-03-11) → `position` 객체 사용
await notion.call('PATCH', '/blocks/PARENT_ID/children', {
position: { type: 'after_block', after_block: { id: 'BLOCK_ID' } }, // 시작/끝: { type:'start' } / { type:'end' }(기본)
children: [ /* 블록 배열 */ ],
});
// 배치 처리 (동시성 15)
await notion.batch(items, async (item) => {
await notion.createPage(dbId, { '이름': notion.prop.title(item.name) });
});
// Upsert (단건)
const result = await notion.upsertPage(dbId, '이름', 'title', '홍길동', {
'이름': notion.prop.title('홍길동'),
'점수': notion.prop.number(95),
});
// Bulk Upsert (대량, queryAll 캐시 + 동시성 15)
const stats = await notion.bulkUpsert(dbId, '이름', [
{ matchValue: '홍길동', properties: { '이름': notion.prop.title('홍길동'), '점수': notion.prop.number(100) } },
]);
// 파일 업로드
await notion.setCover(pageId, 'C:/path/to/cover.webp');
await notion.addImageBlock(pageId, 'C:/path/to/photo.png');
const uploadId = await notion.uploadFromUrl('https://example.com/img.jpg');
// 코멘트
await notion.createComment(pageId, '코멘트 내용');
const comments = await notion.listComments(pageId);
// 페이지 이동
await notion.movePage(pageId, { page_id: targetPageId });
주의사항:
- 크리덴셜은 모듈이
config.json에서 자동 로드 - API 버전
2026-03-11(DB ID → DS ID 자동 변환 내장)
실패 시 자가 수복 프로토콜
모듈 함수 호출이 실패하면 아래 순서를 따른다. MCP 폴백은 절대 하지 않는다.
- 에러 분석 — API 응답 코드와 메시지 확인
- 인라인 스크립트 작성 — 모듈을 import하되, 실패한 부분만
notion.call()로 우회 - 성공 시 모듈 업데이트 — 우회 코드를
notion-api.mjs에 반영 + 커밋
토큰 절약 규칙
- 페이지 본문은 마크다운 API 우선: 읽기
getPageMarkdown(), 쓰기updatePageMarkdown(). 특수 블록도 확장 태그로 보존됨. 블록 API 대비 읽기 20배, 쓰기 6배 토큰 절약. - 블록 API는 세밀한 조작이 필요할 때만: 특정 블록 하나만 수정/삭제 등.
- 여러 페이지 작업 시
notion.batch()로 동시성 15 병렬 처리. - 전체 조회 시
notion.queryAll()로 자동 페이지네이션. - Upsert 전략 선택: 10건 미만 →
upsertPage(), 10건 이상 →bulkUpsert().
Priorisation de Tâches
Productivite
Priorise vos tâches avec les frameworks Eisenhower, ICE et RICE.
Generateur de Rapport Hebdomadaire
Productivite
Generez des rapports de statut hebdomadaires structures et concis.
Rapport de Daily Standup
Productivite
Génère des rapports de daily standup structurés et concis.