A1 Lane

Hosted MCP server for A1 Lane, a social post scheduler. 26 tools to create drafts, request approval, schedule posts and check delivery receipts. Seven of twelve channels connect today; read-back verification depends on the channel. Streamable HTTP with OAuth 2.0 or a workspace token.

Hosted MCP Server

npx add-mcp 'https://a1lane.ai/mcp/v1'

Installs into Claude Code, Codex, Cursor and more

Documentation

MCP reference

Assistant tools, generated from the server's tool definitions on each request: 26 tools on contract v1.7, the same list tools/list returns. Streamable HTTP, JSON-RPC over POST, protocol 2025-06-18. Authorise with OAuth 2.0 (discovery at /.well-known/oauth-authorization-server, authorization code + PKCE S256) or, for developers, a workspace token. The stdio server (python -m postlane.mcp) exposes the same tools.

https://a1lane.ai/mcp/v1

Every mutating tool accepts an optional idempotency_key: replaying a key returns the original result and executes nothing again; a key never forces past an uncertain outcome. Inputs are strict (additionalProperties: false) — unknown fields are errors, never dropped. Per-token rate limit: 120 calls a minute. Start with get_delivery_digest.

By job: Orient · Prepare · Review and hand off · Schedule and manage · Verify and recover · Measure · The chain · Errors · A–Z

The chain: draft → schedule → receipt

{
  "create_draft": {
    "destinations": [
      {
        "account_id": "acc_…"
      }
    ],
    "caption": "A weekend outside"
  },
  "schedule_draft": {
    "post_id": "post_…",
    "mode": "scheduled",
    "scheduled_at": "2026-09-19T09:00:00-07:00"
  },
  "get_receipt": {
    "post_id": "post_…"
  }
}

get_receipt returns id, status, destinations[] — each with platform, status (published only after read-back), url, stage, message — and the receipt checkpoints.

Orient

See what is connected and what each platform accepts.

List connected social accounts. Use when the user asks which social media accounts are connected, which account to post to, or whether an account needs reconnecting. Returns each connected account in this workspace with its platform, handle, account id (acc_…), health (ok, credential_invalid, action_required_in_app, unknown) and posting-slot schedule, plus the web Connect page address and the platforms a new account can connect today. An assistant cannot connect an account itself, so hand the user the Connect page address. For what a platform allows, use get_platform_schema.

Annotations: readOnly, idempotent

No inputs.

{}

See this task end-to-end →

Get a platform's posting rules. Use before writing or scheduling a post, or when the user asks what a platform allows: caption length, video and image limits, how many images a carousel takes, whether threads and first comments work there, disclosure flags, and every per-post option with its type and allowed values (for example YouTube title, privacy, tags, category and made-for-kids designation, Pinterest board, Mastodon content warning). Also says whether a new account can connect the platform on this service today. Pass platform for one platform or omit it for all. Checking here first avoids a refused draft and avoids promising a platform that is not open yet.

Annotations: readOnly, idempotent

InputTypeRequiredNotes
platformstringoptionalOne platform to describe; omit to get every platform.
{"platform": "…"}

See this task end-to-end →

Summarize recent deliveries. Use when the user asks what went out, how their posting went today or this week, or for a recap or status update. Returns what was delivered between since and until (default the last 24 hours) with platform links, counting only read-back-verified posts as live and listing limited deliveries separately, plus what needs the user, each with a link to the post.

Annotations: readOnly, idempotent

InputTypeRequiredNotes
sincestringoptionalISO-8601 instant with offset; default 24 hours before until.
untilstringoptionalISO-8601 instant with offset; default now.
{"since": "2026-09-19T09:00:00-07:00"}

See this task end-to-end →

List and filter posts. Use when the user asks to see their posts: drafts, what is scheduled or queued, what was published, or what failed. Returns posts with each destination's status. Filter with status, for example active, attention, draft, pending_approval, scheduled, published, failed or all; an unknown status is refused with the list of valid ones. Newest first; when more posts remain the result carries nextOffset to pass back as offset. For only the problems to fix, use list_attention_items.

Annotations: readOnly, idempotent

