Skip to main content
Glama

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 build

3. 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.js

Añá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.json

  • Windows %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

check_permissions

Comprueba un juego e informa exactamente qué herramientas funcionarán en él y cuáles no, y por qué.

set_project_credentials

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

list_projects

Tus juegos y sus ids de universo.

get_game_info

Consulta cualquier juego de Roblox por enlace, id de lugar o id de universo — no tiene que ser tuyo.

search_roblox_games

Busca en Roblox por nombre o palabra clave.

add_project

Añade un juego a tu cuenta, vinculado a la cuenta de Roblox que pueda editarlo.

list_collaborators / invite_collaborator

Quién más tiene acceso a un proyecto, y un enlace de invitación de un solo uso.

Miniaturas

Herramienta

Qué hace

get_thumbnails

Miniaturas activas e inactivas con QPTR, impresiones, visitas cualificadas, tiempo de juego medio.

set_active_thumbnails

Elige qué miniaturas muestra Roblox realmente — reemplaza, añade o elimina.

upload_thumbnail

Publica una imagen local como miniatura de juego.

delete_thumbnail

Elimina permanentemente una miniatura del juego.

get_qptr_trend

Clics e impresiones diarios durante los últimos 7, 14 o 30 días.

get_thumbnail_momentum

Qué miniaturas individuales están subiendo, bajando o estables.

export_thumbnail_report

El conjunto completo, ordenado por QPTR, como PDF escrito en disco.

Crear miniaturas

Herramienta

Qué hace

generate_thumbnail

Genera una imagen a partir de un prompt y referencias, la escribe en disco y opcionalmente la publica.

list_generations

Todo lo generado para un juego, con los prompts detrás de cada uno.

upload_generation

Publica algo de ese historial sin volver a subirlo.

list_style_profiles

Las guías de estilo con nombre a las que se puede apuntar al generar.

Rotarlas

Herramienta

Qué hace

get_auto_swap

Si un juego se rota solo, con qué reglas, en qué horario y qué hicieron las ejecuciones recientes.

configure_auto_swap

Activa o desactiva la rotación y ajusta sus umbrales.

run_auto_swap

Ejecuta una rotación ahora, sin esperar al horario.

get_queue

Qué hay en cola para promocionarse.

queue_thumbnail / unqueue_thumbnail

Añade o quita una miniatura de esa cola.

Discord

Herramienta

Qué hace

list_discord_roles

Roles que pueden recibir notificaciones.

notify_team

Envía un mensaje directo a un rol, opcionalmente con imágenes y dos botones de respuesta.

get_notification_history

Lo que ya se envió, con las respuestas de cada persona y el estado de pago.

create_ticket

Abre un ticket — publica un embed con Aprobar/Rechazar en el canal del juego.

list_tickets

Los tickets de un juego, con lo que sigue sin responder o sin pagar.

list_artist_channels

Canales de texto en el servidor del estudio, con sus ids.

create_channel / link_channel

Crea un canal y vincula los tickets de un juego a él.

get_channel_messages

Lee un canal — autor, hora, texto, URLs de adjuntos.

send_channel_message

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.500Z

Pagar 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 create en Discord, desde cualquier canal o un mensaje directo con el bot

  • create_ticket aquí, para automatizaciones

  • las 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:#lammyta

Sin 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=117760

Ambos á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

WHT_API_KEY

Tu clave de la página de claves

WHT_BASE_URL

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

Install Server
F
license - not found
A
quality
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

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

View all related MCP servers

Related MCP Connectors

View all MCP Connectors

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/Haydebug/whitehat-thumbnails-mcp'

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