zerochan_get_entry
Retrieve detailed metadata for a ZeroChan anime image post using its numeric ID, including tags, image URLs, dimensions, and associated categories.
Instructions
Retrieve detailed information about a single Zerochan entry by its numeric ID.
Returns full metadata including all tags, image URLs (full/medium/small),
source, dimensions, favorites, and associated anime/manga/game categories.
Args:
params (GetEntryInput): Input parameters including:
- username (str): Your Zerochan username (required)
- entry_id (int): Numeric ID of the Zerochan post (e.g. 3793685)
- response_format (ResponseFormat): 'markdown' or 'json' (default: 'markdown')
Returns:
str: Detailed entry data in the requested format.
Markdown: formatted card with all metadata, tag list, and image URLs.
JSON: complete raw API response with all available fields.
Schema (JSON):
{
"id": int,
"primary": str, # Primary/main tag for this image
"tags": list[str], # All associated tags
"width": int,
"height": int,
"fav": int, # Favorite/popularity count
"source": str, # Original source URL if available
"full": str, # Direct URL to full resolution image
"medium": str, # Medium preview URL
"small": str, # Small thumbnail URL
"anime": str | null, # Associated anime title if any
"manga": str | null,
"game": str | null
}Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| params | Yes |
Implementation Reference
- server.py:382-424 (handler)Main handler function for zerochan_get_entry tool. Retrieves detailed information about a single Zerochan entry by its numeric ID, returning either formatted Markdown or raw JSON based on the response_format parameter.
async def zerochan_get_entry(params: GetEntryInput) -> str: """Retrieve detailed information about a single Zerochan entry by its numeric ID. Returns full metadata including all tags, image URLs (full/medium/small), source, dimensions, favorites, and associated anime/manga/game categories. Args: params (GetEntryInput): Input parameters including: - username (str): Your Zerochan username (required) - entry_id (int): Numeric ID of the Zerochan post (e.g. 3793685) - response_format (ResponseFormat): 'markdown' or 'json' (default: 'markdown') Returns: str: Detailed entry data in the requested format. Markdown: formatted card with all metadata, tag list, and image URLs. JSON: complete raw API response with all available fields. Schema (JSON): { "id": int, "primary": str, # Primary/main tag for this image "tags": list[str], # All associated tags "width": int, "height": int, "fav": int, # Favorite/popularity count "source": str, # Original source URL if available "full": str, # Direct URL to full resolution image "medium": str, # Medium preview URL "small": str, # Small thumbnail URL "anime": str | null, # Associated anime title if any "manga": str | null, "game": str | null } """ try: data = await zerochan_get(f"/{params.entry_id}", {}) except Exception as e: return handle_api_error(e) if params.response_format == ResponseFormat.JSON: return json.dumps(data, indent=2, ensure_ascii=False) return format_post_detail_markdown(data) - server.py:226-236 (schema)Input schema GetEntryInput defining the parameters for zerochan_get_entry: entry_id (required int) and response_format (optional, defaults to 'markdown'). Uses Pydantic BaseModel with validation.
class GetEntryInput(BaseModel): """Input for retrieving a single Zerochan entry by ID.""" model_config = ConfigDict(extra="forbid") entry_id: int = Field( ..., description="The numeric Zerochan entry ID (visible in the URL of any post). e.g. 3793685", ge=1 ) response_format: ResponseFormat = Field(default=ResponseFormat.MARKDOWN, description="Output format: 'markdown' or 'json'") - server.py:372-381 (registration)Tool registration decorator using @mcp.tool with name 'zerochan_get_entry', including annotations for title, readOnlyHint, destructiveHint, idempotentHint, and openWorldHint.
@mcp.tool( name="zerochan_get_entry", annotations={ "title": "Get Zerochan Entry Details", "readOnlyHint": True, "destructiveHint": False, "idempotentHint": True, "openWorldHint": True, } ) - server.py:58-86 (helper)Helper function zerochan_get that performs async HTTP GET requests to Zerochan API with proper User-Agent header, timeout handling, and error status checking.
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() - server.py:134-177 (helper)Formatting helper function format_post_detail_markdown that formats a single Zerochan entry's data into a Markdown card with ID, primary tag, dimensions, favorites, source, tags list, and image URLs.
def format_post_detail_markdown(data: dict) -> str: """Format a single post's detailed data as Markdown.""" entry_id = data.get("id", "N/A") tags = data.get("tags", []) source = data.get("source", "N/A") width = data.get("width", "?") height = data.get("height", "?") fav = data.get("fav", 0) full_url = data.get("full", f"https://www.zerochan.net/{entry_id}") medium_url = data.get("medium", "") small_url = data.get("small", "") primary_tag = data.get("primary", "N/A") anime = data.get("anime", None) manga = data.get("manga", None) game = data.get("game", None) lines = [ f"## Zerochan Entry #{entry_id}", f"", f"**Primary Tag:** {primary_tag}", f"**Dimensions:** {width} × {height}", f"**Favorites:** {fav}", f"**Source:** {source}", f"", f"**Tags ({len(tags)}):** {', '.join(tags)}", ] if anime: lines.append(f"**Anime:** {anime}") if manga: lines.append(f"**Manga:** {manga}") if game: lines.append(f"**Game:** {game}") lines += [ f"", f"**Full Image:** {full_url}", ] if medium_url: lines.append(f"**Medium Preview:** {medium_url}") if small_url: lines.append(f"**Small Preview:** {small_url}") return "\n".join(lines)