# MCP tools

Every tool the Pozy MCP server offers, with its arguments, plus how search_tools and call_tool reach the rest of the API.

The server offers 27 tools. 25 are written for the jobs people ask for most, with simple arguments. Two more, `search_tools` and `call_tool`, open up every operation in the API, so an assistant can do anything the [API reference](https://pozy.ai/docs/api) can.

Your client sees all 27 from the start. The long tail costs nothing in context until the assistant searches for it.

## How tools answer

Each tool returns one text block: a short summary for the assistant to read, then the full JSON response. Very large answers are cut at 60,000 characters with a note asking the assistant to narrow the request.

Errors come back as tool errors with the HTTP status and the [error code](https://pozy.ai/docs/getting-started/errors), such as `Error 403 (read_only_key): This credential is read-only.`, so the assistant can explain or fix the problem.

Platform names are flexible: `x` and `tweet` mean `twitter`, `ig` means `instagram`, `fb` means `facebook`, `yt` means `youtube`, `li` means `linkedin`, `gbp` means `googlebusiness`, and `wa` means `whatsapp`.

Every tool is labelled with standard MCP hints (read-only, destructive, idempotent), which clients use to decide when to ask you before running it.

## Workspace

| Tool | What it does | Arguments |
| --- | --- | --- |
| `whoami` | Shows the workspace and user the connection acts as, the role, and whether it can make changes | none |

## Accounts and profiles

| Tool | What it does | Arguments |
| --- | --- | --- |
| `list_accounts` | Lists connected social, ads, messaging and blog accounts with their ids | `platform`, `profile_id`, `status` (`connected` or `disconnected`), `search`, `limit` (default 100, up to 500) |
| `list_profiles` | Lists profiles, the groups that hold accounts (usually one per brand or client) | `name`, `limit` (default 50) |
| `create_profile` | Creates a profile | `name` (required), `description`, `timezone`, `external_id` |
| `connect_account` | Returns a link the user opens to connect, or reconnect, an account | `platform` (required), `profile_id` (defaults to the default profile), `reconnect_account_id` |

`connect_account` cannot finish the job on its own: the person signs in to the platform in their browser. Afterwards the assistant calls `list_accounts` to find the new account.

## Posts

| Tool | What it does | Arguments |
| --- | --- | --- |
| `create_post` | Publishes now, or saves a draft or a post that waits for approval | `content` (required), `account_ids` or `platforms`, `profile_id`, `media_urls`, `title`, `hashtags`, `idempotency_key`, `is_draft`, `requires_approval`, `dry_run` |
| `schedule_post` | Schedules for a time, or for the next free slot in a profile's queue | Same as above plus `scheduled_for` (ISO 8601), `timezone` (IANA, default UTC), `use_queue` |
| `list_posts` | Lists posts with their status on each platform, newest first | `status`, `platform`, `profile_id`, `account_id`, `from_date`, `to_date`, `search`, `limit` (default 20), `page` |
| `get_post` | Gets one post with its status, URL or error on each platform | `post_id` (required) |
| `retry_post` | Publishes a failed post again where it failed | `post_id` (required) |
| `delete_post` | Deletes a draft or scheduled post, or removes a published one | `post_id` (required) |
| `upload_media_from_url` | Copies an image, video or PDF from a public URL into Pozy media storage, up to 200 MB | `url` (required), `filename` |

Targets come from `account_ids` (the `_id` values from `list_accounts`) or `platforms` (names such as `["linkedin", "instagram"]`). A platform name only works when exactly one account is connected on it; otherwise the tool refuses and lists the candidate accounts, so the assistant asks you which one.

`dry_run: true` checks the post against each platform's rules (length, media type, a missing YouTube title) without creating anything. YouTube needs a `title`; Instagram and TikTok need at least one image or video.

Media goes in as public URLs. When a link might expire or block downloads, the assistant passes it through `upload_media_from_url` first and posts the URL it returns. For a file on your computer, upload it with [`POST /v1/media/presign`](https://pozy.ai/docs/publishing/media) and give the assistant the URL.

## Analytics

| Tool | What it does | Arguments |
| --- | --- | --- |
| `get_analytics` | `view: "summary"` gives totals, followers, daily series and top posts; `view: "posts"` lists per-post metrics | `view`, `from_date` (default 30 days ago), `to_date` (default today), `platform`, `profile_id`, `account_id`, `post_id`, `sort_by`, `limit` (default 20) |
| `best_time_to_post` | The weekly hours when your posts got the most engagement, best first, in UTC | `platform`, `profile_id`, `account_id` |

`sort_by` takes `date`, `engagement`, `impressions`, `reach`, `likes`, `comments`, `shares`, `saves`, `clicks` or `views`.

## Inbox

| Tool | What it does | Arguments |
| --- | --- | --- |
| `list_conversations` | DM conversations across platforms, most recent first, with the last message and unread count | `platform`, `profile_id`, `account_id`, `status` (`active` or `archived`), `folder` (`inbox` or `requests`), `limit`, `cursor` |
| `get_conversation` | One conversation and its latest messages | `conversation_id` and `account_id` (required), `limit` (default 30) |
| `send_message` | Sends a DM in an existing conversation | `conversation_id`, `account_id`, `message` (required), `attachment_url`, `idempotency_key` |
| `list_comments` | Without `post_id`: recent posts that have comments. With `post_id` and `account_id`: the comments on that post | `post_id`, `account_id`, `platform`, `profile_id`, `limit`, `cursor` |
| `reply_to_comment` | Replies publicly to a comment, or comments on the post when `comment_id` is left out | `post_id`, `account_id`, `message` (required), `comment_id`, `idempotency_key` |
| `list_reviews` | Google Business Profile and Facebook reviews with rating, text and reply status | `platform`, `profile_id`, `account_id`, `min_rating`, `max_rating`, `has_reply`, `limit`, `cursor` |
| `reply_to_review` | Posts a public reply to a review | `review_id`, `account_id`, `message` (required) |

Platforms limit when a business may message first, such as Instagram's 24-hour window after the person's last message. A send outside the window fails with the platform's reason.

## Ads

| Tool | What it does | Arguments |
| --- | --- | --- |
| `get_ads_overview` | Spend, impressions, clicks and conversions per platform, the top-spending campaigns and open alerts | `from_date`, `to_date`, `platform`, `profile_id` |
| `list_ads_campaigns` | Campaigns with status, budget and metrics for a date range | `platform`, `status`, `ad_account_id`, `account_id`, `profile_id`, `from_date`, `to_date`, `limit` (default 25) |
| `pause_campaign` | Pauses a campaign so it stops spending | `campaign_id`, `platform` (required) |
| `resume_campaign` | Turns a paused campaign back on | `campaign_id`, `platform` (required) |

## The long tail: search_tools and call_tool

Everything else (WhatsApp templates and broadcasts, comment-to-DM, workflows, queues, Google Business, audiences and creatives, phone numbers, SMS, webhooks, team and usage) is two steps away.

**`search_tools`** finds operations by keywords and returns their ids, summaries and input schemas.

| Argument | Notes |
| --- | --- |
| `query` | What you want to do, such as `"send whatsapp template"` or `"list queue slots"`. Required |
| `limit` | 1 to 20, default 8 |
| `area` | Limit to one product area: `accounts`, `publishing`, `analytics`, `inbox`, `automations`, `ads`, `commerce`, `google-business`, `whatsapp`, `messaging`, `telephony`, `creators`, `productivity` or `workspace` |

**`call_tool`** runs one of them by its operation id, the same `operationId` as in the API reference.

| Argument | Notes |
| --- | --- |
| `id` | The operation id, such as `listQueueSlots`. Required |
| `params` | Path, query and header parameters by name |
| `body` | The JSON request body, for operations that take one |

A search for "list queue slots" returns `listQueueSlots`, whose input schema says it needs `params.profileId`. The assistant then calls:

```json
{
  "id": "listQueueSlots",
  "params": { "profileId": "6650f1c2a8b4e3d2c1b0a998" }
}
```

Good to know:

- Missing required parameters are caught before anything is sent, and the error includes the operation's schema.
- A parameter the operation does not define is sent as a query parameter, with a note in the answer.
- `call_tool` sends JSON bodies only. Operations that take a file upload (multipart), such as CSV bulk upload, need the [REST API](https://pozy.ai/docs/api/bulkUploadPosts).
- Responses that are files (an image, a PDF) are reported by type and size rather than shown.

## Permissions

Tools run with the permissions of the connection:

- A read-only OAuth approval or a [read-only key](https://pozy.ai/docs/getting-started/authentication) can use every read tool. Write tools fail with `read_only_key`.
- A [profile-scoped key](https://pozy.ai/docs/build/tenant-keys) only sees and acts on its profiles.
- A key with a [resource group](https://pozy.ai/docs/getting-started/authentication) switched off fails on tools in that group with `resource_group_disabled`.
- Your workspace role still applies: a viewer can read but not act.
