Skip to main content

Use Upload-Post with Mastra

Mastra connects TypeScript agents to MCP servers through MCPClient. Point it at 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​

npm install @mastra/core @mastra/mcp

API key​

Generate a key in the Upload-Post dashboard under API Keys, connect your social accounts to a profile, then add it to your .env together with the key for your model provider:

UPLOAD_POST_API_KEY=your-upload-post-api-key
OPENAI_API_KEY=your-openai-api-key

Example​

import { Agent } from '@mastra/core/agent';
import { MCPClient } from '@mastra/mcp';

const mcp = new MCPClient({
id: 'upload-post',
servers: {
uploadPost: {
url: new URL('https://mcp.upload-post.com/mcp'),
requestInit: {
headers: {
Authorization: `ApiKey ${process.env.UPLOAD_POST_API_KEY}`,
},
},
},
},
});

const agent = new Agent({
id: 'social-media-manager',
name: 'Social media manager',
instructions:
'You publish social media posts through Upload-Post. Call list_users first to ' +
'find the profile and its connected accounts. After an upload, poll get_status ' +
'with the returned request_id until it finishes.',
model: 'openai/gpt-4.1',
tools: await mcp.listTools(),
});

const result = await agent.generate(
"List my Upload-Post profiles, then post 'Hello from Mastra!' to X and LinkedIn " +
'from the first profile and tell me the final status.',
);
console.log(result.text);

await mcp.disconnect();

listTools() namespaces each tool with the server name (for example uploadPost_upload_text), so it never collides with tools from other servers.

If each request should run with a different Upload-Post key (for example, one key per end customer), build the client per request and pass the tools as toolsets instead: agent.generate(prompt, { toolsets: await mcp.listToolsets() }).

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.