코드로 관리하는
링크 인 바이오
링크인바이오 서비스는 전부 GUI 전용입니다. Onshelf는 웹 편집기와 똑같은 REST API를 터미널·발행 스크립트·AI 에이전트(MCP)에도 그대로 엽니다. 진실의 원천은 API 하나, 클라이언트는 셋.
공개 페이지 · CLI · MCP 서버가 모두 같은 엔드포인트(/api/sites/{handle}/…)를 칩니다.
# 빠른 시작
키를 받아 60초 안에 첫 픽을 올립니다.
1. 사이트 + API 키 발급
/login에서 이메일·비밀번호·원하는 주소(핸들)로 가입하면 사이트와 API 키가 자동 발급됩니다.
키는 로그인 후 /admin 우측 “개발자 · API 연동” 패널에서 언제든 복사·재발급할 수 있어요.
키 형식은 sk_live_… 이며 해당 사이트 한 곳에만 쓰기 권한이 있습니다.
2. 공개 데이터 읽기 (인증 불필요)
# 누구나 읽을 수 있는 공개 데이터 (프로필 + 픽) curl https://onshelf.vercel.app/api/sites/kkanajae
3. 첫 픽 추가하기 (키 필요)
curl -X POST https://onshelf.vercel.app/api/sites/kkanajae/picks \ -H "Authorization: Bearer sk_live_여기에_내_키" \ -H "Content-Type: application/json" \ -d '{ "ep":"EP14", "topic":"텀블러", "verdict":"진공 이중벽이 다 한다", "category":"주방", "coupang":"https://link.coupang.com/a/..", "status":"latest" }'
/kkanajae 공개 페이지에 즉시 나타납니다.
status:"latest" 는 맨 위 대표 카드로 올려줍니다(사이트당 최대 1개).# 인증
쓰기 요청은 Authorization 헤더에 사이트 스코프 키를 담습니다. 공개 GET
(사이트 읽기)은 인증이 필요 없습니다.
Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxx
- 키는 발급된 사이트 한 곳에만 유효합니다. 다른 핸들에 쓰기를 시도하면
403. - 키가 유효하지 않거나 없으면
401. - 키 유출이 의심되면 /admin에서 재발급하세요. 이전 키는 즉시 폐기됩니다.
- 남용 방지를 위해 요청 수가 제한됩니다. 초과 시
429+Retry-After헤더가 옵니다.
sk_live_… 키로 인증할 뿐, 엔드포인트는 동일합니다.# REST API
Base URL — https://onshelf.vercel.app/api
| 메서드 | 경로 | 인증 | 설명 |
|---|---|---|---|
| GET | /sites/{h} | 🔓 | 공개 데이터(프로필 + 픽 + 블록) |
| PUT | /sites/{h} | 🔒 | 사이트 통짜 교체(picks 배열 필수) — GUI 저장용 |
| GET | /sites/{h}/picks | 🔒 | 픽 목록 |
| POST | /sites/{h}/picks | 🔒 | 픽 추가(topic 필수) → 201, 생성된 픽 반환 (자동화 주력) |
| PATCH | /sites/{h}/picks/{id} | 🔒 | 픽 부분 수정(보낸 필드만) |
| DELETE | /sites/{h}/picks/{id} | 🔒 | 픽 삭제 |
| POST | /sites/{h}/picks/{id}/latest | 🔒 | 대표(최신) 지정 — 기존 최신은 일반 게시로 |
| POST | /sites/{h}/picks/reorder | 🔒 | 순서 재정렬 · body { ids:[…] } |
| PATCH | /sites/{h}/profile | 🔒 | 프로필 필드 병합 |
| GET | /sites/{h}/stats | 🔒 | 방문·클릭·전환율 |
응답 형식
쓰기 응답은 { "ok": true, … } 또는 { "ok": false, "error": "…" } 봉투를 씁니다.
공개 GET /sites/{h} 만 사이트 객체를 그대로 반환합니다.
| 상태 | 의미 |
|---|---|
200 / 201 | 성공 (201 = 픽 생성) |
401 | 인증 없음/실패 |
403 | 키가 다른 사이트 소속 |
404 | 픽·경로 없음 |
422 | 검증 실패(필수값 누락 등) |
429 | 요청 제한 초과(Retry-After 참고) |
예) 픽 추가 → 응답
POST /api/sites/kkanajae/picks Authorization: Bearer sk_live_xxx { "ep":"EP14", "topic":"텀블러", "coupang":"https://link.coupang.com/a/..", "toss":"https://sharelink.toss.im/..", "category":"주방", "status":"latest" } → 201 { "ok":true, "pick":{ "id":"p_ab12", "ep":"EP14", "topic":"텀블러", "status":"latest", … } }
예) 부분 수정 · 최신 지정 · 통계
# 토스 링크만 교체 curl -X PATCH …/sites/kkanajae/picks/p_ab12 \ -H "Authorization: Bearer sk_live_xxx" -H "Content-Type: application/json" \ -d '{ "toss":"https://sharelink.toss.im/new" }' # 이 픽을 대표(최신)로 curl -X POST …/sites/kkanajae/picks/p_ab12/latest -H "Authorization: Bearer sk_live_xxx" # 통계 (방문·유입·클릭·전환율) curl …/sites/kkanajae/stats -H "Authorization: Bearer sk_live_xxx" # → { "ok":true, "stats":{ "totalViews":120, "totalClicks":18, "ctr":15, "views":{…}, "clicks":{…} } }
/stats로 집계값만 읽으면 됩니다.
정밀 매출은 쿠팡 파트너스·토스 대시보드가 정본입니다.# 데이터 모델
사이트 하나 = profile + picks[] + blocks[].
{
"profile": { "name", "handle", "tagline", "bio", "avatar", "accent",
"notice", "contactEmail", "disclosure",
"socials": { "youtube", "tiktok", "instagram", "threads", "naverBlog", "x" } },
"picks": [
{ "id", "ep", "topic", "verdict", "category", "image", "youtube",
"buttons": [ { "label", "url" } ], "status" }
],
"blocks": [ { "type": "text|video|link", … } ]
}픽(pick) 필드
id— 서버가 생성(추가 시 자동). 수정·삭제·재정렬의 키.topic— 카드 제목 (추가 시 필수).verdict— 한 줄 코멘트,ep— 회차 뱃지,category— 필터용 분류.buttons— 구매/이동 버튼 배열 (라벨+URL, 최대 4개). 쿠팡·토스·네이버·알리 등 아무 스토어나 자유롭게.coupang/toss— 레거시 단축 필드(buttons가 없을 때 하위호환 렌더). 신규는buttons권장.status—latest(대표, 사이트당 최대 1개·서버 강제) ·live(일반 게시, 기본) ·hidden(숨김).image/youtube— 카드 이미지·리뷰 쇼츠 링크(선택).
http·https·mailto)로 정리됩니다.
javascript:·data:text/html 등은 저장 단계에서 제거되어 XSS를 차단합니다. 길이도 서버에서 슬라이스됩니다.# CLI npm 배포 예정
터미널·발행 스크립트에서 픽·프로필을 관리하는 onshelf 커맨드. 의존성 0(Node 18+ 내장만),
MCP 툴과 1:1 대응합니다.
# 설치 (npm 배포 후) npm i -g onshelf # 로그인 — 키는 ~/.config/onshelf/config.json 에 저장 onshelf login --key sk_live_xxx --handle kkanajae echo sk_live_xxx | onshelf login # 키를 stdin으로(히스토리 안 남김)
onshelf picks list # 픽 목록 onshelf picks add --ep EP15 --topic 쿨매트 --coupang <url> --toss <url> --category 반려 --latest onshelf picks update <id> --toss <url> # 값 없는 --toss = 그 필드 지우기 onshelf picks rm <id> onshelf picks latest <id> # 대표(최신) 지정 onshelf picks reorder <id1> <id2> … onshelf profile get # 공개 읽기(키 불필요) onshelf profile set --notice "이번 주 신상 3종" --instagram <url> onshelf stats # 방문·클릭·전환율 onshelf whoami | url | logout
--json을 붙이면 원본 JSON(파이프·jq용). 환경변수 API_BASE·API_KEY·SITE_HANDLE로도
덮어쓸 수 있어(CI·일회성) 로그인 없이 씁니다.
발행 파이프라인 훅 — "영상 올리면 픽 자동 추가"
onshelf picks add --ep "$EP" --topic "$TOPIC" \ --coupang "$COUPANG" --toss "$TOSS" --category "$CAT" --latest
node cli/onshelf.js …로 바로 실행됩니다(개발·도그푸딩용).
REST API는 배포와 무관하게 지금 동작하니, 키만 있으면 위 명령 없이도 curl·자기 스크립트로 자동화할 수 있습니다.# MCP 서버 npm 배포 예정
클로드·커서 같은 AI 에이전트에 링크 페이지를 도구로 노출합니다. 에이전트에게 말로 시키면 해당 REST 호출로 라이브 반영 — 이게 Onshelf의 핵심 웨지입니다.
설정 (Claude Desktop / Claude Code)
MCP 설정 파일(claude_desktop_config.json 또는 프로젝트 .mcp.json)에 추가:
{
"mcpServers": {
"onshelf": {
"command": "npx",
"args": ["-y", "onshelf-mcp"],
"env": {
"API_KEY": "sk_live_여기에_내_키",
"SITE_HANDLE": "kkanajae"
}
}
}
}API_BASE는 기본값이 프로덕션(https://onshelf.vercel.app/api)이라 생략 가능합니다.
키 없이 실행하면 공개 읽기만 됩니다.
노출 툴 (8종)
| 툴 | 동작 |
|---|---|
list_picks | 픽 목록 |
add_pick | 픽 추가(topic·coupang 필수) |
update_pick | 픽 부분 수정 |
delete_pick | 픽 삭제 |
set_latest | 대표(최신) 지정 |
reorder_picks | 순서 재정렬 |
update_profile | 프로필(이름·공지·소셜 등) 수정 |
get_stats | 방문·유입·클릭·전환율 |
“EP15 쿨매트 픽 추가해줘. 쿠팡 링크는 …, 카테고리 반려, 최신으로.” → 공개 페이지에 즉시 반영.
# 현황
- REST API — 지금 바로 동작. 가입해서 키만 받으면
curl·스크립트로 자동화 가능. - CLI · MCP — 완성·검증 완료, npm 배포 준비 상태(패키지명
onshelf·onshelf-mcp확보). 배포되면 위npm i/npx가 그대로 동작하고, 그전에는 레포에서 직접 실행. - 데이터 소유권 — 언제든
GET /api/sites/{handle}로 내 데이터를 통째로 내려받아 백업할 수 있습니다. - 서비스는 현재 무료 베타입니다. 문의: yugeonjae@gmail.com