Skip to main content
Glama

VitaminMCP

Plugin de servidor MCP de automatización de pruebas de Minecraft para agentes de IA.

Demostración de VitaminMCP: un agente de IA controlando un servidor real de Minecraft

VitaminMCP es un plugin de servidor Paper/Purpur. Coloca VitaminMCP.jar en plugins/, inicia el servidor, y abre un endpoint MCP desde dentro del servidor en ejecución — para que un agente de IA pueda controlar ese servidor y leer lo que ocurrió, mientras clientes bot reales se conectan a él mediante el protocolo de Minecraft.

Nada del plugin que estás probando cambia. No hay framework de pruebas que adoptar, ni código fuente que instrumentar, ni banco de pruebas contra el que compilar, ni servidor simulado que sustituya a uno real: el plugin bajo prueba se ejecuta en un servidor real a lo largo de su ciclo de vida real, y VitaminMCP lo observa desde la siguiente ranura de plugin. Lo que también significa que funciona con plugins que no hayas escrito: cualquier cosa ya instalada es comprobable.

Controla un servidor real de Minecraft y jugadores reales mediante herramientas MCP, y ejecuta pruebas de plugins de extremo a extremo sin abrir el juego.

  • Genera y controla jugadores de prueba: clientes de protocolo reales, no objetos Player simulados.

  • Ejecuta comandos como consola o como jugador.

  • Abre, lee, hace clic y verifica inventarios y GUIs de plugins.

  • Haz clic derecho en NPCs y aldeanos, de la forma en que realmente se activa una tienda o un proveedor de misiones.

  • Mueve jugadores, rompe y usa bloques, chatea.

  • Espera eventos y condiciones en lugar de dormir.

  • Verifica bloques, jugadores, eventos, inventarios y los mensajes que recibió un jugador.

  • Lee la pantalla completa del jugador: menús, chat, barra de acción, títulos, barras de jefe, marcador.

  • Lee el estado en vivo del servidor: eventos, registros, excepciones, permisos.

  • Controla varios servidores a la vez: una sesión por backend de una red BungeeCord, con los bots permaneciendo conectados a todos ellos.

  • Paper / Purpur 1.21 a 1.21.11, desde una sola instalación: el runner determina qué protocolo habla el servidor y se adapta.

El uso completo está en docs/usage.md. Las reglas de contribución están en CONTRIBUTING.md, y los pasos de publicación en docs/publishing.md.


Cómo encaja todo

Tres jars, en tres lugares distintos. Solo el primero es un plugin de Minecraft.

  your MCP client (Claude Code, Cursor, Codex, Gemini CLI, ...)
        |
        |  stdio
        v
  mcp-server.jar ---- HTTP(S) + token ---->  VitaminMCP.jar  <- the plugin, inside your server
        |                                    sees events, logs, exceptions, live state
        |  spawns
        v
  Node runner -------- Minecraft protocol ->  the same server, on :25565
                                             sees what a player's client was actually sent

Se ejecuta

Rol

VitaminMCP.jar

en el servidor, como plugin

Escucha cada evento, accede al registro y sirve un endpoint MCP autenticado. La única pieza con visibilidad de los internals del servidor

mcp-server.jar

en tu máquina, como hijo de tu cliente MCP

Habla stdio con el cliente y HTTP con el plugin, y gestiona los bots

runner.mjs o un asset de plataforma bot-runner-*

en tu máquina, como hijo de mcp-server

Conecta clientes reales mediante el protocolo real: login, paquetes, GUIs y todo

El plugin ve los eventos, registros, permisos y estado del lado del servidor; el runner de Node ve lo que recibe un cliente real. El modo de solo lectura es el predeterminado, y los bots son opcionales.

Related MCP server: Minecraft RCON MCP Server

Ejemplo

Pídele al agente que pruebe un plugin, o pasa un escenario a bot_run_scenario:

[
  {"action":"spawn", "bot":"Tester1"},
  {"action":"command", "bot":"Tester1", "command":"shop"},
  {"action":"wait_for", "condition":"inventory_open", "name":"Tester1", "title":"Shop"},
  {"action":"assert_inventory", "bot":"Tester1", "slots":[
    {"slot":11, "material":"DIAMOND_SWORD", "name":"Diamond Sword"}
  ]}
]

Herramientas

