# MCP server

> The address, sign-in and tools of Ownsite's MCP server, for anyone setting up an AI client.

Ownsite's MCP server lets any MCP client work on a person's site, within the permissions that person set. For step-by-step setup in ChatGPT, Claude and others, see [Connect your AI](https://docs.ownsite.me/connect-ai).

## Server

| | |
|---|---|
| Address | `https://mcp.ownsite.me/mcp` |
| Transport | Streamable HTTP |
| Sign-in | OAuth 2.1 with PKCE, through `auth.ownsite.me` |

The person signs in with their Ownsite email, chooses a site, and presses **Allow**. The connection then acts as that person, limited by their [AI permissions](https://docs.ownsite.me/ai-permissions). Changing those permissions takes effect on the next call, without reconnecting.

## How tools behave

- **Nothing goes live by itself.** New versions and new posts are always drafts. Tools that change what visitors see (`publish_version`, `unpublish_home`, `publish_post`, `unpublish_post`) either act, or return a pending confirmation that the person answers in their app, depending on their permissions.
- **Nothing is deleted.** Versions are set aside, not deleted, and journal entries cannot be deleted.
- **Retries are safe.** Tools that create things take an optional `client_token`. Retrying with the same token doesn't create a second one.
- **Every action is recorded** in the person's **Recent changes**, with the client's name.

## Tools

| Tool | What it does |
|---|---|
| `list_sites` | The sites this connection can use, and what it may do on each. |
| `get_home` | The home page: its addresses, the live version, the version being worked on (the default base for changes) and the newest versions. |
| `list_versions` | Versions of the home page, newest first, with who made them and their preview links. |
| `read_files` | Without paths: the list of files of a version (SOURCE files you can edit; PUBLIC files such as photos the page can point to, e.g. |
| `create_version` | Makes a new draft version from a base version (default: the one being worked on) or a template, and a list of changes; builds it and photographs it (desktop and phone). |
| `list_templates` | The templates a home page (or, with page, any page) can start from (create_version with template_id). |
| `get_version` | A version: its status (BUILDING, READY, FAILED), preview link, screenshots and build error. |
| `set_version_hidden` | Sets a version aside (the person did not want it) or restores it. |
| `publish_version` | Puts a READY version on the public home page, worldwide within seconds. |
| `unpublish_home` | Takes the home page off its public addresses (the address then shows the default home: name, intro, latest posts), or with page: takes that page offline. |
| `create_page` | Makes a new, empty page of the site at <domain>/<page>/ (e.g. |
| `create_upload` | Gets an address to upload a photo to (PUT the bytes, e.g. |
| `get_blog` | The blog: its name, language (write in it), whether it is public, its addresses and its categories (ids for posts). |
| `update_blog` | Sets the blog's name, the line under it (tagline) and its look (theme: paper, magazine or minimal). |
| `list_posts` | Posts, newest first: slug, title, status (DRAFT, PUBLISHED, PRIVATE), date, categories. |
| `read_post` | A whole post: its Markdown, status, links and etag (pass the etag to update_post). |
| `create_post` | Writes a new post as a DRAFT (readers do not see it). |
| `update_post` | Changes the fields given (title, body, date, categories, cover); the post's status stays. |
| `publish_post` | Makes a post public on the blog (readers see it at once when the blog is public). |
| `unpublish_post` | Makes a published post a draft again (readers no longer see it). |
| `upload_post_image` | Gets an address to PUT one photo to (with the returned curl command, at most 4 MB); or, with upload_id (a photo already uploaded, e.g. |
| `list_categories` | The blog's categories (at most two levels), with how many posts each has, and the rev to pass to update_categories. |
| `update_categories` | Saves the whole category tree (order = display order; a category's id is its address and never changes on rename). |
| `list_journal` | The person's private journal, newest day first: id, date, kind, title, the first lines, mood, tags. |
| `search_journal` | Journal entries with every word of the query (in the text or a tag), newest first. |
| `read_journal_entry` | One whole journal entry: its text, answers, mood, tags, photo links (signed, one hour) and rev (pass it to update_journal_entry). |
| `create_journal_entry` | Writes a new private journal entry (only the person sees it). |
| `update_journal_entry` | Changes the fields given; the rest stays. |
| `add_block` | Adds a block: a part of a page that stores things, managed by the person in the app under a tab of its own named label (留言, 作品, 报名). |
| `get_page_data` | What a page stores: its blocks (each a collection: its tab name label, rules in plain lines, record count, and how many places on the live page show it, from data-block="<name>" marks) and its settings (visibility public\|private, lang, render). |
| `set_page_settings` | Advanced: sets the page's collections directly (prefer add_block for a new block). |
| `list_settings_changes` | The page's settings changes, newest first (the last 50): rev, when, who (the person or which AI), and what changed in plain words (lines). |
| `undo_settings_change` | Puts the page's settings back to how they were before change rev (from list_settings_changes); later changes are undone with it, so tell the person which. |
| `list_records` | Records of a collection, newest first (or by an index field: index, value, order asc\|desc). |
| `get_record` | One record and its rev (pass it to update_record / delete_record). |
| `create_record` | Adds a record as the person (the site's owner). |
| `update_record` | Changes the fields given (the rest stays). |
| `delete_record` | Deletes a record (kept in its history, the person can bring it back in the app). |
| `get_site_status` | The site's addresses, its own domain and its state, what is public (home page, each page, the blog), the app address, and what AIs may do on each part (aiPermissions). |
| `get_visitors` | Views and visitors per day for the last days (default 30, at most 90), the totals and the most read pages. |
| `list_pending_approvals` | Actions AIs asked for that wait for the person to confirm in their Ownsite app (e.g. |
| `search_manual` | Searches Ownsite's own manual (in Chinese): how the person's app works (home versions, publishing, the blog, pages, the journal, own domain, visitors, connecting an AI, account). |
| `read_manual_article` | One whole article of the Ownsite manual, by its id from search_manual: its title, section, the app path it is about and the body (Markdown, Chinese). |

## Rules every client follows

See [Who can change what](https://docs.ownsite.me/rules) for the full table of what an AI may do directly, what needs the person's confirmation, and what only the person can do.
