Metadata-Version: 2.4
Name: bili_stalker_mcp
Version: 3.3.0
Summary: Bilibili MCP server for analyzing specific Bilibili users, with profile, video, dynamic, article, subtitle, and following tools
Project-URL: Homepage, https://github.com/222wcnm/BiliStalkerMCP
Project-URL: Documentation, https://github.com/222wcnm/BiliStalkerMCP#readme
Project-URL: Repository, https://github.com/222wcnm/BiliStalkerMCP
Project-URL: Issues, https://github.com/222wcnm/BiliStalkerMCP/issues
Project-URL: Changelog, https://github.com/222wcnm/BiliStalkerMCP/releases
Author-email: 222wcnm <2328072813li@gmail.com>
License-Expression: MIT
License-File: LICENSE
Keywords: bilibili,creator-analysis,dynamics,fastmcp,mcp,mcp-server,model-context-protocol,subtitles,user-analysis,video
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: End Users/Desktop
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Communications
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
Classifier: Topic :: Multimedia :: Video
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.12
Requires-Dist: async-lru>=2.0.4
Requires-Dist: bilibili-api-python==17.4.2
Requires-Dist: curl-cffi>=0.7.0
Requires-Dist: fastmcp>=3.0.0
Requires-Dist: filelock==3.29.7
Requires-Dist: httpx>=0.25.0
Requires-Dist: mcp>=1.26.0
Requires-Dist: pydantic>=2.7.0
Provides-Extra: dev
Requires-Dist: black>=23.0.0; extra == 'dev'
Requires-Dist: flake8>=6.0.0; extra == 'dev'
Requires-Dist: isort>=5.12.0; extra == 'dev'
Requires-Dist: mypy>=1.0.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
Requires-Dist: pytest-cov>=4.0.0; extra == 'dev'
Requires-Dist: pytest>=7.0.0; extra == 'dev'
Requires-Dist: python-dotenv>=1.0.0; extra == 'dev'
Description-Content-Type: text/markdown

# BiliStalkerMCP

