IMMA AI Docs
MCP reference

Tools

Every MCP tool exposed by the IMMA AI MCP server, its arguments, an example call and result, and the rules it enforces.

Preview

Preview: the API and MCP server are in private beta; details may change.

Each tool below mirrors a REST API resource one to one (see MCP reference for the full mapping table), so argument names match the REST request bodies in the API reference. A key's scopes control which tools appear in tools/list; a tool that needs a scope your key does not have is simply not offered to the agent.

list_accounts

When to use it: Call this first in almost any workflow. It lists connected social accounts with platform, username, connection status and remaining daily posting quota, so the agent can find the right account IDs before doing anything else.

Scope: accounts:read

Input

FieldTypeRequiredDescription
profile_idstringNoRestrict to one profile's accounts
platformstringNoFilter to tiktok, instagram, facebook or threads

Output

{
  "accounts": [
    { "id": "acc_tt_01J...", "platform": "tiktok", "username": "dapursekar", "status": "active", "quota_remaining": 12 },
    { "id": "acc_ig_01J...", "platform": "instagram", "username": "dapursekar", "status": "active", "quota_remaining": 87 }
  ]
}

Notes: status is one of active, needs_reconnect, revoked or error (see docs/architecture/data-model.md); a value other than active flags a connection that needs attention, see Troubleshooting.

get_account_capabilities

When to use it: Before building a post for an account you have not used yet, especially TikTok, to learn what is actually allowed: privacy options, max video length, and whether comment, duet and stitch can be toggled at all.

Scope: accounts:read

Input

FieldTypeRequiredDescription
account_idstringYesThe account to inspect

Output

{
  "account_id": "acc_tt_01J...",
  "platform": "tiktok",
  "privacy_level_options": ["PUBLIC_TO_EVERYONE", "MUTUAL_FOLLOW_FRIENDS", "SELF_ONLY"],
  "max_video_post_duration_sec": 180,
  "comment_disabled_by_creator": false,
  "duet_disabled_by_creator": false,
  "stitch_disabled_by_creator": true
}

Notes: This calls TikTok's creator_info live, not a cache, so it reflects the creator's current settings. It never returns a privacy_level for the agent to use directly: privacy is always chosen by the account owner, see create_post below.

upload_media

When to use it: Before referencing media in create_post or create_posts_batch. Accepts a public URL for any media type. Inline base64/data URL upload is images only, for an image the agent's own AI just generated (ADR-20: IMMA AI does not generate images itself, it only stores and validates what the agent produced). Video must be supplied as a URL.

Scope: posts:write

Input

FieldTypeRequiredDescription
urlstringOne of url/dataPublic URL IMMA AI downloads
datastringOne of url/dataRaw base64 or a data URL (data:image/png;base64,...)
profile_idstringYesOwning profile

Output

{ "id": "med_01J...", "status": "processing", "type": "image" }

Notes: Same size limit and MIME whitelist as a dashboard upload: images (JPEG, PNG, WebP, HEIC) up to 20MB. Video is not supported through the inline data path, send a url or use the presigned upload flow instead. Referencing a media ID that is still processing in create_post does not fail the call, the target simply waits for the media to become ready. An oversized payload returns payload_too_large; an unrecognized MIME type returns unsupported_format.

validate_post

When to use it: Before create_post or create_posts_batch, especially for a first-time account or an unfamiliar caption format. Dry runs the same validation without creating anything, so the agent can fix problems before committing.

Scope: posts:write

Input: same shape as create_post, below.

Output

{ "valid": false, "issues": [
  { "target_id": "tgt_1", "field": "media[0]", "code": "media_too_long", "message": "Video is longer than this account allows (180s)." }
] }

Notes: Nothing is persisted by this call, it is safe to call repeatedly while iterating on a draft.

create_post

When to use it: To create and schedule a single post across one or more accounts.

Scope: posts:write

Input

FieldTypeRequiredDescription
profile_idstringYesThe profile this post belongs to
captionstringYesPost text
mediaarrayYesMedia IDs from upload_media, one entry per target's media
targetsarrayYesOne entry per account: { account_id, instagram?, tiktok? }, same shape as POST /posts
scheduled_atstringNoISO 8601 with a UTC offset; omit to post as soon as approved
approvalobjectNo{ mode: "link" | "none", notify? }, defaults to "link"
ai_generatedbooleanNoDefaults to true for MCP-created posts

Output

