6.4 KiB
6.4 KiB
socialmag — Social Media MCP Server
Proposal Draft · 2026-09-10
What
An MCP server that lets any household agent post to social media platforms via a single tool call. Uses bravemag's CDP connection (port 9222) to abang's logged-in Brave browser. No API keys, no OAuth dance, no monthly fees.
Architecture
┌─ Any Agent ─────────────────────┐
│ create_post( │
│ platforms: ["threads","fb"], │
│ text: "Hello world 🚀", │
│ media: "/path/to/img.jpg", │ ← optional
│ schedule: null │ ← future: cron/delay
│ ) │
└─────────────┬───────────────────┘
↓
┌─ socialmag (MCP server) ────────┐
│ Python · stdio MCP interface │
│ CDP client → ws://127.0.0.1:9222
│ │
│ Queue: sequential per-platform │
│ (one browser, one tab at a time)
│ │
│ ┌─ post_threads(text, media?) │
│ ├─ post_facebook(text, media?) │
│ ├─ post_instagram(media, caption)
│ ├─ post_youtube(text) │ ← community post
│ ├─ post_youtube_video(file, title, desc)
│ └─ post_tiktok(file, caption) │
│ │
│ Returns: per-platform status │
│ {threads: "ok", fb: "ok", ...} │
└─────────────────────────────────┘
MCP Tools (public interface)
1. create_post — the main tool
{
"platforms": ["threads", "fb", "ig", "yt", "tiktok"],
"text": "Post content here",
"media": "/absolute/path/to/file.jpg",
"visibility": "public"
}
platforms: array, pick any combotext: required for threads/fb/yt. Used as caption for ig/tiktokmedia: optional for threads/fb/yt. REQUIRED for ig/tiktokvisibility: "public" | "friends" (fb only)
2. check_login — verify which platforms are logged in
{}
→ {"threads": true, "fb": true, "ig": true, "yt": true, "tiktok": true}
3. get_status — last post results
{}
→ {"last_post": "2026-09-10T19:30:00", "results": {...}}
Per-Platform Posting Logic (from FAFO recon)
Threads ⭐
1. navigate("https://www.threads.net/")
2. click([aria-label="Empty text field. Type to compose a new post."])
3. wait for [role=dialog]
4. type into [role=dialog] [role=textbox]
5. if media: inject via CDP DOM.setFileInputFiles on "Attach media" flow
6. click "Post" button in dialog
7. wait for dialog close = success
Facebook ⭐⭐
1. navigate("https://www.facebook.com/")
2. JS: find span with "on your mind" → walk parent to [role=button] → click()
⚠️ Direct element click triggers Messenger!
3. wait for [role=dialog] containing "Create post"
4. type into dialog [role=textbox][contenteditable=true]
5. if media: click "Photo/video" → CDP setFileInputFiles
6. if visibility != "friends": click privacy button → change
7. click [aria-label="Post"]
8. wait for dialog close = success
Instagram ⭐⭐⭐⭐
1. navigate("https://www.instagram.com/")
2. click(svg[aria-label="New post"])
3. wait for "Create new post" dialog
4. CDP: DOM.setFileInputFiles on input[type=file] → inject media
(bypasses native file picker)
5. wait for crop screen → click "Next"
6. wait for filter screen → click "Next"
7. wait for caption screen → type caption in textarea
8. click "Share"
9. wait for dialog close = success
YouTube (community post) ⭐⭐
1. navigate("https://www.youtube.com/")
2. click(button[aria-label="Create"])
3. click "Create post" in dropdown menu
4. wait for redirect to channel/posts page
5. type into #contenteditable-root
6. click button[aria-label="Post"]
7. wait for post to appear = success
TikTok ⭐⭐⭐⭐
1. navigate("https://www.tiktok.com/tiktokstudio/upload?from=upload")
2. wait for upload page
3. for video: CDP setFileInputFiles on input[type=file][accept="video/*"]
4. for photos: click "Photos" tab first, then upload
5. wait for processing
6. type caption/description
7. set hashtags, settings
8. click "Post" / "Publish"
9. wait for success confirmation
Tech Stack
- Python 3 (stdlib-only server, same pattern as tiledmag/pixel-room-mcp)
- CDP client:
websocketslibrary for WebSocket to Chrome DevTools - MCP interface: stdio (standard MCP pattern)
- No framework: plain Python, no LangChain/FastAPI/etc
- Systemd managed:
socialmag.service, auto-restart
File Structure
/mnt/playground/Playground_V2/socialmag/
├── server.py # MCP server + tool definitions
├── cdp.py # CDP WebSocket client (navigate, click, type, setFiles)
├── platforms/
│ ├── threads.py # Threads posting logic
│ ├── facebook.py # Facebook posting logic
│ ├── instagram.py # Instagram posting logic
│ ├── youtube.py # YouTube posting logic
│ └── tiktok.py # TikTok posting logic
├── selectors.py # All platform selectors in one place
├── queue.py # Sequential execution queue
└── README.md
Dependencies
websockets(for CDP WebSocket)- That's it. Everything else is stdlib.
Risks & Mitigations
| Risk | Mitigation |
|---|---|
| Platform UI changes break selectors | selectors.py is one file — update and go |
| Bot detection (especially TikTok) | Human-like delays between actions (random 0.5-2s) |
| Browser not logged in | check_login tool verifies before posting |
| Brave restart kills CDP | Health check + clear error message |
| Rate limiting | Queue with configurable delay between platforms |
| Media file not found | Validate path exists before starting |
| Multi-step IG/TikTok flow fails mid-way | Per-step error handling, screenshot on failure |
Future (not now)
- Schedule posts (cron integration)
- Analytics reading (pull post performance)
- Reply/DM automation
- Multi-account support
- Template system ("post this format every Monday")
Build Order
- CDP client (cdp.py) — navigate, click, type, setFiles
- Threads posting (simplest, validates the pattern)
- Facebook posting
- YouTube community post
- Instagram posting (media flow)
- TikTok posting (media flow)
- MCP server wrapper (server.py)
- Queue + error handling
- systemd service