New:Microsoft Teams Notifications Are Now Available in Socket.Learn more →
Get Started

ihateposting-mcp

Package Overview
Dependencies
Maintainers
1
Versions
13
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

ihateposting-mcp

MCP server for iHatePosting — draft, schedule, and inspect social posts from Claude, Cursor, or any MCP client.

latest
npmnpm
Version
0.12.0
Version published
Maintainers
1
Created
Source

ihateposting-mcp

npm

MCP server for iHatePosting — draft, schedule, and inspect social posts from Claude, Cursor, ChatGPT, or any MCP client.

Write once, publish everywhere: iHatePosting cross-posts to Bluesky, X, LinkedIn, Facebook, Instagram, Threads, Mastodon, Telegram, Discord, Tumblr, Slack, Pinterest, TikTok and YouTube.

Sign in, or use an API key

Remote clients that support MCP sign-in (OAuth) need no key at all: point them at https://ihateposting.com/mcp/oauth, sign in to iHatePosting in the browser and press Allow (see Remote clients below).

This package, the local stdio server, takes an API key instead: iHatePosting → Settings → Developers → create a key (pk_live_…). Treat it like a password: it can post on your behalf.

Tools

ToolWhat it does
whoamiWhich iHatePosting account this key belongs to — the login, not a social handle
get_platform_rulesEach network's real limits: characters, media, aspect ratios, video specs
validate_postCheck a draft against those rules before spending a post
create_postCreate a post — publish now, schedule, or save as a draft
list_postsYour posts, newest first, with per-platform status and live URLs — 50 a page by default, up to 200, with filters
list_accountsYour connected social accounts and their health
list_pinterest_boardsThe Pinterest boards you can pin to, with the boardId a pin requires
get_analyticsHow the posts did — per channel, with the top ones named
reschedule_postMove a scheduled post to a different date and time
list_mediaThe images and videos already in the library, with the ids create_post wants
upload_mediaPut a new image or video in the library from a URL (or small base64) and get an id back
open_upload_widgetIn clients that show MCP app widgets, a file picker in the conversation for a file on your computer
get_postOne post in full: per-platform copy, options, media, per-send outcome
update_postRewrite a draft or scheduled post — replaces what you send
retry_postSend a failed post again; a send that published is left alone
delete_postRemove a post. This does NOT unpublish anything already live

Apart from open_upload_widget, which is registered first, they are declared in that order because it is the order a model reads them, and it is the working sequence: know whose account this is, see what the networks allow, check the draft, then spend the post — and only then manage what is already there.

Use it

Claude Desktop / Claude Code / Cursor (local, stdio)

Requires Node.js 20 or later (since 0.10.0).

{
  "mcpServers": {
    "ihateposting": {
      "command": "npx",
      "args": ["-y", "ihateposting-mcp"],
      "env": { "IHATEPOSTING_API_KEY": "pk_live_…" }
    }
  }
}

Remote clients (hosted, HTTP)

Clients that can't run a local process use the hosted server instead.

Sign in — no key (preferred). If the client supports MCP sign-in (OAuth), add this address and nothing else:

https://ihateposting.com/mcp/oauth

The client opens your browser; sign in to iHatePosting and press Allow. It discovers the sign-in from the server's own metadata and registers itself, so there is no client id or secret to enter. Claude's connector directory, Cursor and Grok Build connect this way. Take a sign-in back under Settings → Developers → Connected apps.

With an API key, for clients that cannot sign in, use https://ihateposting.com/api/mcp and pick whichever your client supports:

Client can sendUse
A custom headerAuthorization: Bearer pk_live_… (preferred)
Only a URLhttps://ihateposting.com/api/mcp?key=pk_live_…

⚠️ A key in a URL can end up in browser history, proxy logs and Referer headers. Prefer the header when your client allows it, and rotate the key (Settings → Developers) if a URL containing it gets shared.

Environment

VariableDefaultNotes
IHATEPOSTING_API_KEY—Required (stdio). Your pk_live_… key.
IHATEPOSTING_API_URLhttps://ihateposting.comOverride for self-hosted/staging.
IHATEPOSTING_CLIENT—Optional. Which tool is running this, e.g. claude-desktop; calls are recorded with that name.

Notes

  • Pinterest also requires a BOARD. list_pinterest_boards is the only way to learn one — a board id is an opaque number, so without it a pin cannot be created at all.
  • Instagram, Pinterest, TikTok and YouTube all require media. upload_media fetches a file from a URL (the reliable way, and the only one for video) or takes small files as base64, and hands back an id for create_post. A file that exists only on your computer is better uploaded with open_upload_widget where the client supports it, or in the composer, and found afterwards with list_media.
  • A post that goes to several platforms is saved as a group, one row per platform. update_post can rewrite a row of a group when you send back that row's own accountIds; adding or swapping an account is refused with a sentence saying so, because it would publish some platforms twice. To change which platforms a group posts to, delete it and create it again.
  • A draft is different: it stays ONE row for every platform it is aimed at until it is scheduled. Deleting it removes every platform (the reply's platformsRemoved names them), and reschedule_post refuses it — schedule a draft with update_post and action schedule, which checks each platform and splits it into one row per platform.
  • delete_post removes iHatePosting's record. A post already live on a network stays live, which is why it asks for force before touching one.
  • Every call is scoped to the key's owner; the server holds no state of its own.

MIT © iHatePosting

Keywords

mcp

FAQs

Package last updated on 05 Oct 2026

Related posts