jmcomic ยท git:20260911.47a868c ยท 2026-09-11 ยท sha256 7d8004f7a8f8a8fc
jmcomic git:20260911.47a868cA
Immutable. This exact content never changes and is served at /api/v1/blob/7d8004f7a8f8a8fc.
---
name: jmcomic
description: Search, browse, inspect album-specific or site-wide comments, list favorite folders, browse, add, and delete favorites, and download manga from JMComic (18comic), obtain the latest Android APK from hect0x7/JMComic-APK, and invoke the upstream jm-view-server `jms` command for local reading. Use for manga discovery, ranking, comment analysis, favorites, downloads, post-processing, configuration, requests to download the JMComic APK, requests to start a local or phone-accessible manga reader, and download-then-read workflows.
---
# JMComic Skill
This skill enables you to interact with JMComic (18comic), a popular manga platform, to search, browse, and download manga content.
## When to Use This Skill
Activate this skill when the user wants to:
- Search for manga by keyword or category
- Browse popular manga rankings (daily, weekly, monthly)
- Read album-specific or site-wide comments and nested replies, including spoiler flags
- List favorite folders, browse saved albums, add an album to favorites, or delete an album from favorites
- Download entire albums or specific chapters (**Returns structured dict with status, paths, and metadata**)
- Get detailed information about a manga album
- Configure download settings (paths, concurrency, proxies)
- Post-process downloaded content (Zip, PDF, LongImage) with **native parameters or `dir_rule`**
- Download the latest Android APK published by `hect0x7/JMComic-APK`
- Run `jms --help` to obtain the current upstream options, then invoke `jms` directly for an existing or newly downloaded manga directory
For APK download, local-reader startup, LAN safety, and download-to-read continuation rules, read
`references/ecosystem.md` before acting.
### ๐ฅ Download Tools Return Structured Data
Both `download_album` and `download_photo` return structured dictionaries:
**`download_album(album_id: str, ctx: Context = None)`** returns:
```python
{
"status": "success" | "failed",
"album_id": str,
"title": str,
"download_path": str, # Absolute path to download directory
"duration": float | None, # Total elapsed time in seconds
"image_paths": list[str], # Actual downloaded or cached image paths
"export_files": dict[str, list[str]], # Plugin outputs grouped by suffix
"task_id": str, # Dedicated ID for this download invocation
"log_path": str, # Absolute path to this task's log file
"error": str | None
}
```
**`download_photo(photo_id: str, ctx: Context = None)`** returns:
```python
{
"status": "success" | "failed",
"photo_id": str,
"image_count": int, # Number of actual image paths in this result
"download_path": str, # Absolute path to download directory
"duration": float | None, # Total elapsed time in seconds
"image_paths": list[str], # Actual downloaded or cached image paths
"export_files": dict[str, list[str]], # Plugin outputs grouped by suffix
"task_id": str, # Dedicated ID for this download invocation
"log_path": str, # Absolute path to this task's log file
"error": str | None
}
```
**Real-time Progress Tracking**: Both methods accept an optional `ctx: Context` parameter (automatically injected by FastMCP). When provided, progress updates are sent via MCP notifications in real-time, allowing AI agents to monitor download progress.
**Persistent Task Logs**: Every download invocation creates an isolated log file and returns its `task_id` and `log_path`, including failed downloads. Logs default to `~/.jmcomic-ai/logs`; set `JM_TASK_LOG_DIR` to use another directory.
**Artifact Handoff**: Use `image_paths` and `export_files` for packaging, sending, or cleanup instead of rescanning the configured directory. `download_path` comes from the completed upstream download result rather than a pre-download path prediction.
**File-only Logging**: Regular `jmcomic`, `jmcomic_ai`, and MCP runtime logs share `~/.jmcomic-ai/jmcomic_ai.log` and are not emitted to stdout or stderr. Set `JM_LOG_PATH` to override the global log file. MCP protocol messages and explicit CLI result output are unaffected.
**Upstream Rich Terminal Progress**: `jmcomic 2.7.4` adds the optional `download_progress` plugin with `log_file` and `terminal_log_lines`. Recommend it only when the user explicitly wants Rich progress in an interactive terminal. Do not enable it for `jmai` MCP/stdio downloads, which already use MCP Context notifications and isolated task logs.
### Album Comments
Use `get_album_comments(album_id: str, page: int = 1)` to read one page of comments. This is a read-only tool; it does not post comments or replies.
```python
{
"album_id": str,
"page": int,
"page_size": int,
"total": int | None,
"page_count": int | None,
"comment_count": int,
"comments": [
{
"comment_id": str | None,
"album_id": str | None,
"user_id": str | None,
"parent_comment_id": str | None,
"content": str,
"username": str,
"nickname": str,
"is_spoiler": bool,
"created_at": object,
"likes": int | None,
"replies": [...] # Recursive nested replies
}
]
}
```
Use `get_forum_comments(page: int = 1)` for the latest site-wide comments. It returns the same comment objects and pagination fields without an `album_id` filter; each comment's own `album_id` identifies its source album. This is also read-only.
### Favorites
All favorite tools require an authenticated client. Call `login` in the same MCP session or configure
valid cookies. For HTML queries authenticated only by Cookie, pass `username`; after `login`, it can
be omitted. The API client ignores `username` and always queries the current account. Separate script
processes need authentication in their configuration; they do not inherit an MCP session's login.
**`get_favorite_folders(username: str = "")`** returns:
```python
{"folders": [{"id": str, "name": str}]}
```
The directory can be empty. Use `folder_id="0"` to browse all favorites even if this ID is absent
from the returned directory.
**`browse_favorite_albums(folder_id: str = "0", page: int = 1, order_by: str = "favorite_time", username: str = "")`** returns:
```python
{
"albums": [{"id": str, "title": str, "tags": list, "cover_url": str}],
"total_count": int,
"page": int,
"folder_id": str,
"error": str # Present only for invalid page, folder ID, or sort parameters
}
```
Pagination starts at 1; `folder_id="0"` means all favorites. An empty result retains pagination and
folder metadata. `order_by` accepts `favorite_time` (default) and `update_time`; the favorites list has
its own upstream sort vocabulary, which differs from `browse_albums`. The service does not sort a page
locally. Invalid arguments return an empty list with `error`; authentication and request failures
propagate as tool errors, not empty collections.
**`add_favorite_album(album_id: str)`** returns:
```python
{
"status": "success" | "error",
"album_id": str,
"title": str, # Album title
"message": str
}
```
`album_id` accepts a numeric ID, a JM-prefixed ID, or an album URL and is normalized when parsing
succeeds. The album is saved to the account's default favorites placement.
Adding an album that is already saved returns `status="error"` and leaves the saved state unchanged.
**`delete_favorite_album(album_id: str)`** returns the same fields and takes the same `album_id` forms.
Deleting an album that is not saved returns `status="error"` and leaves the saved state unchanged.
Both tools behave identically whichever client implementation the configuration selects, and both return
the album `title`. Name every affected album as `title (ID)`; when `title` is empty or absent, reuse an
earlier search, browse, or detail result, or fetch the name with `get_album_detail(album_id)` or
`python scripts/album_info.py --id ID`.
## Core Capabilities
### ๐ ๏ธ Post-Processing
This skill supports advanced post-processing of downloaded manga. It returns structured data including the **output path** of the generated file.
- **๐ฆ Zip Compression**: Pack an entire album or individual chapters into a ZIP file.
- **๐ PDF Conversion**: Merge all images of an album into a single PDF document.
- **๐ผ๏ธ Long Image Merging**: Combine all pages of a chapter into one continuous long image.
**`post_process(album_id: str, process_type: str, params: dict = None)`** returns:
```python
{
"status": "success" | "error",
"process_type": str, # Process type used
"album_id": str, # Album ID processed
"output_path": str, # Absolute path to generated file/directory (empty string on error)
"output_paths": list[str], # All files actually registered by the upstream plugin
"is_directory": bool, # True if output is a directory (e.g., photo-level zip), False on error
"message": str # Success/error message
}
```
**All fields are always present**. On error, `output_path` is empty, `output_paths` is empty, and `is_directory` is `False`.
**Output Control**: Use `dir_rule` (a `{"rule": "DSL_STRING", "base_dir": "BASE_PATH"}` dict) for custom output paths. If omitted, files are saved in the configured default directory. The DSL supports `Bd` (base_dir), `Axxx`/`Pxxx` album/photo attributes, and `{attr}` Python format placeholders. When looping over albums into one `base_dir`, include `{Aid}` or `{Atitle}` to avoid overwrites.
For the full set of ZIP/PDF/LongImg ร album/photo `dir_rule` examples, see `references/post_process.md`.
This skill provides command-line utilities for JMComic operations. All utilities are Python scripts located in the `scripts/` directory and should be executed using Python.
### Data Structure Notes
Most search and browsing tools (e.g., `search_album`, `browse_albums`) return a consistent structure that supports pagination:
```json
{
"albums": [ ... ],
"total_count": 1234
}
```
**`total_count`** provides the total number of items available across all pages, allowing you to calculate the number of remaining pages and decide if further searching is needed.
#### Important: Browse Albums Data Limitations
**`browse_albums`** is the unified tool for browsing albums by `category`, `time_range`, and `order_by` (ranking + category browsing in one interface). Its response is lightweight โ each album has only `id`, `title`, `tags`, and `cover_url`, and **no** stats (likes/views/author). To get those, call **`get_album_detail(album_id)`** per album.
`order_by` accepts: `latest` (default), `likes`, `views`, `pictures`, `score`, `comments`. For the full enumeration, use-case recipes (rankings, category browsing, combined queries), and the "top 10 with details" workflow, see `references/browse_albums.md`.
## Configuration Reference
For detailed configuration options, refer to:
- **`references/reference.md`**: Human-readable configuration guide
- **`assets/option_schema.json`**: JSON Schema for validation
Common configuration examples:
```yaml
# Change download directory
dir_rule:
base_dir: "/path/to/downloads"
rule: "Bd / Ptitle"
# Adjust concurrency
download:
threading:
image: 30 # Max concurrent image downloads
photo: 5 # Max concurrent chapter downloads
# Set proxy
client:
async_impl: async_api # Used by jmcomic native async APIs
cache: level_option # Reuse metadata across clients from this option
postman:
meta_data:
proxies:
http: "http://proxy.example.com:8080"
https: "https://proxy.example.com:8080"
# Or use system proxy
client:
postman:
meta_data:
proxies: system
# Configure login cookies
client:
postman:
meta_data:
cookies:
AVS: "your_avs_cookie_value"
# Use plugins
plugins:
after_album:
- plugin: zip
kwargs:
level: photo
suffix: zip
delete_original_file: true
```
## Available Command-Line Tools
The `scripts/` directory provides utility tools for common tasks. All tools support the `--help` flag for detailed usage. The table below summarizes each script; for full per-script examples and feature lists, see `references/scripts.md`.
| Script | Purpose |
| :--- | :--- |
| `doctor.py` | Environment diagnostics: Python version, deps, config status, network/domain checks. |
| `batch_download.py` | Download multiple albums from a list of IDs (CLI or file) with progress/error summary. |
| `download_photo.py` | Download specific chapters/photos without fetching whole albums. |
| `validate_config.py` | Validate `option.yml` and convert between YAML and JSON. |
| `search_export.py` | Search by keyword/ranking/category and export to CSV or JSON (multi-page); `--tags` keeps only albums carrying every given tag, `--enrich` fills per-album stats. |
| `album_info.py` | Query detailed metadata for one or many albums; print or export to JSON. |
| `album_comments.py` | Fetch one page of album comments and recursive replies; print or export to JSON. |
| `forum_comments.py` | Fetch one page of site-wide comments with source album IDs; print or export to JSON. |
| `favorite_folders.py` | List favorite folders as JSON; supports `--username`, `--output`, and `--option`. |
| `favorite_albums.py` | Browse one page of favorites as JSON; supports folder, page, sort, and username filters. |
| `add_favorite_album.py` | Add one favorite and print its structured result as JSON; failures exit non-zero. |
| `delete_favorite_album.py` | Delete one favorite and print its structured result as JSON; failures exit non-zero. |
| `download_covers.py` | Batch download album cover images to a custom output directory. |
| `ranking_tracker.py` | Track day/week/month rankings over time; export snapshots with timestamps. |
| `post_process.py` | Convert downloads to ZIP/PDF/LongImg, with optional encryption and `dir_rule` DSL; `--outdir` uses a safe file rule and missing deps are auto-installed (`--no-install-deps` to opt out). |
| `download_latest_apk.py` | Download the latest APK published by `hect0x7/JMComic-APK`; supports optional `output_dir`, `--force`, and `--json` (run `--help` for current usage). |
## Script Parameters โ MCP Tools Mapping
The following table clarifies how script CLI parameters map to MCP tools.
| Script | Target Tool | Mapping Level | Notes |
| :--- | :--- | :--- | :--- |
| `search_export.py` | `search_album` / `browse_albums` | Partial | `--keyword` maps to `search_album`; `--ranking` / `--category` maps to `browse_albums`. Ranking is a convenience mode based on `time_range` + configurable sort, not a separate backend API. |
| `post_process.py` | `post_process` | High | `--id`โ`album_id`, `--type`โ`process_type`, optional flags to `params`. `--dir-rule` + `--base-dir` map to `params.dir_rule`. |
| `album_info.py` | `get_album_detail` | Partial | Batch wrapper over repeated single-album calls; output format is script-defined. |
| `album_comments.py` | `get_album_comments` | High | `--id` maps to `album_id`, `--page` maps to `page`, and the JSON response preserves the MCP result shape. |
| `forum_comments.py` | `get_forum_comments` | High | `--page` maps to `page`, and each returned comment preserves its source `album_id`. |
| `favorite_folders.py` | `get_favorite_folders` | High | `--username` maps to `username`; JSON preserves the MCP result shape. |
| `favorite_albums.py` | `browse_favorite_albums` | High | `--folder-id`, `--page`, `--order-by`, `--username` map to the corresponding tool arguments. |
| `add_favorite_album.py` | `add_favorite_album` | High | `--id` maps to `album_id`; an error result exits non-zero. |
| `delete_favorite_album.py` | `delete_favorite_album` | High | `--id` maps to `album_id`; an error result exits non-zero. |
| `download_covers.py` | `download_cover` | Partial | Batch wrapper over repeated cover calls. |
| `ranking_tracker.py` | `browse_albums` | Partial | Uses time-range/category browse semantics and exports snapshots. |
| `batch_download.py` | `download_album` | Partial | Batch wrapper over repeated calls; prints each result's download path and dedicated log path. |
| `download_photo.py` | `download_photo` | Partial | Batch wrapper over repeated calls; prints each result's download path and dedicated log path. |
| `validate_config.py` | `update_option` (adjacent) | None | Validation/format conversion utility; not a direct MCP tool wrapper. |
| `download_latest_apk.py` | None | None | Reads the public `hect0x7/JMComic-APK` GitHub Release API directly. |
### Mapping Policy
- **MCP tools are the source of truth** for agent-facing contracts (name, args, return structure).
- **Scripts are operational helpers** for local package workflows and may expose different output formatting.
- If strict schema guarantees are required, prefer calling MCP tools directly instead of scripts.
## Important Notes
- **Legal Compliance**: Ensure you have the right to download content
- **Rate Limiting**: The platform may rate-limit requests; adjust threading if needed
- **Storage**: Downloads can be large; ensure sufficient disk space
- **Configuration**: Default config is at `~/.jmcomic/option.yml`
- **Next action**: After a successful manga download, offer to start the local reader for the returned
`download_path`. Start it automatically only when the user also asked to open, read, or view the result.
## Troubleshooting
- **Connection errors**: Try updating the domain list in client config
- **Slow downloads**: Reduce threading concurrency
- **Scrambled images**: Ensure `download.image.decode` is set to `true`