Skip to main content

AI Agents & MCP Integration

Give any LLM agent the ability to publish to Instagram, YouTube, TikTok, LinkedIn, X, Facebook, Threads, Pinterest, Reddit and Bluesky by exposing IndReelForge as a structured tool.

There are two ways to connect:

  1. MCP Server — the easiest. Add one URL to Claude, ChatGPT, Cursor, Claude Code or Gemini CLI and the assistant can post for you. No code. Works on every plan, including Free.
  2. Custom tool / function calling — for your own agents (OpenAI, Anthropic, LangChain, n8n, etc.) using an API key server-side.

Native MCP Connector​

IndReelForge hosts a Model Context Protocol server at:

https://api.indreelforge.com/mcp
  • claude.ai, Claude Desktop and ChatGPT connect with OAuth — paste the URL as a custom connector, sign in and click Allow. No API key.
  • Claude Code, Cursor, Windsurf, Gemini CLI and other clients connect with an Authorization: ApiKey YOUR_API_KEY header.
  • Tools cover uploading video, photos and text, scheduling and queues, upload status/retries and analytics — with the same plan limits and validation as the REST API.
  • Manage connected apps, toggle tools and revoke access at API Keys → Connected Apps.

→ See the full MCP Server guide for per-client setup, the complete tool list, example prompts and troubleshooting.


Auto-Import Resources​

ResourceURLPurpose
OpenAPI 3.0 spechttps://api.indreelforge.com/openapi.jsonAuto-import into agent frameworks
LLM context filehttps://api.indreelforge.com/llm.txtMarkdown-optimized docs for AI assistants

Tool Schema​

Define the tool once and use it with any framework (OpenAI, Anthropic, LangChain, LlamaIndex, n8n AI nodes, etc.):

{
"name": "post_to_social",
"description": "Publish a video or text post to one or more social media platforms via IndReelForge.",
"input_schema": {
"type": "object",
"properties": {
"user": {
"type": "string",
"description": "IndReelForge profile name"
},
"video_url": {
"type": "string",
"description": "Public URL to the video file (MP4/MOV). Omit for text-only posts."
},
"title": {
"type": "string",
"description": "Caption or post text"
},
"platforms": {
"type": "array",
"items": {
"type": "string",
"enum": [
"tiktok", "instagram", "youtube", "facebook",
"x", "linkedin", "threads", "pinterest", "reddit", "bluesky"
]
},
"description": "List of platforms to publish to"
}
},
"required": ["user", "title", "platforms"]
}
}
Use the enum

Defining platforms as an enum array prevents the model from hallucinating platform names like "twitter" or "ig".


Server-Side Handler​

Keep the API key on your server — never send it to the LLM:

// Node.js / Express handler
async function handlePostToSocial(input) {
const form = new FormData();
form.append('user', input.user);
form.append('title', input.title);
if (input.video_url) form.append('video_url', input.video_url);
input.platforms.forEach(p => form.append('platform[]', p));

const res = await fetch('https://api.indreelforge.com/api/upload', {
method: 'POST',
headers: { Authorization: `Apikey ${process.env.INREELFORGE_API_KEY}` },
body: form,
});

return res.json();
}

Anthropic / Claude Tool Use​

import anthropic, requests, os

client = anthropic.Anthropic()

tools = [{
"name": "post_to_social",
"description": "Publish content to social media via IndReelForge.",
"input_schema": {
"type": "object",
"properties": {
"user": { "type": "string" },
"title": { "type": "string" },
"video_url": { "type": "string" },
"platforms": {
"type": "array",
"items": {
"type": "string",
"enum": ["tiktok","instagram","youtube","facebook","x",
"linkedin","threads","pinterest","reddit","bluesky"]
}
}
},
"required": ["user", "title", "platforms"]
}
}]

response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
tools=tools,
messages=[{
"role": "user",
"content": "Post 'We just crossed 10 k users!' to X, LinkedIn and Threads."
}]
)

