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:
- 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.
- 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_KEYheader. - 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
| Resource | URL | Purpose |
|---|---|---|
| OpenAPI 3.0 spec | https://api.indreelforge.com/openapi.json | Auto-import into agent frameworks |
| LLM context file | https://api.indreelforge.com/llm.txt | Markdown-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"]
}
}
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
| Topic | Detail |
|---|---|
| API key | Never include it in the tool schema or system prompt — keep it server-side in process.env |
| Enum platforms | Always define the enum so the LLM can't hallucinate invalid platform names |
| Rich results | Return platform_statuses from the API response so the agent can tell the user which platforms succeeded |
| Text vs video | Route to /api/upload_text when no video_url is provided, /api/upload otherwise |
| Rate limits | Add retry logic with exponential backoff if the agent calls the tool in rapid succession |