feat: social video uploads + hero page video + TikTok content
Hero page:
- Replace GIF with squaremcp-hero-loop.mp4 (autoplay, muted, loop)
- Update styles, scripts, tests, Dockerfile, baselines
- Deployed and verified
Social video uploads:
- Twitter/X: uploadVideoAndTweet via v1.1 media/upload + v2 tweets
- Facebook: createVideoPost via Graph API /{pageId}/videos
- Instagram: createReel via Graph API (container → poll → publish)
- TikTok: REST endpoints + OpenAPI schema for video upload
Marketing:
- TikTok content prompts, scripts, and posting schedule
Note: Remotion not mentioned in any user-facing content
This commit is contained in:
285
src/manifest.ts
285
src/manifest.ts
@@ -565,6 +565,29 @@ export function getOpenApiSpec(serverUrl: string) {
|
||||
responses: { '200': { description: 'Photo posted' } },
|
||||
},
|
||||
},
|
||||
'/api/facebook/video': {
|
||||
post: {
|
||||
operationId: 'facebook_create_video_post',
|
||||
summary: 'Publish video post to Facebook Page',
|
||||
requestBody: {
|
||||
required: true,
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: {
|
||||
type: 'object',
|
||||
required: ['video_url'],
|
||||
properties: {
|
||||
video_url: { type: 'string', description: 'Publicly accessible URL of the video' },
|
||||
description: { type: 'string', description: 'Video description text' },
|
||||
account: { type: 'string' },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
responses: { '200': { description: 'Video posted' } },
|
||||
},
|
||||
},
|
||||
|
||||
// ── Twitter/X ───────────────────────────────────────────────
|
||||
'/api/twitter/search': {
|
||||
@@ -602,6 +625,97 @@ export function getOpenApiSpec(serverUrl: string) {
|
||||
responses: { '200': { description: 'Tweet list' } },
|
||||
},
|
||||
},
|
||||
'/api/twitter/video': {
|
||||
post: {
|
||||
operationId: 'twitter_upload_video',
|
||||
summary: 'Upload video and post tweet',
|
||||
requestBody: {
|
||||
required: true,
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: {
|
||||
type: 'object',
|
||||
required: ['video_url', 'text'],
|
||||
properties: {
|
||||
video_url: { type: 'string', description: 'Publicly accessible URL of the MP4 video' },
|
||||
text: { type: 'string', description: 'Tweet text content' },
|
||||
account: { type: 'string' },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
responses: { '200': { description: 'Video tweet posted' } },
|
||||
},
|
||||
},
|
||||
'/api/instagram/reel': {
|
||||
post: {
|
||||
operationId: 'instagram_create_reel',
|
||||
summary: 'Create Instagram Reel',
|
||||
requestBody: {
|
||||
required: true,
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: {
|
||||
type: 'object',
|
||||
required: ['video_url'],
|
||||
properties: {
|
||||
video_url: { type: 'string', description: 'Publicly accessible URL of the MP4 video' },
|
||||
caption: { type: 'string', description: 'Reel caption text' },
|
||||
account: { type: 'string' },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
responses: { '200': { description: 'Reel created' } },
|
||||
},
|
||||
},
|
||||
'/api/tiktok/profile': {
|
||||
get: {
|
||||
operationId: 'tiktok_get_profile',
|
||||
summary: 'Get TikTok profile',
|
||||
parameters: [
|
||||
{ name: 'account', in: 'query', schema: { type: 'string' } },
|
||||
],
|
||||
responses: { '200': { description: 'Profile info' } },
|
||||
},
|
||||
},
|
||||
'/api/tiktok/videos': {
|
||||
get: {
|
||||
operationId: 'tiktok_get_videos',
|
||||
summary: 'Get TikTok videos',
|
||||
parameters: [
|
||||
{ name: 'max_count', in: 'query', schema: { type: 'integer' } },
|
||||
{ name: 'account', in: 'query', schema: { type: 'string' } },
|
||||
],
|
||||
responses: { '200': { description: 'Video list' } },
|
||||
},
|
||||
},
|
||||
'/api/tiktok/video': {
|
||||
post: {
|
||||
operationId: 'tiktok_create_video',
|
||||
summary: 'Upload video to TikTok',
|
||||
requestBody: {
|
||||
required: true,
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: {
|
||||
type: 'object',
|
||||
required: ['video_url'],
|
||||
properties: {
|
||||
video_url: { type: 'string', description: 'Publicly accessible URL of the video' },
|
||||
title: { type: 'string', description: 'Video title (max 150 chars)' },
|
||||
description: { type: 'string', description: 'Video description / caption' },
|
||||
account: { type: 'string' },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
responses: { '200': { description: 'Video upload initiated' } },
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -1326,6 +1440,30 @@ export function getManifest(serverUrl: string, authEnabled: boolean) {
|
||||
},
|
||||
examples: [{ image_url: 'https://example.com/photo.jpg', caption: 'New post!', account: 'default' }],
|
||||
},
|
||||
{
|
||||
name: 'instagram_create_reel',
|
||||
category: 'instagram',
|
||||
description: 'Upload a video as an Instagram Reel',
|
||||
when_to_use:
|
||||
'User wants to publish a video to their Instagram Business/Creator account as a Reel.',
|
||||
input_schema: {
|
||||
type: 'object',
|
||||
required: ['video_url'],
|
||||
properties: {
|
||||
video_url: { type: 'string', description: 'Publicly accessible URL of the MP4 video' },
|
||||
caption: { type: 'string', description: 'Reel caption' },
|
||||
account: { type: 'string', description: 'Which Instagram account to use (default: "default")' },
|
||||
},
|
||||
},
|
||||
returns: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
success: { type: 'boolean' },
|
||||
media_id: { type: 'string' },
|
||||
},
|
||||
},
|
||||
examples: [{ video_url: 'https://example.com/video.mp4', caption: 'New reel!', account: 'default' }],
|
||||
},
|
||||
|
||||
// ── Facebook tools ─────────────────────────────────────────────────────
|
||||
{
|
||||
@@ -1427,6 +1565,30 @@ export function getManifest(serverUrl: string, authEnabled: boolean) {
|
||||
},
|
||||
examples: [{ image_url: 'https://example.com/image.jpg', caption: 'New post!', account: 'default' }],
|
||||
},
|
||||
{
|
||||
name: 'facebook_create_video_post',
|
||||
category: 'facebook',
|
||||
description: 'Publish a video post to a Facebook Page using a public video URL',
|
||||
when_to_use: 'User wants to post a video to their Facebook Page.',
|
||||
input_schema: {
|
||||
type: 'object',
|
||||
required: ['video_url'],
|
||||
properties: {
|
||||
video_url: { type: 'string', description: 'Publicly accessible URL of the video' },
|
||||
description: { type: 'string', description: 'Video description text' },
|
||||
account: { type: 'string', description: 'Which Facebook account to use (default: "default")' },
|
||||
},
|
||||
},
|
||||
returns: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
success: { type: 'boolean' },
|
||||
video_id: { type: 'string' },
|
||||
post_id: { type: 'string' },
|
||||
},
|
||||
},
|
||||
examples: [{ video_url: 'https://example.com/video.mp4', description: 'New video!', account: 'default' }],
|
||||
},
|
||||
|
||||
// ── Twitter/X tools ────────────────────────────────────────────────────
|
||||
{
|
||||
@@ -1536,6 +1698,129 @@ export function getManifest(serverUrl: string, authEnabled: boolean) {
|
||||
},
|
||||
examples: [{ text: 'Hello from Hermes MCP!', account: 'default' }],
|
||||
},
|
||||
{
|
||||
name: 'twitter_upload_video',
|
||||
category: 'twitter',
|
||||
description: 'Upload a video and post it as a tweet on Twitter/X',
|
||||
when_to_use:
|
||||
'User wants to post a video to Twitter/X. NOTE: Free tier is read-only. Paid upgrade required.',
|
||||
input_schema: {
|
||||
type: 'object',
|
||||
required: ['video_url', 'text'],
|
||||
properties: {
|
||||
video_url: { type: 'string', description: 'Publicly accessible URL of the MP4 video' },
|
||||
text: { type: 'string', description: 'Tweet text content' },
|
||||
account: { type: 'string', description: 'Which Twitter account to use (default: "default")' },
|
||||
},
|
||||
},
|
||||
returns: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
success: { type: 'boolean' },
|
||||
tweet_id: { type: 'string' },
|
||||
url: { type: 'string', description: 'Direct link to the tweet' },
|
||||
},
|
||||
},
|
||||
examples: [{ video_url: 'https://example.com/video.mp4', text: 'Check this out!', account: 'default' }],
|
||||
},
|
||||
{
|
||||
name: 'tiktok_get_profile',
|
||||
category: 'tiktok',
|
||||
description: 'Get the TikTok user profile including follower count, following count, likes, and video count',
|
||||
when_to_use: 'User asks about their TikTok profile stats or account details.',
|
||||
input_schema: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
account: { type: 'string', description: 'Which TikTok account to use (default: "default")' },
|
||||
},
|
||||
},
|
||||
returns: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
open_id: { type: 'string' },
|
||||
display_name: { type: 'string' },
|
||||
follower_count: { type: 'number' },
|
||||
following_count: { type: 'number' },
|
||||
likes_count: { type: 'number' },
|
||||
video_count: { type: 'number' },
|
||||
},
|
||||
},
|
||||
examples: [{ account: 'default' }],
|
||||
},
|
||||
{
|
||||
name: 'tiktok_get_videos',
|
||||
category: 'tiktok',
|
||||
description: 'List recent videos from the authenticated TikTok account',
|
||||
when_to_use: 'User wants to see their recent TikTok videos and performance stats.',
|
||||
input_schema: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
max_count: { type: 'number', description: 'Max videos to return (default: 10, max: 20)' },
|
||||
account: { type: 'string', description: 'Which TikTok account to use (default: "default")' },
|
||||
},
|
||||
},
|
||||
returns: {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: { type: 'string' },
|
||||
title: { type: 'string' },
|
||||
view_count: { type: 'number' },
|
||||
like_count: { type: 'number' },
|
||||
share_url: { type: 'string' },
|
||||
},
|
||||
},
|
||||
},
|
||||
examples: [{ max_count: 10, account: 'default' }],
|
||||
},
|
||||
{
|
||||
name: 'tiktok_create_video',
|
||||
category: 'tiktok',
|
||||
description: 'Post a video to TikTok by providing a publicly accessible video URL',
|
||||
when_to_use: 'User wants to upload a video to TikTok.',
|
||||
input_schema: {
|
||||
type: 'object',
|
||||
required: ['video_url'],
|
||||
properties: {
|
||||
video_url: { type: 'string', description: 'Publicly accessible URL of the video to post' },
|
||||
title: { type: 'string', description: 'Video title (max 150 chars)' },
|
||||
description: { type: 'string', description: 'Video description / caption' },
|
||||
account: { type: 'string', description: 'Which TikTok account to use (default: "default")' },
|
||||
},
|
||||
},
|
||||
returns: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
publish_id: { type: 'string' },
|
||||
status: { type: 'string' },
|
||||
},
|
||||
},
|
||||
examples: [{ video_url: 'https://example.com/video.mp4', title: 'My video', account: 'default' }],
|
||||
},
|
||||
{
|
||||
name: 'tiktok_get_video_status',
|
||||
category: 'tiktok',
|
||||
description: 'Check the processing status of a TikTok video upload',
|
||||
when_to_use: 'User wants to check if their TikTok video upload is complete.',
|
||||
input_schema: {
|
||||
type: 'object',
|
||||
required: ['publish_id'],
|
||||
properties: {
|
||||
publish_id: { type: 'string', description: 'Publish ID returned by tiktok_create_video' },
|
||||
account: { type: 'string', description: 'Which TikTok account to use (default: "default")' },
|
||||
},
|
||||
},
|
||||
returns: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
publish_id: { type: 'string' },
|
||||
status: { type: 'string' },
|
||||
fail_reason: { type: 'string' },
|
||||
},
|
||||
},
|
||||
examples: [{ publish_id: 'v123456', account: 'default' }],
|
||||
},
|
||||
|
||||
// ── Obsidian tools ──────────────────────────────────────────────────────
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user