InputTypeRequiredNotes
statusstringoptionalFilter: active, attention, all, draft, pending_approval, approved, scheduled, queued, publishing, published, published_limited, partial, failed, held, cancelled and other stored statuses; omit for all.
limitintegeroptionalMost posts to return; default 50.
offsetintegeroptionalHow many of the newest matching posts to skip, for the next page; use the nextOffset a previous call returned. Default 0.
{"status": "…"}

See this task end-to-end →

Prepare

Bring in media and build drafts. Nothing is queued yet.

Import media from a link. Use when the user gives an https link to a video or image file they want to post. Downloads that file into the workspace media library and returns its media id (med_…) for create_draft. It only imports what the user supplies; it does not generate, edit, resize or post anything. For a file on the user's phone or computer with no link, use create_upload_link.

Annotations: openWorld

InputTypeRequiredNotes
urlstringrequiredPublic https link to the video or image file the user supplied.
titlestringoptionalOptional library title for the file.
tagsarrayoptionalOptional library tags for finding the file later.
idempotency_keystringoptionalOptional client-chosen key (8-200 chars of A-Z a-z 0-9. _: -). Replaying the same key returns the original result and executes nothing again; a key never forces past an uncertain outcome.
{"url": "https://example.com/clip.mp4"}

See this task end-to-end →

Create a file upload link. Use when the user wants to post a video or photo from their phone or computer that has no public link. Creates a single-use link the user opens to upload one file into the media library; the link cannot post or publish anything. Then check get_upload_status for the media id.

Annotations: write

InputTypeRequiredNotes
filenamestringoptionalOptional file name to show the user on the upload page.
expires_in_minutesintegeroptionalHow long the link stays open, 5 to 1440 minutes.
idempotency_keystringoptionalOptional client-chosen key (8-200 chars of A-Z a-z 0-9. _: -). Replaying the same key returns the original result and executes nothing again; a key never forces past an uncertain outcome.
{"filename": "…"}

See this task end-to-end →

Check an upload link. Use after create_upload_link to see whether the user's file has arrived. Returns the link's state: waiting, receiving (with percent), validating, ready (with the media id and which platforms the file fits), rejected (with the reason), expired or revoked.

Annotations: readOnly, idempotent

InputTypeRequiredNotes
link_idstringrequiredUpload link id (lnk_…) returned by create_upload_link.
{"link_id": "lnk_…"}

See this task end-to-end →

Create a draft post. Use when the user asks to write, prepare, cross-post or set up a social media post, video, carousel or thread for one or more connected accounts. Saves a draft with caption, media, per-platform options and destinations; nothing is sent to any platform. Each destination can carry its own caption, media, options, thread parts or first comment. Check get_platform_schema for each platform's limits and options first. To publish or schedule the draft use schedule_draft; the workspace's approval policy still applies. For several posts at once use submit_batch.

Annotations: write

InputTypeRequiredNotes
captionstringoptionalPost text, up to 10,000 characters; each platform's own limit is checked at validation (see get_platform_schema).
media_idstringoptionalMedia id (med_…) from upload_media or the library.
media_idsarrayoptionalOrdered media ids (med_…) for a multi-media post (carousel); order is display order and per-platform caps bind at validation. Give media_ids or media_id, never both — the two naming different media is refused, never guessed. A destination's own media_ids overrides this list for that destination.
destinationsarrayrequiredOne entry per connected account to post to, each with its account_id and optional per-account overrides.
scheduled_atstringoptionalPlanned ISO-8601 instant with offset; used when scheduling.
first_commentstringoptionalPosted as the first comment after the destination is verified live, on platforms whose get_platform_schema entry has supportsFirstComment true.
partsarrayoptionalThread parts, each posted as a reply to the previous, on platforms whose get_platform_schema entry has supportsParts true; other destinations get the caption alone with a parts_unsupported warning.
utmobjectoptionalUTM tags added to links in the caption, for example {"source": "bluesky", "campaign": "launch"}.
labelsobjectoptionalSmall key/value object stored with the post for the user's own grouping, for example {"campaign": "spring"}.
idempotency_keystringoptionalOptional client-chosen key (8-200 chars of A-Z a-z 0-9. _: -). Replaying the same key returns the original result and executes nothing again; a key never forces past an uncertain outcome.
{"destinations": [{"account_id": "acc_…"}]}

