Getting startedMCP server

MCP server

Connect Claude, Cursor, or any Streamable HTTP MCP client.

Streamable HTTP MCP

The HumanPost MCP server turns publishing, content-tagging, account, queue, analytics, and usage operations into structured tools that compatible AI clients can discover and call.

Create an API key in the dashboard →

Connection details#

HumanPost MCP

Server URL

https://us-central1-clickbaitcarousel.cloudfunctions.net/mcp

Authentication

Send your API key as the HTTP header Authorization: Bearer YOUR_API_KEY. The server does not use browser login sessions.

Verifies authentication, tool discovery, company, and scopes. The key is cleared after the test.

Client setup#

Create a key with the tools' required scopes, replace YOUR_API_KEY, and restart the client if it does not discover tools immediately.

01

Claude Code

Register HumanPost as a user-level Streamable HTTP server.

claude mcp add --scope user --transport http humanpost https://us-central1-clickbaitcarousel.cloudfunctions.net/mcp --header "Authorization: Bearer YOUR_API_KEY"

02

Claude (web/desktop)

Add HumanPost as a custom connector in Claude.

  1. 1.Open Settings, then Connectors.
  2. 2.Choose Add custom connector and paste the MCP URL.
  3. 3.Under Request headers, add Authorization with the value Bearer followed by your API key.
URL: https://us-central1-clickbaitcarousel.cloudfunctions.net/mcp
Authorization: Bearer YOUR_API_KEY

03

Cursor

Add this server entry to your Cursor mcp.json file.

{
  "mcpServers": {
    "humanpost": {
      "url": "https://us-central1-clickbaitcarousel.cloudfunctions.net/mcp",
      "headers": {
        "Authorization": "Bearer YOUR_API_KEY"
      }
    }
  }
}

04

Any client

Use Streamable HTTP transport and send the API key on every request.

{
  "name": "humanpost",
  "transport": {
    "type": "streamable-http",
    "url": "https://us-central1-clickbaitcarousel.cloudfunctions.net/mcp"
  },
  "headers": {
    "Authorization": "Bearer YOUR_API_KEY"
  }
}

Tool catalog#

The catalog and schemas are generated from the running tools. MCP tools/list includes input and output schemas, required scopes, and read/write annotations. Tool failures return isError plus structuredContent.error with requestId, field details, and retryability. Keep idempotency keys and payloads unchanged when retrying.

These focused publishing tools enforce the API key's scopes on every call. A client can discover a tool even when the current key cannot run it.

