# Social MCP Multi-platform social media automation service that exposes browser-based actions as both MCP (Model Context Protocol) tools and a REST API. Currently supports **Xiaohongshu** (Little Red Book). ## Features - **13 MCP tools** for Xiaohongshu: login management, content browsing, publishing, and interactions - **REST API** with Bearer token authentication and rate limiting - **Browser automation** via rebrowser-playwright with anti-detection patches - **Cookie persistence** with file-based storage (0600 permissions, atomic writes) - **Security**: DNS rebinding protection, Host header validation, error message sanitization, log redaction - **Docker support** with hardened configuration (non-root user, read-only filesystem, resource limits) - **Plugin architecture** for adding new platforms ## Quick Start ### Prerequisites - Node.js >= 22.0.0 - pnpm ### Install and Run ```bash # Install dependencies pnpm install # Install Playwright browsers (first time only) npx playwright install chromium # Build pnpm build # Start the server pnpm start ``` The server starts on `http://127.0.0.1:3000` by default. A REST API Bearer token is printed to the console on first startup and saved to `~/.social-mcp/.api-token`. ### Development ```bash # Watch mode (rebuilds on file changes) pnpm dev # Type check without emitting pnpm lint # Run tests pnpm test ``` ## MCP Integration ### Claude Desktop Add the following to your Claude Desktop configuration file (`claude_desktop_config.json`): ```json { "mcpServers": { "social-mcp": { "url": "http://127.0.0.1:3000/sse" } } } ``` ### Available MCP Tools | 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 with content, images, stats, comments | | `xhs_get_user_profile` | Get user profile with bio, stats, recent 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` | Like or unlike a note | | `xhs_favorite` | Favorite or unfavorite a note | ## REST API All REST endpoints require a `Bearer` token in the `Authorization` header. The token is generated on first startup and printed to the console. ```bash # Example: check login status curl -H "Authorization: Bearer " http://127.0.0.1:3000/api/xhs/login/status # Example: 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:3000/api/xhs/search ``` ### Endpoints | Method | Path | Description | Rate 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/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/user/profile` | Get user profile | 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` | Like/unlike a note | 10/min | | `POST` | `/api/xhs/favorite` | Favorite/unfavorite a note | 10/min | ### Response Format All REST responses follow a consistent JSON format: ```json // Success { "success": true, "data": { ... } } // Error { "success": false, "error": { "code": "VALIDATION_ERROR", "message": "keyword: Required" } } ``` ### Other Endpoints (no auth required) | Method | Path | Description | |--------|------|-------------| | `GET` | `/health` | Health check (memory, uptime, plugin status) | | `GET` | `/sse` | MCP SSE transport | | `POST` | `/messages` | MCP JSON-RPC messages | ## Docker Deployment ### Using Docker Compose (recommended) ```bash cd deploy docker compose up -d # View logs docker compose logs -f # The API token is printed in the logs on first start docker compose logs social-mcp | grep "Bearer Token" ``` ### Using Docker directly ```bash # Build the image docker build -t social-mcp . # Run with required settings 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 ``` **Important**: The `--shm-size=1gb` flag is required. Chromium uses `/dev/shm` for shared memory and the default 64MB causes crashes. ## Environment Variables | Variable | Default | Description | |----------|---------|-------------| | `PORT` | `3000` | 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` | Environment (`production` disables pretty logs) | | `COOKIE_DIR` | `~/.social-mcp` | Directory for cookie and token storage | | `MAX_QUEUE_DEPTH` | `10` | Max pending operations per platform queue | | `ALLOW_REMOTE` | (unset) | Set to `yes-i-understand-the-risk` to allow `HOST=0.0.0.0` | ## Project Structure ``` social-mcp/ ├── package.json ├── tsconfig.json ├── tsup.config.ts ├── Dockerfile ├── deploy/ │ └── docker-compose.yml ├── src/ │ ├── index.ts # Entry point: bootstrap, plugin registration, graceful shutdown │ ├── server/ │ │ ├── app.ts # AppServer: Express + MCP lifecycle │ │ └── middleware.ts # DNS rebinding guard, bearer auth, rate limiter, error handler │ ├── browser/ │ │ └── manager.ts # BrowserManager: browser lifecycle, serial queues, backpressure │ ├── cookie/ │ │ └── store.ts # CookieStore: per-platform cookie persistence (0600, atomic writes) │ ├── config/ │ │ └── index.ts # Environment-based configuration │ ├── utils/ │ │ ├── logger.ts # Pino logger with deep redaction │ │ ├── errors.ts # Error classification, sanitization, MCP error wrapper │ │ └── downloader.ts # Media file download and path validation │ └── platforms/ │ └── xiaohongshu/ │ ├── index.ts # PlatformPlugin: MCP tool + REST route registration │ ├── routes.ts # REST API route handlers │ ├── schemas.ts # Zod schemas for tool/API parameter validation │ ├── types.ts # Domain types (Feed, Comment, UserProfile, etc.) │ ├── selectors.ts # CSS selector constants │ ├── login.ts # Login management (QR code, status check) │ ├── feeds.ts # Explore page feed extraction │ ├── search.ts # Search with filters │ ├── feed-detail.ts # Note detail + comment loading │ ├── user-profile.ts # User profile extraction │ ├── publish.ts # Image note publishing │ ├── publish-video.ts # Video note publishing │ ├── comment.ts # Comment and reply posting │ └── interaction.ts # Like and favorite toggling └── tests/ ``` ## License ISC