### Install Dependencies and Run Server with uv Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/CONFIGURATION.md Use 'uv sync' to install project dependencies and 'uv run' to start the server for testing. Ensure you are in the project's root directory. ```bash cd /path/to/bilibili-mcp-server uv sync uv run bilibili.py ``` -------------------------------- ### Install Dependencies Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/INDEX.md Installs project dependencies using uv. Navigate to the project directory before running. ```bash cd /path/to/bilibili-mcp-server uv sync ``` -------------------------------- ### ASS Format Example Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/IMPLEMENTATION_DETAILS.md An example demonstrating the structure of an ASS subtitle file, including script info, styles, and event dialogues with timing and text. ```ass [Script Info] Title: 弹幕列表 ScriptType: v4.00+ [V4+ Styles] Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, ... Style: Default,微软雅黑,25,&H00FFFFFF,&H000000FF,&H00000000,&H00000000,0,... [Events] Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text Dialogue: 0,0:00:10.00,0:00:15.00,Default,,0,0,0,,{...}这是一条弹幕 Dialogue: 0,0:00:20.00,0:00:25.00,Default,,0,0,0,,{...}另一条弹幕 ``` -------------------------------- ### MCP Client Tool Usage Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/INDEX.md Examples of calling the four available tools from an MCP client. Ensure the client is configured according to the project's documentation. ```python general_search("keyword") ``` ```python search_user("username", page=1) ``` ```python get_precise_results("username", search_type="user") ``` ```python get_video_danmaku("BV1xx4y1C7ec") ``` -------------------------------- ### Run Bilibili MCP Server Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/INDEX.md Starts the FastMCP server, which listens for JSON-RPC requests on standard input. Press Ctrl+C to stop the server. ```bash uv run bilibili.py ``` -------------------------------- ### Function Signatures with Type Annotations Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/MODULES.md Examples of function signatures demonstrating the use of type hints for parameters and return values. Note the use of `Any` for untyped dictionaries and the absence of type hints in `get_video_danmaku`. ```python def general_search(keyword: str) -> dict[Any, Any]: ... ``` ```python def search_user(keyword: str, page: int = 1) -> dict[Any, Any]: ... ``` ```python def get_precise_results(keyword: str, search_type: str = "user") -> Dict[str, Any]: ... ``` ```python def get_video_danmaku(bv_id): # No type hints ... ``` -------------------------------- ### Launch Bilibili MCP Server via uv Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/API_REFERENCE.md Command to launch the Bilibili MCP server as a subprocess using the 'uv' tool. This command is used by MCP clients to start the server. ```bash uv --directory /path/to/bilibili-mcp-server run bilibili.py ``` -------------------------------- ### Handle Missing or Malformed Results Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/ERROR_HANDLING.md Implement checks for empty or malformed results from tool calls. This example shows how to handle cases where `get_video_danmaku` might return no data. ```python danmaku = get_video_danmaku("BV1...") if danmaku and len(danmaku) > 0: # Process danmaku else: # Handle empty result ``` -------------------------------- ### Example Error Handling for Danmaku Retrieval Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/ERROR_HANDLING.md This snippet demonstrates how to handle various exceptions that may occur during the danmaku retrieval process, including file system errors, network timeouts, and general exceptions. It's crucial for robustly managing potential failures. ```python import os try: danmaku = get_video_danmaku("BV1xx4y1C7ec") print(f"Retrieved {len(danmaku)} bytes of danmaku") except FileNotFoundError: print("Failed to create/read danmaku file") except PermissionError: print("No permission to access current directory") except requests.Timeout: print("Danmaku retrieval timed out") except Exception as e: print(f"Unexpected error: {type(e).__name__}: {e}") ``` -------------------------------- ### User Search Return Structure (Filtered) Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/IMPLEMENTATION_DETAILS.md Example structure for user search results when filtering is applied. It includes a list of users and a boolean indicating if exact matches were prioritized. ```json { "users": [ { "uname": "用户名", "mid": 123456, "face": "https://...", "fans": 999999, "videos": 123, "level": 5, "sign": "个人签名", "official": "认证说明" }, # ... more users (all exact matches or all partial matches) ], "exact_match": True # or False } ``` -------------------------------- ### Other Search Types Return Structure (Raw) Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/IMPLEMENTATION_DETAILS.md Example structure for search types other than 'user'. The raw API response is returned without any specific filtering or remapping. ```json # Raw API response (structure depends on search_type) ``` -------------------------------- ### Get Video Danmaku Function Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/IMPLEMENTATION_DETAILS.md This function generates an ASS subtitle file for video danmaku, reads its content, and then removes the temporary file. It requires the bilibili-mcp-server library and standard Python modules like os. ```python import os import asyncio from bilibili_api import video, ass from bilibili_api.utils import sync @mcp.tool() def get_video_danmaku(bv_id): v = video.Video(bv_id) output_filepath = "protobuf.ass" sync(ass.make_ass_file_danmakus_protobuf( obj=v, page=0, out=output_filepath )) with open(output_filepath, 'r') as f: content = f.read() os.remove(output_filepath) return content ``` -------------------------------- ### Validate Tool Results Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/ERROR_HANDLING.md After receiving results from a tool, validate them before use. Check for expected data structures and specific fields, such as 'exact_match' in this example, to ensure data integrity. ```python result = get_precise_results("keyword", search_type="user") if result and result.get("exact_match"): users = result.get("users", []) ``` -------------------------------- ### Retrieve Video Danmaku Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/API_REFERENCE.md Use this function to get the danmaku content for a specific Bilibili video. The function returns the danmaku as a string in ASS subtitle file format. Ensure the `bilibili_mcp_server` library is imported. ```python from bilibili_mcp_server import get_video_danmaku # Retrieve danmaku for a video danmaku_content = get_video_danmaku("BV1xx4y1C7ec") print(danmaku_content) # Output: ASS subtitle file content with danmaku ``` -------------------------------- ### Get Video Danmaku Function Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/ERROR_HANDLING.md This function retrieves danmaku for a given Bilibili video ID. It handles file operations and returns the danmaku content. Potential errors include file I/O issues, invalid video IDs, or API errors. ```python def get_video_danmaku(bv_id): v = video.Video(bv_id) output_filepath = "protobuf.ass" sync(ass.make_ass_file_danmakus_protobuf(obj=v, page=0, out=output_filepath)) with open(output_filepath, 'r') as f: content = f.read() os.remove(output_filepath) return content ``` -------------------------------- ### Initialize and Run FastMCP Server Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/API_REFERENCE.md Instantiate the FastMCP server and run it with stdio transport when executed as the main module. This registers all tool decorators and implements the Model Context Protocol. ```python mcp = FastMCP("Bilibili mcp server") if __name__ == "__main__": mcp.run(transport='stdio') ``` -------------------------------- ### Initialize FastMCP Server Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/CONFIGURATION.md Instantiate the FastMCP server with a display name. This name is used in protocol messages. ```python mcp = FastMCP("Bilibili mcp server") ``` -------------------------------- ### Import sync wrapper Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/IMPLEMENTATION_DETAILS.md Import the sync wrapper from the bilibili_api library. This is the first step to using the wrapper. ```python from bilibili_api import sync ``` -------------------------------- ### MCP Server Entry Point Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/CONFIGURATION.md The standard entry point for the Bilibili MCP Server script, initializing the FastMCP server with stdio transport. ```python if __name__ == "__main__": mcp.run(transport='stdio') ``` -------------------------------- ### get_precise_results Function Definition Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/IMPLEMENTATION_DETAILS.md The main function definition for get_precise_results, including type mapping and API call setup. It handles different search types and defaults to user search. ```python import json from typing import Dict, Any from bilibili_api import search, sync from bilibili_api.search import SearchObjectType @mcp.tool() def get_precise_results(keyword: str, search_type: str = "user") -> Dict[str, Any]: type_map = { "user": SearchObjectType.USER, "video": SearchObjectType.VIDEO, "live": SearchObjectType.LIVE, "article": SearchObjectType.ARTICLE } search_obj_type = type_map.get(search_type.lower(), SearchObjectType.USER) result = sync(search.search_by_type( keyword=keyword, search_type=search_obj_type, page=1, page_size=50 )) if search_type.lower() == "user" and "result" in result: # User-specific filtering logic ... return result ``` -------------------------------- ### MCP Client Server Configuration Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/CONFIGURATION.md Illustrates how an MCP client typically configures the Bilibili MCP Server. Ensure the 'command' and 'args' are correctly set for your project path. ```json { "mcpServers": { "bilibili": { "command": "uv", "args": [ "--directory", "/your-project-path/bilibili-mcp-server", "run", "bilibili.py" ] } } } ``` -------------------------------- ### Content Discovery Pipeline Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/USAGE_PATTERNS.md This workflow demonstrates how to find a creator by name and then retrieve their video danmaku. Note that direct video search by creator is not supported, requiring a workaround using general search. ```python # Step 1: Find creator by name creator_name = "某个UP主" search_result = get_precise_results(creator_name, search_type="user") if not search_result.get("exact_match"): print(f"Creator '{creator_name}' not found") exit() creator = search_result["users"][0] creator_id = creator["mid"] creator_name = creator["uname"] print(f"Found creator: {creator_name} (UID: {creator_id})") # Step 2: Search for their videos # Note: This would require an extension to search for videos by a specific creator # The current API doesn't support this directly, so we'd use general_search as a workaround video_search = general_search(f"{creator_name} 视频") # Step 3: Extract video BV IDs from results video_ids = [] if "result" in video_search: for item in video_search["result"]: if item.get("type") == "video": # Note: Actual field name may vary; adjust based on API response bv_id = item.get("bvid") if bv_id: video_ids.append(bv_id) # Step 4: Get danmaku for first video if video_ids: print(f"Found {len(video_ids)} videos. Retrieving danmaku for first...") danmaku = get_video_danmaku(video_ids[0]) print(f"Retrieved {len(danmaku)} bytes of danmaku") ``` -------------------------------- ### Video Danmaku Retrieval and File Generation Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/MODULES.md Fetches video danmaku for a given BV ID, generates a protobuf ASS file, reads its content, and then deletes the temporary file. This process involves object creation, asynchronous API calls, and file I/O operations. ```python get_video_danmaku(bv_id) ├─ bilibili_api.video.Video(bv_id) [Object creation] ├─ bilibili_api.ass.make_ass_file_danmakus_protobuf( │ obj=v, page=0, out="protobuf.ass" │ ) [async] │ └─ bilibili_api.sync(...) [async → sync wrapper] │ └─ Creates file: protobuf.ass ├─ File I/O: │ ├─ open("protobuf.ass", 'r') → read │ └─ os.remove("protobuf.ass") → delete └─ returns str (file content) ``` -------------------------------- ### Get Precise Search Results Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/API_REFERENCE.md Performs a refined search for exact or near-exact matches. Supports searching for users, videos, live streams, and articles. For user searches, it returns a filtered list and an exact match flag. ```python from bilibili_mcp_server import get_precise_results # Find exact user match result = get_precise_results("双雷", search_type="user") print(result) # Output: {"users": [{"uname": "双雷", "mid": 123456, ...}], "exact_match": True} # Search for videos (unfiltered raw results) videos = get_precise_results("编程教程", search_type="video") print(videos) # Live stream search live = get_precise_results("直播", search_type="live") ``` -------------------------------- ### Add New Tool to Bilibili MCP Server Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/INDEX.md This snippet shows how to define a new tool compatible with the MCP protocol. Ensure the tool signature matches expectations and update docstrings for descriptions. ```python from typing import Any from bilibili_mcp_server import mcp from bilibili_mcp_server.utils import sync @mcp.tool() def new_tool(param: str) -> dict[str, Any]: """ Human-readable description. Args: param: Parameter description Returns: Return value description """ result = sync(bilibili_api.some_function(param)) return result ``` -------------------------------- ### Project Metadata Configuration (pyproject.toml) Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/CONFIGURATION.md Defines the essential metadata for the Bilibili MCP Server package, including its name, version, Python requirements, and dependencies. ```toml [project] name = "bilibili-mcp-server" version = "0.1.0" description = "Add your description here" readme = "README.md" requires-python = ">=3.12" dependencies = [ "bilibili-api-python>=17.1.4", "mcp[cli]>=1.4.1", "requests>=2.32.3", ] ``` -------------------------------- ### Perform a Basic Search Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/API_REFERENCE.md Use this snippet for a general search across all Bilibili content types using a keyword. Requires importing the `general_search` function. ```Python from bilibili_mcp_server import general_search # Basic search results = general_search("Python tutorial") # Returns: dict with mixed content types matching "Python tutorial" print(results) ``` -------------------------------- ### MCP Tool Docstring Conventions Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/MODULES.md Illustrates the standard docstring format for MCP tools, including descriptions for arguments and return values. This structured docstring is exposed to MCP clients as tool documentation. ```python def tool_name(param: type) -> return_type: """ Human-readable description of the tool. Args: param: Parameter description Returns: Return value description """ ``` -------------------------------- ### Retrieve and Save Video Danmaku to ASS Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/USAGE_PATTERNS.md Fetches danmaku for a given Bilibili video ID and saves it to a file in ASS subtitle format. Ensure the `get_video_danmaku` function is available. ```python # Get danmaku for a video bv_id = "BV1xx4y1C7ec" # Example video ID danmaku_content = get_video_danmaku(bv_id) # Save to file with open(f"{bv_id}_danmaku.ass", "w") as f: f.write(danmaku_content) print(f"Saved {len(danmaku_content)} bytes of danmaku") ``` -------------------------------- ### User Search Implementation with Pagination Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/IMPLEMENTATION_DETAILS.md Searches specifically for users, ordered by fan count, with pagination support. Filters for users only and sorts by fan count in descending order. ```python import bilibili_api.search as search from bilibili_api.utils.async_helper import sync from bilibili_api.search import SearchObjectType, OrderUser @mcp.tool() def search_user(keyword: str, page: int = 1) -> dict[Any, Any]: return sync(search.search_by_type( keyword=keyword, search_type=SearchObjectType.USER, order_type=OrderUser.FANS, page=page )) ``` -------------------------------- ### Video Object Initialization Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/TYPES.md Represents a Bilibili video object. Initialize with a Bilibili video ID (BV format) for use in functions like `get_video_danmaku()`. ```python from bilibili_api import video class Video: def __init__(self, bvid: str): """ Initialize a Video object with a Bilibili video ID. Args: bvid: Video ID in BV format (e.g., "BV1xx4y1C7ec") """ ``` -------------------------------- ### Using sync() wrapper Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/IMPLEMENTATION_DETAILS.md Convert an asynchronous search function to a synchronous call using the sync() wrapper. This allows the function to be called in a synchronous context. ```python # Without sync: would need await in async context # result = await search.search(keyword) # With sync: works in sync context result = sync(search.search(keyword)) ``` -------------------------------- ### Typical User Search Return Structure Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/IMPLEMENTATION_DETAILS.md The structure includes user details such as username, ID, avatar URL, fan count, and official verification status. Supports pagination. ```json { "result": [ { "uname": "用户名", "mid": 123456, "upic": "https://...", # Avatar URL "fans": 999999, "videos": 123, "level": 5, "usign": "个人签名", "official_verify": { "type": 1, # 0=不认证, 1=个人认证, 2=机构认证 "desc": "认证描述" }, # ... other fields }, # ... more users ], "numResults": 1000, "pagesize": 50, "pages": 20 } ``` -------------------------------- ### Register Video Danmaku Tool Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/MODULES.md Registers the `get_video_danmaku` function as an MCP tool. This function requires a video ID (bv_id) and returns a string. ```python @mcp.tool() def get_video_danmaku(bv_id): ... ``` -------------------------------- ### Test a Specific Tool in Bilibili MCP Server Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/INDEX.md Execute a specific tool with given parameters using a Python one-liner. This is useful for isolated testing and debugging. ```python from bilibili import general_search; print(general_search('test')) ``` -------------------------------- ### Exception propagation with sync() Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/IMPLEMENTATION_DETAILS.md Demonstrates how exceptions raised within an asynchronous function are propagated through the sync() wrapper. A try-except block can catch these exceptions. ```python try: result = sync(search.search("keyword")) except requests.Timeout: # Exception from the async function pass ``` -------------------------------- ### Wrap Tool Calls in Try-Except Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/ERROR_HANDLING.md Wrap tool calls in a try-except block to catch and log any exceptions that occur during execution. This is a fundamental practice for robust consumer code. ```python try: results = general_search("keyword") except Exception as e: logger.error(f"Search failed: {e}") ``` -------------------------------- ### Register User Search Tool Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/MODULES.md Registers the `search_user` function as an MCP tool. This function accepts a keyword and an optional page number, returning a dictionary. ```python @mcp.tool() def search_user(keyword: str, page: int = 1) -> dict[Any, Any]: ... ``` -------------------------------- ### External Dependency Imports Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/MODULES.md Imports for core functionalities like search, synchronization, subtitle generation, video objects, and the MCP server framework. ```python from bilibili_api import search, sync, ass, video # Line 4 from bilibili_api.search import SearchObjectType, OrderUser # Line 5 from mcp.server.fastmcp import FastMCP # Line 6 ``` -------------------------------- ### Run FastMCP Server with stdio Transport Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/CONFIGURATION.md Configure the server to communicate with the client using the Standard Input/Output (stdio) transport. This is part of the Model Context Protocol (MCP) using JSON-RPC messages. ```python mcp.run(transport='stdio') ``` -------------------------------- ### Fetch Multiple Pages of Creators Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/USAGE_PATTERNS.md A workflow function to fetch multiple pages of user search results, aggregating them into a single list. Useful for retrieving a comprehensive list of creators matching a keyword. ```python def search_creators(keyword: str, max_pages: int = 5) -> list: """Fetch multiple pages of user results.""" all_users = [] for page_num in range(1, max_pages + 1): results = search_user(keyword, page=page_num) if "result" not in results or not results["result"]: break all_users.extend(results["result"]) return all_users creators = search_creators("Python教程", max_pages=3) print(f"Found {len(creators)} creators") ``` -------------------------------- ### Python Function Signatures for Bilibili MCP Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/INDEX.md Defines function signatures for searching content and retrieving video danmaku. Use these for interacting with the Bilibili MCP server's API. ```python # Search functions def general_search(keyword: str) -> dict[Any, Any] def search_user(keyword: str, page: int = 1) -> dict[Any, Any] def get_precise_results(keyword: str, search_type: str = "user") -> Dict[str, Any] # Content retrieval def get_video_danmaku(bv_id) -> str ``` -------------------------------- ### Standard Library Imports Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/MODULES.md Imports for file system operations and type annotations from Python's standard library. ```python import os # File system operations (line 1) from typing import Any, Optional, Dict, List # Type annotations (line 2) ``` -------------------------------- ### MCP Client Configuration for Bilibili Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/INDEX.md JSON configuration for the MCP client to connect to Bilibili servers. Specifies the command and arguments to run the Bilibili server. ```json { "mcpServers": { "bilibili": { "command": "uv", "args": [ "--directory", "/path/to/bilibili-mcp-server", "run", "bilibili.py" ] } } } ``` -------------------------------- ### Danmaku Generation Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/IMPLEMENTATION_DETAILS.md Generates danmaku data and saves it to an ASS file. This process may take several seconds and can raise exceptions if the video is inaccessible. The output file is created in the current working directory. ```python output_filepath = "protobuf.ass" sync(ass.make_ass_file_danmakus_protobuf( obj=v, page=0, out=output_filepath )) ``` -------------------------------- ### Register General Search Tool Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/MODULES.md Registers the `general_search` function as an MCP tool. This function takes a keyword and returns a dictionary. ```python @mcp.tool() def general_search(keyword: str) -> dict[Any, Any]: ... ``` -------------------------------- ### Register a Tool with FastMCP Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/CONFIGURATION.md Register a tool function with the MCP server using a decorator. The docstring of the function will be used as the tool's description in the MCP protocol. ```python @mcp.tool() def tool_name(param: type) -> return_type: """Docstring becomes tool description in MCP protocol.""" pass ``` -------------------------------- ### Difference Between search_user and get_precise_results Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/USAGE_PATTERNS.md Compares the general search_user function (returns all matches, sorted by fans) with get_precise_results (returns only exact matches if found). get_precise_results is more useful for finding a specific user, avoiding partial matches, and verifying user existence. ```python # search_user: returns all matches (partial and exact), sorted by fans general_matches = search_user("双", page=1) # get_precise_results: returns only exact matches if found precise_result = get_precise_results("双", search_type="user") # get_precise_results is more useful for: # - Finding a specific user when you know exact username # - Avoiding partial matches # - Verifying user existence ``` -------------------------------- ### get_video_danmaku Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/API_REFERENCE.md Generates and retrieves the danmaku (comments/subtitles) for a specific video, returning the data as an ASS subtitle file format. ```APIDOC ## get_video_danmaku Generates and retrieves the danmaku (comments/subtitles) for a specific video, returning the data as an ASS subtitle file format. ### Signature ```python def get_video_danmaku(bv_id) -> str ``` ### Parameters | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | bv_id | (type not annotated) | Yes | — | Bilibili video ID in BV format (e.g., "BV1xx4y1C7ec") | ### Return Value **Type:** `str` **Description:** ASS subtitle file content as a string. This is the raw text of a protobuf-generated ASS file containing formatted danmaku data compatible with video players. ### Throws **FileNotFoundError** — if the generated danmaku file cannot be created or read **HTTPError** (from requests) — if the Bilibili API request fails Other exceptions from `bilibili_api` may also be raised if the video does not exist or is inaccessible. ### Behavior Notes - Generates danmaku for page 0 (the first video part/episode) - Creates a temporary file `protobuf.ass` in the current working directory, then deletes it after reading - The returned string is the complete ASS file content ### Example ```python from bilibili_mcp_server import get_video_danmaku # Retrieve danmaku for a video danmaku_content = get_video_danmaku("BV1xx4y1C7ec") print(danmaku_content) # Output: ASS subtitle file content with danmaku ``` ``` -------------------------------- ### General Search Functionality Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/MODULES.md Initiates a general search using a keyword. This function calls the Bilibili API's search endpoint and wraps asynchronous operations for synchronous use. ```python general_search(keyword: str) └─ bilibili_api.search.search(keyword) [async] └─ bilibili_api.sync(...) [async → sync wrapper] └─ returns dict[Any, Any] ``` -------------------------------- ### Fetch Danmaku with Retry Logic Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/USAGE_PATTERNS.md Implements a retry mechanism for fetching danmaku, handling transient network failures with exponential backoff. Configurable with `max_retries`. ```python import time def fetch_danmaku_with_retry(bv_id: str, max_retries: int = 3) -> str: """Fetch danmaku with retry logic for transient failures.""" for attempt in range(max_retries): try: return get_video_danmaku(bv_id) except Exception as e: if attempt == max_retries - 1: raise # Exponential backoff wait_time = 2 ** attempt print(f"Attempt {attempt+1} failed. Retrying in {wait_time}s...") time.sleep(wait_time) try: danmaku = fetch_danmaku_with_retry("BV1xx4y1C7ec") except Exception as e: print(f"Failed to fetch danmaku: {e}") ``` -------------------------------- ### API Call for Search Results Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/IMPLEMENTATION_DETAILS.md Initiates the search by calling the search_by_type API. The page is hardcoded to 1 and page size is set to 50 to enhance the likelihood of finding exact matches. ```python result = sync(search.search_by_type( keyword=keyword, search_type=search_obj_type, page=1, page_size=50 )) ``` -------------------------------- ### general_search Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/API_REFERENCE.md Performs a basic search on Bilibili using a keyword, returning all matched content types. This tool is implemented as an MCP tool via the FastMCP framework. ```APIDOC ## general_search ### Description Performs a basic search on Bilibili using a keyword, returning all matched content types. This tool is implemented as an MCP tool via the FastMCP framework. ### Method Not Applicable (Python function call) ### Endpoint Not Applicable (Python function call) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```python from bilibili_mcp_server import general_search # Basic search results = general_search("Python tutorial") # Returns: dict with mixed content types matching "Python tutorial" print(results) ``` ### Response #### Success Response **Type:** `dict[Any, Any]` **Description:** Dictionary containing raw search results from the Bilibili API. The structure includes various content types (videos, users, live streams, articles, etc.) as returned by the underlying bilibili_api.search.search() function. #### Response Example ```json { "example": "response body" } ``` ### Throws None — network errors and API errors are propagated as exceptions by the underlying `sync()` and `search.search()` calls. ``` -------------------------------- ### Search Multiple Creators Sequentially Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/USAGE_PATTERNS.md Use this function to perform multiple related searches for creators in a sequential manner. It handles potential errors during individual searches. ```python def search_multiple_creators(names: list) -> dict: """Search for multiple creators.""" results = {} for name in names: try: result = get_precise_results(name, search_type="user") results[name] = result except Exception as e: print(f"Error searching {name}: {e}") results[name] = None return results # Usage creators = ["Creator1", "Creator2", "Creator3"] all_results = search_multiple_creators(creators) for name, result in all_results.items(): if result and result.get("exact_match"): user = result["users"][0] print(f"{name}: {user['uname']} ({user['fans']} fans)") else: print(f"{name}: Not found") ``` -------------------------------- ### Video Object Creation Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/IMPLEMENTATION_DETAILS.md Creates a Video object for a Bilibili video using its bv_id. The bv_id is not validated here; validation occurs during the API call. ```python v = video.Video(bv_id) ``` -------------------------------- ### Find Exact User by Username Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/USAGE_PATTERNS.md Searches for a specific user by exact username match. Use this when you need to find a particular creator or account. It returns an 'exact_match' boolean and a list of users. ```python # Search for exact user match target_username = "双雷" result = get_precise_results(target_username, search_type="user") if result.get("exact_match"): users = result.get("users", []) if users: user = users[0] # Should be exactly one if exact match print(f"Found exact match: {user['uname']}") print(f" UID: {user['mid']}") print(f" Followers: {user['fans']:,}") print(f" Verified: {bool(user['official'])}") else: # Partial matches only users = result.get("users", []) print(f"No exact match. Found {len(users)} similar users:") for user in users[:5]: print(f" - {user['uname']} ({user['fans']} followers)") ``` -------------------------------- ### Handling Unverified Users in Search Results Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/USAGE_PATTERNS.md Demonstrates how to check the 'official' field in the search result to determine if a user is verified. This snippet shows conditional printing based on the verification status. ```python result = get_precise_results("某个用户", search_type="user") if result.get("exact_match"): user = result["users"][0] is_verified = bool(user["official"]) if is_verified: print(f"{user['uname']} is verified: {user['official']}") else: print(f"{user['uname']} is not verified") ``` -------------------------------- ### Handle Network Errors in General Search Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/ERROR_HANDLING.md Use a try-except block to catch network-related exceptions like timeouts and connection errors when performing a general search. This ensures graceful handling of API unavailability. ```python import requests from bilibili_api import search, sync def general_search(keyword: str) -> dict[Any, Any]: return sync(search.search(keyword)) # May raise network errors try: results = general_search("some keyword") except requests.Timeout: print("Search timed out, please retry") except requests.ConnectionError: print("Cannot reach Bilibili API") except Exception as e: print(f"Unexpected error: {e}") ``` -------------------------------- ### Basic Content Search Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/USAGE_PATTERNS.md Searches Bilibili for content across all types using a keyword. Results include mixed content types and lack pagination or filtering. ```python # Client code using the bilibili MCP server # Basic search for "Python tutorial" results = general_search("Python tutorial") # Inspect results structure print(f"Found {results.get('numResults', 0)} total results") if "result" in results: for item in results["result"][:5]: # First 5 results print(f" - {item.get('type', 'unknown')}: {item.get('title', 'N/A')}") ``` -------------------------------- ### Content Retrieval Functions Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/INDEX.md Provides functions for retrieving specific content, such as video danmaku. ```APIDOC ## get_video_danmaku ### Description Retrieves danmaku (bullet comments) for a given video and returns it in ASS subtitle file format. It always retrieves danmaku for the first part of the video. ### Signature ```python def get_video_danmaku(bv_id) -> str ``` ### Parameters #### Path Parameters - **bv_id** - Required - The Bilibili video ID (bv_id). ### Returns - str - A string containing the danmaku in ASS subtitle format. ``` -------------------------------- ### General Search Implementation Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/IMPLEMENTATION_DETAILS.md Delegates directly to the underlying bilibili_api.search.search() function. Returns raw dictionary results without filtering or pagination support. ```python import bilibili_api.search as search from bilibili_api.utils.async_helper import sync @mcp.tool() def general_search(keyword: str) -> dict[Any, Any]: return sync(search.search(keyword)) ``` -------------------------------- ### Python Caching with TTL Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/USAGE_PATTERNS.md Implements an in-memory cache with a Time-To-Live (TTL) for search results to reduce API calls. Cache keys are based on keyword and page number. ```python from functools import lru_cache from datetime import datetime, timedelta # Simple in-memory cache with TTL _search_cache = {} _cache_ttl = timedelta(hours=1) def cached_user_search(keyword: str, page: int = 1) -> dict: """Search users with caching.""" cache_key = (keyword, page) if cache_key in _search_cache: result, timestamp = _search_cache[cache_key] if datetime.now() - timestamp < _cache_ttl: print(f"Cache hit for {keyword} page {page}") return result print(f"Cache miss. Fetching {keyword} page {page}...") result = search_user(keyword, page=page) _search_cache[cache_key] = (result, datetime.now()) return result ``` ```python # Usage # First call: fetches from API users1 = cached_user_search("某个UP主", page=1) # Second call (within TTL): returns cached result users2 = cached_user_search("某个UP主", page=1) # Different page: fetches from API users3 = cached_user_search("某个UP主", page=2) ``` -------------------------------- ### File Reading Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/IMPLEMENTATION_DETAILS.md Reads the entire content of the generated ASS file into a string. This assumes the file exists, is readable, and is UTF-8 encoded. Large files may cause memory issues. ```python with open(output_filepath, 'r') as f: content = f.read() ``` -------------------------------- ### User Search Sorting Enumeration Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/TYPES.md Enumeration for user sorting options in user searches. Specifies the sort order, currently supporting sorting by fan count. ```python from bilibili_api.search import OrderUser # Enumeration value: OrderUser.FANS # Sort users by fan count (descending) ``` -------------------------------- ### Search Users by Keyword Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/API_REFERENCE.md Searches for Bilibili users by a keyword. Supports pagination to retrieve results page by page. Results are ordered by fan count. ```python from bilibili_mcp_server import search_user # Search for users with keyword, first page users = search_user("双雷") print(users) # Get second page of results users_page2 = search_user("双雷", page=2) print(users_page2) ``` -------------------------------- ### Search with Specific Error Diagnosis Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/USAGE_PATTERNS.md This function performs a search and includes specific exception handling for common network issues like timeouts and connection errors, as well as a general catch-all for unexpected exceptions. ```python from requests.exceptions import Timeout, ConnectionError def search_with_error_diagnosis(keyword: str) -> dict: """Search and provide specific error handling.""" try: return general_search(keyword) except Timeout: print("Request timed out - Bilibili may be slow or unreachable") return None except ConnectionError: print("Network error - check your internet connection") return None except Exception as e: print(f"Unexpected error: {type(e).__name__}: {e}") return None # Usage results = search_with_error_diagnosis("Python") if results: process(results) ``` -------------------------------- ### Register Precise Results Search Tool Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/MODULES.md Registers the `get_precise_results` function as an MCP tool. It takes a keyword and an optional search type, returning a dictionary. ```python @mcp.tool() def get_precise_results(keyword: str, search_type: str = "user") -> Dict[str, Any]: ... ``` -------------------------------- ### Precise User Search Return Structure Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/USAGE_PATTERNS.md Illustrates the structure of the JSON object returned by a precise user search. It includes a list of users, each with details like 'uname', 'mid', 'fans', and 'official' status, and an 'exact_match' boolean. ```json { "users": [ { "uname": "双雷", "mid": 123456789, "face": "https://i0.hdslb.com/bfs/face/...", "fans": 999999, "videos": 456, "level": 6, "sign": "我是双雷", "official": "知名UP主" # or "" if not verified } ], "exact_match": True } ``` -------------------------------- ### Typical General Search Return Structure Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/IMPLEMENTATION_DETAILS.md The structure depends on the Bilibili API version. It typically includes a list of results, total number of results, and pagination information. ```json { "result": [ { "type": "video", # or user, live, article, etc. "id": 123456789, "title": "...", "desc": "...", # ... additional fields per type }, # ... more results ], "numResults": 42, "pagesize": 50, "pages": 1 } ``` -------------------------------- ### Convert Async Call to Sync Source: https://github.com/huccihuang/bilibili-mcp-server/blob/main/_autodocs/ERROR_HANDLING.md Use the `sync()` wrapper from `bilibili_api` to convert an asynchronous function call to a synchronous one. This wrapper may raise exceptions from the async function, `RuntimeError` if called in an event loop, or `asyncio.TimeoutError`. ```python from bilibili_api import sync result = sync(async_function()) # Converts async call to sync ```