ToolWhat it doesRequired scope
list_task_typesDiscover comment and Amplify inputs, credit costs, availability and blockers. Optionally inspect a company account. Worker business hours apply; review remains with HumanPost. Requires tasks:read.tasks:read
create_taskCreate an exact Comment or one Amplify request containing Repost + Like and Comment. Requires idempotencyKey; keep payload unchanged for retries. No worker or payout overrides. Creation reserves one credit. Requires tasks:write.tasks:write
list_tasksList company-visible requests and effective status. Operational Amplify children and comment replacements are embedded in the original task. Follow nextCursor even after an empty filtered page. Requires tasks:read.tasks:read
get_taskRead combined Amplify progress or the full bounded comment attempt chain under one stable task ID. Completed means approved; submitted screenshots await review. Requires tasks:read.tasks:read
list_task_eventsPage persisted task revisions; events arrive asynchronously. historyComplete is false for legacy tasks; missing history is not invented. Requires tasks:read.tasks:read
get_task_evidencePage current and archived screenshots with expiring signed URLs. Requires company task ownership. URLs are bearer links until expiry; no worker personal data is included. Requires tasks:evidence:read.tasks:evidence:read
cancel_taskCancel unfinished Comment or Amplify work while retaining evidence/history. Cancellation cannot undo platform actions. Amplify refunds only before either component is approved. Requires tasks:write.tasks:write
resume_taskResume failed/expired components of an unfinished Amplify bundle on the original account and worker. Approved components stay complete; no additional credit is charged. Requires tasks:write.tasks:write
get_contextCall first to confirm the key's company, scopes, available tools, and publishing capabilities.Job scope / authenticated context
list_accountsInspect account IDs, eligibility, daily usage, queue depth, and stored profilePictureUrl, bio, and warmupSearchTerms before choosing targets. Setup values may be requested; stored values do not independently verify the live platform profile or completed warm-up. One account per platform per post. Requires accounts:read.accounts:read
get_accountRead one company-owned publishing account, including stored profilePictureUrl, bio, and warmupSearchTerms. Setup values may be requested; pending profile edits retain previous values until worker approval. This does not independently verify the live platform profile or completed warm-up. Requires accounts:read.accounts:read
get_company_scheduleRead the company's daily posting windows; account overrides take precedence. Requires accounts:read.accounts:read
update_company_scheduleReplace company windows while preserving account overrides. Example: {schedule:{windows:['08:00','17:00']}}. null restores global rules, not a pause; future dispatches only, in worker-local time, up to four posts/day including make-up posts. Requires accounts:write.accounts:write
get_account_scheduleRead the override, company default, effective windows, source, and worker timezone. Requires accounts:read.accounts:read
update_account_scheduleReplace an account's daily worker-local windows. schedule:null restores company inheritance, not a pause. Future dispatches only, up to four posts/day including make-up posts. Requires accounts:write.accounts:write
get_account_queuePage through queued targets. Pass nextCursor back as cursor, even after an empty page. scheduledAfter is an earliest release instant, not a guaranteed posting time. Requires posts:read.posts:read
create_accountSubmit a complete TikTok or Instagram profile to the worker setup pool. Account setup is asynchronous. Requires accounts:write.accounts:write
upload_mediaImport a public sourceUrl (auto-completed), or provide filename, contentType and actual sizeBytes for a signed PUT. After PUT with requiredHeaders, call complete_upload. Videos: MP4/MOV, H.264/HEVC, AAC, <=200MB, <=3 minutes, <=2160x3840, <=60fps; images: JPG/PNG/WebP/HEIC <=50MB. Supported video is not transcoded. Requires posts:write.posts:write
get_upload_statusInspect pending, ready, or failed uploads and corrective errors. Requires posts:read.posts:read
complete_uploadValidate media after the signed PUT finishes. Ready uploads replay safely. Requires posts:write.posts:write
create_upload_batchStart a resumable, ordered import of up to 100 public media URLs. Poll get_job; results retain input indices and per-file errors. Use an idempotencyKey for safe retries. Requires posts:write.posts:write
get_jobPoll a batch upload, draft preview, or analytics report. Access requires the job's scope. Completed jobs return their ordered results or report.Job scope / authenticated context
create_postCreate one-video or 2–20-image post and submit it to up to one account per platform. Managed approval rules apply unless skipApproval is explicitly requested. For review first, use create_draft. Use idempotencyKey for safe retries; scheduledAfter/expiresAt define a release interval, not exact publication times. Requires posts:write.posts:write
create_draftPrepare a video or carousel without queueing or publishing it. Optional slides keep text editable. Use idempotencyKey for safe retries, then inspect content and request a preview before queue_post. Requires posts:write.posts:write
get_post_contentRead media URLs, slide text/styles, and versionId. Background image URLs expire in 15 minutes. Requires posts:read.posts:read
update_draftReplace draft media or slides, or edit metadata. expectedVersionId detects conflicting artwork edits. Submitted or published posts are rejected. Preview the new version before submitting it. Requires posts:write.posts:write
request_post_previewStart a durable render of the current unqueued draft version without approving or queueing it. Poll get_job or get_post_preview. Old renders cannot replace newer artwork. Requires posts:write.posts:write
get_post_previewRead the current version's preview URLs and pending/ready/failed status. A preview does not submit a draft. Requires posts:read.posts:read
queue_postQueue an existing draft with ready media to at most one account per platform. No media creation. Managed approval rules apply unless skipApproval is explicitly requested. Use idempotencyKey for safe retries; scheduledAfter/expiresAt define a release interval. Requires posts:write.posts:write
get_post_statusRead aggregate and per-account publishing status, release times, and posted URLs. Requires posts:read.posts:read
list_postsPage through company posts filtered by account, status, creation date, or content group. Pass nextCursor as cursor, even if a filtered page has no results. Requires posts:read.posts:read
update_postEdit metadata while every target remains editable. contentGroupIds replaces explicit tags and remains editable after publication; [] clears explicit tags while preserving template provenance. Requires posts:write.posts:write
list_content_tagsRead active and archived company tags and stable contentGroupId values. Requires posts:read.posts:read
create_content_tagCreate an optional internal reporting tag; it does not change public captions. Requires posts:write.posts:write
update_content_tagRename, recolor, archive, or restore a tag. Archiving preserves attribution. Requires posts:write.posts:write
delete_content_tagRemove a custom tag from all company posts. Archive instead to preserve history. Requires posts:write.posts:write
cancel_postCancel pre-release targets and report targets already posting, posted, or cancelled as skipped. Published social posts are not deleted. Requires posts:write.posts:write
get_post_analyticsRead the latest summary and paginate historical destination observations. Inspect lastUpdated/collectedAt for freshness. Requires analytics:read.analytics:read
get_account_analyticsRead legacy latest-200-post totals with scannedPosts and coverage metadata; use create_analytics_report for complete rollup comparisons. Requires analytics:read.analytics:read
create_analytics_reportCreate a durable company-scoped report of UTC-day growth, previous-period comparison, account/platform/tag/template breakdowns, and top destinations by latest cumulative views. Poll get_job. Requires active V3 rollups; availability and freshness are explicit. Requires analytics:read.analytics:read
get_usageRead effective daily caps, counters, plan credits, and the next UTC reset. Requires usage:read.usage:read
get_workspaceRead company/account context. includeAssets:true adds a legacy bounded folder/image-pack snapshot; use paginated folder/image tools for efficient complete asset discovery. Requires workspace:read.workspace:read
list_workspace_foldersPage through company folders with optional name search. Follow nextCursor even after an empty search page. Requires workspace:read.workspace:read
list_workspace_imagesPage through available images in a company-owned folder, optionally searching labels, descriptions, or tags. Requires workspace:read.workspace:read
get_workspace_media_urlsResolve company-owned images to signed download URLs valid for 60–3600 seconds. Caller-supplied storage paths are never accepted. Requires media:read.media:read

