# Connect an agent

Canonical page: https://www.socialfaktory.com/docs/mcp

Point an agent client at your SocialFaktory account and let it run a brand end to end, without opening the app.

SocialFaktory is listed in Claude's connector directory. [Open the listing](https://claude.ai/directory/connectors/socialfaktory)

SocialFaktory is a ChatGPT plugin. [Add it to ChatGPT](https://chatgpt.com/plugins/plugin_asdk_app_6acba98d6330819181d1d0fbf6affb98)

Public MCP repository, with setup recipes for Cursor, VS Code and Windsurf: https://github.com/socialfaktory/socialfaktory-mcp

## What it is

A single endpoint your agent client talks to. It can read your brands and channels, generate video and text, upload files, schedule and send posts, and read back how they performed.

It can't connect a social channel or change your plan. What it may spend is bounded by its scopes, the monthly credit cap on its token, and idempotency keys that stop a retry from paying twice. Connecting a channel is a browser sign-in, so it stays in the app.

More for agents: https://www.socialfaktory.com/agents.md

## Get a token

Mint a personal access token in your settings. The secret is shown once, and it works on this endpoint only.

- Scopes decide what the token may do: read on its own, plus generate for anything that spends credits, plus publish for posting.
- Pin it to one brand and it sees only that brand's channels, generations, posts and text. The credit wallet, uploads, actors and products stay shared across the account.
- Set a monthly credit cap and the token starts no paid call once the month's spend reaches it. A text write already running settles at its real cost, which can land a little over.

## Endpoint

`POST https://www.socialfaktory.com/mcp`

Streamable HTTP, protocol version 2025-06-18, bearer authentication on the Authorization header. There is no session id to carry: the token is the session. A GET answers 405.

## Connect from Claude, ChatGPT or Gemini

Add SocialFaktory as a custom connector in the client's settings and paste this address as the server URL. Claude Desktop, claude.ai and Gemini all take it the same way, with no bridge and no local process.

`https://www.socialfaktory.com/mcp`

Using ChatGPT? Add SocialFaktory in one click instead, with no address to paste. [See the ChatGPT plugin](https://www.socialfaktory.com/docs/mcp#chatgpt-plugin)

- There is no token to paste and no client id to create. The app registers itself.
- A consent screen asks which of read, generate and publish to grant, which brand to pin the connection to, how many credits a month it may spend and how long it lasts.
- Disconnect it any time from Settings, API tokens. The app stops working immediately.

### What the consent screen asks

1. Sign in to SocialFaktory if you aren't already. The screen names the app that sent you.
2. Read is always granted and sees your brands, media and posts. Tick the rest. Generate creates video and text on your credits. Publish schedules and sends posts on your channels, so untick it until you trust the brief.
3. Pin it to one brand, or leave it on all brands and it can publish on every channel you have connected.
4. Choose how long the connection lasts, 30, 60 or 90 days.
5. Set a monthly credit cap, or leave it empty for none, then press Connect. You're sent back to the app and it works immediately. It can never connect a channel, change your plan or sign in as you.

## Claude directory

For Claude's connector directory, SocialFaktory serves an address of its own. Connected there, Claude manages your account, writes posts, uploads your own media, and schedules and publishes on every channel you have connected.

[Add to Claude](https://claude.ai/directory/connectors/socialfaktory)

1. Open the SocialFaktory listing in Claude's connector directory.
2. Press Connect. Claude sends you to SocialFaktory.
3. Sign in to your SocialFaktory account.
4. Choose what Claude may do: write posts, publish them, which brand it works on, a monthly credit cap and how long the connection lasts. Confirm, and you're back in Claude, ready to brief it.

`https://www.socialfaktory.com/mcp/claude`

- It doesn't generate AI images, video, voice or music. Make those in the app: once they are in your media library, Claude can schedule and publish them.
- A connection made from the directory works on this address only, and one made on /mcp stays on /mcp. A token you paste yourself works on both.

## ChatGPT plugin

SocialFaktory is a ChatGPT plugin that runs on this same endpoint, with every tool. Added from ChatGPT, it reads your brands and channels, writes posts in your brand's voice, prices and generates video, and schedules and publishes on every channel you have connected. There is no token to paste and no address to copy.

[Add to ChatGPT](https://chatgpt.com/plugins/plugin_asdk_app_6acba98d6330819181d1d0fbf6affb98)

1. Open the SocialFaktory plugin in ChatGPT and add it.
2. ChatGPT sends you to SocialFaktory. Sign in to your account.
3. Choose what ChatGPT may do: read, generate and publish, which brand it works on, a monthly credit cap and how long the connection lasts. Press Connect and you're back in ChatGPT, ready to brief it.

## Connect with a token

Claude Code, Codex and curl are faster with a token you paste yourself. The recipes below still work, unchanged.

### Claude Code

```bash
claude mcp add -s user --transport http socialfaktory https://www.socialfaktory.com/mcp \
  --header "Authorization: Bearer sfp_…"
```


### Codex

```bash
export SOCIALFAKTORY_TOKEN=sfp_…
codex mcp add socialfaktory --url https://www.socialfaktory.com/mcp --bearer-token-env-var SOCIALFAKTORY_TOKEN
```


### Any Streamable HTTP client

Send JSON-RPC 2.0 over POST. Accept both JSON and the event-stream type, and name the protocol version on every request.

```http
POST https://www.socialfaktory.com/mcp
Authorization: Bearer sfp_…
Content-Type: application/json
Accept: application/json, text/event-stream
MCP-Protocol-Version: 2025-06-18

{ "jsonrpc": "2.0", "id": 1, "method": "tools/list" }
```


## Tools

Every tool names the scope it needs. A token without that scope is refused before the tool runs. quote_generation is an optional price check for a video, and generate_text reserves a few credits up front and settles what the write actually used.

- `list_brands` (Read): List the brands this token may act for. A pinned token sees only the brand it is pinned to.
- `list_channels` (Read): List a brand connected social channels with the caption and media limits each one enforces.
- `get_channel_requirements` (Read): Ask the connected social account what it accepts right now: its limits, the TikTok privacy levels the creator allows, and the Pinterest boards a pin can go to.
- `list_formats` (Read): List the video formats a generation can be built from, and the render styles they can be drawn in.
- `get_generation` (Read): Read one generation: where it is, the finished video, and the editor asset it produced. While it runs, stage is its current step, waiting_on names what holds it up and deadline_at is when it would be failed for that. A run waiting on the user will not move until the person acts, so ask them rather than poll.
- `list_generations` (Read): List the generations this token may see, newest first.
- `get_text_generation` (Read): Read one text generation and the variants it wrote.
- `quote_generation` (Read): Show how many credits a generation would use before it starts, so the user can agree to it. Inputs it would refuse to run come back as a refusal instead.
- `create_generation` (Generate): Run a video generation, spending credits already in the account. Quote it first with quote_generation and run only once the user agrees to the quote: the token monthly credit cap is the only other guard on the spend.
- `generate_text` (Generate): Write post variants for a brand from a brief, a link, a finished generation or a media item. Spends the user credits: 3 are reserved up front against the token monthly credit cap, and the write settles at what it used, which can land a little over the cap.
- `create_upload` (Generate): Open a ticket for a file from the user machine, content the service has not seen. Send the bytes in one raw HTTPS PUT to the returned url with exactly the returned headers, then call complete_upload. Limits: 2 GB, 30 minutes, 4096 px a side, 50 megapixels. An editor asset, the default purpose, needs its kind. Purpose video_reference stores a trend remake's source video: pass the ready ticket's video_reference.source_url to create_generation. Purpose actor turns a portrait photo of the user, or of someone who agreed to be cast, into an actor: it needs a name, takes jpg, png, webp or gif up to 10 MB and 4096 px a side, and the ready ticket carries actor.id for create_generation.
- `complete_upload` (Generate): Tell the service the bytes are in place and start the ingest. Safe to call again: the ticket is claimed once, so a repeat reports progress rather than ingesting twice.
- `get_upload` (Read): Read an upload ticket. Poll it every 2 seconds, backing off to 5, for up to 16 minutes: the ingest gives up at 15, so the ticket always reaches ready or failed inside that window. A ready video ticket carries the editor asset id and its thumbnail_url, which a Pinterest pin needs. A ready actor ticket carries the actor id and its portrait_url.
- `list_media` (Read): Browse the finished exports in a brand media library, by folder or by name.
- `create_posts` (Publish): Compose one post per channel from the same media. Drafts by default, which stay inside the service and run no checks; send them one at a time with send_post so a refusal names the channel it belongs to. status "scheduled" instead checks every target first, creates nothing if one fails, then hands the posts to the publisher in the background for the social accounts the user connected: they come back queued, and list_posts shows each one turn scheduled, then published.
- `send_post` (Publish): Send one draft to the social account the user connected for its channel, at its scheduled time or straight away. The channel checks run inside this call, so a refusal comes back here with its code. The post then returns queued and the publisher takes it from there: poll list_posts to see it turn scheduled and then published.
- `list_posts` (Read): List posts with their scheduled time, the link they were released at, and their metrics. A post just sent stays queued until the publisher takes it, then turns scheduled. A release link and metrics appear once the channel reports back, which takes a few minutes.
- `delete_post` (Publish): Delete a post from the account. A scheduled one is withdrawn from the live social channel first, inside this call. A post already published stays online on its channel: only the record here goes. Rescheduling is a delete followed by create_posts.
- `check_reference` (Read): Ask whether a video link can be used as the source of a swap, and if so record it on the account and start fetching that third-party video from its host. Safe to call again while the fetch is running: it reports progress rather than fetching twice.
- `get_wallet` (Read): Read the credit balance of the account the token belongs to, and its auto top-up settings (read-only: they change only in the Billing page).
- `list_actors` (Read): List the actors this account can cast: its own and the ready-made cast, by name, 25 a page. Pass an id as actor_id or actor_ids to quote_generation and create_generation.


## Retrying safely

Pass this argument on every call that spends or publishes. A replay within 24 hours returns the original result, marked replayed, rather than doing the work twice.

`idempotency_key`

## Limits

- 120 calls a minute per token, and 300 requests every 5 minutes per address.
- Cloning a video from a link, and generating still images or carousels, aren't available through an agent yet.

## Gemini, three ways in

Gemini app: add the address as a custom app. The app registers itself, so there are no client credentials to enter under advanced features. Google limits custom apps today to personal accounts, 18 or over, in the United States, in English, connected first on the web, with activity saving on.

Gemini Enterprise: an administrator adds a custom MCP server with the authorization and token addresses from the discovery document, a client id and secret from a registration at /oauth/register with token_endpoint_auth_method client_secret_post and the administrator's callback address, PKCE switched on, and the scopes read, generate and publish. Streamable HTTP only, which is what this endpoint speaks.

Gemini CLI: install the extension and the CLI runs the sign-in itself, consent screen included.

```bash
gemini extensions install https://github.com/socialfaktory/socialfaktory-gemini-extension
```

Gemini API managed agents: name the endpoint as a server tool, with a token you minted in the Authorization header.

```json
{
  "type": "mcp_server",
  "name": "socialfaktory",
  "url": "https://www.socialfaktory.com/mcp",
  "headers": { "Authorization": "Bearer sfp_…" }
}
```

## Support

Something not working, or a question about a connection? We answer within one business day. Write from your account address to hello@socialfaktory.com
