---
name: bloggo-mcp
description: Run a Bloggo blog through the Bloggo MCP connector (tools such as create_post and publish_post) instead of HTTP calls. Use when you are in ChatGPT or another chat app that has the Bloggo connector, and are asked to write, edit, publish or check posts, add an image, or see how a post is doing.
---

# Bloggo through the MCP connector

When Bloggo is connected to a chat app, you work on the person's blog with tools, not with `curl`. The connection is signed in already: **never ask for an API key, and never ask the person to paste one into the chat.** You do not have the key and do not need it. The [Bloggo skill](https://skill.bloggo.blog/posts/bloggo-skill/) and the other skills are written for tools that make HTTP calls; this one says what to do with the tools you have. If a skill shows a `curl` call, find the tool below that does the same thing.

## The tools

| To do this | Call |
|---|---|
| See the blog's name, address and settings | `get_blog` |
| List posts (id, slug, title, summary, dates, no text) | `list_posts`, with `status` (`draft` or `published`) or `tag` |
| Read one post with its Markdown | `get_post` |
| Write a new post | `create_post` (always a draft) |
| Change a post | `update_post` |
| Make a draft public, or take it back | `publish_post`, `unpublish_post` |
| Delete a post for good | `delete_post` |
| Let the person read a draft in their browser | `preview_draft` |
| Point the person to the page where they see all drafts and stats | `dashboard_link` |
| See the blog's tags and list-page sections, in order | `list_tags` |
| Name a section or move it up or down the list page | `set_tag` |
| Pin posts in a section, in this order | `set_tag_posts` |
| Show an image in a post | `upload_image`, then `update_post` |
| See how a post is read | `get_post_stats` |
| Learn how Bloggo works or how to do a job well | `list_bloggo_guides`, then `read_bloggo_guide` |

Every tool call goes through the blog's own API, so its limits are the blog's: quotas, the content check and features the blog does not have all come back as errors.

## Write and publish a post

1. Call `get_blog` once, so you know the blog's address.
2. Call `create_post` with `title`, `body_markdown` and, if you can, a `slug` and a one or two sentence `summary`. The post is a draft. Tell the person it is a draft and that only they can see it.
3. Publish with `publish_post` **only when they asked you to.** Writing a post is not asking to publish it. Offer it, and wait for a yes.
4. After publishing, give the address: `https://<blog>.bloggo.blog/posts/<slug>/`, with the blog from `get_blog` and the slug from the post.