See this task end-to-end →

Edit a draft or scheduled post. Use when the user asks to change a draft or scheduled post before it starts delivering: its caption, media, accounts, per-platform options (for example YouTube privacy or tags), scheduled time, thread parts, first comment or UTM tags. Fields you send replace the saved values. An edit to an approved post resets its approval. To move a post to another time, send scheduled_at here; to stop it, use cancel_scheduled.

Annotations: destructive

InputTypeRequiredNotes
post_idstringrequiredPost id (post_…) from create_draft, list_posts or a receipt.
captionstringoptionalPost text, up to 10,000 characters; each platform's own limit is checked at validation (see get_platform_schema).
media_idstringoptionalMedia id (med_…) from upload_media or the library.
media_idsarrayoptionalOrdered media ids (med_…) for a multi-media post (carousel); order is display order and per-platform caps bind at validation. Give media_ids or media_id, never both — the two naming different media is refused, never guessed. A destination's own media_ids overrides this list for that destination.
destinationsarrayoptionalOne entry per connected account to post to, each with its account_id and optional per-account overrides.
scheduled_atstringoptionalPlanned ISO-8601 instant with offset; used when scheduling.
first_commentstringoptionalPosted as the first comment after the destination is verified live, on platforms whose get_platform_schema entry has supportsFirstComment true.
partsarrayoptionalThread parts, each posted as a reply to the previous, on platforms whose get_platform_schema entry has supportsParts true; other destinations get the caption alone with a parts_unsupported warning.
utmobjectoptionalUTM tags added to links in the caption, for example {"source": "bluesky", "campaign": "launch"}.
labelsobjectoptionalSmall key/value object stored with the post for the user's own grouping, for example {"campaign": "spring"}.
idempotency_keystringoptionalOptional client-chosen key (8-200 chars of A-Z a-z 0-9. _: -). Replaying the same key returns the original result and executes nothing again; a key never forces past an uncertain outcome.
{"post_id": "post_…"}

See this task end-to-end →

Create many posts at once. Use when the user asks to set up several posts in one go, such as a week of content, a content calendar, bulk scheduling, or one video to many accounts. Creates each item with its own result, so one invalid item does not stop the rest, and returns a batch id for get_batch_status. Items are drafts unless the token has the publish scope and the item sets a mode, in which case that item is published or scheduled on its platforms and cannot be recalled by this tool.

Annotations: destructive, openWorld

InputTypeRequiredNotes
postsarrayrequiredThe posts to create, each shaped like create_draft's arguments plus an optional mode.
labelsobjectoptionalSmall key/value object stored on every post in the batch.
same_asset_overridebooleanoptionaltrue applies same_asset_override to every item.
idempotency_keystringoptionalOptional client-chosen key (8-200 chars of A-Z a-z 0-9. _: -). Replaying the same key returns the original result and executes nothing again; a key never forces past an uncertain outcome.
{"posts": [{"destinations": [{"account_id": "acc_…"}]}]}

See this task end-to-end →

Delete a post record. Use when the user asks to delete a draft or remove a finished post from the workspace's post history. Deletes the post and its receipt from the workspace only; a post already live on a platform stays live (use unpublish_post to take it down there). Queued or scheduled posts must be cancelled first with cancel_scheduled.

Annotations: destructive

InputTypeRequiredNotes
post_idstringrequiredPost id (post_…) from create_draft, list_posts or a receipt.
idempotency_keystringoptionalOptional client-chosen key (8-200 chars of A-Z a-z 0-9. _: -). Replaying the same key returns the original result and executes nothing again; a key never forces past an uncertain outcome.
{"post_id": "post_…"}

See this task end-to-end →

Review and hand off

Ask a person, or hand the last step to a human.

