Skip to main content

Use Upload-Post with smolagents

Hugging Face smolagents loads tools from MCP servers with MCPClient. Connect it to the hosted Upload-Post MCP server and your agent gets nearly 60 tools to publish, schedule and analyze posts on TikTok, Instagram, YouTube, LinkedIn, Facebook, X, Threads, Pinterest, Bluesky and more.

  • Endpoint: https://mcp.upload-post.com/mcp (Streamable HTTP)
  • Auth: Authorization: ApiKey <UPLOAD_POST_API_KEY>

Installation​

pip install "smolagents[mcp]" "mcp<2"
note

Pin mcp<2: smolagents loads MCP servers through mcpadapt, which still imports the MCP Python SDK 1.x client. With mcp 2.x installed, opening the connection fails with ImportError: cannot import name 'streamablehttp_client'.

API key​

Generate a key in the Upload-Post dashboard under API Keys, connect your social accounts to a profile, then export it together with your Hugging Face token (or the key of whichever model provider you use):

export UPLOAD_POST_API_KEY="your-upload-post-api-key"
export HF_TOKEN="your-hugging-face-token"

Example​

The server parameters are passed to the MCP SDK's Streamable HTTP client, so the API key goes in headers:

import os

from smolagents import InferenceClientModel, MCPClient, ToolCallingAgent

server_parameters = {
"url": "https://mcp.upload-post.com/mcp",
"transport": "streamable-http",
"headers": {"Authorization": f"ApiKey {os.environ['UPLOAD_POST_API_KEY']}"},
}

with MCPClient(server_parameters, structured_output=True) as tools:
agent = ToolCallingAgent(tools=tools, model=InferenceClientModel())
result = agent.run(
"List my Upload-Post profiles, then post 'Hello from smolagents!' to X and "
"LinkedIn from the first profile. Poll get_status with the returned "
"request_id and tell me the final status."
)
print(result)

CodeAgent works the same way (CodeAgent(tools=tools, model=...)), and so does ToolCollection.from_mcp(server_parameters, trust_remote_code=True) if you prefer the tool-collection API.

Uploads are asynchronous​

upload_video, upload_photos and upload_text return a request_id right away while the post is delivered to each platform in the background. The agent should call get_status with that request_id until it reports success or failure. Scheduled or queued posts return a job_id instead: check them with get_job_status or list_scheduled. See Async uploads.