Skip to main content
Glama

zerochan_browse

Read-onlyIdempotent

Browse Zerochan's global anime image feed with filtering by dimensions, color, and sorting options to find specific content.

Instructions

Browse all Zerochan entries with optional filtering and pagination.

Queries the Zerochan global feed without any tag filter. Supports sorting by
recency or popularity, filtering by dimensions or color, and pagination.

Args:
    params (BrowseAllInput): Input parameters including:
        - username (str): Your Zerochan username for the User-Agent header (required)
        - page (int): Page number (default: 1)
        - limit (int): Results per page, 1–250 (default: 20)
        - sort (SortOrder): 'id' for recent, 'fav' for popular (default: 'id')
        - time_range (Optional[TimeRange]): '0' all-time, '1' last 7000, '2' last 15000
        - dimensions (Optional[Dimensions]): Filter by image shape
        - color (Optional[str]): Filter by dominant color name
        - response_format (ResponseFormat): 'markdown' or 'json' (default: 'markdown')

Returns:
    str: Paginated list of entries in the requested format.
         Markdown: formatted table with ID, tags, dimensions, favorites, links.
         JSON: raw API response with all fields.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
paramsYes

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes

Implementation Reference

  • Main handler function for zerochan_browse tool. Executes the API call to browse all Zerochan entries with optional filtering by time range, dimensions, color, and supports pagination and sorting. Returns results in either Markdown or JSON format.
    async def zerochan_browse(params: BrowseAllInput) -> str:
        """Browse all Zerochan entries with optional filtering and pagination.
    
        Queries the Zerochan global feed without any tag filter. Supports sorting by
        recency or popularity, filtering by dimensions or color, and pagination.
    
        Args:
            params (BrowseAllInput): Input parameters including:
                - username (str): Your Zerochan username for the User-Agent header (required)
                - page (int): Page number (default: 1)
                - limit (int): Results per page, 1–250 (default: 20)
                - sort (SortOrder): 'id' for recent, 'fav' for popular (default: 'id')
                - time_range (Optional[TimeRange]): '0' all-time, '1' last 7000, '2' last 15000
                - dimensions (Optional[Dimensions]): Filter by image shape
                - color (Optional[str]): Filter by dominant color name
                - response_format (ResponseFormat): 'markdown' or 'json' (default: 'markdown')
    
        Returns:
            str: Paginated list of entries in the requested format.
                 Markdown: formatted table with ID, tags, dimensions, favorites, links.
                 JSON: raw API response with all fields.
        """
        query: dict = {
            "p": params.page,
            "l": params.limit,
            "s": params.sort.value,
        }
        if params.time_range is not None:
            query["t"] = params.time_range.value
        if params.dimensions is not None:
            query["d"] = params.dimensions.value
        if params.color:
            query["c"] = params.color
    
        try:
            data = await zerochan_get("/", query)
        except Exception as e:
            return handle_api_error(e)
    
        items = data.get("items", data) if isinstance(data, dict) else data
    
        if params.response_format == ResponseFormat.JSON:
            return json.dumps(data, indent=2, ensure_ascii=False)
    
        return format_post_list_markdown(items if isinstance(items, list) else [], "Global Feed")
  • Input schema (BrowseAllInput) defining the parameters for the zerochan_browse tool. Includes fields for page, limit, sort order, time range, dimensions filter, color filter, and response format with validation constraints.
    class BrowseAllInput(BaseModel):
        """Input for browsing all Zerochan entries."""
        model_config = ConfigDict(str_strip_whitespace=True, extra="forbid")
    
        page: int = Field(default=1, description="Page number for pagination (starts at 1)", ge=1)
        limit: int = Field(default=DEFAULT_LIMIT, description="Number of results per page (1–250)", ge=1, le=MAX_LIMIT)
        sort: SortOrder = Field(default=SortOrder.RECENT, description="Sort order: 'id' = most recent, 'fav' = most popular")
        time_range: Optional[TimeRange] = Field(default=None, description="Time range for popularity sort: '0' = all time, '1' = last 7000 entries, '2' = last 15000 entries")
        dimensions: Optional[Dimensions] = Field(default=None, description="Filter by image dimensions: large, huge, landscape, portrait, square")
        color: Optional[str] = Field(default=None, description="Filter by dominant color, e.g. 'red', 'blue', 'green'", max_length=32)
        response_format: ResponseFormat = Field(default=ResponseFormat.MARKDOWN, description="Output format: 'markdown' or 'json'")
  • server.py:242-251 (registration)
    Tool registration using @mcp.tool decorator with name 'zerochan_browse' and annotations including title, readOnlyHint, destructiveHint, idempotentHint, and openWorldHint.
    @mcp.tool(
        name="zerochan_browse",
        annotations={
            "title": "Browse All Zerochan Entries",
            "readOnlyHint": True,
            "destructiveHint": False,
            "idempotentHint": True,
            "openWorldHint": True,
        }
    )
  • HTTP client helper function zerochan_get that performs GET requests to the Zerochan API with proper headers, error handling, and JSON response parsing. Used by zerochan_browse to fetch data.
    async def zerochan_get(path: str, params: dict) -> dict:
        """
        Perform a GET request to the Zerochan API.
    
        Args:
            path: URL path (e.g. '/Hatsune+Miku')
            params: Query string parameters (json=True always included)
    
        Returns:
            Parsed JSON response dict
    
        Raises:
            ValueError: If ZEROCHAN_USERNAME env var is not set
            httpx.HTTPStatusError: On non-2xx responses
            httpx.TimeoutException: On request timeout
        """
        if not ZEROCHAN_USERNAME:
            raise ValueError(
                "ZEROCHAN_USERNAME is not set. Add it to your MCP config: "
                '"env": {"ZEROCHAN_USERNAME": "YourUsername"}'
            )
        params["json"] = True
        url = f"{ZEROCHAN_BASE_URL}{path}"
        user_agent = f"zerochan-mcp - {ZEROCHAN_USERNAME}"
    
        async with httpx.AsyncClient(timeout=15.0) as client:
            response = await client.get(url, params=params, headers={"User-Agent": user_agent})
            response.raise_for_status()
            return response.json()
  • Formatting helper function format_post_list_markdown that transforms API response data into a formatted Markdown table with columns for ID, tags, dimensions, favorites, and links. Used by zerochan_browse for markdown output.
    def format_post_list_markdown(items: list, source: str) -> str:
        """Format a list of post summaries as a Markdown table."""
        if not items:
            return "No results found."
    
        lines = [f"### Zerochan Results from `{source}`\n"]
        lines.append(f"| ID | Tags | Dimensions | Favorites | Full Image |")
        lines.append(f"|---|---|---|---|---|")
    
        for item in items:
            entry_id = item.get("id", "N/A")
            tags = ", ".join(item.get("tags", [])[:5])
            if len(item.get("tags", [])) > 5:
                tags += f" (+{len(item['tags']) - 5} more)"
            width = item.get("width", "?")
            height = item.get("height", "?")
            fav = item.get("fav", "?")
            full_url = item.get("full", f"https://www.zerochan.net/{entry_id}")
            lines.append(f"| [{entry_id}]({full_url}) | {tags} | {width}×{height} | {fav} | [View]({full_url}) |")
    
        return "\n".join(lines)