Dos grupos. Las herramientas de sesión viven en mcp-server y están siempre presentes. Las herramientas de agente se transmiten por proxy desde el plugin, así que cuáles existen lo decide el servidor al que te conectaste: session_start devuelve sus definiciones reales en agentTools.

Conexión

session_start

Conéctate a un servidor y a su agente. Todas las demás herramientas lo necesitan. Puede haber varias sesiones abiertas a la vez: una por backend de una red con proxy

session_reset

Desconecta todos los bots, manteniendo la conexión. Úsalo entre pruebas independientes. El estado del mundo no se revierte. close: true termina la sesión en su lugar

Jugadores

bot_spawn

Conecta un bot y espera hasta que esté de pie en el mundo. El UUID se deriva del nombre

bot_inspect

Lo que realmente se le envió al cliente del bot: contenido del menú, mensajes (chat, barra de acción, título, subtítulo) con el milisegundo en que llegó cada uno y un cursor para leer solo lo que vino después de una acción, barras de jefe, marcador lateral, salud, comida, experiencia y efectos activos

bot_view

Abre una vista en vivo del mundo o del inventario de un bot, solo accesible desde localhost. La vista de inventario no necesita nada extra; la vista del mundo descarga un recurso opcional la primera vez que se solicita, publicado para Windows x64

bot_run_scenario

Ejecuta un escenario completo. Se detiene en el primer fallo con evidencia adjunta

Servidor

server_info

Versión, TPS, jugadores en línea, plugins instalados, estadísticas de captura

command_exec

Ejecuta un comando como consola o como jugador, incluidos los comandos de vanilla. Cambia el servidor: ausente por completo a menos que read-only: false. Cuando nada acepta el comando, dice por qué, en lugar de solo decir que no lo hizo

Mundo y estado

state_query kind="player"

Posición, gamemode, op, IP y cualquier nodo de permiso que nombres

state_query kind="block"

El bloque en una coordenada

state_query kind="inventory"

El menú que tiene abierto un jugador: el único lugar donde existen los contenidos de una GUI de plugin

Eventos y registros

events_summary

Conteos por tipo de evento. Llama a esto antes de events_query: se mantiene pequeño por muy ocupado que esté el servidor

events_query

Eventos individuales, filtrados por tipo y jugador, paginados por cursor

logs_query

Registros por severidad mínima y expresión regular

exceptions_recent

Excepciones distintas con conteos de ocurrencia y horas de primera aparición. Pasa hash para obtener un stack trace

Espera

wait_for bloquea hasta que se cumple una condición, comprobada cada tick dentro del servidor.

Condition

inventory_open

se abrió un menú, opcionalmente coincidiendo con un título

inventory_contains

un objeto llegó a una ranura, para GUIs que se rellenan después de abrirse

event

se disparó un evento, opcionalmente para un jugador

player_online / player_offline

un jugador entró o salió

player_state

online / gameMode / op alcanzó un valor

player_near

un jugador se acercó dentro de un radio

block_is / block_is_not

un bloque se convirtió en, o dejó de ser, un material

log_matches

una línea de registro coincidió con una regex, para trabajo asíncrono que no cambia nada observable

ticks

el servidor avanzó N ticks

No hay sleep, ni lo habrá. Una espera fija es una suposición sobre el tiempo que es correcta en un servidor inactivo y errónea en uno ocupado: ese es el mecanismo exacto con el que se crean las pruebas flaky. Al agotarse el tiempo, wait_for devuelve los eventos y registros de ese momento.

Acciones — pasos de escenario

Disponibles dentro de bot_run_scenario.

spawn / despawn

conectar o desconectar un bot

move_to

caminar a coordenadas por defecto; usa mode: "teleport" para colocación rápida. El timeoutMillis opcional distingue una ruta sellada de una caminata que no llegó a tiempo

break_block / use_block

romper, o hacer clic derecho en un bloque — use_block es como se abre un cofre

use_entity

hacer clic derecho en un NPC, aldeano o soporte de armadura, identificado por las coordenadas en las que se encuentra

attack_entity

hacer clic izquierdo en el NPC, mob o soporte de armadura más cercano en unas coordenadas

hold_item / drop_item

seleccionar una ranura de la barra de acceso rápido, o soltar el objeto sostenido/un objeto sostenido

place_block

colocar el objeto sostenido contra una cara de bloque

jump / sneak / sprint

realizar un salto, o activar/desactivar el estado de movimiento

look_at

