Docs

Tools and API

Chaviar Connect is a remote MCP server at https://connect.chaviar.app/mcp. Your assistant discovers these tools automatically; this page is for the curious and for anyone scripting against it.

list_brands

read-only

The brands this connection may act on, with website, Connect plan (connect_plan key + plan_label: Paid, Free or Not on Connect), connected channels and creation date (to tell same-named brands apart).

get_brand

read-only

Voice, positioning, audience, palette, fonts, logo, per-platform voice, topic directions and rules. Read this before writing or directing any content.

brand_id? string
Which brand to act on. Optional when the connection covers exactly one brand (see list_brands).

list_brand_rules

read-only

The owner's standing rules for this brand ("Always end with our booking link", "Never mention prices"), each with rule_id, rule, kind (always, never, or null = a hard constraint) and added_at. Chaviar's own generation follows them, and so must you. get_brand `rules` also includes rules read from the website, which the owner manages in Chaviar.

brand_id? string
Which brand to act on. Optional when the connection covers exactly one brand (see list_brands).

add_brand_rule

Save a standing rule the owner just stated ("always…", "never…") so Chaviar and you follow it on everything from now on. Only when the owner gives a lasting instruction — not for a one-off edit to one post, and never a rule you made up. Pass kind "always" for something every post must do, "never" for a prohibition. Then confirm the saved rule back to the owner. At most 200 characters; duplicates are refused.

brand_id? string
Which brand to act on. Optional when the connection covers exactly one brand (see list_brands).
rule string
The rule in the owner's words, e.g. "Never mention discounts". At most 200 characters.
kind? always | never

remove_brand_rule

asks first

Delete one of the owner's saved rules by rule_id (from list_brand_rules) — only when the owner asks to drop it. Confirm back which rule was removed.

brand_id? string
Which brand to act on. Optional when the connection covers exactly one brand (see list_brands).
rule_id string

get_inspiration

read-only

The brand's own photo gallery (with media ids usable as render references or post images) and its most recent published posts.

brand_id? string
Which brand to act on. Optional when the connection covers exactly one brand (see list_brands).
limit? integer

list_channels

read-only

Every social channel with whether it is connected, whether the owner paused it (paused: still connected, but nothing posts there until they resume — schedule_post refuses with channel_paused), which kinds it accepts and its caption limit.

brand_id? string
Which brand to act on. Optional when the connection covers exactly one brand (see list_brands).

get_calendar

read-only

Everything planned, proposed, scheduled and published in a date range (max 90 days): autopilot posts, agent drafts with a proposed time, and the owner's own. Each item has content_id, local date/time, starts_at (ISO), platform, status, source and a caption preview. from/to are YYYY-MM-DD in the brand timezone (returned as `timezone`).

brand_id? string
Which brand to act on. Optional when the connection covers exactly one brand (see list_brands).
from string
to string

list_content

read-only

Recent posts and drafts, newest first, each with status, proposed_for and review_url. Filter by kind, platform or status (awaiting_review, scheduled, publishing, published, failed, skipped = declined or cancelled, paused = its channel is paused by the owner or disconnected, so it will not go out); page with `before`.

brand_id? string
Which brand to act on. Optional when the connection covers exactly one brand (see list_brands).
kind? post | story | reel | ad | email
platform? ig | fb | th | in | x | gbp | bsky
status? awaiting_review | scheduled | publishing | published | failed | skipped | paused
limit? integer
before? string
next_before from the previous page

get_content

read-only