Send a draft for approval. Use when the user asks to send a draft to their team, client or manager for review or sign-off before it is posted. Moves the draft to pending approval and returns the draft's updated summary, including its approval state. Approvers approve or reject in A1 Lane; approval makes the draft schedulable, rejection returns it to draft with the reviewer's note, if they left one. This call never publishes — publishing is schedule_draft, and it refuses a draft whose required approval is still pending.

Annotations: write

InputTypeRequiredNotes
post_idstringrequiredPost id (post_…) from create_draft, list_posts or a receipt.
idempotency_keystringoptionalOptional client-chosen key (8-200 chars of A-Z a-z 0-9. _: -). Replaying the same key returns the original result and executes nothing again; a key never forces past an uncertain outcome.
{"post_id": "post_…"}

See this task end-to-end →

Get steps to finish a post in-app. Use when the user asks how to finish a post in the platform's own app, or what a needs-attention post is waiting on. Returns, for the given post, the handoff pack for every destination awaiting a human finish (find such posts with list_attention_items): the exact caption and every setting to apply, laid out for reading on a phone. It changes nothing and sends nothing.

Annotations: readOnly, idempotent

InputTypeRequiredNotes
post_idstringrequiredPost id (post_…) from create_draft, list_posts or a receipt.
{"post_id": "post_…"}

See this task end-to-end →

Schedule and manage

Queue, schedule, pause and cancel.

Publish or schedule a draft. Use when the user asks to post, publish or share a draft now, schedule it for a date and time, or add it to an account's posting queue (its next free posting slot). mode is now, scheduled (with scheduled_at) or queue (with queue_account_id). This sends the post to the connected platforms under its visibility settings, and a sent post cannot be recalled by this tool (unpublish_post deletes it afterwards). Requires the publish scope; a workspace that requires approval refuses until the post is approved. Not for saving work in progress: use create_draft.

Annotations: destructive, openWorld

InputTypeRequiredNotes
post_idstringrequiredPost id (post_…) from create_draft, list_posts or a receipt.
modestringoptionalnow sends immediately; scheduled sends at scheduled_at; queue takes queue_account_id's next free posting slot. Inferred from scheduled_at or queue_account_id when omitted.
scheduled_atstringoptionalWhen to send, as an ISO-8601 instant with offset, for example 2026-11-03T09:00:00-08:00.
queue_account_idstringoptionalAccount id (acc_…) whose posting-slot schedule picks the time, for mode queue.
idempotency_keystringoptionalOptional client-chosen key (8-200 chars of A-Z a-z 0-9. _: -). Replaying the same key returns the original result and executes nothing again; a key never forces past an uncertain outcome.
{"post_id": "post_…"}

See this task end-to-end →

Cancel a scheduled post. Use when the user asks to cancel, stop or unschedule a queued or scheduled post. Destinations not yet sent are cancelled cleanly; a post the platform itself holds as scheduled is withdrawn from the platform; a destination whose request may already have reached the platform is marked uncertain, not cancelled. Requires the publish scope. To hold every post for a while without cancelling, use pause_workspace; to remove a post that is already live, use unpublish_post.

Annotations: destructive, openWorld

InputTypeRequiredNotes
post_idstringrequiredPost id (post_…) from create_draft, list_posts or a receipt.
idempotency_keystringoptionalOptional client-chosen key (8-200 chars of A-Z a-z 0-9. _: -). Replaying the same key returns the original result and executes nothing again; a key never forces past an uncertain outcome.
{"post_id": "post_…"}

See this task end-to-end →

Pause or resume publishing. Use when the user asks to stop all posting for now, put publishing on hold, or start again. Pauses new deliveries for the whole workspace, or for one account with account_id; queued posts are held, not failed. resume=true lifts the pause. Requires the publish scope. Returns the pause state after the call: whether paused, the accounts covered and how many deliveries are held. Posts already sent to a platform are unaffected; a delivery still in progress stops before its send step and is held.

Annotations: idempotent