create_post accepts 2–20 image upload IDs for a carousel; their upload order is the slide order.

Inspect stored account profiles#

list_accounts({platform: "tiktok"})
get_account({accountId: "ACCOUNT_ID"})

Requires accounts:read. Both tools include stored profilePictureUrl, bio (strings or null), and warmupSearchTerms (an array, empty when absent). Setup placeholders contain requested values; pending profile edits retain previous values until worker approval. These fields let GIMI display and compare stored configuration without independently verifying the live social profile or completed warm-up. create_accountstill accepts warmup.searchTerms (1–5 terms); longer historical lists remain readable.

Review artwork before submission#

Use create_draft, get_post_content, and update_draft with expectedVersionId to edit slide text and styles. request_post_preview renders the current version without approving or queueing it. Poll get_job, inspect get_post_preview, then queue_post. A later artwork edit invalidates the preview.

create_draft({media:["UP1","UP2"],idempotencyKey:"launch-draft-1"})
get_post_content({postId:"POST_ID"})
request_post_preview({postId:"POST_ID",idempotencyKey:"launch-preview-1"})
get_job({jobId:"JOB_ID"}) // poll until complete
get_post_preview({postId:"POST_ID"}) // inspect mediaUrls and status: ready
queue_post({postId:"POST_ID",accountIds:["ACCOUNT_ID"],idempotencyKey:"launch-submit-1"})

Batches and performance reports#

create_upload_batch imports up to 100 URLs with persisted ordered results and per-file errors. create_analytics_report compares UTC-day growth across equal periods, groups by account, platform, tag or template, and ranks destinations by latest cumulative views. Both return a jobId for get_job. Reports expose collection freshness and coverage; dates are UTC midnight, from inclusive to exclusive. Missing observations do not mean zero performance.

Content tags#

Content tags are optional internal reporting groups. They appear beside template attribution in analytics, but never change the public caption or the content sent to a social platform.

  • Tagging is optional. A post can have up to 10 explicit tag or template reporting groups.
  • Use the stable contentGroupId returned when a tag is created, not its display name or bare tagId.
  • contentGroupIds is a replacement list: resend the complete desired list to add or remove one tag, or send [] to remove all explicit tags.
  • Tag assignments can be changed before or after a post is published. Other post fields still follow normal editability rules.
  • A template:<id> group inherited from the template used to create a post is provenance and remains visible even when explicit tags are cleared.
# Create a reusable company tag; keep the returned contentGroupId.
create_content_tag({ name: "Launch", color: "blue" })
→ { contentGroupId: "tag:abc123", ... }

# Add it when creating a post.
create_post({ media: ["UPLOAD_ID"], accountIds: ["ACCOUNT_ID"], contentGroupIds: ["tag:abc123"] })

# Replace the post's tags at any time, including after publishing.
update_post({ postId: "POST_ID", contentGroupIds: ["tag:abc123", "tag:def456"] })

# Remove every explicit tag.
update_post({ postId: "POST_ID", contentGroupIds: [] })

Scheduling posts#

Use get_company_schedule and update_company_schedule for the company default, or get_account_schedule and update_account_schedule for an individual account. Read tools need accounts:read; changes need accounts:write. Set schedule: null to restore inheritance. See Scheduling posts for window selection, examples, and missed-post behavior.

Example workflow#

Connected to HumanPost MCP

You

Upload these 3 videos and spread them across my accounts over the next week. Use the launch caption and trending sound.

Agent

I'll check your ready accounts and queue capacity, upload each video, then create the scheduled posts.

Tools

get_context → list_accounts → upload_media × 3 → create_post (scheduledAfter + idempotencyKey) × 3 → get_post_status × 3

Agent

Done. Three posts are queued with different scheduledAfter dates across seven days. Each becomes eligible for a worker-local posting window after its release date; exact posting times are not guaranteed. I included each post ID for tracking.

Ask for the outcome, not the API calls. A capable agent can inspect your accounts, sequence the right tool calls, and return the IDs you need for follow-up.

Troubleshooting#

401 unauthorized

The key is missing, malformed, or revoked. Confirm the header starts with “Bearer ccb_live_” and rotate the key if its secret was lost.

insufficient_scope

The tool needs a permission the key does not have. Create a new key with the scope shown in the tools table, then update the client configuration.

Media errors

Use a public HTTPS source URL and a supported video or image. Wait for processing before creating a post, and keep carousels between 2 and 20 images.

Conflicts and retries

A version_conflict means artwork changed: read get_post_content and merge your edit into its current versionId. For idempotency_conflict, reuse the original payload or choose a new key for a different operation. Include requestId when asking for support.

Preview or import still pending

Poll get_job with the returned jobId until complete. Use get_post_preview only after rendering completes, and submit only a ready current preview. Partial import results retain indices; reuse successful uploads and retry failed items as a new batch.