mirar directamente a unas coordenadas del mundo

assert_reachable

preguntar si existe una ruta cargada sin moverse; establece reachable: false para comprobaciones de regiones selladas

click_slot

hacer clic en una ranura: left, right, shift_left, shift_right

close_menu

cerrar el menú abierto

chat / command

decir algo, o ejecutar un comando como el bot

console

ejecutar un comando como la consola

wait_for

cualquier condición anterior

Aserciones — pasos de escenario

La verificación es el objetivo, así que aquí es donde la superficie es más amplia.

Comprobaciones

assert_inventory

por ranura: material, name, amount, lore, customModelData, modelDataString, empty — además del title y size del menú

assert_player

online, gameMode, op. Espera en lugar de leer, porque /op se resuelve de forma asíncrona

assert_block

el material en unas coordenadas

assert_event

un evento disparado, opcionalmente para un jugador, desde que comenzó el escenario

assert_message

el servidor le dijo a este bot algo que contiene una cadena

Usa bot_inspect para mensajes, estado de pantalla y efectos; usa state_query para el estado del servidor. Pasa los parámetros proxyados planos en el nivel superior. Los parámetros completos están en docs/usage.md.


Requisitos

Estos son los requisitos para usar una versión precompilada:

Servidor de Minecraft

Paper 1.21 o posterior (Purpur y otras bifurcaciones de Paper funcionan)

Java

21, para el servidor Paper y el servidor MCP local

Node

18.17 o posterior, para npx

Soporte de versiones

Versión de Minecraft

Windows

Linux

macOS

Estado

1.18 – 1.20.6

🟡

🟡

🟡

Planificado; por debajo del mínimo actual del agente (1.21)

1.21 – 1.21.11

🟢

🟢

🟢

Compatible y probado en vivo

26.1, 26.2 y posteriores

🟡

🟡

🟡

Publicado; cada una necesita una prueba de compatibilidad antes de añadirse

Compatibilidad del runner por sistema operativo

Sistema operativo

Runner de código fuente Node

Recurso de runner nativo

Significado

Windows x64

🟢

🟢

Publicado, y la plataforma en la que se ejecuta la matriz

Linux x64 / arm64

🟢

🟢

Publicado desde 3.0.0

macOS Intel / Apple Silicon

🟢

🟢

Publicado desde 3.0.0, con firma ad-hoc

Leyenda: 🟢 compatible · 🟡 planificado o requiere el runtime indicado · 🔴 no compatible.

1.21 a 1.21.11 son compatibles hoy, y cada una de ellas se ejecuta en la matriz (versions.yaml). 1.21.11 es donde termina esa línea — Minecraft pasó a versiones de calendario después de ella, así que lo que sigue a 1.21.11 es 26.1 y 26.2 en lugar de una 1.21.12. Esas están publicadas y aún no están en la matriz: añadir una es una prueba de compatibilidad contra un servidor real más una comprobación de que los datos incluidos del runner siguen cubriéndola, nunca una edición de versions.yaml por sí sola.

De dónde viene la afirmación de cada plataforma. La matriz se ejecuta en Windows, contra builds de Paper que descarga ella misma — así que lo que demuestra es lo mismo en cualquier host, porque el servidor con el que habla es el mismo servidor. Cada versión compila su runner nativo en el sistema operativo para el que es ese runner, nunca compilado de forma cruzada, y cada uno de ellos se inicia en CI y debe rechazar su propio punto de entrada con el código de salida esperado antes de subirse. La vista del mundo es la única pieza que sigue siendo solo de Windows, y así se indica donde se ofrece.

Instalas un único runner de Node sea cual sea la versión. Le pregunta al servidor qué protocolo habla y selecciona la entrada de minecraft-data correspondiente, así que no hay ningún runner específico de protocolo que elegir.

Compilar desde el código fuente

La mayoría de los usuarios no necesitan esta sección. Los colaboradores necesitan JDK 21 y Node/npm:

./gradlew build
cd bot/bot-runner-node && npm ci && npm test

Los runners nativos se compilan con npm run build:sea -- win32-x64, linux-x64, linux-arm64, darwin-x64 o darwin-arm64. Los recursos de macOS reciben una firma ad-hoc en el flujo de trabajo de publicación.

Fuera del rango compatible, las cosas fallan de forma clara en lugar de comportarse mal: un servidor más antiguo rechaza cargar el agente, y un servidor cuyo protocolo no tiene entrada en minecraft-data se menciona al iniciar.

