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

74 lines (67 loc) 1.99 kB
// RootTale CMS 블로그 데이터 레이어 — 서버 전용. // 사이트 UI에 맞는 메타 형태로 변환하는 wrapper. API 키는 env에서만 읽는다. import { fetchPosts, fetchPost, type CmsPostContent, } from "@roottale/cms-client/server"; function getApiKey(): string { const key = process.env.ROOTTALE_API_KEY; if (!key) throw new Error("ROOTTALE_API_KEY is not set"); return key; } const baseUrl = process.env.ROOTTALE_API_BASE; export interface BlogPostMeta { id: string; slug: string; title: string; description: string; date: string; // publishedAt ISO category: string; tags: { name: string; slug: string }[]; image: string | null; authorName?: string; seo?: { title?: string; description?: string; canonical?: string; ogImage?: string; noindex?: boolean; nofollow?: boolean; }; } function toMeta(post: CmsPostContent): BlogPostMeta { const category = post.terms?.find((t) => t.taxonomy === "category"); const meta = (post.metaJson ?? {}) as Record<string, unknown>; return { id: post.id, slug: post.slug, title: post.title, description: post.excerpt ?? "", date: post.publishedAt ?? "", category: category?.name ?? "", tags: post.terms ?.filter((t) => t.taxonomy === "tag") .map((t) => ({ name: t.name, slug: t.slug })) ?? [], image: post.featuredImageUrl ?? null, authorName: post.authorName ?? undefined, seo: meta.seo as BlogPostMeta["seo"], }; } export async function getAllPosts(): Promise<BlogPostMeta[]> { const page = await fetchPosts({ apiKey: getApiKey(), baseUrl, type: "post", limit: 100, }); return page.items.map(toMeta); } export async function getPost( slug: string, ): Promise<(BlogPostMeta & { bodyJson: unknown }) | null> { const post = await fetchPost({ apiKey: getApiKey(), baseUrl, slugOrId: slug }); if (!post) return null; return { ...toMeta(post), bodyJson: post.bodyJson }; }