White Hat Thumbnails
White Hat Thumbnails — servidor MCP
Permite que un asistente de IA gestione tus miniaturas de Roblox de principio a fin desde una ventana de chat: lee cómo están funcionando, genera nuevas, publícalas, elige cuáles están activas, rótalas automáticamente y habla con tu equipo de Discord al respecto.
"how are the thumbnails doing on +1 dumpling escape?"
"what am I actually allowed to do on magnet simulator?"
"generate three variants from this reference and put the best one live"
"drop the worst performer and promote the next one from the queue"
"go notify the thumbnail team on +1 dumpling escape walls to pay this link,
with two options approve and disapprove"Todo se ejecuta contra tu propia cuenta. Una clave solo alcanza los proyectos a los que ya tienes acceso en el sitio, y nunca puede volver a leer una credencial almacenada: solo decir si existe y si funciona.
Configuración
1. Obtén una clave
Inicia sesión en https://whitehatthumbnails.vercel.app, abre Keys y crea una. Se muestra una sola vez: cópiala en ese momento.
2. Instala
git clone https://github.com/Haydebug/whitehat-thumbnails-mcp.git
cd whitehat-thumbnails-mcp
npm install
npm run build3. Señálale tu asistente
claude mcp add whitehat-thumbnails \
--env WHT_API_KEY=wht_your_key_here \
-- node /absolute/path/to/whitehat-thumbnails-mcp/dist/index.jsAñádelo a claude_desktop_config.json:
{
"mcpServers": {
"whitehat-thumbnails": {
"command": "node",
"args": ["/absolute/path/to/whitehat-thumbnails-mcp/dist/index.js"],
"env": { "WHT_API_KEY": "wht_your_key_here" }
}
}
}El archivo de configuración se encuentra en:
macOS
~/Library/Application Support/Claude/claude_desktop_config.jsonWindows
%APPDATA%\Claude\claude_desktop_config.json
Reinicia Claude Desktop después.
Usa una ruta absoluta — el asistente no se ejecuta desde esta carpeta.
Related MCP server: GPT Image MCP Server
Herramientas
Saber qué puedes hacer
Herramienta | Qué hace |
| Comprueba un juego e informa exactamente qué herramientas funcionarán en él y cuáles no, y por qué. |
| Almacena una clave de Open Cloud y/o una cookie de Roblox en un juego — las dos cosas que pide el informe. |
Proyectos
Herramienta | Qué hace |
| Tus juegos y sus ids de universo. |
| Consulta cualquier juego de Roblox por enlace, id de lugar o id de universo — no tiene que ser tuyo. |
| Busca en Roblox por nombre o palabra clave. |
| Añade un juego a tu cuenta, vinculado a la cuenta de Roblox que pueda editarlo. |
| Quién más tiene acceso a un proyecto, y un enlace de invitación de un solo uso. |
Miniaturas
Herramienta | Qué hace |
| Miniaturas activas e inactivas con QPTR, impresiones, visitas cualificadas, tiempo de juego medio. |
| Elige qué miniaturas muestra Roblox realmente — reemplaza, añade o elimina. |
| Publica una imagen local como miniatura de juego. |
| Elimina permanentemente una miniatura del juego. |
| Clics e impresiones diarios durante los últimos 7, 14 o 30 días. |
| Qué miniaturas individuales están subiendo, bajando o estables. |
| El conjunto completo, ordenado por QPTR, como PDF escrito en disco. |
Crear miniaturas
Herramienta | Qué hace |
| Genera una imagen a partir de un prompt y referencias, la escribe en disco y opcionalmente la publica. |
| Todo lo generado para un juego, con los prompts detrás de cada uno. |
| Publica algo de ese historial sin volver a subirlo. |
| Las guías de estilo con nombre a las que se puede apuntar al generar. |
Rotarlas
Herramienta | Qué hace |
| Si un juego se rota solo, con qué reglas, en qué horario y qué hicieron las ejecuciones recientes. |
| Activa o desactiva la rotación y ajusta sus umbrales. |
| Ejecuta una rotación ahora, sin esperar al horario. |
| Qué hay en cola para promocionarse. |
| Añade o quita una miniatura de esa cola. |
Discord
Herramienta | Qué hace |
| Roles que pueden recibir notificaciones. |
| Envía un mensaje directo a un rol, opcionalmente con imágenes y dos botones de respuesta. |
| Lo que ya se envió, con las respuestas de cada persona y el estado de pago. |
| Abre un ticket — publica un embed con Aprobar/Rechazar en el canal del juego. |
| Los tickets de un juego, con lo que sigue sin responder o sin pagar. |
| Canales de texto en el servidor del estudio, con sus ids. |
| Crea un canal y vincula los tickets de un juego a él. |
| Lee un canal — autor, hora, texto, URLs de adjuntos. |
| Publica en un canal como el bot, como texto plano o como embed, opcionalmente con imágenes. |
Los nombres de los juegos se comparan de forma flexible, así que "dumpling escape" encuentra "+1 Dumpling SMASH Walls". Si un nombre es ambiguo, la herramienta lo indica y lista los candidatos en lugar de adivinar.
Saber qué se te permite hacer
La autoridad sobre un juego de Roblox no es un permiso único. Está repartida entre una
cookie .ROBLOSECURITY (subir, eliminar, intercambiar el conjunto activo), una clave
de Open Cloud (analíticas), una configuración de personalización que Roblox solo crea
cuando un juego ya tiene varias miniaturas (si es que tiene un conjunto activo
intercambiable), y un bot de Discord (tickets y notificaciones). Cualquiera de ellas
puede faltar por separado, y el fallo que ves es el mismo encogimiento de hombros en
todos los casos.
check_permissions las comprueba todas a la vez y responde con dos listas:
MAGNET SIMULATOR LEGENDS — universeId 7592711723
You own this project.
Open Cloud key: stored (••••YkpR), encrypted at rest
Roblox account: WH_AIbot (the shared default account)
WORKS (6)
get_thumbnails
2 active, 124 inactive
analytics (QPTR, impressions, playtime)
figures came back for 16 of 126 thumbnails via the Open Cloud key ••••YkpR
set_active_thumbnails
a personalization config was resolved, so the live set can be changed
…
DOES NOT WORK (2)
upload_thumbnail, delete_thumbnail
WH_AIbot (the shared default account) is signed in but Roblox refuses it
edit access to this game
Fix: give that account permission on the experience, or store a cookie for
one that already has it with set_project_credentials.
ticket posting to a channel
this game is not linked to a Discord channel, so tickets only go out as DMs
Fix: call create_channel with this game, or link_channel with an id.Cada "no" incluye el motivo y la solución, porque un "no" por sí solo te manda a dar vueltas al mismo bucle. Ejecútalo antes de una escritura importante, o después de que una falle y no sea evidente qué credencial faltaba.
Las dos credenciales que pide se guardan con set_project_credentials. Se
almacenan cifradas y nunca se vuelven a leer — el informe solo puede decir si una clave
está presente y si funciona, y nada más.
Elegir qué está activo
Subir una miniatura no hace que cualquiera la vea. Roblox conserva todas las imágenes
que un juego ha tenido y sirve un subconjunto elegido; set_active_thumbnails es lo que
cambia ese subconjunto, y el cambio tiene efecto inmediato.
set_active_thumbnails(game: "magnet simulator", ids: ["108286870859415"], mode: "add")
set_active_thumbnails(game: "magnet simulator", ids: ["112922133257215"], mode: "remove")add y remove ajustan lo que ya está activo y son lo que normalmente quieres usar.
replace deja exactamente la lista indicada como activa y todo lo demás inactivo — es
fácil dispararlo por accidente cuando querías decir add. Los ids pueden ser los ids
de asset con los que empiezan los informes o los ids internos de miniatura; ambos son
válidos.
Aquí no se elimina nada. Una miniatura desactivada conserva su historial y puede
recuperarse. delete_thumbnail es la única operación que no se puede deshacer, y se
niega a eliminar la última imagen activa de un juego.
Generar
generate_thumbnail ejecuta el mismo proceso que la página de generación del sitio: tu
prompt se reescribe según una guía de estilo y luego se renderiza contra una o más
imágenes de referencia. El resultado se escribe en un archivo de tu máquina para que
puedas verlo antes de que se acerque a un juego.
generate_thumbnail(
game: "magnet simulator",
prompt: "character yanking a giant magnet out of a pile of loot",
referencePaths: ["ref.png"],
profile: "Simulator"
)Las referencias pueden ser rutas locales o URLs públicas; se requiere al menos una, ya
que el modelo parte de una imagen y no de la nada. profile elige una de las guías de
estilo que lista list_style_profiles. Pasa publish: true solo cuando la imagen ya
se haya acordado — si no, genera, mira el archivo y luego usa upload_thumbnail.
Rotación automática
El intercambio automático elimina las miniaturas activas con peor rendimiento según QPTR y promociona reemplazos desde una cola, según un horario.
queue_thumbnail(game: "magnet simulator", id: "108286870859415")
configure_auto_swap(game: "magnet simulator", enabled: true, dropCount: 1,
frequencyMinutes: 1440, qptrThreshold: 2)
run_auto_swap(game: "magnet simulator")qptrThreshold es un porcentaje, no una fracción: 2 significa 2%. Un juego con la
cola vacía ejecutará la rotación y no hará nada, así que consulta get_queue antes de
activarla. get_auto_swap muestra las reglas, el horario y qué movieron realmente las
ejecuciones recientes — y si la rotación se desactivó sola, el motivo que da es lo que
hay que arreglar.
Botones de respuesta
notify_team puede adjuntar dos botones y dejar que la gente responda:
notify_team(
game: "+1 dumpling escape",
role: "Thumbnail Team",
message: "Pay here please: https://…",
askForAnswer: true,
approveLabel: "Paid",
declineLabel: "Cancel"
)Quien haga clic hace que su decisión se envíe por mensaje directo a todos los que tengan ese rol, incluida esa misma persona. Cada persona puede responder una vez.
get_notification_history informa de cada respuesta en su propia línea con el id de
Discord de la persona y el momento en que hizo clic, de modo que una automatización
puede condicionarse a que un par concreto de personas hayan aprobado ambas, en lugar de
depender de un recuento:
2026-08-20T03:42:31.704Z — Hayden S → "Thumbnail Team" (2/2 delivered) · ticket clx…
Dumpling concept art from lamy
payment: $10 · https://paypal.me/asianlamy · PAID by Bug at 2026-08-20T03:45:02.118Z
answers:
Bug (4207…) = Paid at 2026-08-20T03:45:02.118Z
ang (9931…) = Deny at 2026-08-20T03:46:44.500ZPagar por trabajo encargado
Pasa paymentAmount y el ticket se convierte en una factura — el mensaje directo
muestra el importe y un botón de pago, los botones pasan a ser Pagado / Cancelar
por defecto, y el primer clic en Pagado marca el ticket como pagado:
notify_team(
game: "+1 dumpling escape",
role: "Thumbnail Team",
message: "Dumpling concept art from lamy",
paymentAmount: 10,
paypalLink: "paypal.me/asianlamy"
)paid queda fijado. Un rechazo después de que alguien ya lo haya marcado como pagado
se registra como respuesta pero no deshace el pago del ticket — el dinero que salió no
puede recuperarse con un botón.
Tickets
Un ticket es el mismo registro que una notificación de equipo — misma tabla, mismas respuestas por persona, mismo indicador de pago — con un título, un tipo y un canal donde vivir. Puede abrirse de tres formas y después son indistinguibles:
/ticket createen Discord, desde cualquier canal o un mensaje directo con el botcreate_ticketaquí, para automatizacioneslas herramientas de notificación del sitio
create_ticket(
game: "+1 dumpling escape",
type: "concept_review",
title: "Dumpling wall smash — first pass",
description: "Three angles from lamy. Picking one for the A/B.",
imagePaths: ["pass1.png", "pass2.png"]
)Los tipos son concept_review, final_review, payment y status. Todo excepto
status lleva botones de Aprobar / Rechazar; un ticket de pago lleva Pagado / Cancelar
además del importe y un enlace de PayPal en el que se puede hacer clic, y el primer clic
en Pagado fija el indicador de pago. Las respuestas aparecen en
get_notification_history exactamente igual que las respuestas a botones en un mensaje
directo, y el embed del canal se reescribe a medida que la gente responde, de modo que
el mensaje que todos están mirando muestra el estado actual.
Cada juego publica sus tickets en un canal, configurado una vez desde Discord:
/ticket config game:<game> channel:#lammytaSin eso, un ticket igualmente se crea y sigue siendo legible — solo que no tiene dónde aparecer, y la herramienta lo dice en lugar de fingir que se entregó.
Hablar con los artistas
Cada artista tiene su propio canal de texto en el servidor del estudio. Las tres
herramientas de canal son un bucle de sondeo, no una fuente en vivo: lee con since
ajustado al lastMessageId que se te dio la última vez, y solo ves lo que ha llegado
desde entonces.
list_artist_channels() → #lammyta — id 1539…
get_channel_messages(channelId: "1539…", since: "…") → replies + art
send_channel_message(channelId: "1539…", text: "…", imagePaths: ["brief.png"])Las URLs de adjuntos de Discord están firmadas y caducan en aproximadamente un día, así que descarga el arte en cuanto lo veas en lugar de guardar el enlace para más tarde.
Embeds
Una publicación de canal puede ser un embed en lugar de una línea de texto: la tarjeta con la barra de color en el lateral, la misma que usan los mensajes directos de notificación. Pasa embed en lugar de text, o junto a él:
send_channel_message(
channelId: "1539…",
embed: {
author: "White Hat Thumbnails · MCP",
title: "+1 Dumpling SMASH Walls",
url: "https://whitehatthumbnails.vercel.app/projects/10307670587",
color: "#facc15",
description: "Five thumbnails live. **0.41% QPTR** on 1.95M impressions.",
fields: [
{ name: "Top QPTR", value: "0.41%", inline: true },
{ name: "Impressions", value: "1,947,283", inline: true }
],
thumbnailUrl: "https://tr.rbxcdn.com/…",
imageUrl: "https://tr.rbxcdn.com/…",
footer: "Sent by the MCP",
buttons: [{ label: "View project", url: "https://whitehatthumbnails.vercel.app/…" }]
}
)La forma es plana a propósito: Discord anida el pie de página, la imagen y cada botón dentro de contenedores, y nada de eso merece la pena saberlo para enviar un mensaje. Los campos se recortan a las longitudes que Discord impone en lugar de enviarse largos, porque rechaza el mensaje entero por un solo campo demasiado grande.
Los botones aquí solo abren enlaces. Un botón que hace una pregunta y registra la respuesta pertenece a notify_team o create_ticket, que tienen dónde anotar la respuesta.
Para que el bot vea un canal necesita Ver canal, Leer historial de mensajes, Enviar mensajes y Adjuntar archivos en él. Invítalo con:
https://discord.com/oauth2/authorize?client_id=<APP_ID>&scope=bot%20applications.commands&permissions=117760Ambos ámbitos importan. bot lo introduce en el servidor; applications.commands es lo que hace que /ticket sea visible allí. Un bot invitado sin el segundo funciona bien para mensajes directos y publicaciones de canal, mientras que sus comandos de barra nunca aparecen en silencio.
Configuración
Variable | Requerido | Significado |
| sí | Tu clave de la página de claves |
| no | Solo si ejecutas tu propia copia del sitio |
Notas
Discord puede rechazar los mensajes directos, y eso no es un error. Discord no permite que un bot envíe mensajes a alguien que lo haya bloqueado, que tenga desactivados los mensajes directos de miembros del servidor o que no comparta ningún servidor con el bot. notify_team informa por persona de cuál de esos casos ha ocurrido en lugar de un único recuento de éxitos.
Roblox modera las subidas de forma asíncrona. Que upload_thumbnail devuelva Pending significa que se ha aceptado y se está revisando, normalmente unos minutos.
Algunos juegos son de solo lectura. Subir e intercambiar requieren una cuenta de Roblox con acceso de edición a esa experiencia; una clave de Open Cloud no puede hacer ninguna de las dos cosas. El sitio muestra cada proyecto como Edición completa, Solo vista o Vista pública, y las herramientas avisan cuando algo no está disponible en lugar de fallar en silencio. check_permissions es la forma más rápida de saber en qué caso se encuentra un juego.
Tres herramientas cambian lo que los jugadores ven realmente, y lo hacen en el momento en que devuelven: set_active_thumbnails, run_auto_swap y configure_auto_swap con enabled: true. Subir y generar no lo hacen: una miniatura subida permanece inactiva hasta que algo la publica.
Una herramienta no se puede deshacer. delete_thumbnail elimina la imagen de Roblox junto con su historial de análisis. Desactivar con set_active_thumbnails(mode: "remove") es la versión reversible y casi siempre es lo que se quería hacer.
check_permissions no prueba la generación. La única comprobación honesta sería generar una imagen, lo que cuesta dinero y deja un rastro. Si generate_thumbnail va a fallar, falla en la primera llamada, con el motivo.
Licencia
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseAqualityBmaintenanceMCP server for YouTube creator-ops — video metadata, comments, playlists, channel analytics, plus a ComfyUI bridge for AI thumbnail generation.15431MIT
- AlicenseAqualityDmaintenanceAn MCP server for image generation, editing, and analysis using OpenAI's gpt-image-1 model, with specialized templates for YouTube thumbnails, blog headers, social media, and more.7MIT
- FlicenseNot gradedqualityDmaintenanceMCP server that lets AI assistants manage an art catalogue — find paintings, post to social media, upload to galleries, schedule posts, and update metadata.
- AlicenseNot gradedqualityAmaintenanceAn MCP server that gives an AI coding agent real control of Roblox Studio and Roblox Open Cloud, with a test-and-security layer no other Studio MCP has.223MIT
Related MCP Connectors
MCP server for NanoBanana AI image generation and editing
MCP server for Flux AI image generation
An MCP server that integrates with Discord to provide AI-powered features.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/Haydebug/whitehat-thumbnails-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server