InputTypeRequiredNotes
account_idstringoptionalAccount id (acc_…) to pause or resume alone; omit for the whole workspace.
resumebooleanoptionaltrue lifts the pause instead of setting it.
reasonstringoptionalOptional note shown with the pause.
idempotency_keystringoptionalOptional client-chosen key (8-200 chars of A-Z a-z 0-9. _: -). Replaying the same key returns the original result and executes nothing again; a key never forces past an uncertain outcome.
{"account_id": "acc_…"}

See this task end-to-end →

Check a batch's delivery. Use when the user asks how a batch of posts or a bulk schedule is going. Returns, for a batch id from submit_batch, every post with each destination's status, and destination counts as live, pending, attested (confirmed by a person, not read back) or parked by status, such as failed or uncertain, plus whether the batch is fully live and whether it is done. For the proof behind a live destination, use get_receipt.

Annotations: readOnly, idempotent

InputTypeRequiredNotes
batch_idstringrequiredBatch id (batch_…) returned by submit_batch.
{"batch_id": "batch_…"}

See this task end-to-end →

Verify and recover

Read the receipt; resolve what didn't land; take a post down.

Get a post's delivery receipt. Use when the user asks whether a specific post went out, where it is live, what its link is, or what happened to it. Returns the full delivery receipt for one post: each destination's status, platform post id and URL, flags, and every recorded checkpoint. A destination counts as live only when its status is published. For views and likes, use get_post_engagement.

Annotations: readOnly, idempotent

InputTypeRequiredNotes
post_idstringrequiredPost id (post_…) from create_draft, list_posts or a receipt.
{"post_id": "post_…"}

See this task end-to-end →

Check if posts are verified live. Use when the user asks whether their posts actually went live, or wants a post they just published double-checked. For one post, or across the workspace's active posts, returns which destinations are verified live by read-back from the platform, still pending, waiting for the user to finish in the platform's app, or uncertain. For one post's full delivery record, use get_receipt.

Annotations: readOnly, idempotent

InputTypeRequiredNotes
post_idstringoptionalPost id (post_…) to check; omit to check the workspace's active posts.
limitintegeroptionalMost posts to return when post_id is omitted; default 50.
{"post_id": "post_…"}

See this task end-to-end →

List posts that need attention. Use when the user asks what needs fixing, why a post failed, what went wrong, or what is waiting on them. Returns the needs-attention list: failed or uncertain deliveries, posts waiting for the user to finish in a platform app, held or blocked posts, flagged deliveries, pending approvals, and accounts that need reconnecting. Each item carries its action and the destination's status, message and link. To fix an item use resolve_attention; the full delivery record is in get_receipt.

Annotations: readOnly, idempotent

No inputs.

{}

See this task end-to-end →

Fix a delivery problem. Use when the user asks to fix, retry or re-send a failed post, or to clear an item from the attention list. action: probe checks the platform for an uncertain destination; retry re-sends destinations that provably failed (uncertain ones are refused); release lets a post held as a possible duplicate go out; acknowledge_force_retry re-sends an uncertain destination and needs acknowledge=true because a duplicate post is possible; confirm_deleted records that the user deleted the post in the platform's app and needs destination_id and acknowledge=true. Requires the publish scope.

Annotations: destructive, openWorld

InputTypeRequiredNotes
post_idstringrequiredPost id (post_…) from create_draft, list_posts or a receipt.
actionstringrequiredWhich fix to apply; see the tool description for each.
destination_idstringoptionalDestination id (dst_…) from get_receipt or list_attention_items: one account's copy of the post.
acknowledgebooleanoptionalSet true only after the user accepts the stated risk; required by acknowledge_force_retry and confirm_deleted.
idempotency_keystringoptionalOptional client-chosen key (8-200 chars of A-Z a-z 0-9. _: -). Replaying the same key returns the original result and executes nothing again; a key never forces past an uncertain outcome.
{"post_id": "post_…", "action": "probe"}

See this task end-to-end →

Delete a live post from platforms. Use when the user asks to take a published post down or delete it from a platform. Deletes the live post from its platforms, or from one destination with destination_id, and requires acknowledge=true after the user confirms. A deletion counts as done only when read-back shows the post gone; where the platform has no delete API it returns the steps to delete it in the app. To remove only A1 Lane's record, use delete_draft.

