socialmag v0.1 — 4/5 platforms live (Threads, FB, IG, TikTok)
This commit is contained in:
+193
@@ -0,0 +1,193 @@
|
||||
# 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
|
||||
```json
|
||||
{
|
||||
"platforms": ["threads", "fb", "ig", "yt", "tiktok"],
|
||||
"text": "Post content here",
|
||||
"media": "/absolute/path/to/file.jpg",
|
||||
"visibility": "public"
|
||||
}
|
||||
```
|
||||
- `platforms`: array, pick any combo
|
||||
- `text`: required for threads/fb/yt. Used as caption for ig/tiktok
|
||||
- `media`: optional for threads/fb/yt. REQUIRED for ig/tiktok
|
||||
- `visibility`: "public" | "friends" (fb only)
|
||||
|
||||
### 2. `check_login` — verify which platforms are logged in
|
||||
```json
|
||||
{}
|
||||
→ {"threads": true, "fb": true, "ig": true, "yt": true, "tiktok": true}
|
||||
```
|
||||
|
||||
### 3. `get_status` — last post results
|
||||
```json
|
||||
{}
|
||||
→ {"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**: `websockets` library 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
|
||||
|
||||
1. CDP client (cdp.py) — navigate, click, type, setFiles
|
||||
2. Threads posting (simplest, validates the pattern)
|
||||
3. Facebook posting
|
||||
4. YouTube community post
|
||||
5. Instagram posting (media flow)
|
||||
6. TikTok posting (media flow)
|
||||
7. MCP server wrapper (server.py)
|
||||
8. Queue + error handling
|
||||
9. systemd service
|
||||
Reference in New Issue
Block a user