# Aivy agent MCP

The agent endpoint is `https://aivymarketing.com/api/mcp`. Create a publisher key at `/connect/agent` and confirm that the key may schedule and publish. This example uses a grant with requireApproval turned off.

## Create a LinkedIn post, attach an image, and schedule it

1. `get_brand_context` with the brand id.
2. `list_channels` and confirm LinkedIn `canPublishNow` is true.
3. `upload_media` with `filename`, `mimeType`, and an `idempotencyKey`. Upload the image bytes to the returned URL.
4. `create_post_draft` with one LinkedIn variant, the caption, and `mediaIds` from the upload. The post stays unpublished.
5. `schedule_post` with `scheduledAt` of `2026-10-22T09:00:00` and the brand timezone `Europe/Prague`. A timestamp without an offset uses the brand timezone, so this is 09:00 in Prague (07:00 UTC while Prague is on summer time).
6. `get_publish_status` returns `scheduled`, the provider post id, and a permalink when the network has one.
7. After the post is live, `get_post_metrics` returns impressions, reach, engagement, clicks, and the permalink. Fields the provider has not sent are null.

```json
{
  "name": "schedule_post",
  "arguments": {
    "brandId": "BRAND_ID",
    "postId": "POST_ID",
    "scheduledAt": "2026-10-22T09:00:00",
    "idempotencyKey": "linkedin-prague-2026-10-22"
  }
}
```

A successful direct schedule looks like:

```json
{
  "ok": true,
  "data": {
    "status": "scheduled",
    "providerPostId": "PROVIDER_POST_ID",
    "permalink": null,
    "scheduledAt": "2026-10-22T07:00:00.000Z",
    "scheduledAtLocal": "2026-10-22T09:00:00",
    "timeZone": "Europe/Prague"
  }
}
```

## Approval

When the same publisher grant has requireApproval on, `schedule_post` and `publish_post` do not send the post. `get_publish_status` returns `pendingApproval` until a person approves it in Aivy. After approval, the existing scheduler sends it.

A drafter key cannot call `schedule_post` or `publish_post`.
