## MCP reference

Endpoint: `https://a1lane.ai/mcp/v1` (Streamable HTTP, JSON-RPC over POST; protocol 2025-06-18; tool contract `v1.3`, 26 tools). Authorise with OAuth 2.0 (discovery at `/.well-known/oauth-authorization-server`, authorization-code + PKCE S256; clients identify themselves with a Client ID Metadata Document URL or register dynamically) or, for developers, a pasted workspace token. The stdio server (`python -m postlane.mcp`) exposes the same tools.

Every mutating tool accepts an optional `idempotency_key`: replaying a key returns the original result and executes nothing again; a key can never force past an uncertain outcome. The tool list, annotations and schemas below are frozen at `v1.3`; changes are announced on the [changelog](/docs/changelog). Start with `get_delivery_digest`; per-assistant setup: [Claude, ChatGPT, Grok](/docs/agents).

Every tool validates its input strictly (`additionalProperties: false`): unknown fields are errors, never dropped. Errors are `{code, reason, fix_hint}`. Writes are draft-first; scheduling needs the publish scope; retries pass the same uncertain-probe and duplicate guards as every other surface. Per-token rate limit: 120 calls/minute.

| Tool | Title | Annotations | Description |
| `list_accounts` | List connected accounts | readOnly, idempotent, openWorld | Connected social accounts in this workspace with health state (ok / credential_invalid / action_required_in_app / unknown) and posting-slot schedules. |
| `get_platform_schema` | Get platform constraints | readOnly, idempotent, openWorld | Media constraints, caption limits, per-destination options and disclosure fields per platform — call before composing to avoid validation errors. |
| `upload_media` | Import media from a link | openWorld | Ingest a video or image the user supplies (https URL) into the workspace library; returns the media id. No generation. |
| `create_draft` | Create a draft post | openWorld | Create a DRAFT (never queued). Schedule it with schedule_draft; the workspace's approval policy applies. |
| `schedule_draft` | Schedule or queue a draft | openWorld | Queue a draft now, at an instant, or into an account's next free slot. Needs the publish scope; a workspace that requires approval refuses until approved. |
| `update_draft_settings` | Update a draft | openWorld | Change caption, destinations, options, schedule, parts, first comment or UTM on a post that has not started delivering. Edits after an approval reset the approval. |
| `cancel_scheduled` | Cancel a scheduled post | destructive, openWorld | Cancel before send = clean stop; a destination whose request may have landed becomes uncertain, never silently cancelled. |
| `delete_draft` | Delete a draft | destructive, openWorld | Delete a draft or finished post. Queued or scheduled posts must be cancelled first. |
| `submit_batch` | Submit a batch of drafts | openWorld | Create many posts in one call with per-item results; one bad item never sinks the batch. Items are drafts unless the token has publish scope and the item names a mode. |
| `get_batch_status` | Get batch status | readOnly, idempotent, openWorld | Roll-up for a batch: live / pending / parked per destination, fullyLive and done flags. |
| `get_receipt` | Get a delivery receipt | readOnly, idempotent, openWorld | Full receipt for one post: destinations, platform ids and URLs, flags, every checkpoint. |
| `get_verification_status` | Get verification status | readOnly, idempotent, openWorld | Which destinations are verified live, still pending, awaiting a human finish, or parked as uncertain — for one post or across the workspace's active posts. |
| `list_attention_items` | List attention items | readOnly, idempotent, openWorld | The needs-attention feed: failed, uncertain, awaiting human finish, held, blocked, flagged, approvals, unhealthy accounts. |
| `resolve_attention` | Resolve an attention item | destructive, openWorld | probe: run the read-back probe on an uncertain destination. retry: retry provably-failed destinations (uncertain is refused). release: release a same-asset hold. acknowledge_force_retry: after a probe, re-send an uncertain destination — requires acknowledge=true because a duplicate is possible. confirm_deleted: record that the user deleted the post in the platform's app, closing a delete_manual destination whose route has no read-back — requires destination_id and acknowledge=true; the delete is human-attested, never read-back verified. |
| `create_handoff_pack` | Create a handoff pack | readOnly, idempotent, openWorld | For destinations that end with a human finishing in the platform app: caption and every toggle to set, phone-sized. |
| `request_approval` | Request approval | openWorld | Submit a draft to the workspace's approvers (draft → pending_approval). |
| `list_posts` | List posts | readOnly, idempotent, openWorld | Posts with per-destination status. status filter: active | attention | published | draft | pending_approval | scheduled | failed | … |
| `get_delivery_digest` | Get the delivery digest | readOnly, idempotent, openWorld | Start here: what went out since a time (default the last 24 hours) with platform links — live counts published only, limited deliveries on their own line — plus what needs you, each with a link to the exact post. |
| `create_upload_link` | Create an upload link | openWorld | A single-use link the user opens to drop ONE file into the library (phone or desktop). The link adds exactly one library item and can never post or publish. Poll get_upload_status, then create_draft with the media id. |
| `get_upload_status` | Get upload status | readOnly, idempotent, openWorld | State of an upload link: waiting / receiving (percent) / validating / ready (media id + per-platform fit) / rejected (code, reason, fix_hint) / expired / revoked. |
| `pause_workspace` | Pause or resume publishing | idempotent, openWorld | Pause every new delivery in the workspace (or one account with account_id): queued posts are held, not failed. resume=true clears that pause. Needs the publish scope. |
| `unpublish_post` | Unpublish a post | destructive, openWorld | Delete a live post from its platforms (or one destination). Requires acknowledge=true. Ends deleted only when a read-back confirms it is gone; delete_uncertain is probed, never blindly re-deleted; delete_manual means the platform has no delete API and returns the in-app steps. |
| `get_post_engagement` | Get post engagement | readOnly, idempotent, openWorld | Engagement for one post, per destination: latest platform-reported views / likes / comments / shares, each with its as-of time, the pull pipeline state, and the series. Metrics a platform did not report are marked unavailable with the reason, never shown as zero. Engagement is the platform's number, not delivery truth — use get_receipt for delivery. |
| `get_engagement_rollup` | Get engagement rollup | readOnly, idempotent, openWorld | Engagement totals over a window (default 30 days, capped by the plan's history), per metric, platform and channel. Posts whose platform did not report a metric are excluded from that metric and counted with their reason — never zero-filled. |
| `get_best_times` | Get best times to post | readOnly, idempotent, openWorld | Best weekday x hour slots for one channel, from that channel's own scored history (never other accounts, never a reschedule). Below the evidence threshold the answer is {enough: false, message: "Not enough data yet."} instead of a guess. |
| `get_engagement_coverage` | Get engagement coverage | readOnly, idempotent, openWorld | Which engagement metrics each platform exposes, which are scope-gated, and the pull cadence — the same generated matrix as the public /docs/engagement page. Discord and Telegram expose none; X reads are off until the operator enables them (they bill per read). |

R-42: a listing in an assistant directory is a listing of this connector. It is not an approval of your platform apps by YouTube, Meta, TikTok, X or LinkedIn.

---
HTML version: https://a1lane.ai/docs/mcp
