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.
{}
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
| Input | Type | Required | Notes |
|---|---|---|---|
platform | string | optional | One platform to describe; omit to get every platform. |
{"platform": "…"}
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
| Input | Type | Required | Notes |
|---|---|---|---|
since | string | optional | ISO-8601 instant with offset; default 24 hours before until. |
until | string | optional | ISO-8601 instant with offset; default now. |
{"since": "2026-09-19T09:00:00-07:00"}
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
| Input | Type | Required | Notes |
|---|---|---|---|
status | string | optional | Filter: active, attention, all, draft, pending_approval, approved, scheduled, queued, publishing, published, published_limited, partial, failed, held, cancelled and other stored statuses; omit for all. |
limit | integer | optional | Most posts to return; default 50. |
offset | integer | optional | How many of the newest matching posts to skip, for the next page; use the nextOffset a previous call returned. Default 0. |
{"status": "…"}
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
| Input | Type | Required | Notes |
|---|---|---|---|
url | string | required | Public https link to the video or image file the user supplied. |
title | string | optional | Optional library title for the file. |
tags | array | optional | Optional library tags for finding the file later. |
idempotency_key | string | optional | Optional 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"}
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
| Input | Type | Required | Notes |
|---|---|---|---|
filename | string | optional | Optional file name to show the user on the upload page. |
expires_in_minutes | integer | optional | How long the link stays open, 5 to 1440 minutes. |
idempotency_key | string | optional | Optional 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": "…"}
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
| Input | Type | Required | Notes |
|---|---|---|---|
link_id | string | required | Upload link id (lnk_…) returned by create_upload_link. |
{"link_id": "lnk_…"}
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
| Input | Type | Required | Notes |
|---|---|---|---|
caption | string | optional | Post text, up to 10,000 characters; each platform's own limit is checked at validation (see get_platform_schema). |
media_id | string | optional | Media id (med_…) from upload_media or the library. |
media_ids | array | optional | Ordered 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. |
destinations | array | required | One entry per connected account to post to, each with its account_id and optional per-account overrides. |
scheduled_at | string | optional | Planned ISO-8601 instant with offset; used when scheduling. |
first_comment | string | optional | Posted as the first comment after the destination is verified live, on platforms whose get_platform_schema entry has supportsFirstComment true. |
parts | array | optional | Thread 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. |
utm | object | optional | UTM tags added to links in the caption, for example {"source": "bluesky", "campaign": "launch"}. |
labels | object | optional | Small key/value object stored with the post for the user's own grouping, for example {"campaign": "spring"}. |
idempotency_key | string | optional | Optional 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_…"}]}
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
| Input | Type | Required | Notes |
|---|---|---|---|
post_id | string | required | Post id (post_…) from create_draft, list_posts or a receipt. |
caption | string | optional | Post text, up to 10,000 characters; each platform's own limit is checked at validation (see get_platform_schema). |
media_id | string | optional | Media id (med_…) from upload_media or the library. |
media_ids | array | optional | Ordered 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. |
destinations | array | optional | One entry per connected account to post to, each with its account_id and optional per-account overrides. |
scheduled_at | string | optional | Planned ISO-8601 instant with offset; used when scheduling. |
first_comment | string | optional | Posted as the first comment after the destination is verified live, on platforms whose get_platform_schema entry has supportsFirstComment true. |
parts | array | optional | Thread 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. |
utm | object | optional | UTM tags added to links in the caption, for example {"source": "bluesky", "campaign": "launch"}. |
labels | object | optional | Small key/value object stored with the post for the user's own grouping, for example {"campaign": "spring"}. |
idempotency_key | string | optional | Optional 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_…"}
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
| Input | Type | Required | Notes |
|---|---|---|---|
posts | array | required | The posts to create, each shaped like create_draft's arguments plus an optional mode. |
labels | object | optional | Small key/value object stored on every post in the batch. |
same_asset_override | boolean | optional | true applies same_asset_override to every item. |
idempotency_key | string | optional | Optional 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_…"}]}]}
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
| Input | Type | Required | Notes |
|---|---|---|---|
post_id | string | required | Post id (post_…) from create_draft, list_posts or a receipt. |
idempotency_key | string | optional | Optional 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_…"}
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
| Input | Type | Required | Notes |
|---|---|---|---|
post_id | string | required | Post id (post_…) from create_draft, list_posts or a receipt. |
idempotency_key | string | optional | Optional 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_…"}
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
| Input | Type | Required | Notes |
|---|---|---|---|
post_id | string | required | Post id (post_…) from create_draft, list_posts or a receipt. |
{"post_id": "post_…"}
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
| Input | Type | Required | Notes |
|---|---|---|---|
post_id | string | required | Post id (post_…) from create_draft, list_posts or a receipt. |
mode | string | optional | now 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_at | string | optional | When to send, as an ISO-8601 instant with offset, for example 2026-11-03T09:00:00-08:00. |
queue_account_id | string | optional | Account id (acc_…) whose posting-slot schedule picks the time, for mode queue. |
idempotency_key | string | optional | Optional 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_…"}
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
| Input | Type | Required | Notes |
|---|---|---|---|
post_id | string | required | Post id (post_…) from create_draft, list_posts or a receipt. |
idempotency_key | string | optional | Optional 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_…"}
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
| Input | Type | Required | Notes |
|---|---|---|---|
account_id | string | optional | Account id (acc_…) to pause or resume alone; omit for the whole workspace. |
resume | boolean | optional | true lifts the pause instead of setting it. |
reason | string | optional | Optional note shown with the pause. |
idempotency_key | string | optional | Optional 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_…"}
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
| Input | Type | Required | Notes |
|---|---|---|---|
batch_id | string | required | Batch id (batch_…) returned by submit_batch. |
{"batch_id": "batch_…"}
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
| Input | Type | Required | Notes |
|---|---|---|---|
post_id | string | required | Post id (post_…) from create_draft, list_posts or a receipt. |
{"post_id": "post_…"}
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
| Input | Type | Required | Notes |
|---|---|---|---|
post_id | string | optional | Post id (post_…) to check; omit to check the workspace's active posts. |
limit | integer | optional | Most posts to return when post_id is omitted; default 50. |
{"post_id": "post_…"}
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.
{}
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
| Input | Type | Required | Notes |
|---|---|---|---|
post_id | string | required | Post id (post_…) from create_draft, list_posts or a receipt. |
action | string | required | Which fix to apply; see the tool description for each. |
destination_id | string | optional | Destination id (dst_…) from get_receipt or list_attention_items: one account's copy of the post. |
acknowledge | boolean | optional | Set true only after the user accepts the stated risk; required by acknowledge_force_retry and confirm_deleted. |
idempotency_key | string | optional | Optional 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"}
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
| Input | Type | Required | Notes |
|---|---|---|---|
post_id | string | required | Post id (post_…) from create_draft, list_posts or a receipt. |
destination_id | string | optional | Destination id (dst_…) to remove from one platform only; omit to remove every live copy. |
acknowledge | boolean | required | Must be true, and only after the user confirms the deletion. |
idempotency_key | string | optional | Optional 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}
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
| Input | Type | Required | Notes |
|---|---|---|---|
post_id | string | required | Post id (post_…) from create_draft, list_posts or a receipt. |
{"post_id": "post_…"}
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
| Input | Type | Required | Notes |
|---|---|---|---|
days | integer | optional | Window in days, 1 to 366; default 30. |
{"days": 1}
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.
{}
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
| Input | Type | Required | Notes |
|---|---|---|---|
account_id | string | required | Account id from list_accounts (acc_…). |
{"account_id": "acc_…"}
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.
| Code | Reason (example) | fix_hint |
|---|---|---|
invalid_input | caption is required. | Fix the field named in the reason. |
unauthorized | The token is invalid, expired or revoked. | Re-authorize (OAuth) or create a new workspace token. |
plan_limit | Plan 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. |
forbidden | Forbidden. | The token lacks the permission; scopes nest read ⊂ write ⊂ publish, and manage/approve are never token-grantable. |
not_found | Post not found. | Check the id against list_posts / list_accounts; another workspace's objects are invisible here. |
conflict | Destination is uncertain. | Run resolve_attention action=probe first; if the probe reports absent, retry normally. Forcing needs acknowledge_force_retry with acknowledge=true. |
too_large | File too large. | Use a smaller file or free space in the library. |
rate_limited | Too many requests. | Wait and retry; limits are per token and per account plan. |
provider_unavailable | The platform or an upstream provider did not answer correctly. | Retry later; nothing was published. |
server_error | The 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.