Content
Tool List
[](https://go.dev/)
[](https://modelcontextprotocol.io/)
[](LICENSE)
A toolkit for automating Toutiao creator backend operations based on [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) and Go. Supports integration with AI clients like Cursor, DeepSeek, Claude Desktop, and Claude Code as a standard MCP server, and exposes standard RESTful HTTP interfaces for self-media posting, data analysis, and content management automation.
## 🚀 Core Features
- **Dual-channel service architecture**: Provides both MCP protocol-compliant JSON-RPC routing (`/mcp`) and traditional Webhooks-oriented RESTful HTTP API on the same port (default `8080`). Also supports standard Stdio pipeline startup for seamless integration with Cursor/Claude Desktop.
- **Weitoutiao full history crawling**: Supports obtaining real Weitoutiao historical lists. The underlying automatically docks with the front-end actually used Feed stream interface `/api/feed/mp_provider/v1/`, passing in `category=mp_wtt` and `offset_mode=2` and paging according to the response `offset`; then merges the statistical indicators returned by `/mp/agw/statistic/v2/item/list?type=3` to avoid issues with the works management interface cursor getting stuck quantity not being complete.
- **High-speed HTTP operation analysis and degradation**:
- Data overview and statistical reports prioritize pure HTTP high-speed extraction mode (time reduced from 10s to 200ms). Instantly obtain fan count, total reading, and accumulated income through `/home/merge_v2`; pull the first 100 pieces of content through the Feed stream interface and accumulate likes and forwards in memory.
- Trend pulling uses a global filter `type=0` to ensure that fan changes and various indicators trends perfectly match the official background.
- Automatically retains high-fault-tolerant headless browser DOM crawling as a graceful degradation bottom line.
- **Article online secondary modification and security testing sandbox**: Supports secondary modification of published or draft articles without residue. Newly supports `SaveAsDraft` option (only saves draft without publishing), supports pure draft box security testing, test data does not pollute the real homepage, and can be physically cleared through the browser after testing. Intelligently skips unnecessary cover retransmission to prevent timeout; introduces React onChange underlying strong drive and 3s delay calm period to thoroughly prevent React asynchronous redraw rollback; performs "consistency secondary curing verification and forced coverage" before final publishing to ensure 100% curing of submitted data; physically compatible with "publish" confirmation pop-up.
- **Article full history mixed crawling and deduplication**: Lifts the original interface restriction on published articles only showing the latest 3 articles. For articles with `all` / `published` status, adopts dual-channel mixed pulling: first calls the list API to get the draft, then pulls historical articles through the Feed interface, and performs **dual deduplication and merging** in memory according to ID and non-empty title to prevent redundant stacking of duplicate items.
- **Field naming alias normalization and unification**: Thoroughly translates and shields obscure and difficult-to-understand field names in the original Toutiao interface (such as `go_detail_count_v2`, `digg_count`), and uniformly exposes standard field aliases such as `read_count`, `view_count`, `like_count`, `impression_count`, and `ctr`.
- **Real comment reading and verifiable reply**: The comment list prioritizes reading the interface actually used by the Toutiao comment management page, stably returns real `comment_id`, article ID, user name, content, time, and `reply_count`; the reply operation is physically completed through the browser, and after submission, it takes the real interface reply count growth as the success condition to avoid "button clicked but actually not published" false success.
- **Login state self-healing mechanism**: Supports automatic loading and lifecycle management of local `cookies.json`. If the session expires, the program will automatically pop up a Chrome browser window to wait for scan code login in headless mode, and after login success, it will automatically update and capture credentials and write them back.
- **Markdown intelligent typesetting engine**:
- Automatically parses and splits the content into text blocks and image blocks, and completes the typesetting through browser control.
- Supports automatic parsing of runtime relative image paths (such as `./testdata/test.png`) and conversion and upload of Chrome absolute paths.
- The content illustrations and cover images are uniformly uploaded through Chrome's native file chooser, avoiding the "invalid image data" issue caused by directly writing hidden file input.
- Possesses powerful cleaning of typesetting format symbols, and automatically filters out Markdown marker symbols remaining in the content.
- **Compliance and compliance**: Supports automatically physically clicking and checking the "Material network, fictional story" work statement in the posting settings to reduce the risk of blocking.
## 🛠️ Technical Stack and Dependency Preprocessing
| Component | Selection and Dependency |
|------|------|
| **Programming Language** | Go 1.20+ |
| **MCP Protocol SDK** | `github.com/modelcontextprotocol/go-sdk` |
| **Browser Automation** | `github.com/go-rod/rod` (high-fault-tolerant Chrome control library) |
| **HTTP Framework** | `github.com/gin-gonic/gin` (high-performance HTTP engine) |
| **System Dependency** | **The running environment must have Chrome or Chromium browser installed** (dependent on automation control) |
## ⚙️ Quick Start
### 1. Project Compilation
```bash
go build -o toutiaohao-server .
```
### 2. Start Service
```bash
# Start mixed service (default listening on port 8080, including MCP routing and HTTP interface)
./toutiaohao-server
# Run in standard Stdio pipeline transmission mode (exclusive for AI local integration)
./toutiaohao-server -stdio
# Specify custom port to start mixed service
./toutiaohao-server -port 9000
```
### 3. Initialize Login State (Cookie)
1. When the service is started for the first time and a posting or query function is called, if the local `cookies.json` does not exist, the program will automatically pop up a Chrome browser window.
2. Please manually perform **scan code login** or **SMS login** in the popped-up browser.
3. After login success, the terminal will output `Detected login success!`, and the program will automatically capture the latest Session Cookie and save it as `cookies.json` in the project root directory.
4. Subsequent calls will converted to headlessless) silent operation, without human intervention.
## AI Collaboration and MCP Configuration
To make AIsuch as Cursor, Claude Desktop) integrate more efficientlyably, it is recommended to use the local non-port-occupied **Stdio pipeline transmission mode** (add `-stdio` parameter). This avoids local port occupation and conflict, and has a higher response speed than HTTP/SSE transmission.
### 1. Cursor Configuration
Open `Settings -> Features -> MCP` in Cursor, and add a new MCP service:
- **Name**: `toutiao`
- **Type**: `command`
- **Commandpath/to/your/toutiaohao-server -stdio`
### 2. Claude Desktop Configuration
Edit your `config.json` (usually in `~/Library/Application Support/Claude/claude_desktop_config.json`):
```json
{
"mcpServers": {
"toutiao-mcp": {
"command": "/path/to/your/toutiaohao-server",
"args": ["-stdio"]
}
}
}
```
> [!TIP]
> This project has been deeply optimized for AI tools. The `AGENTS.md` in the project root directory contains detailed design intelligence and constraint specifications for AI development.
## 🔗 HTTP Interface List (REST API)
| Request Method | Request Path | Function Description |
|:---:|---|---|
| **POST** | `/api/v1/publish/article` | Publish graphic articles (support Markdown image splitting and illustration typesetting) |
| **POST** | `/api/v1/publish/micro` | Publish Weitoutiao up to 9 illustrations and) |
| **POST** | `/api/v1/publish/micro/draft` | Save Weitoutiao draft |
| **GET** | `/api/v1/articles` | Get article list (support `published/draft/review`) |
| ** | `/api/v1/articles/update` | Modify/update existing graphic articles |
| **POST** | `/api/v1/articles/delete` | Physically delete articles or delete drafts |
| **GET** | `/api/v1/comments` | Get real comment list, can be narrowed down by `article_id` or `keyword`, return `comment_id` and `reply_count` |
| **POST** | `/api/v1/comments/reply` | Reply to user comments and verify actual submission, need to provide `reply_content `comment_id` or `comment_text` |
| **GET** | `/api/v1/analytics/overview` | Account overall operation data (fans, reading volume, display volume indicators) |
| **GET** | `/api/v1/analytics/article` | Single article reading and interaction detailed statistics |
| **GET** | `/api/v1/analytics/report` | Automatically generate operation daily/weekly/monthly report |
| **GET** | `/health` | Health check endpoint |
## 📂 Project Structure
```
toutiaohao-mcp-server/
├── main.go # Service main entrance
├── app_server.go # Mixed server engine (aggregated routing, MCP and HTTP server)
├── mcp_server.go # MCP Protocol server initialization and Tools mapping registration
├── mcp_handlers.go # Specific dispatcher for MCP tools (parameter verification and business scheduling)
├── handlers_api.go # Specific processor for REST API interfaces
├── routes.go # Gin HTTP routing registry
├── middleware.go # Cross-domain (CORS) filtering and global Panic interception middleware
├── service.go # Core business service layer (abstract call underlying automation components)
├── types.go # Global common business data structure definition
├── configs/ # Static configuration module
│ ├── urls.go # Toutiao various navigation page URLs and API interface endpoints
│ ├── content.go # Toutiao article word count, image size limit
│ └── browser.go # Browser performance current limiting and Chrome path configuration
├── cookies/ # Credential storage and reading module
│ └── cookies.go # Cookie interface and local file FileCookieStore implementation
├── browser/ # Browser control encapsulation module
│ └── browser.go # go-rod browser instance initialization and Cookie injection
└── toutiaohao/ # [Core business component]
├── login.go # Scan code login, status polling, and Cookie automatic saving
├── dom.go # High-fault-tolerant DOM addressing, page smooth scrolling, and obstacle removal
├── selectors.go # CSS selectors for various buttons/input boxes on Toutiao creator platform
├── publish_article.go # Publish graphic articles (Markdown parsing, image automatic upload typesetting, fictional statement checking)
├── publish_micro.go # Publish Weitoutiao
├── draft_micro.go # Save Weitoutiao draft
├── comments.go # Comment list crawling and reply comments
├── article_list.go # Content list pulling and management
└── analytics.go # Creator operation data panel parsing and crawling
```
## 🧪 Automated Testing and Verification
### 1. Static Compilation Self-Inspection
```bash
go build ./...
```
### 2. Automated Graphic Article Publishing Integration Test
The test requires a valid `cookies.json` to exist locally (need to start the service and scan code login once to generate).
During testing, the program will prepare temporary test images, verify cover upload, timed publishing pop-up, and draft save path. The cleaned intermediate files are uniformly written to the project root directory `.tmp/`:
```bash
cd toutiaohao
go test -v -run TestPublishArticleManual
```
### 3. Content Illustration Upload Special Test
This test specifically covers the Markdown content `` illustration path to ensure that the browser receives files through Chrome's native file chooser and the image upload confirmation pop-up can be normally closed:
```bash
cd toutiaohao
go test -v -run TestPublishArticleBodyImageManual
```
Expected logs should appear:
```text
Chrome file chooser received file
Content image upload confirmation pop-up successfully closed
```
### 4. Automated Article Modification Integration Test (Security Sandbox Closed Loop)
This test automatically conducts a closed-loop test of "publishing a temporary new article -> extracting the new article ID from the article list -> physically modifying the new article -> automatically deleting the temporary new article" to ensure high fault tolerance and no consumption of precious modification quotas for online old articles, with no dirty data residue:
```bash
cd toutiaohao
go test -v -run TestUpdateArticleManual
```
### 5. Automated Weitoutiao Full List and Statistics Merging Test
This test specifically covers Weitoutiao Feed and statistical indicator merging logic, outputting the total number and corresponding CTR, display volume, reading number, comment count, likes, etc.:
```bash
cd toutiaohao
go test -v -run TestGetMicroPostsManual
```
### 6. Data Analysis Trend and Details Test
This test specifically covers the account change trend for the last N days and the specific draft details acquisition:
```bash
cd toutiaohao
go test -v -run "TestGetAccountTrendsManual|TestGetArticleDetailManual"
```
### Image Upload Implementation Convention
- All local/downloaded/cleaned temporary images must be generated under the project root directory `.tmp/`.
- Content illustrations and cover images upload must use go-rod `HandleFile to intercept Chrome's native file chooser, and then physically click the "local upload" button in the current visible upload pop-up. The cover slot may directly trigger the file chooser, so the cover upload will first register the file chooser interception, and then click slot; if pops up the upload panel, continue to click the "local upload" in the panel.
- Graphic article cover source: `cover > explicitly passed` > content image adaptive.1 image is a single-image used, and3 or more passed, a cover is used Toutiao may the cover from content illustrations. If after clicking the cover slot, the "local upload" panel does not appear, the service will review the target `.article-cover-img-wrap`; if the slot already has a real image, directly adopt the platform synchronization result, and no longer report upload failure. The preview button and empty slot plus icon will not be considered as a valid cover.
- Do not directly call `SetFiles` on hidden `input[type=file]`. This method may produce local blob preview, but the server actually receives about 210 bytes of damaged request body, and finally displays "invalid image data".
- `/spice/image`, `upload_source=` and `multipart/form-data` image upload requests must bypass `HijackRequests`'s `LoadResponse` proxy, directly `ContinueRequest` to pass through as is.
- If the image confirmation pop-up does not close, save an error screenshot and return an error to avoid missing images in the content.
### Title Verification and Failed Draft Protection
- Graphic title has a maximum of 30 Toutiao weighted characters: ASCII English letters and numbers are counted as 0.5, blank is not counted, Chinese and punctuation and other characters are counted as 1. If the title exceeds the limit, the service will directly return a readable error, requiring the caller to regenerate or shorten the title, and will not automatically truncate and damage semantics.
- If the content, illustrations, cover, or final submission fails during publishing, the service will retain theiao may saved in the and prompt in the error message to go to the draft box to check.
- Ordinary publishing failure automatically call the delete interface. Only when the user explicitly calls the delete function, or the integration test cleans up the temporary data created by itself, will the draft be deleted.
- Clicking "preview and publish" to enter the preview page does not represent the completion of publishing; the service will continue to click the "publish/confirm publish" in the preview page, and only return success after jumping to the explicit management page or appearing a success prompt.
### Draft Deletion Implementation Convention
- The delete interface will first call Toutiao's HTTP delete API, but does not trust only the result; must requery the list to confirm the article has disappeared.
- Draft deletion failure will fall back to browser automation: use `rodBrowser.MustPage("https://mp.toutiao.com/profile_v4/graphic/articles?status=draft") open the in one step, inject Cookie and ``, then locate card that matches theID on the current page.
- Do not create a blank page and then `page.Navigate()` to the draft box; this two-step navigation may cause the SPA data request to not carry Cookie, manifested as the URL is correct but the list card is empty.
- The `status=draft` or `status=1` in the URL is only used as an initial navigation aid and cannot be used to determine if the draft box tab's `active` / `selected` / `aria-selected` state URL is as an initial and cannot be determine if the tab is selected deletion, must `active`selected` / `aria-selected` state of the "Draft Box" tab on the page; if not selected, need to click the draft box tab for the card to re-render Do not create a blank page `page.Navigate()` to the draft box; this two-step navigation SPA data requests to not carry Cookie, manifested as URL correct but list card empty.
- URL `status=draft` or `status=1` only serves as initial navigation assistance and cannot be used to determine if the Draft Box tab is selected. Before deletion, must read the `active` / `selected` / `aria-selected` state of the "Draft Box" tab on the page; if not selected, need to click the Draft Box tab and wait for the card to re-render.
- Draft deletion does not depend on the "More" menu or edit page delete button; should check the real checkbox of the target draft row, and then click the "Delete" in the batch operation bar, and finally handle the confirmation pop-up.
- The checkbox, batch delete button, and confirmation button must all click on visible small button body, on the outer container `.-content`. Before clicking, need into the viewport center and use coordinate physical click.
- If still failed, will save `screenshotraft_not_found.png`, `screenshotraft_checkbox_error.png`, `screenshotraft_batch_error.png`, or `_draft_confirm_error.png` to.
### Comment Reply Implementation Convention
tool `get_comments` is used to read the comment list, can pass_id`, `keyword`, `page_size`; `reply_comment` is used to.
- `get_comments` prioritizes calling the interface actually used by the Tout management page `/comment/author_receive_comment/`, and continues to page according to the cursor; DOM crawling is only used as a fallback when the interface fails. Each result returns real `comment_id`, `article_id`, `user_name`, `content`, `create_time`, and `reply_count`.
- `reply_comment` must provide `reply_content`, and at least one of `comment_id` and `comment_text`. It is pass `comment_id` preferentially; the service will first supplement the comment content from the real interface, and then locate the target card through the browser.
- The reply content adopts go-rod physical typing, and verifies the input value and "publish" button state. After clicking submit, it will poll the real interface, and only returns `success: true` when the target comment's `reply_count` grows, and returns `reply_count_before` and `reply_count_after`.
- If reply fails, save `screenshot_comment_page_error `screenshot_comment_reply_not_found `screenshot_comment_reply_fill_error.png`, `screenshot_comment_reply_submit_error.png`, or `screenshot_comment_reply_verify_error.png` to assist analysis.
Example of core fields in comment list response:
```json
{
"comment_id": "7655725926924206911",
"article_id": "7655556701420061184",
"user_name": "Example User",
"content": "Comment content",
"reply_count": 1
}
```
## 📄 Open Source License
This project is open-sourced under the [MIT License](LICENSE). Please be aware of the security of credential files, and strictly prohibit uploading `cookies.json` containing sensitive session tokens to any public code repository.
MCP Config
Below is the configuration for this MCP Server. You can copy it directly to Cursor or other MCP clients.
mcp.json
Connection Info
You Might Also Like
No recommendations available