# Posy: full guide for AI agents

Site: https://posy.page

# Connect an AI to Posy

Posy has a hosted MCP server, so an AI can make and edit your page: "make me a link in bio page", "add my latest video", "switch to the dark look".
Everything an AI does lands in your **draft**. Nothing goes live until you (or it, when you ask) publish.

The server is `https://posy.page/api/mcp`. On the hosted Posy that is `https://posy.page/api/mcp`. You sign in with your Posy account, so there is no key to copy.

<!-- docs-site: install-buttons -->

## Claude (claude.ai, Desktop and mobile)

Settings → Connectors → **Add custom connector** → name it Posy, paste the URL, then sign in to Posy when asked.

## ChatGPT

Settings → Apps & Connectors → Advanced → turn on Developer mode → **Create** → paste the URL, choose OAuth, and sign in to Posy.

## Claude Code

```bash
claude mcp add --transport http posy https://posy.page/api/mcp
```

Then run `/mcp` inside Claude Code and choose **Authenticate**. Or install the plugin, which adds a "make a page" skill:

```
/plugin marketplace add Himanshu-Sangshetti/posy
/plugin install posy@posy
```

## Cursor, VS Code, Codex

- **Cursor:** use the one-click install, or add the config below by hand.
- **VS Code:** `code --add-mcp '{"name":"posy","type":"http","url":"https://posy.page/api/mcp"}'`
- **Codex:** `codex mcp add posy --url https://posy.page/api/mcp`

<!-- docs-site: skip -->
### Cursor: one click