{
  "id": "post_01J...",
  "status": "awaiting_approval",
  "approval": { "id": "apr_...", "url": "https://getimma.com/approve/k8Fq2...", "expires_at": "..." },
  "targets": [
    { "id": "tgt_1", "account_id": "acc_ig_...", "status": "awaiting_approval" },
    { "id": "tgt_2", "account_id": "acc_tt_...", "status": "awaiting_approval" }
  ],
  "warnings": []
}

Notes: Never choose a privacy level for the user. For TikTok targets, create_post does not accept privacy_level or interaction toggles from the agent; if sent, they are ignored and the result includes a warning ("Privacy is chosen by the account owner on the approval page"). Use the default hosted approval link (recommended, works from any client) or tiktok.mode: "inbox" to send a draft to the creator's TikTok inbox. See Platform rules for why this cannot be skipped. create_post applies idempotency automatically, based on a hash of the arguments, for 10 minutes, so an agent that retries the same call does not create a duplicate post (same rule as reply_comment, see M14 FR-M14-12).

create_posts_batch

When to use it: To create up to 31 scheduled drafts or posts in one call, for example a month of content, instead of calling create_post in a loop.

Scope: posts:write

Input

FieldTypeRequiredDescription
profile_idstringYesThe profile these posts belong to
itemsarray (max 31)YesEach item has the same shape as create_post's input (caption, media, targets, scheduled_at, approval, ai_generated)

Output

{ "results": [
  { "index": 0, "status": "awaiting_approval", "id": "post_01J...", "approval": { "url": "https://getimma.com/approve/..." } },
  { "index": 1, "status": "error", "error": { "code": "quota_exceeded_for_day", "message": "TikTok daily quota is full for 2026-10-02." } }
] }

Notes: Each item is validated and returned independently, one bad item does not block the rest. Idempotency applies per item, not per call. Every TikTok item still goes through approval or inbox mode, with no batch-level shortcut. Daily platform quota is checked per target day from that item's scheduled_at, not just against the whole batch, so one full day does not reject the rest of the month.

get_calendar

When to use it: Before calling create_posts_batch, to see what is already scheduled, published or drafted, so the agent avoids clashing with existing posts and can fill empty days.

Scope: posts:read

Input

FieldTypeRequiredDescription
fromstringYesStart date (ISO 8601)
tostringYesEnd date, at most 90 days after from
profile_idstringYesThe profile to read the calendar for

Output

{ "timezone": "Asia/Jakarta", "slots": [
  { "post_id": "post_01J...", "scheduled_at": "2026-10-01T18:30:00+07:00", "status": "scheduled",
    "platforms": ["instagram", "tiktok"], "caption_preview": "Rendang 1 kg, pre-order..." }
] }

Notes: Times are in the workspace's own timezone. Results are summarized (not the full post detail) to keep the response small. A range longer than 90 days is rejected so the result stays useful in a limited context window.

get_post

When to use it: To check a specific post's status per target, its permalink once published, or a plain-language error if a target failed.

Scope: posts:read

Input

FieldTypeRequiredDescription
post_idstringYesThe post to look up

Output

{ "id": "post_01J...", "status": "published", "targets": [
  { "id": "tgt_2", "account_id": "acc_tt_...", "status": "published", "permalink": "https://www.tiktok.com/@dapursekar/video/..." }
] }

list_posts

When to use it: To see recent or upcoming posts, for example to summarize what is scheduled this week.

Scope: posts:read

Input

FieldTypeRequiredDescription
statusstringNoFilter by status
fromstringNoStart date
tostringNoEnd date

Output

{ "data": [
  { "id": "post_01J...", "status": "scheduled", "scheduled_at": "2026-10-01T18:30:00+07:00" }
], "cursor": { "next": null, "has_more": false } }

Notes: Same { data, cursor } shape as GET /posts, see Pagination. 20 items per page, so a large history does not fill up the agent's context.

update_post

When to use it: To change a post's caption or schedule before it starts publishing.

Scope: posts:write

Input

FieldTypeRequiredDescription
post_idstringYesThe post to update
captionstringNoNew caption
scheduled_atstringNoNew schedule time

Output

{ "id": "post_01J...", "status": "scheduled", "caption": "Updated caption text", "scheduled_at": "2026-10-01T19:00:00+07:00" }

Notes: Only works while the post has not yet moved into publishing. A TikTok target already awaiting_approval keeps its existing approval link; changing the caption does not silently re-approve it.

cancel_post