El soporte del agente y el soporte de los bots también pueden diferir. El agente necesita una API de Paper compatible; los bots necesitan una entrada de minecraft-data coincidente y un entorno de runner compatible. Así que un servidor puede ser legible por el agente antes de que los bots puedan unirse a él — la inspección, los registros y los eventos siguen funcionando sin ellos.


Instalación

Dos mitades, y ninguna es útil por sí sola: un servidor MCP en tu máquina, que tu cliente lanza, y el plugin del agente en el servidor de Minecraft, que es donde ocurre todo lo que merece la pena preguntar.

1. Conecta tu cliente MCP

El servidor MCP es stdio simple: cualquier cliente que pueda lanzar npx -y vitaminmcp funciona — Claude Code, Cursor, Codex, Gemini CLI, Windsurf, Claude Desktop, VS Code. Esta es la única configuración que cada cliente expresa en su propio archivo:

{
  "mcpServers": {
    "vitaminmcp": {
      "command": "npx",
      "args": ["-y", "vitaminmcp"]
    }
  }
}

Claude Code tiene un atajo: el plugin trae el servidor MCP y el conocimiento práctico de cómo manejarlo, como una skill que se carga sola cuando una pregunta lo requiere. Escribe estos en el prompt de Claude Code (son comandos de Claude Code, no comandos de shell):

/plugin marketplace add Backas03/VitaminMCP
/plugin install vitaminmcp@vitaminmcp

En cualquier otro lugar, registra el servidor donde ese cliente guarda su configuración de MCP:

Cliente

Dónde

Claude Code (sin el plugin)

claude mcp add vitaminmcp -- npx -y vitaminmcp en una shell, o el JSON anterior en el .mcp.json del proyecto

Cursor

el JSON anterior en .cursor/mcp.json (proyecto) o ~/.cursor/mcp.json (global)

Codex CLI

codex mcp add vitaminmcp -- npx -y vitaminmcp, o en ~/.codex/config.toml: [mcp_servers.vitaminmcp] con command = "npx", args = ["-y", "vitaminmcp"]

Gemini CLI

gemini mcp add vitaminmcp npx -y vitaminmcp, o el JSON anterior en ~/.gemini/settings.json

Windsurf

el JSON anterior en ~/.codeium/windsurf/mcp_config.json

Claude Desktop

el JSON anterior en claude_desktop_config.json

VS Code

.vscode/mcp.json, bajo una clave "servers" en lugar de "mcpServers"

cualquier otro

donde sea que ese cliente acepte un servidor MCP stdio; el comando es siempre npx -y vitaminmcp

Cada herramienta funciona igual en todos los clientes. Lo único que recibe Claude Code es la skill del plugin — el manual de pruebas escrito. Los demás clientes siguen recibiendo el conocimiento operativo que importa en el momento de la llamada: session_start devuelve las definiciones completas de las herramientas del agente, y las descripciones de las herramientas incluyen sus propias advertencias.

Eso es todo el lado del cliente. No hay nada que descargar a mano ni ninguna ruta que acertar: el paquete vitaminmcp descarga los jars que necesita en la primera ejecución, en ~/.vitaminmcp/jars/<version>/, cada uno verificado contra un SHA-256 fijado en el paquete cuando se publicó.

mcp-server.jar pesa dos megabytes y se espera por él. Con Node instalado, se usa directamente el runner de código fuente y no se descarga ningún asset de runner. Sin Node, el lanzador selecciona el asset de runner nativo para la plataforma actual, y todas las plataformas compatibles tienen uno.

mcp-server habla por stdio. No tiene puerto ni token: es un proceso hijo del cliente, por lo que la relación de confianza ya existe. Solo el lado del agente cruza la red, y por eso solo el lado del agente se autentica.

Necesita Node 18.17+ para npx, y Java 21 para ejecutar los jars. ¿No tienes npm o no tienes con qué descargar? Instala desde los jars.

2. Instala el plugin en el servidor

Pídelo y el agente lo hace. El servidor MCP publica un prompt setup que guía al agente por este paso: comprueba que el servidor es Paper 1.21+, coloca el jar en plugins/, reinicia y se conecta. Los clientes muestran los prompts MCP con sus propios nombres, construidos a partir del nombre bajo el que se registró el servidor. En Claude Code:

