UNPKG

@roottale/cms-mcp

Version:

RootTale CMS integration MCP server — bundled integration docs, Next.js example code, and public API lookup tools. Run with: npx @roottale/cms-mcp

186 lines (138 loc) 7.01 kB
--- title: HTTP API 레퍼런스 description: 공개 API raw 엔드포인트 — JS 외 스택이나 저수준 연동용 --- # HTTP API 레퍼런스 베이스 URL: `https://api.roottale.com` 인증: 모든 요청에 `Authorization: Bearer rtlk_cust_...` 헤더. JS/TS 스택은 raw 호출 대신 `@roottale/cms-client`를 사용하세요 — 에러 처리, 브라우저 노출 방지, 전화번호 포맷 등이 포함되어 있습니다. ## GET /v1/cms/public/posts 발행된 글 목록 (커서 페이지네이션). | 쿼리 | 설명 | |---|---| | `limit` | 페이지 크기 (서버에서 상한 clamp) | | `cursor` | 이전 응답의 `next_cursor` | | `type` | `post` \| `page` | | `site_id` | 멀티 사이트 키일 때만 — site-scoped 키면 생략 | ```json { "items": [ { "id": "…", "slug": "…", "title": "…", "body_json": {}, "terms": [{ "taxonomy": "category", "name": "…", "slug": "…" }], "published_at": "…" } ], "has_more": false, "next_cursor": null } ``` ## GET /v1/cms/public/posts/{identifier} 글 1개 — `identifier`는 slug 또는 UUID. 미발행/없는 글은 `404`. ## GET /v1/cms/public/search 발행된 글 키워드 검색 (사이트 내 검색, WP `?s=` 패리티). title·excerpt·본문 텍스트의 case-insensitive 부분일치, 최신 발행순. 응답은 카드 렌더용 슬림 hit — 본문(`body_json`)은 미포함이므로 상세는 slug 로 글 1API를 호출하세요. | 쿼리 | 설명 | |---|---| | `q` | 검색 키워드 (필수, 1~100자) | | `limit` | 결과 수 1~50, 기본 10 | | `type` | `post`(기본) \| `page` | | `site_id` | 멀티 사이트 키일 때만 | ```json { "tenant_id": "…", "site_id": "…", "query": "세무", "items": [ { "id": "…", "type": "post", "title": "…", "slug": "…", "excerpt": "…", "featured_media_url": "…", "published_at": "…" } ] } ``` JS/TS 는 `@roottale/cms-client/server` 의 `searchPosts({ apiKey, query })` 를 사용하세요 — 구 서버(라우트 미배포)의 404 를 빈 배열로 처리합니다. ## GET /v1/cms/public/menus 네비게이션 메뉴 전체 — 어드민 "디자인 > 메뉴" 저장값. 항목은 깊이 2 트리. ```json { "tenant_id": "…", "site_id": "…", "items": [ { "id": "…", "name": "헤더 메뉴", "slug": "primary", "items": [ { "id": "…", "label": "회사 소개", "url": "/about", "children": [ { "id": "…", "label": "오시는 길", "url": "/about/location" } ] }, { "id": "…", "label": "블로그", "url": "/blog" } ], "updated_at": "…" } ] } ``` ## GET /v1/cms/public/menus/{slug} 위치 핸들(`primary`, `footer` 등)로 메뉴 1개. 없으면 `404` — 사이트는 자체 fallback 네비를 렌더하세요 (`menus.md` 참고). ## GET /v1/cms/public/theme 어드민에서 설정한 디자인 토큰. 설정된 그룹만 포함됩니다. ```json { "tenant_id": "…", "site_id": "…", "colors": {}, "fonts": {}, "radius": {}, "updated_at": "…" } ``` ## GET /v1/cms/public/blog-settings 블로그 표시 설정 (TOC·작성자·발행일·작성자 카드, 저자 프로필). ```json { "show_table_of_contents": false, "show_author": true, "show_date": true, "show_author_card": true, "toc_title": null, "author_profile_name": null, "author_profile_bio": null, "author_profile_image_url": null, "author_profile_image_radius": "circle", "updated_at": null } ``` ## GET /v1/cms/public/business-profile 비즈니스 프로필 (로컬 SEO) — 어드민 "운영 > 비즈니스 프로필" 저장값. 미설정이면 `configured: false` + 필드 `null`. ```json { "tenant_id": "…", "site_id": "…", "configured": true, "name": "길동세무회계", "legal_name": null, "business_type": "AccountingService", "telephone": "02-1234-5678", "email": null, "address": { "street_address": "테헤란로 123", "address_locality": "강남구", "address_region": "서울특별시", "postal_code": "06234" }, "geo": { "latitude": 37.5006, "longitude": 127.0364 }, "opening_hours": [ { "days": ["Mo","Tu","We","Th","Fr"], "opens": "09:00", "closes": "18:00" } ], "price_range": "₩₩", "area_served": ["서울 강남구"], "profiles": { "naver_place": "https://…", "google_business": "https://…", "kakao_channel": null, "instagram": null, "naver_blog": null }, "updated_at": "…" } ``` `business_type`: `LocalBusiness` | `ProfessionalService` | `AccountingService` | `LegalService` | `MedicalClinic` | `Dentist` | `RealEstateAgent` | `Restaurant` | `BeautySalon`. ## GET /v1/cms/public/analytics 분석 태그 설정. ```json { "tags": [ { "provider": "ga4", "id": "G-XXXXXXX", "enabled": true } ] } ``` `provider`: `ga4` | `clarity` | `meta_pixel` | `naver`. ## GET /v1/cms/public/jwks 웹훅 서명 검증용 site-scoped JWKS 공개키. **site-scoped 키 필수** — 테넌트 전체 키로 호출하면 `400 site_scope_required`. ## POST /v1/public/inquiries 상담문의(리드) 접수. `multipart/form-data`. | 필드 | 필수 | 비고 | |---|---|---| | `vertical` | | `consulting` \| `medical` \| `tax` \| `legal` | | `contact_name` | | | | `business_name` | | | | `email` | | `.+@.+\..+` | | `phone` | | | | `privacy_consent` | | 체크박스 (`on`) | | `overseas_transfer_consent` | medical 시 | | | `message`, `consultation_field`, `current_site_url` | | | | `lead_kind` | | `patient`(기본) \| `sales` | | `_redirect_url` | | 완료 후 redirect base (allowlist 검증) | | `attr_landing_path`, `attr_rt_src`, `attr_utm_source`, `attr_utm_medium`, `attr_utm_campaign`, `attr_referrer`, `attr_first_touch_at` | | 유입 어트리뷰션 — CRM에 유입 경로 표시 (`inquiries.md` 참고). 그 외 `attr_*` 키는 무시 | | 기타 임의 필드 | | 최대 50개, 암호화 보관, CRM 상세 노출 | 응답: `302` redirect — 성공 `?ok=1`, 실패 `?err=<code>` (`consent_privacy`, `consent_overseas`, `invalid_vertical`, `missing_fields`, `invalid_email`, `internal`). 잘못된 키는 `401`. 서버-서버 호출 시 redirect를 따라가지 말고(`redirect: "manual"`) `Location` 헤더를 파싱하세요 — `@roottale/cms-client`의 `submitInquiry`가 이를 대신합니다. ## POST /v1/cms/revalidate 수동 캐시 갱신 트리거 (등록된 웹훅으로 재발송). ```json { "event": "post.updated", "paths": ["/blog", "/blog/my-post"], "slug": "my-post" } ``` ## 에러 형식 비 2xx 응답은 JSON 에러 바디(`code`, `message`)를 가집니다. 주요 코드: `invalid_key`(401), `insufficient_scope`(403), `rate_limited`(429), `not_found`(404). ## 캐시 헤더 공개 콘텐츠 응답은 private 캐시 헤더로 내려갑니다 — CDN 공유 캐시에 의존하지 말고 사이트 측 ISR + 발행 웹훅 조합을 사용하세요.