Annotations: destructive, openWorld

InputTypeRequiredNotes
post_idstringrequiredPost id (post_…) from create_draft, list_posts or a receipt.
destination_idstringoptionalDestination id (dst_…) to remove from one platform only; omit to remove every live copy.
acknowledgebooleanrequiredMust be true, and only after the user confirms the deletion.
idempotency_keystringoptionalOptional client-chosen key (8-200 chars of A-Z a-z 0-9. _: -). Replaying the same key returns the original result and executes nothing again; a key never forces past an uncertain outcome.
{"post_id": "post_…", "acknowledge": true}

See this task end-to-end →

Measure

Read what each platform reports, with the time it was read.

Get a post's engagement. Use when the user asks how a post performed: its views, likes, comments, shares or stats. Returns, per destination, the latest platform-reported views, likes, comments and shares with the time each was read, plus their history. A metric the platform does not report is marked unavailable with the reason, never shown as zero.

Annotations: readOnly, idempotent

InputTypeRequiredNotes
post_idstringrequiredPost id (post_…) from create_draft, list_posts or a receipt.
{"post_id": "post_…"}

See this task end-to-end →

Get engagement totals. Use when the user asks how their accounts or posts did over a period, for engagement totals, or for a performance report. Returns engagement totals for the last days (default 30, limited by the plan's history) per metric, platform and account. Posts whose platform did not report a metric are left out of that metric and counted with the reason, never counted as zero.

Annotations: readOnly, idempotent

InputTypeRequiredNotes
daysintegeroptionalWindow in days, 1 to 366; default 30.
{"days": 1}

See this task end-to-end →

See which metrics each platform reports. Use when the user asks why a metric is missing or which numbers are available for a platform. Returns which engagement metrics each platform exposes, which need extra permission, and how often they are read. Discord and Telegram report none; X reads stay off until the operator enables them because X bills per read.

Annotations: readOnly, idempotent

No inputs.

{}

See this task end-to-end →

Get best times to post. Use when the user asks when to post or what time to schedule on one account. Returns the best weekday and hour slots from that account's own past engagement; it does not change any schedule. With too little history it says "Not enough data yet." instead of guessing.

Annotations: readOnly, idempotent

InputTypeRequiredNotes
account_idstringrequiredAccount id from list_accounts (acc_…).
{"account_id": "acc_…"}

See this task end-to-end →

Errors, with the server's fix hints

Every error is {code, reason, fix_hint}. The hints below are produced by the server's own error translator on this request.

CodeReason (example)fix_hint
invalid_inputcaption is required.Fix the field named in the reason.
unauthorizedThe token is invalid, expired or revoked.Re-authorize (OAuth) or create a new workspace token.
plan_limitPlan limit reached on this workspace's plan. The call was not performed.Tell the user which plan limit was reached; nothing was changed, and the same call will be refused again.
forbiddenForbidden.The token lacks the permission; scopes nest read ⊂ write ⊂ publish, and manage/approve are never token-grantable.
not_foundPost not found.Check the id against list_posts / list_accounts; another workspace's objects are invisible here.
conflictDestination is uncertain.Run resolve_attention action=probe first; if the probe reports absent, retry normally. Forcing needs acknowledge_force_retry with acknowledge=true.
too_largeFile too large.Use a smaller file or free space in the library.
rate_limitedToo many requests.Wait and retry; limits are per token and per account plan.
provider_unavailableThe platform or an upstream provider did not answer correctly.Retry later; nothing was published.
server_errorThe request could not be completed; no changes were confirmed.Retry; if it persists, contact support.

All tools, A–Z

cancel_scheduled · create_draft · create_upload_link · delete_draft · get_batch_status · get_best_times · get_delivery_digest · get_engagement_coverage · get_engagement_rollup · get_handoff_pack · get_platform_schema · get_post_engagement · get_receipt · get_upload_status · get_verification_status · list_accounts · list_attention_items · list_posts · pause_workspace · request_approval · resolve_attention · schedule_draft · submit_batch · unpublish_post · update_draft_settings · upload_media

Directory listings of our assistant connector are not platform approvals.