/mcp__plugin_vitaminmcp_vitaminmcp__setup    # installed as the plugin
/mcp__vitaminmcp__setup                      # added with claude mcp add vitaminmcp

/mcp muestra cómo se llama realmente el tuyo. En un cliente que liste los prompts en otro sitio (o no los liste en absoluto), basta con pedirlo en palabras sencillas:

Prompt: Configura VitaminMCP en mi servidor de Minecraft en ~/servers/test y conéctate a él.

En su lugar, a mano:

Descarga VitaminMCP.jar desde Lanzamientos a la carpeta plugins/ del servidor — un plugin normal de Bukkit/Paper, sin flags de servidor y sin agente java que adjuntar — e inicia el servidor.

[VitaminMCP] No auth token was configured, so one was generated and written to config.yml: kQ8s...
[VitaminMCP] MCP endpoint listening on http://127.0.0.1:25585/mcp

No necesitas copiar ese token. Un cliente en la misma máquina lo lee del handshake del propio agente. Cópialo solo para un cliente en otro lugar.

Esa es la instalación mínima. El resto de ajustes están documentados en config.yml, junto con el motivo de cada valor por defecto. Tres valores por defecto que conviene conocer antes de cambiar nada:

  • read-only: true es el valor por defecto. Las herramientas que cambian el estado, como command_exec, no se exponen en absoluto: una instalación por defecto no puede alterar el servidor ni siquiera con un token válido. Desactívalo solo cuando lo necesites.

  • El endpoint nunca se abre sin autenticación. Un auth-token vacío se rellena con uno generado en lugar de dejarse pasar, y si no se puede escribir, el plugin igualmente se niega a arrancar. Lo que nunca fue negociable es que exista un token; hacer que lo saques de un registro de fallos no era parte de ello.

  • Sacar bind-address de loopback hace que TLS sea obligatorio. El token concede acceso a la consola y, a través de HTTP sin cifrar, cruza la red en claro, donde cualquier cosa en el camino puede leerlo. Así que esa combinación es una negativa a arrancar, no un aviso. Resuélvelo con tls.enabled (el agente sirve HTTPS por sí mismo) o con tls.terminated-upstream (un proxy delante lo termina). El agente no generará un certificado autofirmado por ti: es cómodo, pero enseñaría a todos los clientes a saltarse la verificación.

3. Configuración del servidor, si quieres bots

Sáltate esta sección si solo necesitas el agente.

Los bots usan el modo offline y reutilizan el mismo UUID determinista cuando se reutiliza el nombre del bot:

# server.properties
online-mode=false

Nunca expongas un servidor en modo offline a internet. Esta es una configuración de entorno de pruebas, no de producción. No se requiere ningún ajuste de BungeeCord para los inicios de sesión normales de Node.

Reutilizar un nombre de bot reutiliza su UUID offline determinista. Activa el reenvío de BungeeCord explícitamente solo para una prueba que pase clientIp y necesite una dirección o UUID falsificados.

move_to camina hasta su destino por defecto, usando el mismo bucle de física del lado del cliente que envía los paquetes de movimiento entre los dos puntos. Eso significa que los plugins que escuchan placas de presión y eventos de movimiento observan la ruta. Una ruta que no se puede encontrar falla con No path exists; una ruta que no llega antes de timeoutMillis falla con did not arrive ... within ....

Para pasos de configuración que solo necesitan un bot en una coordenada, usa "mode":"teleport". Esto conserva el comportamiento heredado de paquete de una sola posición y sigue siendo rápido, pero no dispara los eventos que un jugador caminando habría causado.

Caminar no excava ni coloca bloques. El pathfinder está configurado intencionadamente para el desplazamiento normal, de modo que un muro de prueba sigue siendo un muro de prueba.

4. Conecta

Solo pídelo. Estos son prompts: copia uno y rellena con tus propios valores.

Un servidor en esta máquina

Prompt: Conéctate al servidor de Minecraft de esta máquina y dime la versión del servidor y qué plugins están cargados.

Detrás de un túnel SSH — indica qué puertos locales reenvía el túnel

Prompt: El servidor de prueba está tunelizado a esta máquina — Minecraft en localhost:10000, el agente en localhost:25685. El token es kQ8s…. Conéctate y confirma que está activo.

O mantén el token fuera de la conversación e indica un archivo en su lugar: el agente lo lee y lo pasa a session_start:

Prompt: El servidor de prueba está tunelizado a esta máquina — Minecraft en localhost:10000, el agente en localhost:25685. El token está en ~/.secrets/vitaminmcp-token. Conéctate y confirma que está activo.

Para un token que nunca aparezca en un prompt, define VITAMINMCP_TOKEN en el entorno del servidor MCP (un bloque "env" junto a "command" en la configuración del cliente) — session_start recurre a él siempre que no se proporcione un argumento token.

Remoto, a través de TLS — pega el bloque que el agente imprimió al arrancar

Prompt: Conéctate usando esto: host 203.0.113.10, mcpPort 25585, tls true, token YLwNyFij…, fingerprint sha256:ffb61d8f…f163. Minecraft está en 25565.

O con el token en un archivo en lugar de en la conversación:

Prompt: Conéctate usando esto: host 203.0.113.10, mcpPort 25585, tls true, fingerprint sha256:ffb61d8f…f163, token en ~/.secrets/vitaminmcp-token. Minecraft está en 25565.

Para cualquier cosa que no esté en esta máquina, incluye los números de puerto y el token. Sin ellos, el agente tiene que adivinar los valores por defecto, y una suposición equivocada se manifiesta como un token rechazado en lugar de una dirección incorrecta: el mismo fallo sin importar qué detalle faltara.

Lo que el agente llama: session_start

session_start

Sin argumentos. El agente escribe su host, ambos puertos y su token en ~/.vitaminmcp/agents/<port>.properties mientras se ejecuta, y session_start los lee — así que para un servidor en esta máquina no hay nada que pasar ni nada que buscar. Una conexión correcta devuelve la versión del servidor, el TPS y la lista de plugins, las definiciones reales de las herramientas del agente y la lista actual de sesiones. Las sesiones cuyo proceso runner ha terminado se eliminan de esa lista.

Pasa lo que difiera, y solo eso. Un servidor en otro lugar necesita host y token, porque un token emitido en esta máquina no dice nada sobre un servidor en otra y no se envía allí:

{
  "host": "203.0.113.10",
  "token": "auth-token from config.yml",
  "tls": "true",
  "tlsFingerprint": "sha256:ffb61d8f...f163"
}

Una red con proxy son varios servidores. Abre una sesión por backend: coexisten, y arrancar una nunca molesta a otra, lo cual importa porque cerrar una sesión desconecta sus bots. port es el del proxy en cada sesión; lo que las distingue es mcpPort, el agente dentro de cada backend. Con más de un agente ejecutándose localmente, eso es también lo que permite elegir entre ellos, y omitirlo es un error que los nombra, no una suposición.

session_start {"session": "lobby",    "mcpPort": 25585, "port": 25577}
session_start {"session": "survival", "mcpPort": 25586, "port": 25577}
bot_spawn     {"session": "lobby", "name": "Tester1"}

Todas las demás herramientas aceptan session. Si lo omites, solo se resuelve mientras haya una sesión abierta; con varias, es un error que las nombra, en lugar de una suposición sobre qué servidor querías decir. El tutorial completo está en docs/usage.md.

Instalar desde los jars en su lugar

npx es una comodidad, no un requisito. Dos artefactos, más los assets opcionales de runner por plataforma, se adjuntan a cada lanzamiento, y cada uno va a un sitio distinto:

Archivo

Ubicación

Qué

VitaminMCP.jar

el plugins/ del servidor

el agente — un plugin normal de Bukkit/Paper

mcp-server.jar

en cualquier sitio (recuerda la ruta)

tu cliente MCP lo lanza

runner.mjs o un asset bot-runner-* de la plataforma

junto a mcp-server.jar

mcp-server lo lanza como proceso hijo

Para compilarlos tú mismo en su lugar:

./gradlew dist

En cualquier caso, apunta el cliente al jar en lugar de al paquete: el mismo registro que en el paso 1, pero con otro comando:

{
  "mcpServers": {
    "vitaminmcp": {
      "command": "java",
      "args": ["-jar", "/absolute/path/mcp-server.jar"]
    }
  }
}

O en Claude Code: claude mcp add vitaminmcp -- java -jar /absolute/path/mcp-server.jar.

VITAMINMCP_RUNNER_JAR, o el runnerJar de session_start, designa el script de Node o el runner nativo.

Un solo runner de Node para todas las versiones compatibles. Hace ping al servidor antes de que cualquier bot se conecte y selecciona los datos de mineflayer correspondientes, de modo que el mismo runner de código fuente funciona de 1.21 a 1.21.11.