[![Python](https://img.shields.io/badge/Python-3.12+-blue?logo=python)](https://www.python.org/)
[![MCP](https://img.shields.io/badge/MCP-Compatible-orange)](https://github.com/jlowin/fastmcp)
[![PyPI version](https://badge.fury.io/py/bili-stalker-mcp.svg)](https://pypi.org/project/bili-stalker-mcp/)

## Bilibili MCP Server for Specific User Analysis

BiliStalkerMCP is a Bilibili MCP server built on [Model Context Protocol (MCP)](https://modelcontextprotocol.io), designed for AI agents that need to analyze a specific Bilibili user or creator.

It is optimized for workflows that start from a target uid or username, then retrieve that user's profile, videos, dynamics, articles, subtitles, and followings with structured tools.

If you are searching for a Bilibili MCP server, a Bilibili Model Context Protocol server, or an MCP server for tracking and analyzing a specific Bilibili user, this repository is designed for that use case.

**English | [中文说明](README_zh.md)**

### Installation

```bash
uvx bili-stalker-mcp
# or
pip install bili-stalker-mcp
```

### Configuration (Claude Desktop, Recommended)

```json
{
  "mcpServers": {
    "bilistalker": {
      "command": "uv",
      "args": ["run", "--directory", "/path/to/BiliStalkerMCP", "bili-stalker-mcp"],
      "env": {
        "SESSDATA": "required_sessdata",
        "BILI_JCT": "optional_jct",
        "BUVID3": "optional_buvid3"
      }
    }
  }
}
```

> Prefer `uv run --directory ...` for faster local updates when PyPI release propagation is delayed.
> You can still use `uvx bili-stalker-mcp` for quick one-off usage.

> **Auth**: Provide `SESSDATA` directly, or put it in `BILI_COOKIE_FILE`. Obtain it from Browser DevTools (F12) > Application > Cookies > `.bilibili.com`.

### Environment Variables

| Key | Req | Description |
|-----|:---:|-------------|
| `SESSDATA` | Conditional | Bilibili session token; required unless `BILI_COOKIE_FILE` provides it. |
| `BILI_JCT` | No | CSRF protection token. |
| `BUVID3` | No | Hardware fingerprint (reduces rate-limiting risk). |
| `BILI_COOKIE_FILE` | No | Path to a plain Cookie file. |
| `BILI_REFRESH_TOKEN_FILE` | No | Path to the separate refresh-token file; never set the token through an environment variable. |
| `BILI_ENABLE_COOKIE_REFRESH` | No | `true` enables safe automatic refresh; default: `false`. |
| `BILI_COOKIE_REFRESH_CHECK_INTERVAL_SECONDS` | No | Refresh-check interval; default: `21600`, minimum: `60`. |
| `BILI_LOG_LEVEL` | No | `DEBUG`, `INFO` (Default), `WARNING`. |
| `BILI_TIMEZONE` | No | Output time zone for formatted timestamps (default: `Asia/Shanghai`). |

### Optional Safe Cookie Refresh

Automatic refresh is disabled by default. Enable it only when the Cookie file and
refresh-token file are existing, readable, writable regular files. The Cookie file
may contain only ordinary Cookie values (`SESSDATA`, `bili_jct`, `buvid3`,
`buvid4`, and `DedeUserID`); the refresh token belongs only in its own file.

```json
{
  "BILI_COOKIE_FILE": "/secure/bilibili-cookie.txt",
  "BILI_REFRESH_TOKEN_FILE": "/secure/bilibili-refresh-token.txt",
  "BILI_ENABLE_COOKIE_REFRESH": "true",
  "BILI_COOKIE_REFRESH_CHECK_INTERVAL_SECONDS": "21600"
}
```

When refresh is enabled, do not set `SESSDATA`, `BILI_JCT`, or `DEDEUSERID` in
the environment: those rotating values must come from the Cookie file so a restart
cannot reload stale credentials. `BUVID3` and `BUVID4` may still be provided through
the environment. Refresh checks are rate-limited, and concurrent MCP calls or server
processes sharing these files use one refresh lock. Pending confirmation is recovered
before another refresh. The `.bili-cookie-refresh.lock` sidecar may remain on disk
between runs.

For a quicker initial setup, copy the complete Cookie header value from a Bilibili
browser request and `ac_time_value` from Local Storage, then run:

```powershell
uv run bili-stalker-cookie-setup --directory D:\BiliStalkerSecrets
```

For a PyPI-only invocation without cloning this repository:

```powershell
uvx --from bili-stalker-mcp bili-stalker-cookie-setup --directory D:\BiliStalkerSecrets
```

The script hides both pasted values, refuses directories inside the repository and
existing credential files, and prints only a non-secret MCP `env` block. Do not
paste an entire cURL command: paste only the value after its `cookie:` header.

### Local Verification

All verification commands use mocks and do not require Bilibili credentials:

```powershell
uv run pytest -q tests/test_credentials.py tests/test_cookie_refresh.py tests/test_tool_contract.py
uv run pytest -q
uv run black --check bili_stalker_mcp tests scripts
uv run isort --check-only bili_stalker_mcp tests scripts
uv run flake8 bili_stalker_mcp tests scripts
uv run mypy bili_stalker_mcp
```

## Available Tools

| Tool | Capability | Parameters |
|------|------------|------------|
| `get_user_info` | Profile & core statistics | `user_id_or_username` |
| `get_user_videos` | Lightweight video list | `user_id_or_username`, `page`, `limit` |
| `search_user_videos` | Keyword search in one user's video list | `user_id_or_username`, `keyword`, `page`, `limit` |
| `get_video_detail` | Full video detail + optional subtitles | `bvid`, `fetch_subtitles` (default: `false`), `subtitle_mode` (`smart`/`full`/`minimal`), `subtitle_lang` (default: `auto`), `subtitle_max_chars` |
| `get_user_dynamics` | Structured dynamics with image metadata and cursor pagination | `user_id_or_username`, `cursor`, `limit`, `dynamic_type` |
| `get_user_articles` | Lightweight article list | `user_id_or_username`, `page`, `limit` |
| `get_article_content` | Full article markdown content | `article_id` |
| `get_user_followings` | Subscription list analysis | `user_id_or_username`, `page`, `limit` |
| `get_content_comments` | Comments for a video, article, or dynamic (including images and note metadata) | `content_type`, `content_id`, `cursor`, `limit`, `sort` |
| `get_content_comment_replies` | Full sub-replies for a video, article, or dynamic comment | `content_type`, `content_id`, `root_rpid`, `page`, `limit` |

Comment `pictures` contain the original image URLs. Regular long comments retain the
full text returned by Bilibili. Note-style comments may contain only a preview; use
the returned `note.cvid` with `get_article_content` to retrieve the full note.
For video comments, pass `content_type="video"` and a BVID, AV number, or video URL
as `content_id`. Use a top-level comment's `rpid` as `root_rpid` when fetching its
complete reply thread.

### Dynamic Filtering (`dynamic_type`)

- `ALL` (default): Text, Draw, and Reposts.
- `ALL_RAW`: Unfiltered (includes Videos & Articles).
- `VIDEO`, `ARTICLE`, `DRAW`, `TEXT`: Specific category filtering.
- `REVIEW`: Recognized five-slot rating cards only. Each result exposes
  `review.rating` (filled stars, 0-5), `review.title`, `review.text`, cover and
  jump URLs, plus the source score description when available. This filter does
  not independently classify whether the rated title is an anime.

Each dynamic item includes an `images` list. Every image contains `url`, `width`,
and `height`; invalid URLs are omitted, and unavailable dimensions are `null`.
`image_count` always equals the number of returned images. Reposts expose the same
fields under `origin.images` and `origin.image_count`. Non-image dynamics return
an empty `images` list.

**Pagination**: Responses include `next_cursor`. Pass this to subsequent requests for seamless scrolling.

### Subtitle Modes (`get_video_detail`)

- `smart` (default when `fetch_subtitles=true`): fetch metadata for all pages, download only one best-matched subtitle track text.
- `full`: download text for all subtitle tracks (higher cost).
- `minimal`: skip subtitle metadata and subtitle text fetching.

`subtitle_lang` can force a language (for example `en-US`); `auto` uses built-in priority fallback.  
`subtitle_max_chars` caps returned subtitle text size to avoid token explosion.

## Bundled Skill

The repository ships a ready-to-use AI agent skill in `skills/bili-content-analysis/`:

```
skills/bili-content-analysis/
├── SKILL.md                        # Workflow & output contract
└── references/
    └── analysis-style.md           # Detailed writing style rules
```

### What It Does

Guides compatible AI agents (Gemini, Claude, etc.) through a structured 6-step workflow for deep Bilibili content analysis:

1. **Clarify** target and scope (uid / bvid / keyword).
2. **Collect** evidence — lightweight lists first, heavy detail only for high-value items.
3. **Reconstruct** source structure before interpreting (timeline, chapters, speakers).
4. **Analyze** — facts, logic chain, assumptions, themes, and shifts.
5. **Retain anchors** — uid, bvid, article_id, timestamps, key source snippets.
6. **Handle failures** — state blockers explicitly, stop speculation.

### Usage

Copy the `bili-content-analysis` folder into your project's skill directory:

```
<project>/.agent/skills/bili-content-analysis/
```

The agent will automatically activate the skill when user requests involve Bilibili creator tracking, transcript interpretation, timeline reconstruction, or content analysis.

## Development

```bash
# Setup
git clone https://github.com/222wcnm/BiliStalkerMCP.git
cd BiliStalkerMCP
uv sync --dev

# Test
uv run pytest -q

# Integration & Performance (Requires Auth)
uv run python scripts/integration_suite.py -u <UID>
uv run python scripts/perf_baseline.py -u <UID> --tools dynamics -n 3
```

## Release (Maintainers)

> **Credentials**: The release script uses `UV_PUBLISH_TOKEN` when set; otherwise it reads the matching `[pypi]` or `[testpypi]` token from `$HOME\.pypirc`.
> Twine is invoked transiently through `uvx` only for package metadata validation and is not a project dependency.

```powershell
# Build + test + package metadata validation (no upload)
.\scripts\pypi_release.ps1

# Upload to TestPyPI
.\scripts\pypi_release.ps1 -TestPyPI -Upload

# Upload to PyPI
.\scripts\pypi_release.ps1 -Upload
```

## Docker

Runs via `stdio` transport. No ports exposed.

```bash
docker build -t bilistalker-mcp .
docker run -e SESSDATA=... bilistalker-mcp
```

## Troubleshooting

- **412 Precondition Failed**: Bilibili anti-crawling system triggered. Refresh `SESSDATA` or provide `BUVID3`.
- **Cloud IPs**: Highly susceptible to blocking; local execution is recommended.

## License

MIT

> **Disclaimer**: For personal research and learning only. Bulk profiling, harassment, or commercial surveillance is prohibited.

---
*This project is built and maintained with the help of AI.*