When to use it: To stop a scheduled or draft post before it publishes.

Scope: posts:write

Input

FieldTypeRequiredDescription
post_idstringYesThe post to cancel

Output

{ "id": "post_01J...", "status": "canceled" }

Notes: Same restriction as update_post: only works before publishing starts.

get_analytics

When to use it: To report performance, either for one post or for an account over a date range.

Scope: analytics:read

Input

FieldTypeRequiredDescription
post_idstringOne of post_id/account_idMetrics for a single post
account_idstringOne of post_id/account_idMetrics for an account
fromstringNoStart date (account queries)
tostringNoEnd date (account queries)

Output

{ "account_id": "acc_ig_...", "from": "2026-09-01", "to": "2026-09-27",
  "views": 48210, "reach": 31022, "likes": 2104, "comments": 88, "shares": 41, "follower_trend": [ { "date": "2026-09-27", "followers": 4120 } ] }

list_comments

When to use it: To read recent comments on an account so the agent can triage or draft replies.

Scope: inbox:write

Input

FieldTypeRequiredDescription
account_idstringNoFilter to one connected account
statusstringNoopen, replied or hidden

Output

{ "comments": [
  { "id": "cmt_01J...", "account_id": "acc_ig_...", "text": "Harga berapa untuk 1kg?", "author_handle": "@pembeli123", "created_at": "..." }
] }

Notes: Instagram, Facebook and Threads only. TikTok comments are not available through the API.

reply_comment

When to use it: To reply to a specific comment found through list_comments.

Scope: inbox:write

Input

FieldTypeRequiredDescription
comment_idstringYesComment to reply to
textstringYesReply text

Output

{ "id": "cmt_reply_01J...", "status": "sent" }

Notes: Instagram, Facebook and Threads only, same as list_comments. Idempotency is applied automatically based on a hash of the arguments for 10 minutes, so a retried call does not send a duplicate reply.

generate_caption

When to use it: To draft captions and hashtags using IMMA AI's own light built-in assistant. This is mainly for dashboard-only users without their own AI subscription; an agent connected through MCP usually already writes captions itself and does not need this tool.

Input

FieldTypeRequiredDescription
briefstringYesWhat the post should be about
languagestringYesen or id
platformsarrayYesTarget platforms, affects tone and length

Output

{ "captions": [
  { "platform": "instagram", "text": "Rendang 1 kg, pre-order sampai Jumat.", "hashtags": ["#rendang", "#preorder"] }
] }

Notes: The user must be able to edit the draft before it is posted; a tool call alone never publishes it.

Common workflows

Post to TikTok and Instagram with approval

Prompt: "Post this video to TikTok and Instagram tomorrow at 18:30, and ask the owner to approve it first."

  1. list_accounts finds the TikTok and Instagram account IDs.
  2. upload_media uploads the video by url (inline base64 upload only works for images).
  3. validate_post checks for problems before creating anything.
  4. create_post with approval: { mode: "link" } returns approval.url.
  5. The agent replies with the approval link to send to the account owner.

A month of Ramadan content, with images, sent for approval

Prompt (Indonesian): "Buatkan kalender konten Ramadan sebulan untuk toko kue saya, dengan gambar, jadwalkan jam 19.00 WIB, kirim ke saya untuk approval."

Prompt (English): "Build a 30 day Ramadan content calendar for my cake shop, with images, schedule for 7pm local time, and send it to me for approval."

  1. list_accounts finds the TikTok and Instagram account IDs.
  2. get_calendar for the target month shows which slots are already taken, so the new posts do not clash.
  3. The agent writes a daily brief itself (Ramadan themes, relevant dates) and drafts a caption per day with its own writing ability, then generates an image per post with its own image generation ability. IMMA AI does not generate images itself, see MCP reference.
  4. upload_media is called once per image with inline data, returning a media ID each time.
  5. validate_post checks a few sample items before sending the whole batch (optional but recommended).
  6. create_posts_batch sends all items (up to 31) with approval: { mode: "link" } and ai_generated: true. The response's results[] includes an approval.url per TikTok target.
  7. The agent replies with a summary: the drafts are scheduled and waiting for approval, with the link(s) to send the owner.

Weekly performance summary

Prompt: "Summarize this week's performance across all my accounts."

  1. list_accounts lists every connected account.
  2. get_analytics is called per account with from/to covering the last 7 days.
  3. The agent summarizes views, reach and engagement trends in plain language.

On this page