One post or draft with its media, caption, status (awaiting_review, scheduled, publishing, published, failed, skipped, paused), proposed_for, schedule and review_url (the owner's review page).

brand_id? string
Which brand to act on. Optional when the connection covers exactly one brand (see list_brands).
content_id string

update_caption

Replace the caption of an unpublished post or draft. Must fit the channel's caption limit.

brand_id? string
Which brand to act on. Optional when the connection covers exactly one brand (see list_brands).
content_id string
caption string

schedule_post

The owner said yes: APPROVE a draft and schedule it. Call this only after the user explicitly approved this post — never to save or propose one (create_post does that). Omit publish_at to keep the draft's proposed time (proposed_for); pass publish_at to set another. X posts cost 3 credits (25 when the caption has a link), charged when the post publishes; every other network is free. The result shows credits_to_charge and the credits left. Subject to per-channel publishing limits; a refusal says when to retry.

brand_id? string
Which brand to act on. Optional when the connection covers exactly one brand (see list_brands).
content_id string
publish_at? string
ISO timestamp with a timezone offset, e.g. 2026-11-03T09:30:00+00:00 — in the future, within 30 days

publish_post

asks first

Publish a draft to its channel RIGHT NOW: it goes public immediately and cannot be undone. Call only after the user explicitly approved publishing this post now. X posts cost 3 credits (25 when the caption has a link), charged when the post publishes; every other network is free. The result shows credits_to_charge and the credits left.

brand_id? string
Which brand to act on. Optional when the connection covers exactly one brand (see list_brands).
content_id string

cancel_post

asks first

Withdraw an unpublished post or draft: takes it out of the schedule and sets its status to "skipped". The owner can restore it in Chaviar, where it keeps its proposed time. Published posts cannot be cancelled here.

brand_id? string
Which brand to act on. Optional when the connection covers exactly one brand (see list_brands).
content_id string

get_usage

read-only

Answers "what will this cost?": credits left (monthly + top-up), what a credit is worth (1 credit = 1p GBP), the plan and its price, credits already committed to scheduled X posts (charged when they publish) and what's left after them, today's remaining spend under the daily cap, and roughly how many finished images that buys. Check before generating several images or scheduling X posts.

brand_id? string
Which brand to act on. Optional when the connection covers exactly one brand (see list_brands).

render_image

20 credits final · 8 draft

Generate one on-brand image. You direct the subject, composition and mood in `prompt`; Chaviar adds the brand's logo, palette and look, keeps text out of the picture unless you ask for it, and sizes it for `format`. quality "final" (default, 20 credits) or "draft" (8 credits, only to compare directions). Pass the brand's own photos as reference_media_ids where they help. Waits up to ~45s; if it is still rendering, call get_render with the render_id. Use the returned media_id (not the render_id) in create_post. Failed renders are refunded.

brand_id? string
Which brand to act on. Optional when the connection covers exactly one brand (see list_brands).
prompt string
format? string
square | portrait | story | landscape, or an aspect like 4:5, 9:16, 16:9 (default square)
quality? final | draft
reference_media_ids? list of string
A list of up to 4 media_id strings, e.g. ["<media_id>","<media_id>"] — the brand's own photos to ground the render.
idempotency_key? string
Repeat-safe: the same key returns the same render without charging twice.

get_render

read-only

Status of a render_image call (queued, rendering, ready with media_id + url, or failed and refunded).

brand_id? string
Which brand to act on. Optional when the connection covers exactly one brand (see list_brands).
render_id string

upload_media

Add a photo to the brand library from a public https URL or base64 data (JPEG, PNG or WebP). Returns a media_id to use in create_post or as a render reference. Free.

brand_id? string
Which brand to act on. Optional when the connection covers exactly one brand (see list_brands).
url? string
data? string
base64 or a data: URL
filename? string

list_media

read-only

The brand's images — uploads, renders, logo, gallery and product shots — newest first, with media ids, source, created_at and recently_used_on (channels where it went out or is scheduled in the last 30 days) and duplicate_risk_on (the channels that would refuse it as a duplicate image — it is fine everywhere else). Page with cursor = next_cursor.

brand_id? string
Which brand to act on. Optional when the connection covers exactly one brand (see list_brands).
limit? integer
cursor? string

create_post

Save a caption plus media as REVIEW DRAFTS — one per platform — that wait for the owner's OK. Nothing is published or scheduled. Optionally pass publish_at to PROPOSE a time: the drafts show on the calendar at that slot, and approving later keeps exactly that time. Each draft comes back with proposed_for and a review_url to share with the owner. Use media_id values (from upload_media, list_media, get_inspiration or a finished get_render), not a render_id. Keep each caption within its channel limit (list_channels). DUPLICATES: a caption or image already scheduled or published on that channel within 30 days will be REFUSED when the owner approves — the result lists them in `warnings`; fix them first (update_caption / replace_media) before asking the owner. A `crowded` warning (another post on that channel within 2 hours of publish_at) is only a hint: mention it or pick another time. Free.

brand_id? string
Which brand to act on. Optional when the connection covers exactly one brand (see list_brands).
caption string
media_ids? list of string
A list of media_id strings, e.g. ["<media_id>"] — exactly one image per post or story for now. Empty for a text-only post.
platforms "all" or list of ig | fb | th | in | x | gbp | bsky
Either the string "all" (every connected channel that can take it) or a list of platform codes like ["ig","fb"] — codes: ig, fb, th, in, x, gbp, bsky.
kind? post | story
publish_at? string
Proposed publish time — ISO with offset, future, within 30 days. The drafts still need approval.
idempotency_key? string

replace_media

Swap the image of an unpublished post or draft for another media_id (from upload_media, list_media, get_inspiration or a finished get_render — not a render_id). Same image rules as create_post (text-only channels refuse; Instagram is fitted to 4:5…1.91:1). Stories are not supported. A draft comes back with duplicate `warnings` like create_post; an already-scheduled post refuses a duplicate image. Free.

brand_id? string
Which brand to act on. Optional when the connection covers exactly one brand (see list_brands).
content_id string
media_ids list of string
A list of media_id strings, e.g. ["<media_id>"] — exactly one image per post or story for now.

Authentication

Claude, ChatGPT and other consumer apps sign in with OAuth 2.1 (PKCE, dynamic client registration). Each person authorises their own assistant and picks which brands it may use; you can disconnect any of them from Account → Connections. Editors, CLIs and scripts send an API key as Authorization: Bearer cvk_….

Errors and limits

Refusals come back as a tool error with a stable code, a readable message and, when waiting helps, retry_after_seconds — for example insufficient_credits, daily_cap, plan_required, spacing or duplicate_caption. Each connection may make 120 calls a minute.

REST API

Prefer plain HTTP? Your Connect API key also works at https://chaviar.app/api/v1 with Authorization: Bearer cvk_…. Making images and drafts is MCP-only for now (render_image, create_post).

GET/channels
GET/calendar?from=YYYY-MM-DD&to=YYYY-MM-DD
GET/content
GET/content/{id}
PATCH/content/{id}
POST/content/{id}/actions
GET/library

Errors use {"error": {"code", "message"}}, the same codes as the tools above.