# Social MCP [中文文档](./README.zh-CN.md) Multi-platform social media automation service that exposes browser-based actions as both MCP (Model Context Protocol) tools and a REST API. Current platform support: **Xiaohongshu** (Little Red Book). ## Features - **17 MCP tools** for Xiaohongshu (login, browsing, publishing, interactions, notifications) - **REST API** with Bearer token authentication and per-route rate limiting - **Browser automation** via `rebrowser-playwright` with per-platform serial queueing - **Cookie persistence** with file-based storage (`0600`, atomic writes) - **Web dashboard** (React + Vite) for login, feed exploration, publishing, and API testing - **Security controls**: timing-safe token comparison, bind-address safety gate, error sanitization, log redaction - **Docker deployment** support with hardened runtime defaults - **Plugin architecture** for adding additional social platforms ## Quick Start ### Prerequisites - Node.js >= 22.0.0 - pnpm ### Install and Run (Backend) ```bash # Install dependencies pnpm install # Install Playwright browser (first time only) npx playwright install chromium # Build backend pnpm build # Start server pnpm start ``` The server listens on `http://127.0.0.1:9527` by default in local mode. A REST API Bearer token is printed on startup and persisted at `~/.social-mcp/.api-token`. ### Build With Web Dashboard ```bash # Build backend + web dashboard bundle pnpm build:all # Start server (serves dashboard from /) pnpm start ``` ### Development ```bash # Backend watch build pnpm dev # Frontend dev server pnpm dev:web # Type check pnpm lint # Tests pnpm test ``` ## MCP Integration ### Claude Desktop Add this in `claude_desktop_config.json`: ```json { "mcpServers": { "social-mcp": { "url": "http://127.0.0.1:9527/sse" } } } ``` ### Available MCP Tools (Xiaohongshu) | Tool | Description | |------|-------------| | `xhs_check_login` | Check Xiaohongshu login status | | `xhs_get_login_qrcode` | Get login QR code for phone scanning | | `xhs_delete_cookies` | Delete cookies and reset login session | | `xhs_list_feeds` | Get explore page recommended feed list | | `xhs_search` | Search notes by keyword with filters | | `xhs_get_feed_detail` | Get note detail (content/media/stats/comments) | | `xhs_get_sub_comments` | Load all sub-comments for a parent comment | | `xhs_get_user_profile` | Get user profile with recent notes | | `xhs_list_my_notes` | List current account's published notes | | `xhs_publish_image` | Publish an image note | | `xhs_publish_video` | Publish a video note | | `xhs_post_comment` | Post a comment on a note | | `xhs_reply_comment` | Reply to a comment | | `xhs_like` | Toggle like state on a note | | `xhs_favorite` | Toggle favorite state on a note | | `xhs_get_comment_notifications` | Get unread comment/@ notifications | | `xhs_reply_notification` | Reply to a specific notification | ## REST API All `/api/*` endpoints require: - `Authorization: Bearer ` - `Content-Type: application/json` (for POST bodies) Example: ```bash # Login status curl -H "Authorization: Bearer " \ http://127.0.0.1:9527/api/xhs/login/status # Search notes curl -X POST \ -H "Authorization: Bearer " \ -H "Content-Type: application/json" \ -d '{"keyword":"travel","filters":{"sort":"popularity_descending"}}' \ http://127.0.0.1:9527/api/xhs/search ``` ### Endpoint List Read endpoints are limited to **60/min** per IP. Write endpoints are limited to **10/min** per IP. | Method | Path | Description | Limit | |--------|------|-------------|-------| | `GET` | `/api/xhs/login/status` | Check login status | 60/min | | `GET` | `/api/xhs/login/qrcode` | Get login QR code | 60/min | | `DELETE` | `/api/xhs/login/cookies` | Delete cookies | 10/min | | `GET` | `/api/xhs/login/cookie-check` | Check whether cookie file exists | 60/min | | `GET` | `/api/xhs/feeds` | Get recommended feeds | 60/min | | `POST` | `/api/xhs/search` | Search notes | 60/min | | `POST` | `/api/xhs/feeds/detail` | Get note detail | 60/min | | `POST` | `/api/xhs/feeds/sub-comments` | Load sub-comments for parent comment | 60/min | | `POST` | `/api/xhs/user/profile` | Get user profile | 60/min | | `GET` | `/api/xhs/my-notes` | List my published notes | 60/min | | `POST` | `/api/xhs/publish/image` | Publish image note | 10/min | | `POST` | `/api/xhs/publish/video` | Publish video note | 10/min | | `POST` | `/api/xhs/comment` | Post a comment | 10/min | | `POST` | `/api/xhs/comment/reply` | Reply to a comment | 10/min | | `POST` | `/api/xhs/like` | Toggle like | 10/min | | `POST` | `/api/xhs/favorite` | Toggle favorite | 10/min | | `GET` | `/api/xhs/notifications/comments` | Get comment notifications | 60/min | | `POST` | `/api/xhs/notifications/reply` | Reply to notification | 10/min | ### Response Format ```json { "success": true, "data": {} } ``` ```json { "success": false, "error": { "code": "VALIDATION_ERROR", "message": "keyword: Required" } } ``` ### Public Endpoints (No Bearer Token) | Method | Path | Description | |--------|------|-------------| | `GET` | `/health` | Health check (uptime/memory/plugin status) | | `GET` | `/sse` | MCP SSE transport | | `POST` | `/messages` | MCP JSON-RPC message endpoint | ## Docker Deployment ### Using Compose (Recommended) ```bash cd deploy docker compose up -d # View logs docker compose logs -f # Find Bearer token in logs docker compose logs social-mcp | grep "Bearer Token" ``` ### Docker Run ```bash docker build -t social-mcp . docker run -d \ --name social-mcp \ -p 127.0.0.1:3000:3000 \ --shm-size=1gb \ --memory=2g \ --cpus=2.0 \ --security-opt=no-new-privileges:true \ --cap-drop=ALL \ --read-only \ --tmpfs /tmp:size=512m \ -v social-mcp-data:/home/appuser/.social-mcp \ social-mcp ``` Note: Docker defaults expose port `3000` because container env sets `PORT=3000`. ## Environment Variables | Variable | Default (local) | Description | |----------|------------------|-------------| | `PORT` | `9527` | HTTP server port | | `HOST` | `127.0.0.1` | Bind address (`0.0.0.0` requires `ALLOW_REMOTE`) | | `HEADLESS` | `true` | Run browser in headless mode | | `BROWSER_BIN` | (auto) | Custom Chromium executable path | | `LOG_LEVEL` | `info` | Pino log level (`debug`, `info`, `warn`, `error`) | | `NODE_ENV` | `development` | Runtime environment | | `COOKIE_DIR` | `~/.social-mcp` | Cookie/token storage directory | | `MAX_QUEUE_DEPTH` | `10` | Max pending operations per platform queue | | `ALLOW_REMOTE` | (unset) | Must be `yes-i-understand-the-risk` to allow public bind | ## Project Structure ```text social-mcp/ ├── src/ │ ├── index.ts │ ├── server/ │ │ ├── app.ts │ │ └── middleware.ts │ ├── browser/ │ │ └── manager.ts │ ├── cookie/ │ │ └── store.ts │ ├── config/ │ │ └── index.ts │ ├── utils/ │ │ ├── logger.ts │ │ ├── errors.ts │ │ └── downloader.ts │ └── platforms/ │ └── xiaohongshu/ │ ├── index.ts │ ├── routes.ts │ ├── schemas.ts │ ├── selectors.ts │ ├── login.ts │ ├── feeds.ts │ ├── search.ts │ ├── feed-detail.ts │ ├── user-profile.ts │ ├── my-notes.ts │ ├── publish.ts │ ├── publish-video.ts │ ├── comment.ts │ ├── interaction.ts │ └── notification.ts └── web/ └── src/ ``` ## License ISC