dosbox-x-mcp
dosbox-x-mcp
Un servidor MCP que controla un invitado de DOSBox-X sin tocar el escritorio: sin robar el foco, sin pulsaciones sintéticas del sistema anfitrión, sin mover el puntero. Un modelo puede ejecutar un programa de DOS de principio a fin mientras sigues trabajando delante de él.
Comenzó como el flujo de captura de un proyecto de ingeniería inversa y ahora es una ayuda general. Dado un invitado de DOS en ejecución, puede localizar ese invitado sin ningún conocimiento previo, decirte qué programas hay cargados y dónde, leer y parchear cualquier segmento, muestrear valores con el tiempo, leer la pantalla desde la memoria de vídeo, manejar los grabadores del propio emulador y observar el código mientras se ejecuta, sin depurador y sin cambiar un solo byte del disco.
Lo que puede hacer
Encontrar un invitado | Localiza un invitado de DOS solo con las invariantes de la BIOS: sin perfil, sin marcador, sin saber nada de antemano. Recorre la cadena de memoria de DOS y nombra cada programa cargado, su segmento y la ruta de la que vino. |
Abordar cualquier segmento | Otro programa en una cadena de lanzadores, una TSR, un overlay, la tabla de vectores de interrupción, las páginas EMS. Leer, parchear, volcar, buscar. |
Conduirlo | Teclas en el anillo del teclado de la BIOS. Clics en las palabras propias del juego posteriores a INT 33h. Ninguno se acerca a la cola de entrada del anfitrión. |
Verlo | Lee el framebuffer directamente de la memoria de vídeo del emulador: índices exactos, sin ventana, sin reescalado, sin coste para el invitado, y confirmado byte a byte contra una referencia. O fotografía la ventana cuando sea necesario. |
Medirlo | Bloquea hasta que se cumpla una condición de memoria, o muestrea una lista de observación a hasta 200 Hz en un archivo TSV: todas las columnas salen de una misma instantánea, así no pueden descuadrarse. Observa la memoria de vídeo para detectar cada fotograma distinto y cuándo apareció. |
Grabarlo | La captura OPL, MIDI y WAVE del propio emulador, lanzada sin tomar el foco y sin el mapeador del anfitrión. |
Instrumentarlo | Redirige un |
Related MCP server: re-winedbg
Cómo funciona
Nada de lo que hay aquí utiliza la cola de entrada ni la pantalla del anfitrión.
Descubrimiento del invitado. Todo invitado de DOS tiene las palabras de correo del anillo del teclado de la BIOS
0x001E/0x003Een0040:0080, una cabeza y una cola dentro de ese rango, y un vectorINT 21hvivo. Encontrar ese trío en la memoria del emulador da con el cero físico del invitado, y a partir de ahí se puede direccionar cualquier segmento. Esto no necesita perfil, que es lo que rompe el huevo y la gallina con el que arranca un proyecto nuevo.Las teclas se añaden al anillo del teclado de la BIOS del invitado exactamente igual que lo haría una interrupción real de teclado.
Los clics se escriben en las palabras que rellena el propio gestor de INT 33h del juego, es decir, el estado que el juego lee de verdad. Se vuelven a escribir continuamente durante un instante, porque el gestor del juego no deja de sobrescribirlos y una sola escritura perder más que la carrera.
Los fotogramas vienen de la memoria de vídeo. DOSBox guarda una página encielada 4 igual que el hardware: el desplazamiento
ode la CPU, en la dirección lineal4 * (o & ~3) + (o & 3), de modo que tomar cada grupo de dieciséis de cuatro devuelve una región a la pantalla. Averiguar qué bytes son la pantalla diff unde un fotograma de referencia: la memoria de un emulador está llena de datos con aspecto de imagen que no son la imagen, así que una página se confirma byte a byte contra una referencia o se notifica como no confirmada. Ver Lectura de la pantalla.Las trazas parchean un
CALLcercano para que apunte a un bloque de ceros. La cueva llama al objetivo desplazado, preserva sus banderas, copia lo que hayas pedido en los huecos posteriores a su propio código y regresa. El emulador muere con la reese y se lleva el parche con él.
Instalar
pip install "dosbox-x-mcp[all] @ git+https://github.com/md0-code/dosbox-x-mcp"Los extras son todos opcionales, y llevan el nombre de lo que aportan:
Extra | Para |
| Pillow, para fotografiar la ventana del emulador |
| numpy, para un desenredo chain-4 más rápido (hay una alternativa en Python puro) |
| python-xlib, para listar y fotografiar ventanas en Linux |
Regístralo con tu cliente MCP. Para Claude Code, un .mcp.json en la raíz del proyecto:
{
"mcpServers": {
"dosbox": {
"command": "python",
"args": ["-m", "dosbox_mcp.server"],
"env": {
"DOSBOX_MCP_PROFILE_DIR": "dosbox-x/profiles",
"DOSBOX_MCP_EXECUTABLE": "dosbox-x/dosbox-x.exe"
}
}
}
}Variable | Significado |
| dónde viven los perfiles (por defecto: |
| nombre de perfil por defecto; |
| el binario |
| el lugar desde donde se interpreta una ruta relativa de puente de salida o referencia |
Toda ruta que una herramienta lea o escriba sigue una única regla: la absoluta se usa tal cual y la relativa se ubica bajo DOSBOX_MCP_OUTPUT_DIR. Las herramientas devuelven la ruta resuelta, así que nunca hay duda de dónde ha ido a parar un archivo.
Herramientas
Herramienta | Qué hace |
| lo que este anfitrión puede y no puede hacer |
| listar perfiles; mostrar los desplazamientos con nombre de un perfil |
| iniciar DOSBox-X y esperar hasta que el invitado se pueda manejar |
| conectarse a un emulador ya ejecutándose por su |
| sesiones adjuntas en otras ventanas de DOSBox-X |
| terminar una sesión |
| encontrar el invitado y listar todo programa cargado — no requiere perfil |
| buscar una secuencia byte a byte, notificado como |
| teclear en el anillo de teclado de la BIOS |
| hacer clic en las palabras de ratón propias del juego |
| mantener, dejar presionado un conjunto de botones, opcionalmente hasta que una prueba de memoria pase |
| leer el segmento de datos, o cualquier segmento |
| parchear el segmento de datos, o cualquier segmento |
| escribir un segmento completo de 64 KiB en un archivo |
| bloquear hasta que un campo de memoria satisfaga una condición |
| muestrear una lista de observación a lo largo del tiempo en un TSV |
| devolver el frame actual como una imagen para mirar |
| guardar una captura exacta, desde la memoria de vídeo o la ventana |
| leer la página de la memoria de vídeo |
| cada frame distinto en un intervalo de tiempo, con sus tiempos |
| disparar uno de los elementos de menu de DOSBox-X |
| grabar la salida OPL, MIDI o WAVE en un archivo |
| encontrar bloques de tamaño suficiente para una traza |
| redirigir un |
| leer lo que ha grabado una traza |
| restaurar el punto de llamada y dejar la cueva vacía |
En cualquier sitio donde se acepte un desplazamiento, funciona también un nombre simbólico de perfil, por ejemplo treasury en lugar de 0x634A.
Empezar con un juego que nadie ha perfilado
Un perfil no es un prerrequisito. Esta es entera la primera sesión:
dosbox_launch(config="game.conf", profile="none") → pid
dosbox_find_guest()
→ 640 KiB, INT 21h live, and:
JP2D load segment 2456 1.1 MB C:\JP\JP2D.EXE
JP load segment 08A1 64 KB C:\JP\JP.EXE
COMMAND load segment 0801 16 KB C:\COMMAND.COM
dosbox_search_memory(text="sprites.dbt") → 2456:027A
dosbox_dump_segment(path="jp2d.bin", segment="0x2456")Ese volcado es la simiente del perfil: elige de 50 a 100 bytes que no cambien entre ejecuciones, añade dos o tres comprobaciones baratas y todas las herramientas de dos funcionarán por nombre.
Leyendo la pantalla
dosbox_read_framebuffer devuelve los índices de paleta que escribió el invitado en el instante de la lectura. Es exacto, no puede cazar un frame a mitad de dibujo y no cuesta nada al invitado, por eso es la vía preferida para cualquier medición.
Necesita un fotograma de referencia, y lo dice en vez de adivinar. Localizar la página es encontrar 64.000 bytes entre cientos de megabytes, y la simple coherencia no basta: probado contra un juego real, un escaneo a ciegas devolvió una página con una puntuación de 0.999 que era un banco de sprites decodificado, no la pantalla. Así que pasa reference= con un archivo de 64.000 bytes que contenga lo que hay en pantalla ahora mismo, y la página se confirma byte a byte:
dosbox_read_framebuffer(reference="credits_logo.bin", stem="shots/logo")
→ page_offset 16, confirmed true, pages [16, 64016, 128016, 192016]De dónde sale una referencia:
Un proyecto de port tiene una referencia gratis: su propio render de la misma pantalla. Esa es también la comparación que vale la pena: si las dos coinciden byte a byte, el renderizador es correcto.
Cualquier captura confirmada anterior de la misma pantalla la vuelve a confirmar.
Una fotografía de la ventana, cuando el perfil tiene una paleta — es automática y no requiere argumento.
Una vez confirmada, la ubicación queda en caché: así que toda lectura posterior y cada los frames de dosbox_watch_frames son gratuitos. allow_unconfirmed=true toma la estimación del escaneo ciego para quien quiera comprobarlo por su cuenta.
La página no está necesariamente donde te imaginas: comienza en la posición que le indica el CRTC, que es un límite de cuatro bytes y nada más fino. La que se midió en vivo estaba en el desplazamiento 16.
Perfiles
Un perfil es un único archivo JSON que describe un juego: cómo reconocer su segmento de datos, dónde guarda el estado del ratón, su colorido de pantalla y su paleta, desplazamientos con nombre, conjuntos de observación y cuevas conocidas.
profiles/example.json es una plantilla anota; el repositorio OpenJP tiene perfiles reales escritos para un juego de 1993 que se distribuyó.
{
"name": "example",
"ds_segment": "0x1234",
"marker": { "bytes": "6578616d706c652e64617400", "offset": "0x0100" },
"checks": [ { "kind": "cstring_via_pointer", "pointer": "0x0200", "value": "game" } ],
"mouse": { "buttons": "0x00B2", "position": "0x00B6" },
"screen": { "width": 320, "height": 200 },
"symbols": { "lives": { "offset": "0x1234", "size": 1, "description": "Lives left." } },
"watch_sets": { "player": ["lives", "score", "level"] }
}El marcador se puede poner por línea según bytes escrito en hexadecimal, o se saca cortándose de un volcado de referencia (source_dump + offset + length). Comprobaciones disponibles: cstring_via_pointer, max, max_range y equals — suficiente para que un falso positivo sea altamente improbable, y eso importa porque la alternativa es parchear una asignación aleatoria.
Plataformas
Windows | Linux | macOS | |
Memoria del invitado, segmentos, búsqueda, teclas, clics | sí | sí | sin backend |
Framebuffer, muestreo, trazas | sí | sí | sin backend |
Listado de ventanas, captura, cambio de tamaño | sí | con X11 | — |
Comandos de menú del emulador | sí | no — usa un display aislado | — |
Pantalla fuera de pantalla | — | con | — |
dosbox_capabilities informa de todo esto para el host en ejecución, así que pregunte en lugar de adivinar.
En Linux, kernel.yama.ptrace_scope controla el acceso a la memoria de otro proceso exactamente igual que el nivel de integridad en Windows:
Valor | Efecto |
| cualquier proceso con el mismo uid — |
| solo descendientes — |
| solo |
| no se puede adjuntar en absoluto |
Con el predeterminado habitual, ejecute con dosbox_launch en lugar de adjuntarse. El servidor lee el sysctl y lo indica en lugar de mostrar un EPERM crudo.
Linux no tiene forma de fotografiar una ventana ocluida sin un gestor de composición, y Wayland no tiene captura entre clientes. La respuesta no es emular PrintWindow, sino eliminar la restricción que PrintWindow existe para satisfacer: dosbox_launch(isolated=true) coloca el emulador en su propio display Xvfb, donde no hay escritorio que proteger y los atajos de teclado del propio emulador se pueden usar sin quitar una pulsación a nadie.
macOS necesitaría task_for_pid y, por tanto, ejecutarse como root o un binario firmado y con entitlements. No existe un backend para eso.
Advertencias
El emulador debe ser alcanzable: el mismo nivel de integridad en Windows, un
ptrace_scopeaceptable en Linux.Un emulador por perfil a la vez. Dos invitados ejecutando el mismo juego hacen que el escaneo de segmentos sea ambiguo, y el servidor se niega en lugar de adivinar.
dosbox_capture_screenconsource="window"redimensiona la ventana del emulador para obtener una escala entera exacta. Ese es el único efecto visible que este servidor tiene en el escritorio, y la razón para preferirsource="vram", que además es más rápida y no puede capturar un frame a medio dibujar.Fotografiar la ventana le cuesta tiempo real al invitado: un bucle de grabación estira las fases visibles para el invitado en aproximadamente 1,6 veces. Use el framebuffer para cualquier cosa cuantitativa.
Un clic puede avanzar dos páginas de «click to continue» en algunos juegos; envíe una tecla al paginar por listas.
Las escrituras en un juego en ejecución no se pueden deshacer, y el juego puede recalcular un campo justo después de que usted lo establezca; aplique el parche en un momento en que el campo se lea antes de que se recalcule.
Las capturas de memoria trazadas se leen a través de lo que
DScontenga cuando se ejecuta el cave. Para un juego con un solo segmento de datos, eso es exacto; para una rutina que conmuteDS, capturedsjunto a la captura y compruébelo.Solo se lee de memoria de vídeo la que corresponda al modo lineal 13h chain-4. Todo lo demás necesita
source="window".Un escaneo ciego del framebuffer es una pista, no una respuesta, y se informa como no confirmado. Proporcione un frame de referencia.
Desarrollo
pip install -e ".[dev,all]"
pytestLa suite completa es enteramente offline: un invitado DOS, una cadena de memoria, un framebuffer chain-4 y un segmento de código trazable se construyen en un bytearray, de modo que se ejecuta en cualquier plataforma sin un emulador y sin juego. Lo que no cubre son las dos llamadas al sistema en el nivel más bajo —escribir otro proceso— y la ventana.
Licencia
MIT.
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
- FlicenseAqualityDmaintenanceEnables programmatic control of the mGBA emulator for Game Boy, Game Boy Color, and Game Boy Advance games, including screenshot capture, memory reading, sprite data dumping, and custom Lua script execution for automated testing and game analysis.63
- AlicenseNot gradedqualityCmaintenanceEnables headless debugging of Windows executables from Linux/macOS hosts by orchestrating winedbg's gdbserver and a GDB client, exposing 19 tools for launch, attach, breakpoints, stepping, register/memory access, and session lifecycle.MIT
- AlicenseNot gradedqualityCmaintenanceBridges AI agents to a DOSBox emulator, enabling control of DOS programs via MCP tools for typing, screen reading, video capture, Lua scripting, and memory access.1GPL 2.0
- FlicenseAqualityBmaintenanceEnables an MCP client to observe and control a text-mode DOS system via a Python bridge, supporting keyboard input and screen capture.8
Related MCP Connectors
Eyes and hands on real Windows PCs — observe, click, type via Glasswarp API.
Live browser debugging for AI assistants — DOM, console, network via MCP.
Operate Linux, macOS and Windows from your LLM. Every action runs through an auditable allowlist.
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/md0-code/dosbox-x-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server