*Social Media Manual — [index](../MANUAL.md)*

# 1. What the social tools do

The `social_*` tools let an agent manage a person's social media accounts on their behalf:
connect a Facebook Page, an Instagram business account or an X account, draft a post, check it
against each platform's rules, publish it now or on a schedule, read it back later, edit or
delete it where the platform allows, and account for the platform calls that were made.

They are part of the same `datahandler-epic-mcp` server as the Epic CLI tools and follow the
same conventions. They appear in `tools/list` only when the server operator has enabled the
feature; when it is off there is no `social_` tool, and calling one by name answers
`SOCIAL_NOT_CONFIGURED`.

## The flow in one line

Connect an account → draft a post → preview it → publish now or put it on a schedule → read it
back, edit or take it down later.

## What ever sends anything to a platform

Nothing leaves the server except through these four paths. Everything else (drafts, previews,
media uploads, invitations, authorizations, schedules that have not fired) is local state.

1. `social_publish_now` called by the account **owner**, or by an editor who holds an
   authorization (chapter 3).
2. A **schedule** reaching a slot that has a post attached, where the schedule's creator is the
   owner or an editor whose standing authorization is still active at that moment.
3. `social_update_published_post` (Facebook text edits only).
4. `social_delete_published_post`.

Connecting an account (chapter 4) grants nothing beyond access to the account. It never
implies permission to publish.

## The eleven groups

| group | tools |
|---|---|
| status, accounts, sharing | `social_get_status`, `social_list_accounts`, `social_connect_account`, `social_disconnect_account`, `social_invite_member`, `social_claim_invitation`, `social_list_access`, `social_revoke_access` |
| browser connect, recovery | `social_start_connect`, `social_complete_connect`, `social_create_recovery_code`, `social_claim_recovery_code` |
| media | `social_upload_media`, `social_list_media`, `social_delete_media` |
| drafts | `social_create_draft`, `social_update_draft`, `social_get_post`, `social_list_posts`, `social_archive_post` |
| preview | `social_preview_post` |
| authorization | `social_grant_authorization`, `social_list_authorizations`, `social_revoke_authorization` |
| publishing | `social_publish_now`, `social_get_publication`, `social_list_publications` |
| schedules, calendar | `social_create_schedule`, `social_list_schedules`, `social_update_schedule`, `social_list_calendar`, `social_fill_occurrence`, `social_skip_occurrence` |
| published posts | `social_get_published_post`, `social_update_published_post`, `social_delete_published_post` |
| usage | `social_get_usage` |

37 tools. The `tools/list` entry for each one is the contract: its input schema has
`additionalProperties: false`, so an unknown or mistyped argument is rejected before any logic
runs, and its output schema describes the `structuredContent` you get back.

## The result contract

Every reply carries the same base fields as the Epic tools:

| field | meaning |
|---|---|
| `schema_version` | contract version of the payload |
| `ok` | `true` on success; `false` with `error` set |
| `request_id` | quote it to the operator when something is wrong server-side |
| `warnings[]` | non-fatal notes (nothing in them changes the result) |
| `error` | `null`, or `{code, message, retryable, next_action, details}` |

Two kinds of failure, and they look different:

- **JSON-RPC error `-32602`** — you sent something the schema does not allow (unknown field,
  wrong type, missing required argument). The result has no `structuredContent`. Fix the call.
- **`ok:false` with `error.code`** — the call was well formed but the business rule said no
  (`AUTHORIZATION_REQUIRED`, `REVISION_CONFLICT`, `RATE_LIMITED`, …). `error.next_action` says
  what to do; `error.retryable` says whether simply calling again can help; `error.details`
  carries anything you need to recover (for example the current text on a revision conflict).
  Chapter 12 lists every code.

The failure payload still has the tool's typed fields, filled with empty values (`[]`, `null`,
`0`), so a client that reads the structure never sees a missing key.

## Where to start

Always call `social_get_status` first. It tells you whether the caller has a social identity
yet, which platforms this server can connect, how each one is connected (browser sign-in,
credential, or both), what the credential fields are called, each platform's capabilities and
limits, and how many accounts the caller can already use. Everything else in this manual
assumes you have read it.
