mcp-blotato-higgsfield
by keerthanar24
README.md
# mcp-blotato-higgsfield
An MCP server that combines [Higgsfield](https://higgsfield.ai/mcp) (AI image/video
generation) with **direct, native posting to X, YouTube, Instagram, Facebook, and
Bluesky** — no Blotato or other paid middleman required. A composite
`generate_and_post` tool chains the two halves together.
> This project originally aggregated Blotato's hosted MCP for social publishing.
> Blotato has no free tier — its API/MCP access requires a paid plan starting at
> $29/mo — so publishing was rebuilt to talk to each platform's own free/native API
> directly instead. See "Why not Blotato" below.
## What's in here
- **Higgsfield** — connected as an MCP *client* to Higgsfield's official hosted MCP
server (it ships one already; we don't reimplement its API). Exposed as
`higgsfield__<tool>`.
- **Direct social publishers** — hand-written, native API integrations for:
| Platform | API | Auth |
|---|---|---|
| X (Twitter) | REST v1.1 (media) + v2 (tweet) | OAuth 1.0a user-context app |
| YouTube | YouTube Data API v3 | Google OAuth2 refresh token |
| Instagram | Meta Graph API (Content Publishing) | Long-lived token + Business/Creator account |
| Facebook | Meta Graph API | Page access token |
| Bluesky | AT Protocol | App password (no OAuth, no app review) |
Each is exposed as `<platform>__post` and only appears in the tool list once
its credentials are set.
- **`generate_and_post`** — generate media from a prompt via Higgsfield, then fan
out and publish it to whichever of the above platforms you ask for, in one call.
## Why not Blotato
Blotato is a paid unified API/MCP over these same platforms. Wrapping it yourself
doesn't avoid the cost — its API key is gated the same way whether you call it
through Blotato's hosted MCP or your own client. Going direct means:
- **Free** for X (limited tier), YouTube (free daily quota), and Bluesky (fully open).
- Meta (Instagram/Facebook) is free but requires app review for anything beyond
your own test accounts.
- You take on what Blotato was abstracting: a separate developer app + OAuth flow
per platform, and keeping up with each API's own quirks.
## Setup
```bash
npm install
cp .env.example .env # fill in credentials for the platforms you want, see below
npm run build
```
You don't need every platform configured — the server only advertises tools for
what's set. Start with Bluesky (easiest, no approval process) if you want to try
it end-to-end quickly.
### Higgsfield
Higgsfield's hosted MCP is OAuth-only. Authorize once via `mcp-remote`, which opens
a browser and caches the token locally:
```bash
npx -y mcp-remote https://mcp.higgsfield.ai/mcp
```
Then set in `.env`:
```
HIGGSFIELD_TRANSPORT=stdio
HIGGSFIELD_MCP_COMMAND=npx
HIGGSFIELD_MCP_ARGS=-y mcp-remote https://mcp.higgsfield.ai/mcp
```
### Bluesky (start here — easiest)
1. In the Bluesky app: Settings → App Passwords → create one.
2. Set `BLUESKY_IDENTIFIER` (your handle, e.g. `you.bsky.social`) and
`BLUESKY_APP_PASSWORD`.
No developer account, no app review, no OAuth. Works immediately.
### X (Twitter)
1. Create a project/app at [developer.x.com](https://developer.x.com).
2. Under the app's "Keys and tokens", generate: API Key/Secret and an
**Access Token & Secret with Read and Write permissions** (regenerate the
access token after changing permissions, or it stays read-only).
3. Set `X_API_KEY`, `X_API_SECRET`, `X_ACCESS_TOKEN`, `X_ACCESS_TOKEN_SECRET`.
⚠️ X's free-tier limits (post volume, whether media upload is included) have
changed more than once — check your app's current tier in the developer portal.
### YouTube
1. In [Google Cloud Console](https://console.cloud.google.com), create a project,
enable the **YouTube Data API v3**, and create an OAuth2 **Desktop app** client
ID (gives you a client ID + secret).
2. Get a refresh token once via the OAuth consent flow with scope
`https://www.googleapis.com/auth/youtube.upload` (e.g. using
[Google's OAuth Playground](https://developers.google.com/oauthplayground)
with your own client ID/secret plugged in under its settings gear icon).
3. Set `YOUTUBE_CLIENT_ID`, `YOUTUBE_CLIENT_SECRET`, `YOUTUBE_REFRESH_TOKEN`.
Free tier: 10,000 quota units/day; one video upload costs ~1,600 units (~6
uploads/day).
### Instagram
1. Requires an Instagram **Business or Creator** account connected to a Facebook Page.
2. Create a Meta app at [developers.facebook.com](https://developers.facebook.com),
add the Instagram + Facebook Login products.
3. Generate a long-lived access token with the `instagram_content_publish`
permission (works immediately for your own account in dev mode; posting on
behalf of others needs Meta App Review).
4. Set `IG_ACCESS_TOKEN` and `IG_USER_ID` (your Instagram Business Account ID,
fetched via `GET /me/accounts` → `GET /{page-id}?fields=instagram_business_account`).
### Facebook
1. Same Meta app as above.
2. Generate a **Page access token** (not a user token) with `pages_manage_posts`.
3. Set `FB_PAGE_ACCESS_TOKEN` and `FB_PAGE_ID`.
## Running
```bash
npm run build && npm start
# or, for local development without a build step:
npm run dev
```
This starts an MCP server on **stdio**.
### Add it to Claude Code / Claude Desktop
```json
{
"mcpServers": {
"blotato-higgsfield": {
"command": "node",
"args": ["/absolute/path/to/mcp_blotato_higgsfield/dist/index.js"],
"env": {
"HIGGSFIELD_TRANSPORT": "stdio",
"HIGGSFIELD_MCP_COMMAND": "npx",
"HIGGSFIELD_MCP_ARGS": "-y mcp-remote https://mcp.higgsfield.ai/mcp",
"BLUESKY_IDENTIFIER": "you.bsky.social",
"BLUESKY_APP_PASSWORD": "...",
"X_API_KEY": "...", "X_API_SECRET": "...",
"X_ACCESS_TOKEN": "...", "X_ACCESS_TOKEN_SECRET": "..."
}
}
}
}
```
Or with the Claude Code CLI:
```bash
claude mcp add blotato-higgsfield -- node /absolute/path/to/dist/index.js
```
## How it works
```
src/
config.ts # env-driven config for the Higgsfield upstream connection
clients/
upstream.ts # generic MCP client wrapper (http or stdio transport)
publishers/
types.ts # Publisher interface + fetchMediaBytes helper
x.ts # X (Twitter) via twitter-api-v2
youtube.ts # YouTube Data API v3, multipart upload
instagram.ts # Meta Graph API content-publishing flow
facebook.ts # Meta Graph API page posting
bluesky.ts # AT Protocol via @atproto/api
metaGraph.ts # shared helpers for instagram.ts/facebook.ts
index.ts # publisher registry
tools/
passthrough.ts # namespaces + re-lists Higgsfield's MCP tools
publishers.ts # exposes each configured publisher as <platform>__post
composite.ts # generate_and_post: Higgsfield -> fan out to publishers
index.ts # our own MCP server (stdio), wires it all together
```
- On `tools/list`, we return Higgsfield's upstream tools (prefixed `higgsfield__`),
one `<platform>__post` tool per *configured* publisher, and `generate_and_post`
when Higgsfield + at least one publisher are configured.
- On `tools/call`, a `higgsfield__*` name routes to the upstream MCP client; a
`<platform>__post` name routes to that publisher; `generate_and_post` runs the
composite flow.
- We don't hardcode Higgsfield's exact tool/field names (they can change) —
`generate_and_post` **discovers** the right Higgsfield tool at runtime by
matching tool names (e.g. `/generate.*video/i`) and guesses common field names
against its real input schema. Pass `higgsfield_args` to override explicitly if
the guess is wrong. Publisher-side fields (media URL, caption, platform-specific
options) are handled directly by each publisher, since we wrote those ourselves
against each platform's real, stable API — no guessing needed there.
## Known limitations
- Media handling: X, YouTube, and Bluesky's upload APIs take raw bytes, so those
publishers download the generated media first. Instagram/Facebook's Graph API
accepts a remote URL directly, so no download happens there.
- YouTube upload uses a single multipart request rather than the full resumable-
upload protocol — fine for short AI-generated clips, but large files should use
resumable upload instead.
- Higgsfield's tool discovery is heuristic (see above) since its schema isn't
hardcoded here.
- None of the publishers implement an in-process OAuth *authorization* flow —
you obtain each platform's token/credentials out-of-band (see Setup above) and
the server just uses them.
Maintenance
ActivityMaintained
ResponsivenessSyncing