Repository navigation
Releases: iHatePostingOrg/agent-skill
Releases · iHatePostingOrg/agent-skill
Release list
v0.7.3
- A file bigger than the whole library has its own refusal. A single file
larger than the person's entire media library (500 MB on the Free plan and
the 90-day trial) is refused with a sentence that names both sizes.
Deleting cannot make room for it, so the skill now says to upload a smaller
version instead of sending the person to free space — the opposite of what
a full library needs. Added to both skills and todocs/api.md. The hosted
connector gives the same advice with that refusal, and the npm package
ihateposting-mcpdoes from its next release, 0.12.6. - Telegram's limits, measured. iHatePosting now uploads the files to
Telegram itself, so the limits are Telegram's limits for uploads: photos up
to 10 MB (they were 5 MB), video up to 50 MB inside an album as well as
alone (it was 20 MB in an album), and a new limit on the whole post —
every file together, at most 50 MB. Indocs/platforms.md. - The first Release since 0.7.1, so it also carries 0.7.2, which never
had one of its own: a full library names the screen where files can be
deleted,reschedule_postrefuses a failed post, the per-minute caps are
120, and the command line's skill installs withnpx skills add. The 0.7.2
notes inCHANGELOG.mdhave the details.
v0.7.1
How to change a scheduled post, said outright. An agent editing a scheduled
post sent action: "draft", was refused, tried the same call eight times and
then moved to reschedule_post, which cannot change text, so the edit was
never made.
- Changing a scheduled post. Read it with
get_post, then send
update_postwithaction: "schedule"and itsscheduledLocaldate and
time: it is changed and stays scheduled.action: "draft"on a scheduled
post is refused, because it would take the post off the schedule, and the
refusal now names the exact call to make.reschedule_postonly moves a
post's time. Added to both skills and todocs/platforms.md. get_platform_rulesneeds no key. It lists public facts, the same for
everyone, so a client that has not signed in yet can read them. Needs the
iHatePosting MCP server 0.12.1 (npm) or the hosted connector.
v0.7.0
An agent's three most common dead ends on iHatePosting now get a precise
answer instead of a bare refusal, and the skill and docs say how to read it.
One sentence in the skill said the opposite of what is now true (that
validate_post takes platform names only), so this is a minor release.
validate_posttakes account ids. Itsplatformsis now exactly
create_post's: a name checks every active account on that platform, an
account id checks that one account. Agents that handedvalidate_post
the same arguments ascreate_post, as the skill says to, were refused
for the id. Needs the iHatePosting MCP server 0.12.0 (npm) or the hosted
connector;ihateposting post --to <account id> --checkworks from CLI
0.6.0.- An account id as an
optionsoroverrideskey is read as that
account's platform. One customer's agent keyed YouTube's options by the
account id and got only "Invalid key in record". Two keys for one platform
are refused, saying options apply per platform. - A 404 on a post says which kind it is.
post_deletedwith
deletedAtwhen the post was deleted or removed (an agent that deleted
three posts and read them back to check was told only "not found");
post_not_foundwhen no post in the account has that id, with
didYouMeanwhen the id is one of the user's with a few characters
wrong. The skill says to confirm a suggested post with the user before
acting on it.
v0.6.0
The iHatePosting server now checks what an agent sends instead of quietly
ignoring it, and the skill, its references and the docs describe that.
Several sentences here used to say the opposite, so this is a minor release.
- Option names and values are checked. A key a network does not read
used to be saved and ignored: one customer's agent sentmadeForKidsfive
times and was refused each time for theytMadeForKidsit never set, and
privacy: "unlisted"published a YouTube video publicly. Mastodondirect
posted as public. Now such a key or value is refused with a 400, drafts
included. The 400 names the key that was meant ("did you mean
ytMadeForKids?") and lists the network's options.get_platform_rules
lists every option with its allowed values, not only the required ones. - A draft is scheduled with
update_post.reschedule_postrefuses a
draft. It used to schedule one without the network checks, so a post could
be armed that the publisher would only skip at send time.update_post
withaction: "schedule"runs the checks and splits the post per account. - Times come back in the owner's timezone too. Every reply that carries
scheduledAt(UTC) also carriesscheduledLocal: date, time and timezone.
whoamireturnsownerTimezone, andlist_postsfromandtoare whole
days in that timezone. - Refused instead of quietly dropped or changed:
- a date sent without
action: "schedule", which was saved as a draft; - a date that does not exist, such as 2027-02-30, which rolled into March;
- a media id that is not in the library;
- an unknown TikTok audience word, which became private.
- a date sent without
validate_posttakescreate_post's arguments (optionsand
overridesin the same shape, which it used to strip) and fills a missing
YouTube title the waycreate_postdoes, so the two answers agree.- A refused tool call is marked as an error (
isError), so a host or a
workflow no longer reads a refused post as made. - Uploads by link go one at a time per account. A second one waits up to
20 seconds for its turn, then answers 429. - The hosted server carries all of this; the local npm server gets the tool
side inihateposting-mcp0.11.0. Every option value in the examples and
the docs' samples (36 of them) is one the new checks accept.
v0.5.7
- The local npm server needs Node.js 20 or later.
ihateposting-mcp
0.10.0 moved to the MCP SDK v2 (@modelcontextprotocol/server2.2.0),
which requires Node.js 20, and the README now says so above thenpx
config. The hosted server, which every manifest in this package connects
to, asks nothing new of you; it now also speaks the 2026-07-28 MCP
protocol, so Claude and ChatGPT no longer fall back to the older one. - The MCP Registry lists
com.ihateposting/mcp0.10.0 (published
2026-10-02), with the same two addresses as before and the npm server at
0.10.0.
v0.5.6
- The README describes the MCP Registry entry as it now is. The official
MCP Registry listscom.ihateposting/mcp0.9.1-1 (published 2026-09-29)
with both addresses,https://ihateposting.com/mcp/oauthfor signing in
first andhttps://ihateposting.com/api/mcpfor a key, plus the npm
serverihateposting-mcp. The README still said the entry pointed only
at/api/mcp.
v0.5.5
- The README's logo loads from ihateposting.com, with the address under
it. Its first line wasassets/logo.svgas a plain Markdown image, and
Claude's plugin directory does not load such an image until you ask, so
the plugin's Contents tab opened on an empty "Show Image" box above the
heading. The logo is now the site's own icon
(https://ihateposting.com/apple-icon.png, the square mark, 180 px), linked
to the site, which is how the README's badges were already written:
Claude's viewer shows a linked image as its link text, and GitHub shows
the image. Under it, the website address. The viewer shows HTML as raw
text, so neither line uses any. Cursor and Grok Build still show the logo
fromassets/logo.svg, which their manifests name.
v0.5.4
- Every listing names the 14 networks. The description each directory
shows (Claude's plugin directory, Cursor, Grok Build, Gemini CLI, Qwen Code
and Kimi Code) said "14 social networks" without saying which; it now names
X, LinkedIn, Instagram, Facebook, TikTok, YouTube, Threads, Bluesky,
Pinterest, Mastodon, Telegram, Discord, Tumblr and Slack. - Where each agent signs in, corrected. Gemini CLI opens the browser when
it starts and connects to the server, not when a tool first runs (it starts
the sign-in on the server's 401 whenoauth.enabledis set). Grok Build
signs in from/mcps: select ihateposting and pressi; its tools stay
hidden until then. Cursor's MCP servers now live under Customize, then
MCPs. The README, the skill and the Grok Build manifests say so. whoamiin the README names the login a connection acts for, signed in or
with a key, instead of "the login the key belongs to".- The README says Claude plugins need a paid Claude plan (Pro, Max, Team or
Enterprise), and points the Free plan at Claude's connector directory. - Kimi Code gets a manifest,
.kimi-plugin/plugin.json. Kimi Code
(Moonshot AI) installs a plugin from a GitHub repository's latest release
with/plugins install. Its manifest names the server inline, at the same
sign-in address as every other agent here, withtransportset tohttp
and no key. When the server asks for a sign-in, Kimi Code offers an
authenticatestep that opens the browser. Read from Kimi Code's source at
release 2.1.1 (app/plugin/manifest.ts, mcpCore/config-schema.ts,
mcpCore/connection-manager.ts); not yet run in Kimi Code itself.
scripts/check.mjschecks the new manifest like the others. - A copy of the skill for ClawHub, in
clawhub/ihateposting/. OpenClaw
and Hermes Agent install skills from ClawHub and add the MCP server by hand,
so this copy drops the plugin's sign-in steps, its Claude Code tool list and
its licence line (ClawHub publishes every skill under MIT-0), and explains
the tool-name prefixes those agents use. Itsreferences/platform-options.md
is the plugin's file, andscripts/check.mjsfails if the two drift. Not
yet published to ClawHub. - Cursor, ready for its Marketplace. The manifest's homepage is now the
Cursor page at ihateposting.com, which leads with the sign-in, and it names
its category (integrations, as most listed integrations do). The README's
Cursor section says how to install from the Marketplace, and adds three
things Cursor's documentation says about a local copy: a symlink pointing
elsewhere is skipped, on Teams and Enterprise an admin controls it with
Allow Local Plugin Imports (off by default on Enterprise), and a
Marketplace install takes the local copy's place. The
manifest validates against Cursor's own schema (cursor/plugins).
v0.5.3
- Qwen Code gets its own manifest,
qwen-extension.json. Without one,
Qwen Code installed this repository throughgemini-extension.json, which
it checks before the Claude marketplace, and copied that file's server
entry unchanged. Qwen Code readsurlas the older SSE transport and only
httpUrlas Streamable HTTP, so it would have tried SSE against a server
that speaks Streamable HTTP. Qwen Code reads its own manifest first, so the
new file decides:httpUrlset to the same sign-in address as every other
agent here, no key and no settings. Read from Qwen Code's source
(packages/core/src/extension/extension-converter.ts and
config/mcp-server-config.ts); not yet run in Qwen Code itself. - Install with
qwen extensions install iHatePostingOrg/agent-skill:ihateposting,
then choose Authenticate on iHatePosting in/mcp. The server already
accepts Qwen Code's sign-in: its redirect address is on localhost, and the
resource it asks for is exactly the one the server's metadata names. scripts/check.mjschecks the new manifest like the others: the name,
httpUrl, nourl,type, headers or settings, and the shared version.
v0.5.2
- Claude's plugin directory clears the plugin. 0.5.1 was still held under
"Uses a credential from the user's machine" with the same 3 findings, so
the command-line fallback was not the cause. The directory named what it
had matched: "the installer's pass $$".passis also the Unix password
manager, and ten phrases in the skill read like it: "passaccountId",
"PassytTitleto both", "unless you passforce: true" and so on. They
were in exactly the two files it flagged, SKILL.md and
references/platform-options.md, and nowhere else. All ten now say send,
give, set or accept, with the same meaning. Checked before release: the
directory validated a branch with only this change and reported no policy
holds. - Run against the same checks, gitroomhq/postiz-agent is held for 9 findings
of this kind and is listed anyway, so a hold goes to a reviewer rather than
refusing a plugin. Ours no longer needs one.