[Add Posy to Cursor](cursor://anysphere.cursor-deeplink/mcp/install?name=posy&config=eyJ1cmwiOiJodHRwczovL3Bvc3kucGFnZS9hcGkvbWNwIn0=)

That link installs `https://posy.page/api/mcp`. Cursor then asks you to sign in to Posy. For your own server, use the config below.
<!-- /docs-site: skip -->

### A config file

Cursor reads `~/.cursor/mcp.json` (or `.cursor/mcp.json` in a project). Other tools use `.mcp.json` in the project folder. Add this:

```json
{
  "mcpServers": {
    "posy": { "url": "https://posy.page/api/mcp" }
  }
}
```

In Claude Code's `.mcp.json`, add `"type": "http"` next to `url`. On your own server, change the URL to `https://posy.page/api/mcp`.

## An API key instead

Scripts and tools that cannot open a browser can use a key from the dashboard's **Agents** page:

```bash
claude mcp add --transport http posy https://posy.page/api/mcp --header "Authorization: Bearer posy_..."
```

## No connector? Use a file

Any chat can write your page as a small JSON file, which you load at `/new`. See [the page file](/docs/format).

## What an AI can do

| tool | what it does |
|---|---|
| `get_page` | Your draft, public URL, and what to do next. |
| `create_page` | Claim a username and create your page (once). |
| `import_page` | Load a whole page from a [page file](/docs/format). |
| `add_tile` | Add one link, or many at once with `inputs`. Posy picks the right tile. |
| `update_tile`, `move_tile`, `remove_tile` | Change, reorder or delete a tile. |
| `set_theme`, `set_profile` | Look, colours, fonts, name and bio. |
| `publish` | Make the draft live. |
| `list_options` | Allowed looks, themes, fonts and sizes. |

The looks an agent can pick (`style`): `painted` (the default), `cozy` (Desk), `washi`, `lofi`, `cobalt` and `night`. On posy.page, Painted, Desk and Cobalt are free and the other three come with Pro.

More: [the full guide](https://github.com/Himanshu-Sangshetti/posy/blob/main/docs/ai-agents.md).


---

# The Posy page file

A Posy page can be one small JSON file. Any chat (ChatGPT, Claude, Gemini, a local model) can write it, and anyone can load it
at [`/new`](/new), in the editor (Import), or through the API. No connector or account is needed to preview it.

## The easy way

1. Open [`/new`](/new) and press **Copy a prompt for your chat**.
2. Paste the prompt into your chat and answer its questions (name, bio, links, vibe).
3. Paste the JSON it returns back into the box on `/new`. Check the preview, then **Make it mine**.

## The one-link way

An agent that can only write text can hand over a normal link. No JSON, no encoding:

```
/new?name=Mira%20Sol&bio=Illustrator&links=https://github.com/mira,hi@mira.so,mira/atlas
```

It opens a live preview, and one button makes the page yours. Fields: `name`, `bio`, `links` (comma-separated URLs, emails or `owner/repo`), `username`, `look`, `theme`, `layout`, `location`, `avatar`, `photos`, `font`, `backdrop`.

## The brief

```json
{
  "posy": 1,
  "username": "mira",
  "name": "Mira Sol",
  "bio": "Illustrator making small, soft things",
  "location": "Lisbon",
  "look": "washi",
  "theme": "kinari",
  "photos": "mono",
  "links": [
    { "heading": "Find me" },
    "https://github.com/mira",
    "hi@mira.so",
    { "heading": "Work" },
    { "url": "https://mira.so/portfolio", "title": "Portfolio", "size": "w" },
    "mira/atlas",
    { "text": "Open for commissions" },
    { "stamp": "Say hello" },
    { "image": "/samples/tea.jpg", "focus": { "x": 40, "y": 30 }, "zoom": 1.5 }
  ]
}
```

| field | meaning |
|---|---|
| `name` | Required. Display name. |
| `links` | Required. In order. A string is a URL, an email, `owner/repo` or a short note: Posy picks the right tile (GitHub repo, YouTube, Spotify, social profile, link). |
| `username` | Optional. The address, `/<username>`. 3–30 letters, numbers, `-` or `_`. You can choose it when you load the file. |
| `bio`, `location`, `avatar` | Optional. `avatar` is an image URL. |
| `look` | Optional. The look of the page: `painted`, `cozy` (Desk), `washi`, `lofi`, `cobalt` or `night`. Default `painted`. On posy.page, Painted, Desk and Cobalt are free and the others are Pro. |
| `theme` | Optional. Colours. Each look has four palettes, listed in `/schema/brief.schema.json`. The first is the default (`washi`: `kinari`, `sakura`, `yomogi`, `sumi`). |
| `layout` | Optional. `bento` (Grid, the default: the look's own arrangement), `list` (one column, the phone arrangement on every screen) or `canvas` (free placement). Every look follows it. |
| `photos` | Optional. How photos are printed: `natural`, `mono`, `dither` or `ascii`. |
| `font` | Optional. A typeface id (the allowed values are in `/schema/brief.schema.json`). |
| `backdrop` | Optional. `solid`, `dots`, `grid`, or an image URL or `/path`. |

A link can also be an object: `{"heading": "…"}` starts a section, `{"text": "…"}` is a note, and `{"url": "…", "title": "…", "description": "…", "size": "w", "color": "…"}` overrides how one tile looks. Give each object exactly one of `url`, `email`, `repo`, `heading`, `text`, `stamp` or `image`.

- `{"stamp": "Say hello"}` is a short round badge (a note with `look: "stamp"`).
- `{"image": "https://…/me.jpg", "caption": "…", "url": "https://…"}` is a picture; `url` (optional) makes it clickable. A bare image address in `links` (`"/samples/tea.jpg"`, `"http://localhost:3000/a.png"`, anything ending in jpg, png, webp, gif, avif or svg) becomes a picture too.
- `focus` (`{"x": 0–100, "y": 0–100}`, the point to keep in view) and `zoom` (1–3) crop a picture. They work on `image` and on links, videos and music with a preview image. `size` is `s` (small), `w` (wide), `t` (tall) or `l` (large).

Posy is forgiving. It accepts the JSON wrapped in prose or a code fence, smart quotes and trailing commas. Unknown fields and small mistakes become
warnings, not errors. If something is really wrong, the message says what to ask your chat to fix.

## The full page file

The JSON that Posy exports (Settings → Export) works too: it is the complete page (profile, theme, every tile with its id, size and position).
Its format is [`/schema/page.schema.json`](/schema/page.schema.json). Use the brief when a chat writes the page, and the full file to move a page between Posy sites.

## For agents and scripts

- Schema: [`/schema/brief.schema.json`](/schema/brief.schema.json)
- REST: `POST /api/v1/page/import` with `{ "file": <brief or text>, "username": "mira", "replace": false }`. Creates the page, or with `replace: true` overwrites the draft.
- MCP: the `import_page` tool takes the same arguments.
- Theme only: `PATCH /api/v1/page/theme` (see [ai-agents](ai-agents.md#rest-and-public-json)).
- A link that opens a ready-made preview: `/new#p=<base64url of the brief>`. Handing a user this link means they never need to copy anything.