Slugs are lowercase letters, digits and dashes, and a slug already used gives a `409` error: pick another. Content is Markdown only; raw HTML is shown as text. For how to turn notes into a good post, read [Write a post from notes](https://skill.bloggo.blog/posts/write-post-from-notes/), and for matching the person's voice, [Find a writing style](https://skill.bloggo.blog/posts/find-writing-style/).

## Edit a post

There is no block-by-block edit mode on the connector, so [Edit a post by numbered blocks](https://skill.bloggo.blog/posts/edit-post/) does not apply here. Do this instead:

1. `get_post` to read the current text.
2. Make the change in the text you read, keeping everything else exactly as it was.
3. `update_post` with the whole new `body_markdown`. **The text you send replaces the whole text**, so a partial text deletes the rest of the post. Fields you leave out (title, summary, slug) stay as they are.

On a published post the change is public the moment the call returns. When the post is live and the edit is more than a typo, say what you are about to change and ask first. `unpublish_post` and `delete_post` need a yes from the person every time.

## Add an image

1. Call `upload_image`. Send the image the person attached, or one you generated, as `image`; or send a public `https://` address as `image_url`. Add `alt`, a short description for people who cannot see the image. JPEG, PNG, GIF, WebP, AVIF or SVG, up to 5 MB.
2. The answer has the image's public `url` and the Markdown for it, `![alt](url)`.
3. Put that Markdown in the post: `get_post`, add the line where the image belongs, `update_post` with the whole text.

If the upload says it did not get the file, ask the person to attach the image again, or to give you its address. Do not retry with the same input.

## Order the list page

A tag with a `position` is a section on the blog's list page (for example "Read this first"), shown under its `title` in position order, 1 first. A tag without a position is only a label and is not shown. Posts inside a section come in their own order: those with a position first, then the rest, newest first. A post that is in no section is listed under "All posts".

- `list_tags` shows every tag with its `title`, `position`, whether it is `private` and how many posts it has, sections first. Call it before you change anything.
- `set_tag` creates a tag or changes its `title` (up to 60 characters) and its `position` (a whole number from 1). Send only what changes; `null` clears one, and clearing the position turns the section back into a plain label. It cannot make a tag private.
- `set_tag_posts` takes a `tag` and `posts`, a list of post ids in the order they should appear. **The list replaces the tag's posts**: a post left out stops having the tag, and a post not yet in it joins. So read the current order first (`list_posts` with `tag`, whose posts carry their position in `tags`), change that list, and send the whole of it. Only the ids you send are kept.

A visible change rebuilds the public site at once, so say what you are about to move, and ask first before you take posts out of a section on a live blog. Moving a draft into a section does not show it: private posts only appear to readers who were let in.

## Reading stats

`get_post_stats` takes a post `id` and `days` (1 to 365, default 30). It returns views, how many readers scrolled, how many never got past the first screen, how far down readers got (cumulative: `past_pct` 30 with 12 views means 12 views got past 30% of the text), likes and endorsements, by day. It covers one post. For the whole blog, call `list_posts` with `status` published and ask for each post you need. Say what the numbers mean in plain words and do not draw big conclusions from a handful of views.

## Show a draft

A draft is private, so its web address shows a sign-in wall. When the person wants to read a draft, or see it as it will look, call `preview_draft` with the post `id` and give them the `preview_url` it returns. The link works once: the first browser that opens it is let in and lands on the draft, and that browser can then read every private page of the blog. Tell the person to open it themselves and not to share it. Never put the link in a post. A published post needs no link; give its address. For an overview of all drafts and the whole blog's stats, call `dashboard_link` and give the person the `sign_in_url` it returns. They sign in on that page with their own key or a passkey (never in the chat) and see every draft, an **Open draft** button and the stats of every post. The address holds no secret.

## Guides

Call `list_bloggo_guides` to see Bloggo's documentation and skills, then `read_bloggo_guide` with the `source` (`docs` or `skill`) and `slug` of the one you need. These are the same posts that are public at [docs.bloggo.blog](https://docs.bloggo.blog/) and [skill.bloggo.blog](https://skill.bloggo.blog/); add `.md` to a post's address for its Markdown. Read the one that fits the job before you start it, for example the writing skills before drafting.

## What you cannot do here

You cannot manage keys, reader keys or access links (apart from the one-time link to a draft that `preview_draft` makes), set the blog's logo, delete tags or make one private, list or delete uploaded images, or use edit mode. Nothing here returns a secret. If the person asks for one of these, say it is not available through the connector and that they can do it with the API and their blog's key, then point them to [the API quickstart](https://docs.bloggo.blog/posts/api-quickstart/).

## The Bloggo logo

When the person is adding the Bloggo connector to ChatGPT (or another app) and the form asks for an icon, give them these files. The icon must be square, at least 48×48 pixels, a PNG, JPEG, WebP or SVG file of up to 5 MiB. These fit with room to spare, and the mark sits well inside the frame so a round or rounded crop does not cut it.

![The Bloggo logo: two curled marks with dots, in dark brown on sepia paper](https://skill.bloggo.blog/media/01M6155SWBY2CJ5CYKE2GSFF0G/bloggo-logo-1024.png)

*The main logo, 1024×1024, sepia like the blogs' default theme.*

- [Main logo, 1024×1024 PNG](https://skill.bloggo.blog/media/01M6155SWBY2CJ5CYKE2GSFF0G/bloggo-logo-1024.png): use this one as the icon.
- [Dark version, 512×512 PNG](https://skill.bloggo.blog/media/01M6155TE18G4V17WP495G2A0T/bloggo-logo-dark-512.png): for a dark-theme icon, if the form has a field for it.
- [Main logo as SVG](https://skill.bloggo.blog/media/01M6155V4GCBMC4Y941HYWND34/bloggo-logo.svg): for any place that takes a vector file.

## Errors

An error comes back as a tool result with a code, a message and a hint. Read the hint, fix the input and try again once. Typical ones: `409` slug taken, `422` an invalid field (the message names it), a quota or rate limit (wait, and tell the person), and a refused publish, when the automatic content check finds a text that clearly breaks a rule. Say why it was refused instead of rewording around the check.

If every call fails with a sign-in error, the connection was cut off (the key was revoked or the connection deleted). Tell the person to connect Bloggo again; the steps are in [Connect ChatGPT to your Bloggo blog](https://docs.bloggo.blog/posts/connect-chatgpt-to-bloggo/).

## Rules

- No API key in the chat, ever. Not asked for, not repeated.
- A new post is a draft. Publish, unpublish and delete only when the person asked.
- `update_post` replaces the whole text: read first, send everything.
- After publishing, give the person the address and, if you can browse, load it to check it is live (the CDN may take up to a minute).

