Skip to main content
Glama
Ukenn2112

Bangumi TV MCP Service

by Ukenn2112

get_subject_details

Retrieve detailed information about a specific subject such as anime, books, or games by providing a subject ID, formatted for easy use and integration.

Instructions

Get details of a specific subject (e.g., anime, book, game).

Args:
    subject_id: The ID of the subject.

Returns:
    Formatted subject details or an error message.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
subject_idYes

Implementation Reference

  • main.py:525-596 (handler)
    The core handler function for the 'get_subject_details' MCP tool. It is decorated with @mcp.tool(), which handles both definition and registration. Fetches subject details from the Bangumi API endpoint /v0/subjects/{subject_id}, processes the response, handles errors, and formats a detailed text summary including name, type, summary, rating, tags, collection stats, and image URL.
    @mcp.tool()
    async def get_subject_details(subject_id: int) -> str:
        """
        Get details of a specific subject (e.g., anime, book, game).
    
        Args:
            subject_id: The ID of the subject.
    
        Returns:
            Formatted subject details or an error message.
        """
        response = await make_bangumi_request(
            method="GET", path=f"/v0/subjects/{subject_id}"
        )
    
        error_msg = handle_api_error_response(response)
        if error_msg:
            return error_msg
    
        # Expecting a dictionary
        if not isinstance(response, dict):
            return f"Unexpected API response format for get_subject_details: {response}"
    
        subject = response
        infobox = subject.get("infobox")
        tags = subject.get("tags")
    
        details_text = f"Subject Details (ID: {subject_id}):\n"
        details_text += f"  Name: {subject.get('name')}\n"
        if subject.get("name_cn"):
            details_text += f"  Chinese Name: {subject.get('name_cn')}\n"
        try:
            details_text += f"  Type: {SubjectType(subject.get('type')).name if subject.get('type') is not None else 'Unknown Type'}\n"
        except ValueError:
            details_text += f"  Type: Unknown Type ({subject.get('type')})\n"
    
        if subject.get("date"):
            details_text += f"  Date: {subject.get('date')}\n"
        if subject.get("platform"):
            details_text += f"  Platform: {subject.get('platform')}\n"
        if subject.get("volumes"):
            details_text += f"  Volumes: {subject.get('volumes')}\n"
        if subject.get("eps") is not None:  # Could be 0
            details_text += f"  Episodes (Wiki): {subject.get('eps')}\n"
        if subject.get("total_episodes"):
            details_text += f"  Episodes (DB): {subject.get('total_episodes')}\n"
    
        details_text += f"  Summary:\n{subject.get('summary')}\n"
    
        if subject.get("rating", {}).get("score") is not None:
            details_text += f"  Score: {subject['rating'].get('score')} (Votes: {subject['rating'].get('total')})\n"
        if subject.get("rating", {}).get("rank") is not None:
            details_text += f"  Rank: {subject['rating'].get('rank')}\n"
    
        if tags:
            tags_list = [f"{t['name']} ({t['count']})" for t in tags]
            details_text += f"  Tags: {', '.join(tags_list)}\n"
    
        if infobox:
            details_text += (
                "  Infobox: (Details available in raw response, potentially complex)\n"
            )
    
        if "collection" in subject:  # requires auth and user had collected it
            collection = subject["collection"]
            details_text += f"  Collection (Total Users): Wish: {collection.get('wish',0)}, Collected: {collection.get('collect',0)}, Doing: {collection.get('doing',0)}, On Hold: {collection.get('on_hold',0)}, Dropped: {collection.get('dropped',0)}\n"
    
        images = subject.get("images")
        if images and images.get("large"):
            details_text += f"  Cover Image: {images.get('large')}\n"
    
        return details_text
  • main.py:525-525 (registration)
    The @mcp.tool() decorator registers the get_subject_details function as an MCP tool.
    @mcp.tool()
  • The function signature (subject_id: int -> str) and docstring define the input schema (single integer parameter) and output (formatted string). No separate Pydantic or JSON schema; relies on type hints and decorator.
    """
    Get details of a specific subject (e.g., anime, book, game).
    
    Args:
        subject_id: The ID of the subject.
    
    Returns:
        Formatted subject details or an error message.
    """
  • Uses shared helper functions make_bangumi_request to call the API and handle_api_error_response for error handling.
    response = await make_bangumi_request(
        method="GET", path=f"/v0/subjects/{subject_id}"
    )
    
    error_msg = handle_api_error_response(response)
    if error_msg:
        return error_msg
    
    # Expecting a dictionary
    if not isinstance(response, dict):
        return f"Unexpected API response format for get_subject_details: {response}"
    
    subject = response
    infobox = subject.get("infobox")
    tags = subject.get("tags")
    
    details_text = f"Subject Details (ID: {subject_id}):\n"
    details_text += f"  Name: {subject.get('name')}\n"
    if subject.get("name_cn"):
        details_text += f"  Chinese Name: {subject.get('name_cn')}\n"
    try:
        details_text += f"  Type: {SubjectType(subject.get('type')).name if subject.get('type') is not None else 'Unknown Type'}\n"
    except ValueError:
        details_text += f"  Type: Unknown Type ({subject.get('type')})\n"
    
    if subject.get("date"):
        details_text += f"  Date: {subject.get('date')}\n"
    if subject.get("platform"):
        details_text += f"  Platform: {subject.get('platform')}\n"
    if subject.get("volumes"):
        details_text += f"  Volumes: {subject.get('volumes')}\n"
    if subject.get("eps") is not None:  # Could be 0
        details_text += f"  Episodes (Wiki): {subject.get('eps')}\n"
    if subject.get("total_episodes"):
        details_text += f"  Episodes (DB): {subject.get('total_episodes')}\n"
    
    details_text += f"  Summary:\n{subject.get('summary')}\n"
    
    if subject.get("rating", {}).get("score") is not None:
        details_text += f"  Score: {subject['rating'].get('score')} (Votes: {subject['rating'].get('total')})\n"
    if subject.get("rating", {}).get("rank") is not None:
        details_text += f"  Rank: {subject['rating'].get('rank')}\n"
    
    if tags:
        tags_list = [f"{t['name']} ({t['count']})" for t in tags]
        details_text += f"  Tags: {', '.join(tags_list)}\n"
    
    if infobox:
        details_text += (
            "  Infobox: (Details available in raw response, potentially complex)\n"
        )
    
    if "collection" in subject:  # requires auth and user had collected it
        collection = subject["collection"]
        details_text += f"  Collection (Total Users): Wish: {collection.get('wish',0)}, Collected: {collection.get('collect',0)}, Doing: {collection.get('doing',0)}, On Hold: {collection.get('on_hold',0)}, Dropped: {collection.get('dropped',0)}\n"
    
    images = subject.get("images")
    if images and images.get("large"):
        details_text += f"  Cover Image: {images.get('large')}\n"
    
    return details_text
  • A related MCP prompt that instructs usage of get_subject_details along with other tools for full subject info.
    def get_subject_full_info(subject_id: int) -> str:
        """
        Get detailed information, related persons, characters, and relations for a subject.
    
        Args:
            subject_id: The ID of the subject to get information for.
        """
        return f"Get the full details for subject ID {subject_id} using 'get_subject_details'. Also get related persons using 'get_subject_persons', related characters using 'get_subject_characters', and other related subjects using 'get_subject_relations'. Summarize the key information from all these tool outputs."
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries full burden for behavioral disclosure. It mentions that it returns 'formatted subject details or an error message', which gives some output context, but lacks critical information such as whether this is a read-only operation, authentication requirements, rate limits, or what happens with invalid IDs.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is appropriately sized and front-loaded with the core purpose. The Args and Returns sections are structured clearly, though the 'Returns' section could be more specific about the format of subject details.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the lack of annotations, no output schema, and 0% schema description coverage, the description is incomplete. It doesn't adequately address behavioral aspects, error conditions, or provide enough context about the subject ID parameter for reliable tool invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The description adds minimal semantics beyond the input schema, which has 0% description coverage. It clarifies that 'subject_id' refers to 'The ID of the subject', but doesn't explain what constitutes a valid subject ID, where to find these IDs, or provide format examples. With only one parameter, this meets the baseline expectation.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose with a specific verb ('Get details') and resource ('specific subject'), and provides examples of subject types (anime, book, game). However, it doesn't explicitly differentiate from sibling tools like 'get_character_details' or 'get_person_details' beyond the resource type.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is provided on when to use this tool versus alternatives like 'browse_subjects' or 'search_subjects'. The description only states what it does without indicating appropriate contexts or prerequisites for usage.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Related Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Ukenn2112/BangumiMCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server