Behavior4/5

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

The description adds valuable behavioral context beyond annotations. While annotations already indicate read-only, non-destructive, idempotent operations, the description specifies that it 'Supports sorting by recency or popularity, filtering by dimensions or color, and pagination' and details the return format options. It doesn't contradict annotations (readOnlyHint=true aligns with 'browse'), but provides important implementation details about filtering capabilities and output formats.

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

Conciseness5/5

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

The description is perfectly structured and concise. It begins with a clear purpose statement, provides usage context, then details parameters in a well-organized format, and concludes with return value information. Every sentence earns its place, and the information is front-loaded with the most important details first.

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

Completeness5/5

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

Given the tool's complexity (multiple filtering/sorting options) and the presence of annotations and output schema, the description is complete. It explains what the tool does, when to use it, all parameters with semantics, and the return format differences. The output schema existence means the description doesn't need to detail return structure, and it appropriately focuses on behavioral aspects.

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

Parameters5/5

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

Despite 0% schema description coverage (the schema has descriptions but coverage calculation shows 0%), the description provides comprehensive parameter documentation in the Args section. It explains all 8 parameters with their purposes, defaults, constraints, and enums. This fully compensates for any schema coverage gaps and adds substantial value beyond what the schema structure alone provides.

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

Purpose5/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: 'Browse all Zerochan entries with optional filtering and pagination.' It specifies the verb ('browse'), resource ('Zerochan entries'), and scope ('all'), distinguishing it from sibling tools like zerochan_search (which presumably filters by tags) and zerochan_get_entry (which likely retrieves a specific entry).

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

Usage Guidelines5/5

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

The description explicitly states when to use this tool: 'Queries the Zerochan global feed without any tag filter.' This clearly differentiates it from zerochan_search (which would use tag filters) and provides a specific use case (browsing the global feed). The guidance is direct and helpful for tool selection.

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

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/citronlegacy/zero-chan-mcp'

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