Polyblog Multilingual Blog
Write, translate and publish blog articles, plan topic ideas and check each blog's languages.
사용해야 할까요
품질 및 안전성
발견 사항 (1)
- LOWset_topic_idea_status에서
도구 정의와 프로토콜 준수에 대한 자동 분석을 기반으로 합니다.
컨텍스트 비용
이는 서버의 도구가 모델의 컨텍스트에 로드될 때마다 소비되는 대략적인 토큰 수입니다. 수치가 높을수록 다른 작업에 사용할 수 있는 주의가 줄어듭니다.
설치
원클릭 설치
`claude_desktop_config.json` 파일에 다음을 추가하세요:
{
"mcpServers": {
"polyblog": {
"url": "https://mcp.polyblog.io/mcp"
}
}
}원격 엔드포인트
https://mcp.polyblog.io/mcpstreamable-http할 수 있는 일
도구 목록
도구 (18)
🟢search_articles(blogId, locale, slug, published, limit, ...)
Use this when someone asks to see their blog posts, drafts or published articles, optionally for one blog, language or slug. Returns id, title, language, slug and published state, most recently edited first, 25 per page by default with a cursor. It filters by those fields and does not search the text. Not for reading a post.
입력 스키마
{
"type": "object",
"properties": {
"blogId": {
"type": "string",
"maxLength": 200,
"description": "Only posts in this blog"
},
"locale": {
"type": "string",
"maxLength": 50,
"description": "Only posts in this language, an ISO 639-1 code such as en or it"
},
"slug": {
"type": "string",
"maxLength": 300,
"description": "Only the post with this exact slug"
},
"published": {
"type": "string",
"enum": [
"true",
"false"
],
"description": "\"true\" for published posts only, \"false\" for drafts only; omit for both"
},
"limit": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 100,
"description": "Posts per page, from 1 to 100; defaults to 25"
},
"cursor": {
"type": "string",
"maxLength": 4096,
"description": "The nextCursor of the previous page with the same filters; absent for the first page"
}
},
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}출력 스키마
{
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"anyOf": [
{
"type": "string",
"maxLength": 200
},
{
"type": "null"
}
]
},
"title": {
"anyOf": [
{
"type": "string",
"maxLength": 300
},
{
"type": "null"
}
]
},
"locale": {
"anyOf": [
{
"type": "string",
"maxLength": 50
},
{
"type": "null"
}
]
},
"slug": {
"anyOf": [
{
"type": "string",
"maxLength": 300
},
{
"type": "null"
}
]
},
"published": {
"type": [
"boolean",
"null"
]
}
},
"required": [
"id",
"title",
"locale",
"slug",
"published"
],
"additionalProperties": false
},
"maxItems": 100
},
"hasMore": {
"type": "boolean"
},
"nextCursor": {
"anyOf": [
{
"type": "string",
"maxLength": 2048
},
{
"type": "null"
}
],
"description": "Cursor for the next page; null on the last page"
}
},
"required": [
"items",
"hasMore",
"nextCursor"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}🟢get_article(idOrSlug, locale)
Use this when someone wants to read, check or quote one blog post. Returns its title, summary, language, slug, blog, author, published state, dates and up to 8,000 characters of content, looked up by id or by slug plus language. Not for a visual preview card.
입력 스키마
{
"type": "object",
"properties": {
"idOrSlug": {
"type": "string",
"minLength": 1,
"maxLength": 300,
"description": "Article id, or its slug together with locale"
},
"locale": {
"type": "string",
"maxLength": 50,
"description": "Language of the post, an ISO 639-1 code such as en; needed when looking up by slug"
}
},
"required": [
"idOrSlug"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}출력 스키마
{
"type": "object",
"properties": {
"status": {
"type": "string",
"enum": [
"found",
"not-found"
]
},
"article": {
"anyOf": [
{
"type": "object",
"properties": {
"id": {
"anyOf": [
{
"type": "string",
"maxLength": 200
},
{
"type": "null"
}
]
},
"title": {
"anyOf": [
{
"type": "string",
"maxLength": 300
},
{
"type": "null"
}
]
},
"locale": {
"anyOf": [
{
"type": "string",
"maxLength": 50
},
{
"type": "null"
}
]
},
"slug": {
"anyOf": [
{
"type": "string",
"maxLength": 300
},
{
"type": "null"
}
]
},
"published": {
"type": [
"boolean",
"null"
]
},
"lastEditTime": {
"anyOf": [
{
"type": "string",
"maxLength": 100
},
{
"type": "null"
}
]
},
"blogId": {
"$ref": "#/properties/article/anyOf/0/properties/id"
},
"description": {
"anyOf": [
{
"type": "string",
"maxLength": 1000
},
{
"type": "null"
}
]
},
"content": {
"anyOf": [
{
"type": "string",
"maxLength": 8000
},
{
"type": "null"
}
]
},
"contentTruncated": {
"type": "boolean"
},
"format": {
"anyOf": [
{
"type": "string",
"maxLength": 20
},
{
"type": "null"
}
]
},
"author": {
"anyOf": [
{
"type": "string",
"maxLength": 200
},
{
"type": "null"
}
]
},
"created": {
"$ref": "#/properties/article/anyOf/0/properties/lastEditTime"
},
"coverUrl": {
"anyOf": [
{
"type": "string",
"maxLength": 2048
},
{
"type": "null"
}
]
}
},
"required": [
"id",
"title",
"locale",
"slug",
"published",
"lastEditTime",
"blogId",
"description",
"content",
"contentTruncated",
"format",
"author",
"created",
"coverUrl"
],
"additionalProperties": false
},
{
"type": "null"
}
]
}
},
"required": [
"status",
"article"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}🟢list_article_translations(originalArticleId, blogId)
Use this when someone asks which languages a blog post exists in, or which translations are still missing. Returns each language version sharing the original article id, up to 100, with title, slug, published state and how it was translated; with blogId it also lists the blog's missing languages. Not for a whole blog's coverage.
입력 스키마
{
"type": "object",
"properties": {
"originalArticleId": {
"type": "string",
"minLength": 1,
"maxLength": 200,
"description": "Id of the original article that every translation shares, as reported on each of its versions"
},
"blogId": {
"type": "string",
"maxLength": 200,
"description": "Blog id; when given, the result also lists the blog languages that still lack this post"
}
},
"required": [
"originalArticleId"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}출력 스키마
{
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"anyOf": [
{
"type": "string",
"maxLength": 200
},
{
"type": "null"
}
]
},
"title": {
"anyOf": [
{
"type": "string",
"maxLength": 300
},
{
"type": "null"
}
]
},
"locale": {
"anyOf": [
{
"type": "string",
"maxLength": 50
},
{
"type": "null"
}
]
},
"slug": {
"anyOf": [
{
"type": "string",
"maxLength": 300
},
{
"type": "null"
}
]
},
"published": {
"type": [
"boolean",
"null"
]
},
"translatedBy": {
"type": "string",
"enum": [
"google",
"human",
"unknown"
]
}
},
"required": [
"id",
"title",
"locale",
"slug",
"published",
"translatedBy"
],
"additionalProperties": false
},
"maxItems": 100
},
"truncated": {
"type": "boolean"
},
"missingLocales": {
"type": "array",
"items": {
"type": "string",
"maxLength": 50
},
"maxItems": 100
},
"missingLocalesKnown": {
"type": "boolean"
},
"missingLocalesTruncated": {
"type": "boolean"
}
},
"required": [
"items",
"truncated",
"missingLocales",
"missingLocalesKnown",
"missingLocalesTruncated"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}🔴create_article(blogId, title, content, format, locale, ...)
Use this when someone gives you a finished blog post, or a translation of one, to save in their blog. Returns the new post's id, title, slug, language and published state; it stays a draft unless published is true. A translation is saved with the original's id as originalArticleId and its own locale. Not for writing a post with AI.
입력 스키마
{
"type": "object",
"properties": {
"blogId": {
"type": "string",
"minLength": 1,
"maxLength": 200,
"description": "Blog to add the post to"
},
"title": {
"type": "string",
"maxLength": 300,
"minLength": 1,
"description": "Post title, 1 to 300 characters"
},
"content": {
"type": "string",
"maxLength": 100000,
"minLength": 1,
"description": "Post body in the chosen format, Markdown or HTML, up to 100,000 characters"
},
"format": {
"type": "string",
"enum": [
"markdown",
"html"
],
"description": "markdown or html; content is treated as HTML when omitted"
},
"locale": {
"type": "string",
"maxLength": 50,
"description": "Post language, an ISO 639-1 code such as en or it; required with originalArticleId"
},
"originalArticleId": {
"type": "string",
"maxLength": 200,
"description": "Makes this article the `locale` version in an existing article's translation group. It is the original article's id, never a sibling translation's id; absent means a new original."
},
"slug": {
"type": "string",
"maxLength": 300,
"description": "URL slug such as my-first-post, up to 300 characters"
},
"description": {
"type": "string",
"maxLength": 1000,
"description": "Short summary shown in listings and search results, up to 1,000 characters"
},
"author": {
"type": "string",
"maxLength": 200,
"description": "Author name shown on the post, up to 200 characters"
},
"categories": {
"type": "array",
"items": {
"type": "string",
"maxLength": 100
},
"maxItems": 50,
"description": "Up to 50 category names, each up to 100 characters"
},
"published": {
"type": "boolean",
"description": "true publishes the post on the blog; false or omitted keeps it a draft"
}
},
"required": [
"blogId",
"title",
"content"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}출력 스키마
{
"type": "object",
"properties": {
"status": {
"type": "string",
"const": "created"
},
"article": {
"type": "object",
"properties": {
"id": {
"anyOf": [
{
"type": "string",
"maxLength": 200
},
{
"type": "null"
}
]
},
"title": {
"anyOf": [
{
"type": "string",
"maxLength": 300
},
{
"type": "null"
}
]
},
"locale": {
"anyOf": [
{
"type": "string",
"maxLength": 50
},
{
"type": "null"
}
]
},
"slug": {
"anyOf": [
{
"type": "string",
"maxLength": 300
},
{
"type": "null"
}
]
},
"published": {
"type": [
"boolean",
"null"
]
},
"lastEditTime": {
"anyOf": [
{
"type": "string",
"maxLength": 100
},
{
"type": "null"
}
]
}
},
"required": [
"id",
"title",
"locale",
"slug",
"published",
"lastEditTime"
],
"additionalProperties": false
}
},
"required": [
"status",
"article"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}🔴update_article(id, title, content, format, description, ...)
Use this when someone asks to change a blog post's title, text, summary, slug, author or categories, or to publish or unpublish it. Returns the updated post; only the fields passed change, and each edit notifies the blog's webhooks. Not for adding a translation.
입력 스키마
{
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1,
"maxLength": 200,
"description": "Id of the post to change"
},
"title": {
"type": "string",
"maxLength": 300,
"description": "New title, up to 300 characters"
},
"content": {
"type": "string",
"maxLength": 100000,
"description": "New body in the post's format, up to 100,000 characters; replaces the whole body"
},
"format": {
"type": "string",
"enum": [
"markdown",
"html"
],
"description": "markdown or html, describing how content is written"
},
"description": {
"type": "string",
"maxLength": 1000,
"description": "New summary, up to 1,000 characters"
},
"slug": {
"type": "string",
"maxLength": 300,
"description": "New URL slug, up to 300 characters; changes the post's URL"
},
"author": {
"type": "string",
"maxLength": 200,
"description": "New author name, up to 200 characters"
},
"categories": {
"type": "array",
"items": {
"type": "string",
"maxLength": 100
},
"maxItems": 50,
"description": "Complete new list of up to 50 categories; replaces the old list"
},
"published": {
"type": "boolean",
"description": "true publishes the post, false turns it back into a draft"
}
},
"required": [
"id"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}출력 스키마
{
"type": "object",
"properties": {
"status": {
"type": "string",
"enum": [
"updated",
"not-found"
]
},
"article": {
"anyOf": [
{
"type": "object",
"properties": {
"id": {
"anyOf": [
{
"type": "string",
"maxLength": 200
},
{
"type": "null"
}
]
},
"title": {
"anyOf": [
{
"type": "string",
"maxLength": 300
},
{
"type": "null"
}
]
},
"locale": {
"anyOf": [
{
"type": "string",
"maxLength": 50
},
{
"type": "null"
}
]
},
"slug": {
"anyOf": [
{
"type": "string",
"maxLength": 300
},
{
"type": "null"
}
]
},
"published": {
"type": [
"boolean",
"null"
]
},
"lastEditTime": {
"anyOf": [
{
"type": "string",
"maxLength": 100
},
{
"type": "null"
}
]
}
},
"required": [
"id",
"title",
"locale",
"slug",
"published",
"lastEditTime"
],
"additionalProperties": false
},
{
"type": "null"
}
]
}
},
"required": [
"status",
"article"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}🔴delete_article(id)
Use this when someone asks to permanently delete a blog post in every language. Given the original post's id, that post and all its translations are deleted and their pages go offline; given a translation's own id, nothing is deleted although the result still says deleted. Returns the id. Not for unpublishing.
입력 스키마
{
"type": "object",
"properties": {
"id": {
"type": "string",
"minLength": 1,
"maxLength": 200,
"description": "Id of the original post (its originalArticleId); every language version of it is deleted"
}
},
"required": [
"id"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}출력 스키마
{
"type": "object",
"properties": {
"status": {
"type": "string",
"const": "deleted"
},
"articleId": {
"type": "string",
"maxLength": 200,
"description": "The id passed in. The API deletes every article whose originalArticleId equals it, so a translation id deletes nothing even though status is deleted."
}
},
"required": [
"status",
"articleId"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}🔴generate_article(blogId, topic, topicIdeaId, locale, autoPublish, ...)
Use this when someone asks you to write a new blog post on a topic or saved topic idea. Returns the draft's id, URL, title, word count and internal links (text only; published only with autoPublish). It uses paid AI and can take about a minute, and a call that times out can still save the draft. Not for saving your own text.
입력 스키마
{
"type": "object",
"properties": {
"blogId": {
"type": "string",
"minLength": 1,
"maxLength": 200,
"description": "Blog to write for"
},
"topic": {
"type": "object",
"properties": {
"title": {
"type": "string",
"minLength": 1,
"maxLength": 200,
"description": "Article topic title"
},
"angle": {
"type": "string",
"maxLength": 500,
"description": "One-line angle / framing for the article"
}
},
"required": [
"title"
],
"additionalProperties": false,
"description": "Title and optional angle to write about; omit when topicIdeaId is given"
},
"topicIdeaId": {
"type": "string",
"maxLength": 200,
"description": "Saved topic idea to write about; omit when topic is given"
},
"locale": {
"type": "string",
"maxLength": 50,
"description": "Language of the post, an ISO 639-1 code; defaults to the blog's default locale"
},
"autoPublish": {
"type": "boolean",
"description": "true publishes the post immediately; defaults to false, a draft"
},
"persist": {
"type": "boolean",
"description": "false returns a preview without saving anything; defaults to true"
},
"sitemapMaxUrls": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 500,
"description": "How many sitemap URLs to offer as internal links, from 1 to 500; defaults to 150"
}
},
"required": [
"blogId"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}출력 스키마
{
"type": "object",
"properties": {
"status": {
"type": "string",
"const": "generated"
},
"article": {
"type": "object",
"properties": {
"id": {
"anyOf": [
{
"type": "string",
"maxLength": 200
},
{
"type": "null"
}
]
},
"url": {
"anyOf": [
{
"type": "string",
"maxLength": 2048
},
{
"type": "null"
}
]
},
"title": {
"anyOf": [
{
"type": "string",
"maxLength": 300
},
{
"type": "null"
}
]
},
"slug": {
"anyOf": [
{
"type": "string",
"maxLength": 300
},
{
"type": "null"
}
]
},
"locale": {
"anyOf": [
{
"type": "string",
"maxLength": 50
},
{
"type": "null"
}
]
},
"wordCount": {
"anyOf": [
{
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
{
"type": "null"
}
]
},
"internalLinksKept": {
"$ref": "#/properties/article/properties/wordCount/anyOf/0"
},
"internalLinksDropped": {
"$ref": "#/properties/article/properties/wordCount/anyOf/0"
},
"imageGeneration": {
"type": "string",
"const": "disabled"
},
"published": {
"type": [
"boolean",
"null"
]
}
},
"required": [
"id",
"url",
"title",
"slug",
"locale",
"wordCount",
"internalLinksKept",
"internalLinksDropped",
"imageGeneration",
"published"
],
"additionalProperties": false
}
},
"required": [
"status",
"article"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}🟢list_blogs(limit, cursor)
Use this when someone asks which blogs they have in Polyblog, or a blog's id is needed. Returns each blog's id, name and custom domain, 25 per page by default with a cursor. Not for a blog's posts.
입력 스키마
{
"type": "object",
"properties": {
"limit": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 100,
"description": "Blogs per page, from 1 to 100; defaults to 25"
},
"cursor": {
"type": "string",
"maxLength": 4096,
"description": "The nextCursor of the previous page; absent for the first page"
}
},
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}출력 스키마
{
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"anyOf": [
{
"type": "string",
"maxLength": 200
},
{
"type": "null"
}
]
},
"name": {
"anyOf": [
{
"type": "string",
"maxLength": 200
},
{
"type": "null"
}
]
},
"customDomain": {
"anyOf": [
{
"type": "string",
"maxLength": 300
},
{
"type": "null"
}
]
}
},
"required": [
"id",
"name",
"customDomain"
],
"additionalProperties": false
},
"maxItems": 100
},
"hasMore": {
"type": "boolean"
},
"nextCursor": {
"anyOf": [
{
"type": "string",
"maxLength": 2048
},
{
"type": "null"
}
],
"description": "Cursor for the next page; null on the last page"
}
},
"required": [
"items",
"hasMore",
"nextCursor"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}🟢get_blog(idOrName)
Use this when someone asks about one blog's setup, such as its domain, default language or languages. Returns the blog's id, name, custom domain, default locale, locales, cover image URL and dates, by id or name. Not for a visual overview with recent posts.
입력 스키마
{
"type": "object",
"properties": {
"idOrName": {
"type": "string",
"minLength": 1,
"maxLength": 200,
"description": "Blog id, or the blog's name"
}
},
"required": [
"idOrName"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}출력 스키마
{
"type": "object",
"properties": {
"status": {
"type": "string",
"enum": [
"found",
"not-found"
]
},
"blog": {
"anyOf": [
{
"type": "object",
"properties": {
"id": {
"anyOf": [
{
"type": "string",
"maxLength": 200
},
{
"type": "null"
}
]
},
"name": {
"anyOf": [
{
"type": "string",
"maxLength": 200
},
{
"type": "null"
}
]
},
"customDomain": {
"anyOf": [
{
"type": "string",
"maxLength": 300
},
{
"type": "null"
}
]
},
"defaultLocale": {
"anyOf": [
{
"type": "string",
"maxLength": 50
},
{
"type": "null"
}
]
},
"locales": {
"type": "array",
"items": {
"type": "string",
"maxLength": 50
},
"maxItems": 100
},
"localesTruncated": {
"type": "boolean"
},
"coverUrl": {
"anyOf": [
{
"type": "string",
"maxLength": 2048
},
{
"type": "null"
}
]
},
"created": {
"anyOf": [
{
"type": "string",
"maxLength": 100
},
{
"type": "null"
}
]
},
"edited": {
"$ref": "#/properties/blog/anyOf/0/properties/created"
}
},
"required": [
"id",
"name",
"customDomain",
"defaultLocale",
"locales",
"localesTruncated",
"coverUrl",
"created",
"edited"
],
"additionalProperties": false
},
{
"type": "null"
}
]
}
},
"required": [
"status",
"blog"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}🟢get_blog_localization_summary(blogId)
Use this when someone asks how well their blog is translated, or which languages are missing posts. Returns per-language counts of posts, published posts and drafts with a coverage percentage, from the 100 most recently edited posts. Not for one post's translations.
입력 스키마
{
"type": "object",
"properties": {
"blogId": {
"type": "string",
"minLength": 1,
"maxLength": 200,
"description": "Blog id, or the blog's name"
}
},
"required": [
"blogId"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}출력 스키마
{
"type": "object",
"properties": {
"blog": {
"anyOf": [
{
"type": "object",
"properties": {
"name": {
"type": "string",
"maxLength": 200
},
"defaultLocale": {
"anyOf": [
{
"type": "string",
"maxLength": 50
},
{
"type": "null"
}
]
},
"configuredLocales": {
"type": "array",
"items": {
"type": "string",
"maxLength": 50
},
"maxItems": 50
},
"configuredLocalesTruncated": {
"type": "boolean"
}
},
"required": [
"name",
"defaultLocale",
"configuredLocales",
"configuredLocalesTruncated"
],
"additionalProperties": false
},
{
"type": "null"
}
]
},
"sample": {
"type": "object",
"properties": {
"articles": {
"type": "integer",
"minimum": 0
},
"translationGroups": {
"type": "integer",
"minimum": 0
},
"truncated": {
"type": "boolean"
}
},
"required": [
"articles",
"translationGroups",
"truncated"
],
"additionalProperties": false,
"description": "Coverage is computed from the 100 most recently edited posts; truncated means the blog has more"
},
"locales": {
"type": "array",
"items": {
"type": "object",
"properties": {
"locale": {
"type": "string",
"maxLength": 50
},
"configured": {
"type": "boolean"
},
"articles": {
"type": "integer",
"minimum": 0
},
"published": {
"type": "integer",
"minimum": 0
},
"drafts": {
"type": "integer",
"minimum": 0
},
"missingFromTranslationGroups": {
"type": "integer",
"minimum": 0
},
"coveragePercent": {
"type": "integer",
"minimum": 0,
"maximum": 100
}
},
"required": [
"locale",
"configured",
"articles",
"published",
"drafts",
"missingFromTranslationGroups",
"coveragePercent"
],
"additionalProperties": false
},
"maxItems": 50
}
},
"required": [
"blog",
"sample",
"locales"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}🔴create_blog(name, description, defaultLocale, locales, articlesFormat)
Use this when someone asks to start a new blog in Polyblog with a given name and languages. Returns the new blog's id, name, domain and languages; the name becomes the public <name>.polyblog.io subdomain, so a name already taken fails. Not for adding a post to an existing blog.
입력 스키마
{
"type": "object",
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 200,
"description": "Blog name, which becomes the public <name>.polyblog.io subdomain and has to be globally unique"
},
"description": {
"type": "string",
"maxLength": 600,
"description": "Short description of what the blog is about, up to 600 characters"
},
"defaultLocale": {
"type": "string",
"maxLength": 50,
"description": "Main language, an ISO 639-1 code such as en"
},
"locales": {
"type": "array",
"items": {
"$ref": "#/properties/defaultLocale"
},
"maxItems": 100,
"description": "Every language the blog publishes in, ISO 639-1 codes such as en and it"
},
"articlesFormat": {
"type": "string",
"enum": [
"markdown",
"html"
],
"description": "Format for the blog's posts: markdown or html"
}
},
"required": [
"name"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}출력 스키마
{
"type": "object",
"properties": {
"status": {
"type": "string",
"const": "created"
},
"blog": {
"type": "object",
"properties": {
"id": {
"anyOf": [
{
"type": "string",
"maxLength": 200
},
{
"type": "null"
}
]
},
"name": {
"anyOf": [
{
"type": "string",
"maxLength": 200
},
{
"type": "null"
}
]
},
"customDomain": {
"anyOf": [
{
"type": "string",
"maxLength": 300
},
{
"type": "null"
}
]
},
"defaultLocale": {
"anyOf": [
{
"type": "string",
"maxLength": 50
},
{
"type": "null"
}
]
},
"locales": {
"type": "array",
"items": {
"type": "string",
"maxLength": 50
},
"maxItems": 100
},
"localesTruncated": {
"type": "boolean"
},
"coverUrl": {
"anyOf": [
{
"type": "string",
"maxLength": 2048
},
{
"type": "null"
}
]
},
"created": {
"anyOf": [
{
"type": "string",
"maxLength": 100
},
{
"type": "null"
}
]
},
"edited": {
"$ref": "#/properties/blog/properties/created"
}
},
"required": [
"id",
"name",
"customDomain",
"defaultLocale",
"locales",
"localesTruncated",
"coverUrl",
"created",
"edited"
],
"additionalProperties": false
}
},
"required": [
"status",
"blog"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}🟢get_sitemap_urls(blogId, locale, maxUrls)
Use this when someone asks what pages their blog's sitemap lists, or which pages are available to link to. Returns the sitemap's URL count and the first 25 URLs with language and last-modified date, read live from the blog's custom domain. Not for the posts stored in Polyblog.
입력 스키마
{
"type": "object",
"properties": {
"blogId": {
"type": "string",
"minLength": 1,
"maxLength": 200,
"description": "Blog whose sitemap to read"
},
"locale": {
"type": "string",
"maxLength": 50,
"description": "Only URLs in this language, a two-letter code such as en"
},
"maxUrls": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 2000,
"description": "How many sitemap URLs to read and count, from 1 to 2,000; defaults to 500, and only the first 25 are listed"
}
},
"required": [
"blogId"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}출력 스키마
{
"type": "object",
"properties": {
"baseUrl": {
"anyOf": [
{
"type": "string",
"maxLength": 2048
},
{
"type": "null"
}
]
},
"rootSitemap": {
"$ref": "#/properties/baseUrl"
},
"childSitemaps": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"totalUrls": {
"$ref": "#/properties/childSitemaps"
},
"returned": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991,
"description": "How many sitemap URLs were read, at most maxUrls"
},
"sample": {
"type": "array",
"items": {
"type": "object",
"properties": {
"locale": {
"anyOf": [
{
"type": "string",
"maxLength": 50
},
{
"type": "null"
}
]
},
"lastmod": {
"anyOf": [
{
"type": "string",
"maxLength": 100
},
{
"type": "null"
}
]
},
"url": {
"$ref": "#/properties/baseUrl"
}
},
"required": [
"locale",
"lastmod",
"url"
],
"additionalProperties": false
},
"maxItems": 25,
"description": "The first 25 URLs read; returned counts every URL read"
},
"sampleTruncated": {
"type": "boolean"
}
},
"required": [
"baseUrl",
"rootSitemap",
"childSitemaps",
"totalUrls",
"returned",
"sample",
"sampleTruncated"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}🔴refresh_topic_ideas(blogId, sources, audience, sinceHours, limitPerSource, ...)
Use this when someone asks for new blog topic ideas from Reddit or RSS feeds. Returns counts and up to 5 of the saved ideas; it fetches the sources, scores candidates with paid AI and saves those that pass. Not for ideas already saved.
입력 스키마
{
"type": "object",
"properties": {
"blogId": {
"type": "string",
"minLength": 1,
"maxLength": 200,
"description": "Blog to find ideas for"
},
"sources": {
"type": "object",
"properties": {
"reddit": {
"type": "array",
"items": {
"type": "string",
"minLength": 1,
"maxLength": 100,
"pattern": "^[A-Za-z0-9_]+$"
},
"maxItems": 20,
"description": "Subreddit names (without /r/)"
},
"rss": {
"type": "array",
"items": {
"type": "string",
"format": "uri",
"maxLength": 2048
},
"maxItems": 20,
"description": "Full RSS / Atom feed URLs"
}
},
"additionalProperties": false,
"description": "Subreddits and RSS feeds for this run only; the blog's saved sources when absent"
},
"audience": {
"type": "string",
"maxLength": 600,
"description": "Who the blog writes for; defaults to the blog's context"
},
"sinceHours": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 8760,
"description": "How far back to read, in hours, from 1 to 8,760; defaults to 168 (7 days)"
},
"limitPerSource": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 100,
"description": "Items to read from each source, from 1 to 100; defaults to 25"
},
"minScore": {
"type": "integer",
"minimum": 0,
"maximum": 10,
"description": "Lowest AI score, 0 to 10, an idea needs to be saved; defaults to 5"
},
"perSourceCap": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 100,
"description": "Most candidates to score from each source, from 1 to 100; no cap by default"
}
},
"required": [
"blogId"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}출력 스키마
{
"type": "object",
"properties": {
"status": {
"type": "string",
"const": "refreshed"
},
"fetched": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"newCandidates": {
"$ref": "#/properties/fetched"
},
"saved": {
"$ref": "#/properties/fetched"
},
"duplicatesSkipped": {
"$ref": "#/properties/fetched"
},
"alreadyPublishedSkipped": {
"$ref": "#/properties/fetched"
},
"topIdeas": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"anyOf": [
{
"type": "string",
"maxLength": 200
},
{
"type": "null"
}
]
},
"title": {
"anyOf": [
{
"type": "string",
"maxLength": 300
},
{
"type": "null"
}
]
},
"angle": {
"anyOf": [
{
"type": "string",
"maxLength": 500
},
{
"type": "null"
}
]
},
"score": {
"anyOf": [
{
"type": "integer",
"minimum": 0,
"maximum": 10
},
{
"type": "null"
}
]
}
},
"required": [
"id",
"title",
"angle",
"score"
],
"additionalProperties": false
},
"maxItems": 5
},
"topIdeasTruncated": {
"type": "boolean"
},
"sourceErrorCount": {
"$ref": "#/properties/fetched"
},
"sourceErrorDetailsSuppressed": {
"type": "boolean",
"const": true
}
},
"required": [
"status",
"fetched",
"newCandidates",
"saved",
"duplicatesSkipped",
"alreadyPublishedSkipped",
"topIdeas",
"topIdeasTruncated",
"sourceErrorCount",
"sourceErrorDetailsSuppressed"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}🟢list_topic_ideas(blogId, status, minScore, limit, cursor)
Use this when someone asks what they could write about next from topic ideas already saved. Returns each idea's id, score out of 10, title, status and source, filtered by status or minimum score, 25 per page by default. Not for fetching new ideas.
입력 스키마
{
"type": "object",
"properties": {
"blogId": {
"type": "string",
"minLength": 1,
"maxLength": 200,
"description": "Blog whose ideas to list"
},
"status": {
"type": "string",
"enum": [
"new",
"used",
"dismissed"
],
"description": "Only ideas with this status: new, used or dismissed; omit for all"
},
"minScore": {
"type": "integer",
"minimum": 0,
"maximum": 10,
"description": "Only ideas with at least this AI score, 0 to 10"
},
"limit": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 100,
"description": "Ideas per page, from 1 to 100; defaults to 25"
},
"cursor": {
"type": "string",
"maxLength": 4096,
"description": "The nextCursor of the previous page with the same filters; absent for the first page"
}
},
"required": [
"blogId"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}출력 스키마
{
"type": "object",
"properties": {
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"anyOf": [
{
"type": "string",
"maxLength": 200
},
{
"type": "null"
}
]
},
"title": {
"anyOf": [
{
"type": "string",
"maxLength": 300
},
{
"type": "null"
}
]
},
"score": {
"anyOf": [
{
"type": "integer",
"minimum": 0,
"maximum": 10
},
{
"type": "null"
}
]
},
"status": {
"type": "string",
"enum": [
"new",
"used",
"dismissed",
"unknown"
]
},
"source": {
"anyOf": [
{
"type": "string",
"maxLength": 300
},
{
"type": "null"
}
]
}
},
"required": [
"id",
"title",
"score",
"status",
"source"
],
"additionalProperties": false
},
"maxItems": 100
},
"hasMore": {
"type": "boolean"
},
"nextCursor": {
"anyOf": [
{
"type": "string",
"maxLength": 2048
},
{
"type": "null"
}
],
"description": "Cursor for the next page; null on the last page"
}
},
"required": [
"items",
"hasMore",
"nextCursor"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}🔴set_topic_idea_status(topicIdeaId, status, usedForArticleId)
Use this when someone asks to mark a topic idea as used, dismiss it, or bring it back as new. Returns the idea with its new status and, when given, the article it produced; nothing else about the idea changes. Not for editing an idea's title or angle.
입력 스키마
{
"type": "object",
"properties": {
"topicIdeaId": {
"type": "string",
"minLength": 1,
"maxLength": 200,
"description": "Topic idea id"
},
"status": {
"type": "string",
"enum": [
"new",
"used",
"dismissed"
],
"description": "New status: new, used or dismissed"
},
"usedForArticleId": {
"type": "string",
"maxLength": 200,
"description": "Id of the article written from this idea; only with status used"
}
},
"required": [
"topicIdeaId",
"status"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}출력 스키마
{
"type": "object",
"properties": {
"status": {
"type": "string",
"const": "updated"
},
"topicIdea": {
"type": "object",
"properties": {
"id": {
"anyOf": [
{
"type": "string",
"maxLength": 200
},
{
"type": "null"
}
]
},
"title": {
"anyOf": [
{
"type": "string",
"maxLength": 300
},
{
"type": "null"
}
]
},
"score": {
"anyOf": [
{
"type": "integer",
"minimum": 0,
"maximum": 10
},
{
"type": "null"
}
]
},
"status": {
"type": "string",
"enum": [
"new",
"used",
"dismissed",
"unknown"
]
},
"usedForArticleId": {
"$ref": "#/properties/topicIdea/properties/id"
}
},
"required": [
"id",
"title",
"score",
"status",
"usedForArticleId"
],
"additionalProperties": false
}
},
"required": [
"status",
"topicIdea"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}🔴set_topic_sources(blogId, reddit, rss, clear)
Use this when someone asks to choose which subreddits or RSS feeds their blog's topic research reads. Returns the saved sources; each list passed replaces the old one, and clear removes them all. Not for fetching ideas now.
입력 스키마
{
"type": "object",
"properties": {
"blogId": {
"type": "string",
"minLength": 1,
"maxLength": 200,
"description": "Blog id, or the blog's name"
},
"reddit": {
"type": "array",
"items": {
"type": "string",
"minLength": 1,
"maxLength": 100,
"pattern": "^[A-Za-z0-9_]+$"
},
"maxItems": 20,
"description": "Complete new list of up to 20 subreddit names, without /r/; replaces the old list"
},
"rss": {
"type": "array",
"items": {
"type": "string",
"format": "uri",
"maxLength": 2048
},
"maxItems": 20,
"description": "Complete new list of up to 20 HTTPS RSS or Atom feed URLs; replaces the old list"
},
"clear": {
"type": "boolean",
"description": "true removes every saved source"
}
},
"required": [
"blogId"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}출력 스키마
{
"type": "object",
"properties": {
"status": {
"type": "string",
"enum": [
"updated",
"not-found"
]
},
"blog": {
"anyOf": [
{
"type": "object",
"properties": {
"id": {
"anyOf": [
{
"type": "string",
"maxLength": 200
},
{
"type": "null"
}
]
},
"name": {
"anyOf": [
{
"type": "string",
"maxLength": 200
},
{
"type": "null"
}
]
},
"reddit": {
"type": "array",
"items": {
"type": "string",
"maxLength": 100
},
"maxItems": 20
},
"rss": {
"type": "array",
"items": {
"type": "string",
"maxLength": 2048
},
"maxItems": 20
},
"redditTruncated": {
"type": "boolean"
},
"rssTruncated": {
"type": "boolean"
}
},
"required": [
"id",
"name",
"reddit",
"rss",
"redditTruncated",
"rssTruncated"
],
"additionalProperties": false
},
{
"type": "null"
}
]
}
},
"required": [
"status",
"blog"
],
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
}🟢show_blog_overview(blogId)
Use this when someone wants a quick overview of one of their blogs. Returns an overview card with the blog's domain, languages and up to 10 most recently edited posts. Not for translation coverage.
입력 스키마
{
"type": "object",
"properties": {
"blogId": {
"type": "string",
"minLength": 1,
"maxLength": 200,
"description": "Polyblog blog id to render, at most 200 characters"
}
},
"required": [
"blogId"
],
"$schema": "https://json-schema.org/draft/2020-12/schema"
}출력 스키마
{
"type": "object",
"properties": {
"blog": {
"anyOf": [
{
"type": "object",
"properties": {
"id": {
"anyOf": [
{
"type": "string",
"maxLength": 200
},
{
"type": "null"
}
]
},
"name": {
"type": "string",
"maxLength": 200
},
"customDomain": {
"anyOf": [
{
"type": "string",
"maxLength": 300
},
{
"type": "null"
}
]
},
"defaultLocale": {
"anyOf": [
{
"type": "string",
"maxLength": 50
},
{
"type": "null"
}
]
},
"locales": {
"maxItems": 100,
"type": "array",
"items": {
"type": "string",
"maxLength": 50
}
}
},
"required": [
"id",
"name",
"customDomain",
"defaultLocale",
"locales"
],
"additionalProperties": false
},
{
"type": "null"
}
]
},
"articles": {
"maxItems": 10,
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"anyOf": [
{
"type": "string",
"maxLength": 200
},
{
"type": "null"
}
]
},
"title": {
"type": "string",
"maxLength": 300
},
"slug": {
"anyOf": [
{
"type": "string",
"maxLength": 300
},
{
"type": "null"
}
]
},
"locale": {
"anyOf": [
{
"type": "string",
"maxLength": 50
},
{
"type": "null"
}
]
},
"published": {
"type": "boolean"
},
"lastEditTime": {
"anyOf": [
{
"type": "string",
"maxLength": 100
},
{
"type": "null"
}
]
}
},
"required": [
"id",
"title",
"slug",
"locale",
"published",
"lastEditTime"
],
"additionalProperties": false
}
},
"hasMoreArticles": {
"type": "boolean"
}
},
"required": [
"blog",
"articles",
"hasMoreArticles"
],
"$schema": "https://json-schema.org/draft/2020-12/schema",
"additionalProperties": false
}🟢show_article_preview(articleId)
Use this when someone wants to see how one blog post looks, with its status and details. Returns a preview card with the post's title, language, published state, metadata and up to 6,000 characters of content. Not for finding posts.
입력 스키마
{
"type": "object",
"properties": {
"articleId": {
"type": "string",
"minLength": 1,
"maxLength": 200,
"description": "Polyblog article id to preview, at most 200 characters"
}
},
"required": [
"articleId"
],
"$schema": "https://json-schema.org/draft/2020-12/schema"
}출력 스키마
{
"type": "object",
"properties": {
"article": {
"anyOf": [
{
"type": "object",
"properties": {
"id": {
"anyOf": [
{
"type": "string",
"maxLength": 200
},
{
"type": "null"
}
]
},
"blogId": {
"anyOf": [
{
"type": "string",
"maxLength": 200
},
{
"type": "null"
}
]
},
"title": {
"type": "string",
"maxLength": 300
},
"description": {
"anyOf": [
{
"type": "string",
"maxLength": 1000
},
{
"type": "null"
}
]
},
"contentPreview": {
"type": "string",
"maxLength": 6000
},
"contentTruncated": {
"type": "boolean"
},
"format": {
"anyOf": [
{
"type": "string",
"maxLength": 20
},
{
"type": "null"
}
]
},
"locale": {
"anyOf": [
{
"type": "string",
"maxLength": 50
},
{
"type": "null"
}
]
},
"slug": {
"anyOf": [
{
"type": "string",
"maxLength": 300
},
{
"type": "null"
}
]
},
"published": {
"type": "boolean"
},
"coverUrl": {
"anyOf": [
{
"type": "string",
"maxLength": 2048
},
{
"type": "null"
}
]
},
"lastEditTime": {
"anyOf": [
{
"type": "string",
"maxLength": 100
},
{
"type": "null"
}
]
}
},
"required": [
"id",
"blogId",
"title",
"description",
"contentPreview",
"contentTruncated",
"format",
"locale",
"slug",
"published",
"coverUrl",
"lastEditTime"
],
"additionalProperties": false
},
{
"type": "null"
}
]
}
},
"required": [
"article"
],
"$schema": "https://json-schema.org/draft/2020-12/schema",
"additionalProperties": false
}권장 프롬프트
search_articlessearch_articlesget_articleget_articlelist_article_translations커뮤니티
증거