Automate posting and Warmup with MCP
Connect your assistant from Connect AI in the Web App. The MCP endpoint is
/api/mcp on your tame Web App. Your assistant signs in through tame and uses
the permissions of the Operator who connected it.
This workflow needs a Mac that is online, provisioned Devices and Accounts already signed into Instagram or TikTok. Initial Device trust, Platform sign-in and verification challenges still need a person. MCP never accepts Platform passwords or session credentials.
Discover before scheduling#
list_clients,list_fleetandlist_accountssupply the real identifiers.list_actionswithplatform: "instagram"orplatform: "tiktok"returns Action ids, media limits and input definitions. Use these inputs rather than guessing names from the interface. The photo publication family ispost.list_warmupshows the Mac-reported niches, Session preferences, ramp, Device policy and schedule participation.
Owners and Managers can use save_account to add a tame Account record,
set_account_device to assign it, and delete_account to remove the tame
record. Omitting devicePseudonym from set_account_device unassigns it without
removing it. These operations do not create, delete or sign into the Account
on the Platform. Wait for each request to be applied before issuing work that
depends on it.
delete_account removes the record from the one Mac it is addressed to. If the
same handle was saved on two Macs, list_accounts lists both under macs with
the Device each has it on, and the Mac with the Device is the one in charge of
its Posts. Address delete_account to the other Mac to remove the extra copy
and keep the working one.
Rename Devices#
Use list_fleet to find the Mac's id, the Device's pseudonym, and its
nameVersion. Call rename_device with:
{
"installationId": "<Mac id>",
"devicePseudonym": "<Device pseudonym>",
"expectedVersion": 0,
"displayName": "Studio 01"
}
Use the actual nameVersion as expectedVersion. Names contain 1 to 80
characters. Send displayName: null to restore the detected name. Renaming
changes only the label, preserving Device IDs, Accounts and schedules. The
Web App reflects the saved label immediately; the updated Desktop App receives
it on its next sync. Owner, Manager and Team Member can rename accessible
Devices. If the name changed elsewhere, read list_fleet again before retrying.
Upload generated slides and preserve their order#
For every slide, call begin_content_upload, send the file bytes directly to
the returned upload URL, then call complete_content_upload. Keep the returned
Content Item ids in your intended slide order. Generation happens in your
integration; these tools receive the finished media.
Call schedule_post with contentItemIds in that exact order. The first id is
slide 1. Do not sort by filename, upload completion time or id. Legacy
contentItemId is for a single item; never send both forms.
The following is an illustrative TikTok request. Replace the placeholders with actual ids and future RFC 3339 UTC timestamps. The window must be at least 15 minutes long; a shorter one is refused, because a window of a minute or two closes before the Mac can start the Post:
{
"accountId": "<Account id>",
"actionId": "post",
"contentItemIds": ["<slide 1 id>", "<slide 2 id>", "<slide 3 id>"],
"caption": "Your caption",
"values": { "privacy": "Only you" },
"windowStart": "<future UTC start>",
"windowEnd": "<future UTC end>"
}
Current photo carousels take 2–10 slides on Instagram and 2–9 on TikTok. The Action catalog is authoritative. Order is preserved in storage and Device delivery. Instagram stops before publication when a selected slide is missing, rather than appending it in the wrong position. Platform selection remains subject to screen recognition; inspect the actual Post outcome.
For recurring publication, use save_action_schedule. Each slot's items
contains one occurrence per entry, with ordered contentIds, values and
optional localDate/localTime. A dated occurrence uses the Schedule's IANA
time zone. Keep the existing slots when updating a Schedule and supply its
current revision.
Captions and music#
schedule_post.caption is copied to the Action's caption input. Other inputs
belong in values, using the names from list_actions.
Instagram photo Posts support named music through these Action values:
{
"music": "A track by name",
"trackTitle": "Your track title",
"trackArtist": "Optional artist"
}
The track must be available to that Account. Check the catalog for the inputs
of other Actions, such as Reels. Top-level music and musicVolume arguments
are not supported by MCP publication. Exact volume selection is not supported.
TikTok music-track selection is not implemented. Its photo publication Flow removes automatically added sound. Do not promise a selected soundtrack for a TikTok carousel. Unsupported Action inputs are refused rather than ignored.
A 15-minute niche Session#
First set the Account's keywords with set_account_niches, sending the complete
list you want to keep. Wait until list_accounts reports the new list.
Then call start_account_warmup:
{
"installationId": "<Mac id>",
"devicePseudonym": "<Device pseudonym>",
"platform": "tiktok",
"handle": "your.handle",
"sessionOptions": {
"durationMinutes": 15,
"source": "niche",
"likePercent": 20,
"followPercent": 5
}
}
Use platform: "instagram" for Instagram. The time budget accepts 1–60
minutes, including browsing navigation. Niche-only Sessions keep searching
saved niches until the budget ends, a failure occurs or you stop them. A failed
search does not silently switch to the ordinary feed.
Percentages are probabilities per eligible watched item, not guaranteed counts.
Zero disables that engagement. Foundation does not follow. Saves and comments
are not percentage-controlled Warmup inputs. withSearch: true is the separate
shortcut for one search attempt during an ordinary Session; do not combine it
with sessionOptions.
Daily and pre/post preferences#
Call save_account_warmup_session with the Account identity and sessionOptions:
{
"durationMinutes": 15,
"source": "niche",
"likePercent": 20,
"followPercent": 0,
"beforePostMinutes": 2,
"afterPostMinutes": 1,
"endsAt": "<chosen RFC 3339 end timestamp>"
}
This replaces the complete preference set. Omitted values use automatic
behavior; {} clears it. Pre/post visits accept 0–60 minutes independently of
the daily Session length. Zero skips that visit. The browsing source and
engagement settings apply to both. A failed pre-post visit prevents publication;
a failed after-post visit does not erase a confirmed Post or authorize a retry.
An explicit before-post visit must fit within one third of the remaining
Posting Window, leaving the rest for publication. If it cannot fit, widen the
window or reduce the requested minutes; tame does not silently shorten it.
endsAt stops scheduling new daily visits. It can be sooner than 7 days. Manual
Sessions and scheduled Posts remain available. Ramp days are a separate setting:
save_account_warmup sets Account overrides, while save_warmup_policy controls
Device defaults and which Accounts participate. Saving Session preferences alone
does not enable the daily schedule.
Shared defaults for all Devices#
list_warmup returns defaults.version, defaults.settings and
defaults.sessionOptions. Use save_warmup_defaults for the same Edit defaults
control shown above the Warmup queue in both apps. Send the complete settings and
Session bundle, preserving values you did not intend to change:
{
"expectedVersion": 0,
"settings": {
"intensity": "standard",
"rampDays": 14,
"maxVisitsPerDay": 10,
"wakeHour": 6,
"sleepHour": 0,
"nicheSearches": "often"
},
"sessionOptions": {
"durationMinutes": 15,
"source": "niche",
"likePercent": 20,
"followPercent": 0,
"beforePostMinutes": 2,
"afterPostMinutes": 1
},
"applyToExistingDevices": true
}
Use the version you read, not always zero. Add clientId to choose a visible
Client. Stale versions are refused. The optional endsAt timestamp can stop daily
Warmup after any duration, including one or three days; ramp days are separate.
New or unconfigured Devices use the saved rhythm. With
applyToExistingDevices: true, existing Device policies also receive it. This
preserves their enabled state, included Accounts and Account rhythm overrides.
With false, existing Device policies stay unchanged. Session defaults apply to
Accounts without custom Session preferences regardless of that flag.
An Account's custom Session preferences are a complete bundle, including automatic
values. Use save_account_warmup_session with {} to follow shared defaults again,
or with {"source":"automatic"} to explicitly retain automatic behavior for all
Session fields. The response to saving shared defaults says status: "saved" and
returns the new version and count of Device policies updated. It does not start
work or mean a Mac has applied the change. Current Desktop Apps apply on their
next permitted heartbeat; older Desktop versions must be updated for shared
Session defaults. Execution outcomes still come from list_activity and
list_posts.
Both apps expose these controls under Settings → Customize Warmup, grouped as Daily Warmup, Browsing & niches and Around Posts. Every control is available over MCP:
| App control | MCP tool and input |
|---|---|
| Shared defaults above the queue | save_warmup_defaults, read via list_warmup.defaults |
| Follow shared Session defaults | save_account_warmup_session with sessionOptions: {} |
| Session length | save_account_warmup_session.sessionOptions.durationMinutes |
| End date, including 1 or 3 days | save_account_warmup_session.sessionOptions.endsAt as the chosen UTC timestamp |
| Browse: Automatic, Feed only, Niches only | save_account_warmup_session.sessionOptions.source: automatic, feed, niche |
| Likes / follows | save_account_warmup_session.sessionOptions.likePercent / followPercent |
| Before / after posting | save_account_warmup_session.sessionOptions.beforePostMinutes / afterPostMinutes |
| Search frequency | save_account_warmup.nicheSearches: rarely, sometimes, often |
| Intensity / ramp / daily limit | save_account_warmup.intensity / rampDays / maxVisitsPerDay |
| Active hours | save_account_warmup.wakeHour / sleepHour, in the Mac's local time |
| Saved keywords | set_account_niches.niches, the complete list |
| Device defaults, inclusion, schedule on/off | save_warmup_policy |
| Run one Session / force a search | start_account_warmup, optionally withSearch: true |
| Stop the current Session | stop_device |
| Reset defaults | save_account_warmup with clear: true, plus save_account_warmup_session with sessionOptions: {} |
Read list_warmup before replacing either preference set, preserve unrelated
values, and track both request IDs when changing both groups. Search frequency
is a probability per Automatic Session: Rarely halves the phase-dependent
default, Sometimes uses it, and Often multiplies it by 2.5 with a 60% cap.
Feed only and Niches only bypass that dial. The same Account preferences govern
visits around manual, dated and recurring Posts on both Platforms.
Comments your Accounts leave on a niche search#
Your assistant can write and manage the same comment bank as the Comments page. The rules are enforced by tame, not by the assistant: a comment with a link, more than 20 hashtags or 5 mentions, over 300 characters, or near enough to one already in the bank is refused, and the refusal says why.
Who says a comment: everything for every Account, plus what is written for an Account, minus what is blocked for it, and only on niches that Account searches. A comment for chosen Accounts on a niche some of them do not search is not said by those Accounts until the niche is added to them.
| Comments page | MCP tool and input |
|---|---|
| The cards, with counts and who searches each niche | list_comment_niches |
| The comments, with who says each and who is blocked | list_comments |
| Add a comment, for every Account or chosen ones | save_comment with body, niches, and accountIds for chosen Accounts |
| Who says it | set_comment_accounts, the complete list; empty means every Account |
| Blocked for | set_comment_blocks, the complete list; empty removes every block |
| Not on this niche, for a comment on every niche | set_comment_skipped_niches, the complete list; or skipNiches on save_comment |
| Add a niche to Accounts | save_niche_to_accounts with niche and accountIds |
| Remove this comment | delete_comment |
| Delete this niche, once no Account searches it | delete_comment_niche |
| Whether Accounts comment, and how much | list_comment_settings |
| Turn commenting on or off | set_commenting |
| Comments a day, the gap, the cooldowns, how often a post is considered, the canary | set_comment_settings, only what changes; null goes back to the recommendation |
Adding a niche to an Account changes what it searches during Warmup, not only
what it comments, so ask before calling save_niche_to_accounts. It applies when
the Mac next checks in, within a few minutes. To replace an Account's whole list
of niches, or take one off it, use set_account_niches.
Every comment setting has tame's recommendation as its default and limits it cannot go past: at most 10 comments a day, at least 30 minutes apart, and a comment never said twice within a day. The canary is off unless you turn it on; with it on, a new comment is said by one Account and held from the others for 48 hours.
The Write comments for a niche prompt walks an assistant through this: it reads the niche and what is already written, proposes a list, and waits for you before saving anything.
Requests, results and errors#
A returned intentId is a request, not proof that work ran. Poll
find_request_status with that id:
| Status | Meaning |
|---|---|
| pending | Waiting for a capable Mac to collect it |
| delivered | Collected, without an acknowledgement yet |
| applied | The Mac accepted/applied the command; a Session may still be running |
| refused | The Mac refused it; cause explains why |
| expired | No acknowledgement arrived in time; do not blindly repeat it |
Use list_activity for completed Sessions and their durations, outcomes and
failure causes. Use list_posts for publication outcomes and list_schedule
for upcoming work. With includeWarmup: true, list_schedule also returns each
scheduled Account's planned Warmup Sessions for today and tomorrow: every one
carries values.minutes (its length) and values.status (planned, due,
running, done, cancelled, failed or missed), as the Mac last reported
them. Activity is separate from request acknowledgement; it does
not currently link a Session directly to its originating intentId.
start_device/stop_device and start_fleet/stop_fleet control execution.
cancel_post cancels pending publication. Pausing the Warmup policy is separate
from stopping the current Session. Do not resubmit a Post merely because a
request timed out; check whether it published first.
An offline Mac leaves changes pending. New Session preferences require an updated Desktop App; older builds do not collect those commands. MCP does not yet provision, resolve or remove Devices. Initial setup and these Device management operations remain Desktop App work.
Optional automatic failure reports#
list_failure_reporting returns { "enabled": false, "version": 0 } before
anyone saves the Workspace setting. Owners and Managers can change it with
set_failure_reporting:
{ "enabled": true, "expectedVersion": 0 }
Use the actual version returned by list_failure_reporting. Enable sharing only
when the Operator explicitly requests it: screenshots can contain personal
information visible on the Device. Reports include the reporting member,
Device and Account details, app version, the last 300 lines of the Mac’s log (which can include names and words seen on screen), and the technical steps leading to the
failure. They are private to authorized tame support staff and expire after
30 days.
The setting applies to all Macs in the Workspace. Connected Desktop Apps pick
it up within about 30 seconds. Send enabled: false with the latest version to
stop future sharing and clear pending uploads on their next sync. Reports
already received remain until expiry. MCP does not upload failure screenshots,
read internal support reports or grant staff permission.