for block in response.content:
if block.type == "tool_use":
inp = block.input
data = [("user", inp["user"]), ("title", inp["title"])]
for p in inp["platforms"]:
data.append(("platform[]", p))
if "video_url" in inp:
data.append(("video_url", inp["video_url"]))

result = requests.post(
"https://api.indreelforge.com/api/upload_text",
data=data,
headers={"Authorization": f"Apikey {os.environ['INREELFORGE_API_KEY']}"}
)
print(result.json())

OpenAI Function Calling​

import openai, json, requests, os

client = openai.OpenAI()

tools = [{
"type": "function",
"function": {
"name": "post_to_social",
"description": "Publish a video or text post to social media via IndReelForge.",
"parameters": {
"type": "object",
"properties": {
"user": { "type": "string" },
"title": { "type": "string" },
"video_url": { "type": "string" },
"platforms": {
"type": "array",
"items": {
"type": "string",
"enum": ["tiktok","instagram","youtube","facebook","x",
"linkedin","threads","pinterest","reddit","bluesky"]
}
}
},
"required": ["user", "title", "platforms"]
}
}
}]

response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "Post our product launch video to TikTok and Instagram."}],
tools=tools,
tool_choice="auto"
)

for call in response.choices[0].message.tool_calls:
args = json.loads(call.function.arguments)
data = [("user", args["user"]), ("title", args["title"])]
for p in args["platforms"]:
data.append(("platform[]", p))
if "video_url" in args:
data.append(("video_url", args["video_url"]))

result = requests.post(
"https://api.indreelforge.com/api/upload",
data=data,
headers={"Authorization": f"Apikey {os.environ['INREELFORGE_API_KEY']}"}
)
print(result.json())

LangChain Tool​

from langchain.tools import tool
import requests, os

@tool
def post_to_social(user: str, title: str, platforms: list[str], video_url: str = "") -> str:
"""
Publish a video or text post to social media via IndReelForge.
Platforms: tiktok, instagram, youtube, facebook, x, linkedin, threads, pinterest, reddit, bluesky, google_business.
"""
data = [("user", user), ("title", title)]
for p in platforms:
data.append(("platform[]", p))

endpoint = "/api/upload" if video_url else "/api/upload_text"
if video_url:
data.append(("video_url", video_url))

res = requests.post(
f"https://api.indreelforge.com{endpoint}",
data=data,
headers={"Authorization": f"Apikey {os.environ['INREELFORGE_API_KEY']}"}
)
result = res.json()
return f"Posted! Upload ID: {result.get('upload_id', 'n/a')}" if result.get("success") else f"Failed: {result.get('error')}"

Check Upload Status Tool​

Add a check_upload_status tool so the agent can poll for completion:

{
"name": "check_upload_status",
"description": "Check the status of a social media upload by its upload_id.",
"input_schema": {
"type": "object",
"properties": {
"upload_id": { "type": "string" }
},
"required": ["upload_id"]
}
}
// Handler
const res = await fetch(
`https://api.indreelforge.com/api/uploadposts/status?request_id=${input.upload_id}`,
{ headers: { Authorization: `Apikey ${process.env.INREELFORGE_API_KEY}` } }
);
return res.json();

Compatible Frameworks​

IndReelForge works with any framework that supports tool/function calling:

  • Claude Code (via MCP or tool use)
  • Cursor / Windsurf / Copilot agents
  • OpenAI Assistants API
  • LangChain / LangGraph
  • LlamaIndex
  • AutoGen / CrewAI
  • Vercel AI SDK
  • Hugging Face Transformers Agents

Tips​

TopicDetail
API keyNever include it in the tool schema or system prompt — keep it server-side in process.env
Enum platformsAlways define the enum so the LLM can't hallucinate invalid platform names
Rich resultsReturn platform_statuses from the API response so the agent can tell the user which platforms succeeded
Text vs videoRoute to /api/upload_text when no video_url is provided, /api/upload otherwise
Rate limitsAdd retry logic with exponential backoff if the agent calls the tool in rapid succession