- Gelbooru Mcp
Gelbooru Mcp
gelbooru-mcp
A Python MCP server that wraps the Gelbooru API. Connect it to any MCP-compatible client (Claude Desktop, Cursor, etc.) to search posts, look up tags, and generate Stable Diffusion prompts from real character appearance data — all directly from your AI assistant.
✨ Features
🎨 Stable Diffusion Prompt Generation
- Character Prompts: Auto-generate accurate SD prompts from real Gelbooru tag frequency data
- Appearance Breakdown: Separate eye, hair, and clothing/accessory tag categories
- Smart Caching: Results cached for 24 hours — no repeated API hits
🔍 Post & Tag Search
- Advanced Filtering: Search by tags, score, resolution, rating, uploader, pool, and more
- Full Tag Syntax: AND, OR, wildcard, exclusion, meta-tags, sorting, and pagination
- Tag Lookup: Check tag existence, post counts, and discover related tags
👥 Community Tools
- User Search: Find Gelbooru user accounts by name or wildcard pattern
- Comments: Retrieve post comments for any post ID
- Deleted Posts: Track removed content above a given post ID
📦 Installation
Prerequisites
- Python 3.10+
git
Quick Start
- Clone the repository:
git clone https://github.com/citronlegacy/gelbooru-mcp.git
cd gelbooru-mcp
- Run the installer:
chmod +x install.sh && ./install.sh
# or without chmod:
bash install.sh
- Or install manually:
pip install mcp
Note: Add
.gelbooru_cache/and.venv/to your.gitignoreto avoid committing cached data or your virtual environment.
Getting a Gelbooru API Key
- Visit your Gelbooru account options page
- Log in to your Gelbooru account
- Copy your API Key and User ID
- Set them as environment variables (see below)
🔑 Authentication
API credentials are optional but strongly recommended — unauthenticated requests are throttled and limited to 2 tags per query. Gelbooru Patreon supporters receive unlimited requests.
export GELBOORU_API_KEY="your_api_key"
export GELBOORU_USER_ID="your_user_id"
Both values are on your Gelbooru account options page. Without them the server still works but requests may be throttled. Patreon supporters of Gelbooru are not rate-limited.
▶️ Running the Server
python gelbooru_mcp.py
# or via the venv created by install.sh:
.venv/bin/python gelbooru_mcp.py
⚙️ Configuration
Claude Desktop
Add the following to your claude_desktop_config.json:
{
"mcpServers": {
"gelbooru-mcp": {
"command": "/absolute/path/to/.venv/bin/python",
"args": ["/absolute/path/to/gelbooru_mcp.py"],
"env": {
"GELBOORU_API_KEY": "your_api_key",
"GELBOORU_USER_ID": "your_user_id"
}
}
}
}
Other MCP Clients
Configure according to your client's documentation:
- Command:
/absolute/path/to/.venv/bin/python - Args:
/absolute/path/to/gelbooru_mcp.py - Transport: stdio
💡 Usage Examples
Generate a Stable Diffusion prompt for a character
"Build me a Stable Diffusion prompt for Rem from Re:Zero."
The LLM calls build_prompt with character_name: "rem_(re:zero)" and gets back:
rem (re:zero), blue eyes, blue hair, short hair, maid, maid headdress, maid apron, ...
Find high-quality wallpaper images
"Show me the top-rated scenery images that are at least 1920px wide."
The LLM calls search_posts with tags: "scenery width:>=1920 sort:score:desc".
Look up how popular a tag is
"How many posts does the tag 'misty_(pokemon)' have on Gelbooru?"
The LLM calls search_tags with name: "misty_(pokemon)" and reads the count field.
🛠️ Available Tools
| Tool | Description | Key Parameters |
|---|---|---|
build_prompt | Generate a Stable Diffusion prompt string for a character | character_name, max_images, include_other |
get_character_tags | Get structured tag breakdown with frequency counts | character_name, max_images |
search_posts | Search posts with full tag syntax support | tags, limit, pid, id |
search_tags | Look up tags by name, pattern, or ID | name, name_pattern, orderby, limit |
search_users | Find Gelbooru user accounts | name, name_pattern, limit |
get_comments | Retrieve comments for a post | post_id |
get_deleted_posts | List recently deleted posts | last_id, limit |
📖 Tools Reference
build_prompt
Fetches the most-tagged rating:general solo posts for a character and assembles a ready-to-paste Stable Diffusion prompt string. Internally calls get_character_tags so results are cached after the first fetch.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
character_name | string | ✅ | — | Gelbooru character tag, e.g. misty_(pokemon) |
max_images | integer | ❌ | 300 | Posts to analyse. More = slower first fetch, more reliable tags. Cached afterward. |
include_other | boolean | ❌ | true | Include non-eye/hair tags (clothing, accessories, etc.). Set to false for appearance-only prompts. |
Example response
{
"prompt": {
"character": "misty (pokemon)",
"posts_analysed": 284,
"cache_hit": false,
"prompt_string": "misty (pokemon), green eyes, orange hair, side ponytail, gym leader, shorts, suspenders",
"tags": {
"eye": ["green eyes"],
"hair": ["orange hair", "side ponytail"],
"other": ["gym leader", "shorts", "suspenders"]
}
}
}
LLM Tip: Always use Gelbooru's underscore format (
misty_(pokemon)notMisty (Pokemon)). If unsure of the exact tag, callsearch_tagswithname_patternfirst.
get_character_tags
Same data source as build_prompt but returns the full structured tag breakdown with frequency counts. Use this when you want to inspect, filter, or reformat tags yourself.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
character_name | string | ✅ | — | Gelbooru character tag, e.g. rem_(re:zero) |
max_images | integer | ❌ | 300 | Number of top-scored posts to analyse. |
Example response
{
"character_tags": {
"name": "rem_(re:zero)",
"posts_analysed": 300,
"cache_hit": true,
"eye": [
{ "tag": "blue eyes", "count": 261, "frequency": 0.87 }
],
"hair": [
{ "tag": "blue hair", "count": 274, "frequency": 0.913 },
{ "tag": "short hair", "count": 198, "frequency": 0.66 }
],
"other": [
{ "tag": "maid", "count": 231, "frequency": 0.77 }
]
}
}
frequency is the fraction of analysed posts that had that tag (0.0–1.0). Tags near 1.0 are near-universal; tags below 0.3 are situational.
Cache environment variables:
| Env var | Default | Description |
|---|---|---|
GELBOORU_CACHE_DIR | .gelbooru_cache/ next to script | Custom cache folder path |
GELBOORU_CACHE_TTL | 86400 (24 hours) | Cache lifetime in seconds |
search_posts
Search Gelbooru posts using any tag combination. Supports the full Gelbooru tag syntax including meta-tags, sorting, and filtering.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
tags | string | ❌ | — | Tag query string (see Tag Syntax Reference below) |
limit | integer | ❌ | 20 | Posts to return (max 100) |
pid | integer | ❌ | 0 | Page number (0-indexed) for pagination |
id | integer | ❌ | — | Fetch a single post by its Gelbooru post ID |
cid | integer | ❌ | — | Fetch posts by change ID (Unix timestamp) |
get_deleted_posts
Retrieve posts that have been deleted from Gelbooru, optionally filtered to those above a given post ID.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
last_id | integer | ❌ | — | Only return deleted posts whose ID is above this value. Useful for syncing a local mirror. |
limit | integer | ❌ | 20 | Posts to return (max 100) |
search_tags
Look up Gelbooru tags by name, wildcard pattern, or ID. Useful for checking tag existence, finding post counts, discovering related tags, or autocomplete.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
name | string | ❌ | — | Exact tag name, e.g. blue_hair |
names | string | ❌ | — | Space-separated list of exact tag names, e.g. cat_ears dog_ears fox_ears |
name_pattern | string | ❌ | — | SQL LIKE wildcard: % = any chars, _ = one char. E.g. %schoolgirl% |
id | integer | ❌ | — | Look up a tag by its database ID |
after_id | integer | ❌ | — | Return tags with ID greater than this value |
limit | integer | ❌ | 20 | Tags to return (max 100) |
order | string | ❌ | — | ASC or DESC |
orderby | string | ❌ | — | Sort field: date, count, or name |
LLM Tip: If the user gives a character name in natural language (e.g. "Misty from Pokemon"), use
name_patternwith%misty%_(pokemon)%to find the correct Gelbooru tag before callingget_character_tagsorbuild_prompt.
search_users
Search for Gelbooru user accounts by name.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
name | string | ❌ | — | Exact username |
name_pattern | string | ❌ | — | SQL LIKE wildcard username search |
limit | integer | ❌ | 20 | Results to return (max 100) |
pid | integer | ❌ | 0 | Page number for pagination |
get_comments
Retrieve comments on a specific post.
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
post_id | integer | ✅ | — | The Gelbooru post ID to fetch comments for |
🏷️ Tag Syntax Reference
| Syntax | Meaning |
|---|---|
tag1 tag2 | Posts with both tag1 AND tag2 |
{tag1 ~ tag2 ~ tag3} | Posts with tag1 OR tag2 OR tag3 |
-tag1 | Exclude posts with tag1 |
*tag1 | Wildcard prefix (tags ending with tag1) |
tag1* | Wildcard suffix (tags starting with tag1) |
rating:general | Filter by rating: general, questionable, or explicit |
-rating:explicit | Exclude a rating |
score:>=50 | Score at least 50 |
width:>=1920 | Image width ≥ 1920px |
height:>1080 | Image height > 1080px |
user:bob | Uploaded by user "bob" |
fav:1 | Posts favourited by user with ID 1 |
pool:2 | Posts in pool ID 2 |
sort:score:desc | Sort by score (desc or asc) |
sort:random | Random order on every request |
sort:random:1234 | Random order with a fixed seed (0–10000) |
sort:updated:desc | Sort by most recently updated |
🤖 Notes for LLMs
- Character tag format: Gelbooru uses
character_(series)format with underscores. Always convert natural language names before passing to tools — "Rem from Re:Zero" →rem_(re:zero), "Saber from Fate" →saber_(fate). - Workflow for character prompts: If the exact tag is unknown, call
search_tagswithname_patternfirst → confirm the tag exists and has posts → then callbuild_prompt. - Pagination:
search_postsreturns max 100 results per call. Usepidto walk through pages.get_character_tagsandbuild_prompthandle their own pagination internally. - Cache:
get_character_tagsandbuild_promptcache results for 24 hours. Thecache_hitfield in the response indicates whether live or cached data was used. - Ratings: Gelbooru uses
general,questionable, andexplicit.get_character_tagsandbuild_promptalways filter torating:generalfor cleaner, more representative character data.
⚠️ Known Limitations
- Tag search limit: Gelbooru enforces a maximum of 2 tags per unauthenticated search query. For complex multi-tag queries, set
GELBOORU_API_KEYandGELBOORU_USER_ID. get_character_tagsaccuracy: Results depend on how consistently a character is tagged on Gelbooru. Niche or recently added characters may have fewer posts and less reliable frequency data.rating:generalonly for character tools:build_promptandget_character_tagsintentionally restrict torating:generalfor clean, representative appearance data. Explicit posts are excluded by design.- Cache is per
(character_name, max_images)pair: Changingmax_imagesbusts the cache for that character.
🐛 Troubleshooting
Server won't start:
- Ensure Python 3.10+ is installed:
python --version - Verify the virtual environment was created:
ls .venv/ - Re-run the installer:
bash install.sh
API rate limiting / throttled requests:
- Set
GELBOORU_API_KEYandGELBOORU_USER_IDenvironment variables - Gelbooru Patreon supporters receive unlimited requests
Character not found / empty results:
- Confirm the tag exists with
search_tagsusingname_pattern - Check spelling — Gelbooru uses
character_(series)underscore format - Some characters may have very few consistently tagged posts
Tag syntax errors / too many tags:
- Unauthenticated users are limited to 2 tags per query
- Authenticate with API credentials for complex multi-tag searches
🤝 Contributing
Pull requests are welcome! If you find a character tag being miscategorised (e.g. a hair style tag missing from the hair bucket, or a noise tag slipping through the purge filter), please open an issue or PR with the tag and which list it belongs in.
Development Setup
- Fork the repository
- Create a feature branch
- Make your changes
- Submit a pull request
📄 License
MIT License — see LICENSE for details.
🔗 Links
Server Config
{
"mcpServers": {
"gelbooru-mcp": {
"command": "/absolute/path/to/.venv/bin/python",
"args": [
"/absolute/path/to/gelbooru_mcp.py"
],
"env": {
"GELBOORU_API_KEY": "your_api_key",
"GELBOORU_USER_ID": "your_user_id"
}
}
}
}