xueqiu-mcp
# xueqiu-mcp
An MCP server for Xueqiu (Snowball) that exposes community posts, stock quotes, watchlists, portfolios, and market news to AI assistants through standard Model Context Protocol tools.
It is designed for Claude Desktop, Cursor, Codex, QoderWork, and other MCP-compatible clients that can launch stdio servers.
> This project relies on publicly reachable Xueqiu endpoints and an optional user cookie token. API availability, permissions, and response shapes may change without notice.
## Highlights
| Area | Tools | Capabilities |
| --- | ---: | --- |
| Community and KOL tracking | 11 | User search, profiles, following list, timelines, original articles, post details, comments, hot posts, stock KOLs, news feeds, and 7x24 live news |
| Stock market data | 8 | Single-stock quotes, batch quotes, hot stocks, stock screener, company profiles, dividend history, industry/concept tags, and industry performance |
| Watchlist viewing (read-only) | 4 | Read personal or public user watchlists and inspect watchlist stocks and funds |
| Watchlist editing (write) | 6 | Add or remove stocks, funds, and cubes in the logged-in user's watchlists |
| Portfolio tracking | 3 | Read public Xueqiu portfolios, current holdings, and rebalancing history |
## Use Cases
- Track recent posts, long-form articles, and discussions from Xueqiu users or market KOLs.
- Query real-time quotes and valuation metrics for A-shares, Hong Kong stocks, and US stocks.
- Inspect your own watchlists or public watchlists from other Xueqiu users.
- Pull Xueqiu hot discussions, news feeds, and 7x24 live updates into AI workflows.
- Combine stock screening, industry data, and company profiles for research workflows.
## Installation
### Requirements
- Node.js 20 or later
- npm
- An MCP client that supports stdio servers
### Build Locally
```bash
git clone <repo-url>
cd xueqiu-mcp
npm install
npm run build
```
The compiled server entrypoint is `dist/index.js`.
## Authentication
Login state is resolved in this order:
1. `XUEQIU_TOKEN` environment variable (a bare `xq_a_token` value or a full cookie string)
2. A local cookie file written by `npm run login`
3. An in-memory anonymous token (public endpoints only)
### One-time login (recommended)
`npm run login` opens your installed Google Chrome. Sign in once with the QR code or SMS code, and the login cookie is saved locally. The server picks it up automatically on startup — no environment variable needed and no browser download.
```bash
npm run login
```
It reuses your installed Chrome, so nothing extra is downloaded. If Chrome is missing, either install it or fall back to Playwright's bundled Chromium (a ~150 MB one-time download):
```bash
npx playwright install chromium
```
The cookie is stored at `~/.config/xueqiu-mcp/cookies.json` (`%USERPROFILE%\.config\xueqiu-mcp\cookies.json` on Windows). When it expires, run `npm run login` again.
### Manual token
You can still copy the cookie by hand:
1. Log in to [Xueqiu](https://xueqiu.com).
2. Open Developer Tools → `Application` / `Storage` → `Cookies` for `https://xueqiu.com`.
3. Copy `xq_a_token`. Login-only endpoints usually also need `u`, so copying `xq_a_token=...; u=...` together is safest.
### Claude Desktop / Cursor / QoderWork
Add the server to your MCP client configuration:
```json
{
"mcpServers": {
"xueqiu-mcp": {
"command": "node",
"args": ["/path/to/xueqiu-mcp/dist/index.js"]
}
}
}
```
> If you already ran `npm run login`, no `env` block is needed. To override the saved cookie, add `"env": { "XUEQIU_TOKEN": "your value" }`.
### Codex CLI
Add the server to `~/.codex/config.toml`:
```toml
[mcp_servers.xueqiu-mcp]
command = "node"
args = ["/path/to/xueqiu-mcp/dist/index.js"]
```
> If you already ran `npm run login`, no `env` block is needed. To override the saved cookie, add `env = { XUEQIU_TOKEN = "your value" }`.
Restart your MCP client after saving the configuration.
## Tools
### Community and KOL Tracking
| Tool | Description | Parameters |
| --- | --- | --- |
| `get_current_user` | Get the current logged-in user profile | None |
| `get_my_following` | Get the current user's following list with automatic pagination | None |
| `search_users` | Search Xueqiu users by keyword | `query`, `page?`, `count?` |
| `get_user_profile` | Get a user's detailed profile | `user_id` |
| `get_user_posts` | Get a user's timeline, including original and reposted content | `user_id`, `page?`, `count?` |
| `get_user_articles` | Get a user's original long-form articles | `user_id`, `page?`, `count?` |
| `get_post_detail` | Get full content for a post or article | `post_id` |
| `get_post_comments` | Get comments for a post | `post_id`, `page?`, `count?`, `sort?` |
| `get_hot_posts` | Get hot posts by day, week, or month | `scope?`, `count?`, `page?` |
| `get_stock_kol` | Get active users for a stock symbol | `symbol`, `count?`, `start?` |
| `get_news_feed` | Get Xueqiu news feeds or 7x24 live news | `category?`, `count?` |
`get_hot_posts.scope` supports `day`, `week`, and `month`. `get_news_feed.category` supports `headline`, `a_stock`, `us_stock`, `hk_stock`, `fund`, and `live`.
### Stock Market Data
| Tool | Description | Parameters |
| --- | --- | --- |
| `get_stock_quote` | Get detailed quote and valuation metrics for one stock | `symbol` |
| `get_batch_quotes` | Get quotes for multiple symbols | `symbols` |
| `get_hot_stocks` | Get hot stock rankings | `market?`, `count?` |
| `screen_stocks` | Sort and screen stocks by percent change, market cap, PE, PB, turnover, amount, or volume | `market?`, `order_by?`, `order?`, `page?`, `size?` |
| `get_company_profile` | Get A-share company profile data | `symbol` |
| `get_stock_dividend` | Get A-share dividend and allotment history | `symbol` |
| `get_stock_industry` | Get industry and concept tags for a stock | `symbol` |
| `get_industry_list` | Get industry sectors and performance data | `level?` |
Symbol examples: `SH600519`, `SZ000001`, `00700`, `AAPL`.
### Watchlist Viewing (read-only)
| Tool | Description | Parameters |
| --- | --- | --- |
| `get_watchlists` | Get the current user's watchlist folders | None |
| `get_user_watchlists` | Get public watchlist folders for any user | `user_id` |
| `get_watchlist_stocks` | Get stocks in a watchlist folder, optionally for a public user | `pid`, `category?`, `user_id?` |
| `get_watchlist_funds` | Get funds in a watchlist folder, optionally for a public user | `pid?`, `user_id?` |
Common system folder IDs include `-1` for all stocks, `-5` for A-shares, `-6` for US stocks, and `-7` for Hong Kong stocks; `-110` for all funds, `-17` for funds, and `-16` for private funds. Prefer IDs returned by `get_watchlists` or `get_user_watchlists`.
### Watchlist Editing (write)
| Tool | Description | Parameters |
| --- | --- | --- |
| `add_watchlist_stock` | Add a stock to the current user's default watchlist | `symbol` |
| `add_watchlist_fund` | Add a fund to the current user's default fund watchlist | `symbol` |
| `add_watchlist_cube` | Follow a Xueqiu cube and add it to the current user's watchlist | `cube_symbol` |
| `remove_watchlist_stock` | Remove a stock from the current user's watchlist | `symbol` |
| `remove_watchlist_fund` | Remove a fund from the current user's fund watchlist | `symbol` |
| `remove_watchlist_cube` | Unfollow a Xueqiu cube and remove it from the current user's watchlist | `cube_symbol` |
These write tools require a valid login (`npm run login` or `XUEQIU_TOKEN`). Items are added to or removed from the default folder of each kind; the server routes by symbol prefix (`SH`/`SZ` stocks, `F`/`P` funds, `ZH` cubes).
### Portfolio Tracking
| Tool | Description | Parameters |
| --- | --- | --- |
| `get_user_cubes` | Get public portfolios created by a Xueqiu user | `user_id`, `page?`, `count?` |
| `get_cube_holdings` | Get current holdings for a portfolio | `cube_symbol` |
| `get_cube_rebalancing` | Get historical rebalancing records for a portfolio | `cube_symbol`, `page?`, `count?` |
## Examples
```text
Show me the latest posts from this Xueqiu user.
```
```text
Search for Xueqiu users who discuss new energy stocks.
```
```text
What is in user 2292705444's public watchlist?
```
```text
Get the current quote, PE, PB, and dividend yield for SH600519.
```
```text
Compare quotes for SH600519, SZ300750, and AAPL.
```
```text
What are the hottest A-share stocks today?
```
```text
Show current holdings for portfolio ZH2001629.
```
```text
Show the latest Xueqiu 7x24 live news.
```
## Development
```bash
npm run dev # Start from TypeScript source with tsx
npm run build # Compile TypeScript to dist/
npm start # Start the compiled MCP server
```
## Architecture
```text
xueqiu-mcp/
├── src/
│ ├── index.ts # MCP server entrypoint, tool registration, and response formatting
│ ├── xueqiu-api.ts # Xueqiu API client, token handling, and HTTP helpers
│ ├── login.ts # One-time browser login helper
│ ├── login-cookie.ts # Login-state validation and Cookie serialization
│ └── cookie-store.ts # Local Cookie persistence
├── test/ # Login and API regression tests
├── dist/ # Compiled output
├── package.json # Package metadata and scripts
├── tsconfig.json # TypeScript configuration
└── README.md
```
The implementation intentionally keeps the runtime small:
- Node.js / ESM / ES2022
- TypeScript
- `@modelcontextprotocol/sdk`
- Playwright (login helper)
- `zod`
## Data, Permissions, and Safety
- `XUEQIU_TOKEN` is read from the environment and should not be committed to source control.
- Anonymous tokens are fetched only when needed and are kept in memory.
- Login-required tools fail fast when neither a valid local Cookie nor `XUEQIU_TOKEN` is available.
- Visibility of other users' watchlists, portfolios, and profiles depends on their privacy settings and Xueqiu's API permissions.
- Xueqiu may change endpoints, fields, rate limits, or access policies at any time.
- Requests are throttled (default ~1–1.5 s between requests, jittered) and retried with exponential backoff for transient `429`/`5xx`/network errors only. `401`/`403`/`400` are never auto-retried. After 5 consecutive transient failures the client opens a 5-minute circuit breaker. Set `XUEQIU_MIN_INTERVAL_MS` to override the throttle interval (`0` disables it).
- Use reasonable request rates and respect Xueqiu's terms of service.
## Disclaimer
This project is for personal learning, research, and automation assistance only. It is not investment advice, trading advice, or a recommendation to buy or sell securities. This project is not affiliated with, endorsed by, or officially authorized by Xueqiu or Beijing Xueqiu Information Technology Co., Ltd. Users are responsible for complying with Xueqiu's terms, platform rules, and applicable laws. All consequences arising from use of this project are the user's responsibility.
## License
MIT
TDQS
Scored across 32 tools
Most tools map to distinct resource/action pairs, but several are easy to confuse: get_watchlists vs get_user_watchlists overlap for the current user, and get_stock_quote vs get_batch_quotes are the same quote concept with different cardinality. Descriptions help, but the boundaries are not always obvious.
The dominant verb_noun pattern is consistent, with get_, add_, and remove_ prefixes across resources. Minor deviations like get_my_following, screen_stocks, and get_stock_kol break the pattern slightly but do not create real confusion.
32 tools is a heavy surface for an MCP server, even though Xueqiu covers multiple subdomains. Several tools could be consolidated, such as single vs batch quotes and the overlapping watchlist listing tools, making the count feel excessive for agent selection.
The set covers user/social, quotes, screening, watchlist add/remove, and cube data well. However, there are notable gaps: there is no get_watchlist_cubes to list followed cubes despite add/remove cube tools, and no fund quote/detail tools to support fund watchlist entries.