Un servidor en otra máquina

Dos opciones: reenvía los puertos por SSH o expón el agente con TLS. Si ya tienes SSH a la máquina, el túnel es menos trabajo y no expone nada.

Mediante un túnel SSH

Deja el agente en su valor por defecto de loopback y reenvía ambos puertos:

ssh -L 25585:127.0.0.1:25585 -L 25565:127.0.0.1:25565 user@your-server

Luego conéctate como si todo fuera local — host: "127.0.0.1", sin tls, sin tlsFingerprint. El agente ve una conexión de loopback porque, desde su lado, eso es lo que es. Nada en el servidor se publica en la red, y el token nunca la cruza en claro: SSH es la seguridad de transporte que TLS tendría que proporcionar de otro modo.

Reenvía ambos puertos. mcpPort es como las herramientas llegan al agente, y port es donde se conectan los bots: reenviar solo el primero te da un server_info que funciona y un bot_spawn que no puede conectarse.

Elige puertos locales que estén realmente libres. ssh -L vincula el lado local, y si algo en tu máquina ya ocupa ese puerto, el túnel no lo toma: tus peticiones llegan al otro programa en su lugar. El fallo que eso produce es engañoso: un agente de VitaminMCP distinto que responda en 25585 rechaza tu token, así que se lee como un token incorrecto en lugar de un destino incorrecto. En caso de duda, mapea a un puerto local distinto (-L 25685:127.0.0.1:25585) y pásalo como mcpPort.

Exponer el agente con TLS

Una vez que bind-address sale de loopback, el agente no arranca sin TLS. Configura un certificado e inícialo, y el agente imprime todo lo necesario para conectarse:

[VitaminMCP] MCP endpoint listening on https://203.0.113.10:25585/mcp
[VitaminMCP] Connect with session_start:
  "host": "203.0.113.10", "mcpPort": 25585, "tls": "true",
  "token": "YLwNyFij...",
  "tlsFingerprint": "sha256:ffb61d8f...f163"

Pégalo y listo. Un certificado autofirmado sigue sin requerir instalar nada en el clientetlsFingerprint fija ese único certificado. Sin exportar, sin copiar, sin truststore.

Con un certificado real (Let's Encrypt y similares), elimina tlsFingerprint y la verificación transcurre con normalidad.


Ejecutar contra varias versiones

El mismo escenario puede ejecutarse en todas las versiones compatibles de una sola pasada. La matriz es versions.yaml, no código: añadir una versión es un solo bloque. Los jars del servidor se descargan de la API de PaperMC y se inician de forma nativa (sin Docker, sin ViaProxy; sin capa de traducción adicional).

El protocolo está deliberadamente fuera de ese archivo. El runner de Node pregunta a cada servidor qué protocolo habla y selecciona la entrada de minecraft-data correspondiente, así que una versión no necesita nada más allí que la build que descargar.

Las versiones posteriores a 1.21.11 — que ahora significa 26.1 en adelante, ya que la línea 1.21 terminó ahí — requieren una ejecución de compatibilidad antes de añadirse, y una comprobación de que los datos recortados del runner siguen cubriéndolas. El runner selecciona la versión de datos correspondiente del handshake del servidor, y se niega claramente en lugar de funcionar a medias cuando no tiene entrada.


Licencia

MIT — consulta LICENSE.

Los jars distribuidos incluyen código de terceros, reubicado para que no pueda colisionar con el servidor ni con otros plugins:

Incluido en

Licencia

Jackson

VitaminMCP.jar, mcp-server.jar

Apache-2.0

ClassGraph

VitaminMCP.jar

MIT

mineflayer, minecraft-data, mineflayer-pathfinder

dependencias del ejecutor de Node

MIT

Sus archivos de licencia y avisos viajan dentro de los jars en META-INF/ — reubicar un paquete lo renombra, pero no elimina la obligación de incluir el aviso.

paper-api, log4j-core y las anotaciones de JetBrains son solo de compilación y no se distribuyen. El agente compila contra la API de Paper, que es LGPL-3.0; el jar no la contiene, y el servidor ya la proporciona. Nada de esto toca paper-server (GPL-3.0) — el agente usa únicamente la API de Bukkit/Paper, nunca NMS.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

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/Backas03/VitaminMCP'

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