dosbox-x-mcp
dosbox-x-mcp
Ein MCP-Server, der einen DOSBox-X-Gast steuert, ohne den Desktop zu berühren: kein Fokus-Klau, keine synthetischen Host-Tastendrücke, keine Zeigergeräte-Bewegung. Ein Modell kann ein DOS-Programm von Anfang bis Ende ausführen, während Sie direkt davor weiterarbeiten.
Ursprünglich war er der Screencapture-Workflow eines einzelnen Reverse-Engineering-Projekts und ist inzwischen eine allgemeine Hilfe. Bei einem laufenden DOS-Gast kann er diesen Gast ganz ohne Vorwissen finden, Ihnen sagen, welche Programme geladen sind und wo, jedes Segment lesen und patchen, Werte über die Zeit erfassen, den Bildschirm direkt aus dem Videospeicher lesen, die eigenen Aufzeichnungsfunktionen des Emulators steuern und Code beim Ablauf beobachten – ganz ohne Debugger und ohne auf der Festplatte ein einziges Byte zu ändern.
Was er kann
Gast finden | Einen DOS-Gast allein anhand von BIOS-Invarianten lokalisieren – kein Profil, kein Marker, nichts vorab bekannt. Die DOS-Speicherkette durchlaufen und jedes geladene Programm samt Segment und Herkunftspfad benennen. |
Beliebiges Segment ansprechen | Ein anderes Programm in einer Startkette, ein TSR, ein Overlay, die Interrupt-Vektortabelle, EMS-Seiten. Lesen, patchen, sichern, suchen. |
Es steuern | Tasten in den BIOS-Tastaturring. Klicks in die eigenen Post-INT-33h-Mauswörter des Spiels. Keines von beidem kommt in die Nähe der Eingabewarteschlange des Hosts. |
Es sehen | Den Framebuffer direkt aus dem Videospeicher des Emulators lesen: exakte Indizes, kein Fenster, keine Skalierung, keine Kosten für den Gast – gegen ein Referenzbild bestätigt. Oder bei Bedarf das Fenster abfotografieren. |
Es messen | Auf eine Speicherbedingung warten oder eine Watchlist mit bis zu 200 Hz in einer TSV-Datei erfassen – jede Spalte aus einem einzigen Schnappschuss, sodass sie nicht auseinanderlaufen können. Jeden eindeutigen Frame im Videospeicher beobachten und wann er erschien. |
Es aufzeichnen | Die eigenen OPL-, MIDI- und WAVE-Aufnahme-Funktionen des Emulators, ohne Fokus und ohne den Host-Mapper ausgelöst. |
Es instrumentieren | Klopfen eines |
Related MCP server: re-winedbg
Wie es funktioniert
Nichts davon betrifft die Eingabewarteschlange oder den Bildschirm des Hosts.
Gasterkennung. Jeder DOS-Gast hat die Grenzworte
0x001E/0x003Edes BIOS-Tastaturrings bei0040:0080, einen Kopf und Schwanz innerhalb dieses Bereichs und einen lebendigenINT-21h-Vektor. Wer dieses Dreifach im Speicher des Emulators findet, findet die physische Adresse Null des Gastes, und von dort aus ist jedes Segment ansprechbar. Dafür ist kein Profil nötig, und genau das durchbricht das Ei-Ei-Problem, mit dem ein neues Projekt beginnt.Tastendrücke werden an den BIOS-Tastaturring des Gastes angehängt, genau wie ein echter Tastaturinterrupt es tun würde.
Klicks werden in die Wörter geschrieben, die der eigene INT-33h-Handler des Spiels ausfüllt – in den Zustand, den das Spiel wirklich liest. Sie werden für einen Augenblick kontinuierlich neu geschrieben, weil der Handler des Spiels sie dauernd überschreibt und eine einzelne Schreiboperation sonst verloren geht.
Frames stammen aus dem Videospeicher. DOSBox speichert eine Chain-4-Seite genau wie die Hardware – CPU-Offset
oan linearer Adresse4 * (o & ~3) + (o & 3)–, so dass jede sechzehnte Vierergruppe eine Region wieder in einen Bildschirm verwandelt. Um herauszufinden, welche Bytes der Bildschirm sind, benötigt es ein Referenzbild: Der Speicher eines Emulators ist voller bildähnlicher Daten, die nicht das Bild sind, also wird eine Seite entweder byte genau gegen eine Referenz bestätigt oder als unbestätigt gemeldet. Siehe Den Bildschirm lesen.Traces ändern eine
near-CALL-Stelle so, dass sie auf einen Block mit Null-Bytes zeigt. Der Cave ruft das verschobene Ziel auf, bewahrt dessen Flags, kopiert das Gewünschte in die Slots nach dem Code zurück und kehrt zurück. Der Emulator endet mit dem Lauf und nimmt den Patch mit.
Installation
pip install "dosbox-x-mcp[all] @ git+https://github.com/md0-code/dosbox-x-mcp"Die Zusatzpakete sind alle optional und nach den vonDiesen benannt, was sie bringen:
Extra | Verwendung |
| Pillow, um das Fenster des Emulators abzufotografieren |
| numpy, um das Chain-4-Deinterleave zu beschleunigen (es gibt eine reine-Python-Alternative) |
| python-xlib, um unter Linux Fenster aufzulisten und zu fotografieren |
Registrieren Sie es bei Ihrem MCP-Client. Für Claude Code legen Sie eine .mcp.json im Projektstammverzeichnis an:
{
"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 | Bedeutung |
| Verzeichnis, in dem Profile liegen (Standard: |
| Standard-Profilname; |
| das zu startende Programm |
| Verzeichnis als Basis für relative Ausgabe- oder Verzeichnis-Pfade: |
Ein Pfad, den ein Werkzeug liest oder schreibt, folgt folgt der Regel: absolut wird so verwendet, wie er ist; relative unter DOSBOX_MCP_OUTPUT_DIR. Die Werkzeuge geben den aufgelösten Pfad zurück, damit nie Zweifel bestehenbleibt, wohin eine Datei geschrieben wurde.
Werkzeuge
Werkzeug | Aufgabe |
| Was dieser Host kann und nicht kann. |
| Profile auflisten; benannte Offsets eines Profils aufzeigen. |
| DOSBox-X starten und warten, bis der Gast die Ablauf bereit ist. |
| An einem bereits laufenden Emulator anhand einer pid andocken. |
| Angeschlossene Sitzungen sowie andere DOSBox-X-Fenster. |
| Eine Sitzung beenden. |
| Den Gast finden und jedes geladene Programm auflisten. Kein Profil nötig. |
| Ein Byte-Muster finden; gemeldet als |
| In den BIOS-Tastaturring tippen. |
| Über die eigenen Mauswörter des Spiels klicken. |
| Tasten gedrückt halten, optional bis ein Speicherkondition erfüllt ist. |
| Datensegment oder ein beliebiges Segment lesen. |
| Datensegment oder ein beliebiges Segment schreiben/patchen. |
| Ein komplettes 64-KiB-Segment in eine Datei schreiben. |
| Warten, bis ein Speicherfeld einer Bedingung entspricht. |
| Eine Beobachtungsliste über die Zeit in einer TSV-Datei erfassen. |
| Den aktuellen Frame als Bild zum Ansehen zurückgeben. |
| Einen exakten Frame speichern, aus dem Videospeicher oder dem Fenster. |
| Die Seite aus dem Videospeicher lesen. |
| Jeder eindeutigen Frame in einer Zeitspanne, mit Zeitpunkten. |
| Einen der eigenen Menüeinträge von DOSBox-X auslösen. |
| OPL-, MIDI- oder WAVE-Ausgabe in eine Datei aufzeichnen. |
| Null-gefüllte Bereiche finden, die für einen Trace groß genug sind. |
| Einen laufenden |
| Auslesen, was ein Trace aufgezeichnet hat. |
| Aufrufstelle wiederherstellen und den Code-Cave wieder löschen. |
Wo immer ein Offset akzeptiert wird, funktioniert auch ein Profil-Symbolname – treasury
statt 0x634A.
Mit einem Spiel beginnen, das noch niemand profiliert hat
Ein Profil ist keine Voraussetzung. Das ist die insgesamt erste Sitzung:
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")Dieses Speicherabbild is die Grundlage des Profils: Nehmen Sie 50–100 Bytes daraus, die sich zwischen Läufen nicht ändern, ergänzen Sie zwei oder drei einfache Prüfungen, und jedes DS-relative Werkzeug funktioniert ab dann.exe über einen Namen.
Den Bildschirm lesen
dosbox_read_framebuffer liefert diejenigen Palettenindizes zurück, die der Gast im Moment des Abrufs geschrieben hat. Er ist exakt, kann keinen halb gezeichneten Frame erwischen und kostet den Gast nichts – deshalb ist dieser Weg bei allem, was gemessen wird, der Vorzug Verdienen.
Er braucht ein Referenzbild, und er meldet das, anstatt zu raten. Die Seite zu finden heißt, 64.000 Bytes unter Hunderten von Megabytes zu finden, und Kohärenz allein reicht nicht aus: Gegen eine laufende Spielberechnung lieferte ein blinder Scan eine Seite mit Score 0.999 – das war eine dekomprimierte Sprite-Bank, nicht der Bildschirm. Übergibt man jedoch reference= eine 64.000-Byte-Datei mit dem aktuell auf dem Bildschirm sichtbaren Inhalt, wird die Seite Byte für Byte bestätigt:
dosbox_read_framebuffer(reference="credits_logo.bin", stem="shots/logo")
→ page_offset 16, confirmed true, pages [16, 64016, 128016, 192016]Eine Referenz können Sie erhalten von:
Ein Port in der Entwicklung hat eine Referenz kostenlos – seine eigene Darstellung desselben Bildschirms. Das ist auch der Vergleich, der sich lohnt: Stimmen beide Byte für Byte überein, stimmt auch der Renderer des Ports.
Jeder frühere bestätigte Schnappschuss desselben Bildschirms bestätigt sie erneut.
Ein Fensterfoto, sofern das Profil eine Palette enthält – das geschieht vollautomatisch und braucht kein Argument.
Ist die Stelle einmal bestätigt, wird sie gecacht, so dass spätere Lesevorgänge und jeder Frame von dosbox_watch_frames nichts mehr kosten. allow_unconfirmed=true nimmt die Vermutung des Blindscans für alle, die es selbst prüfen möchten.
Die Seite liegt nicht zerstörend da, wo man ahnt: Sie beginnt dort, wo die CRTC-Startadresse sie hinlegt, also exakt auf einer Vier-Byte-Grenze und keinen anderen Randgleichheit. Die eine live vermessene Seite lag bei Offset 16.
Profile
Ein Profile ist eine einzelne JSON-Datei, die ein Spiel beschreibt: wie sein Datensegment zu erkennen ist, wo der Zustand der Maus abliegt, Bildschirmgröße und -palette, benannte Offsets, Beobachtungssätze und bekannte Caves. profiles/example.json ist eine kommentierte Vorlage; das OpenJP-Repository enthält echte Profile, die für ein veröffentlichtes 1993-Spiel geschrieben wurden.
{
"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"] }
}Der Marker kann als bytes-Hexedezimation direkt vorhanden sein oder aus einem Referenz-Dump ausgeschnitten werden (source_dump + offset + length + länge). Verfügbare Prüfungen: cstring_via_pointer, max, max_range, equals – genug, um ein Fake-Positive verschwindend unwahrscheinlich zu machen, und das ist wichtig, weil die Alternative darin besteht, eine zufällige Belegung zu patchen.
Plattformen
Windows | Linux | macOS | |
Gast-Speicher, Segmente, Suche, Tasten, Klicks | ja | ja | kein Backend |
Framebuffer, Stichproben, Traces | ja | ja | kein Backend |
Fensterliste, Aufnahme, Größenänderung | ja | mit X11 | — |
Menübefehle des Emulators | ja | nein – man kann eine separate Anzeige verwenden | — |
Offscreen-Anzeige | — | mit | — |
dosbox_capabilities meldet all dies für den laufenden Host; fragen Sie also nach, statt zu raten.
Unter Linux steuert kernel.yama.ptrace_scope den Zugriff auf den Speicher eines anderen Prozesses genauso wie die Integritätsebene unter Windows:
Wert | Effekt |
| jeder Prozess mit derselben UID – |
| nur Nachfahren – |
| nur |
| überhaupt kein Anhängen möglich |
Unter der üblichen Standardeinstellung sollte man den Emulator starten, statt anzuhängen. Der Server liest die sysctl-Einstellung und teilt das mit, statt ein nacktes EPERM zu liefern.
Linux hat ohne Compositing-Manager keine Möglichkeit, ein verdecktes Fenster zu fotografieren, und Wayland bietet überhaupt keine clientübergreifende Erfassung. Die Lösung ist nicht, PrintWindow zu emulieren, sondern die Einschränkung zu beseitigen, der PrintWindow dienen soll: dosbox_launch(isolated=true) bringt den Emulator auf einem eigenen Xvfb-Display unter, wo es keinen Desktop zu schützen gibt und die eigenen Tastenkürzel des Emulators verwendbar sind, ohne jemandem einen Tastendruck wegzunehmen.
macOS würde task_for_pid benötigen und daher entweder Root-Zugriff oder ein signiertes Binary mit entsprechenden Entitlements. Es gibt dafür kein Backend.
Einschränkungen
Der Emulator muss erreichbar sein: gleiche Integritätsebene unter Windows, ein passender
ptrace_scopeunter Linux.Es läuft zu einem Zeitpunkt nur ein Emulator pro Profil. Zwei Gastinstanzen, die dasselbe Spiel ausführen, machen den Segment-Scan mehrdeutig; der Server lehnt ab, statt zu raten.
dosbox_capture_screenmitsource="window"ändert die Größe des Emulatorfensters, um einen exakt ganzzahligen Skalierungsfaktor zu erreichen. Das ist die eine sichtbare Auswirkung dieses Servers auf dem Desktop – und der Grund,source="vram"zu bevorzugen, das außerdem schneller ist und keinen halb gezeichneten Frame erfassen kann.Das Fotografieren des Fensters kostet den Gast echte Zeit: Eine Aufnahmeschleife dehnt die für den Gast sichtbaren Phasen um etwa den Faktor 1.6x. Verwenden Sie für etwas Quantitatives den Framebuffer.
Ein Klick kann in manchen Spielen zwei Seiten von „Klicke zum Fortfahren“ weiterblättern; senden Sie beim Blättern durch Texte einen Tastendruck.
Schreibzugriffe in ein laufendes Spiel sind nicht rückgängig zu machen, und das Spiel kann ein Feld direkt neu berechnen, nachdem Sie es gesetzt haben – patchen Sie an einem Punkt, an dem es gelesen wird, bevor es neu berechnet wird.
Trace-Speicher-Schnappschüsse werden anhand dessen gelesen, was
DSbeim Ausführen des Code-Caves enthält. Bei einem Spiel mit nur einem Datensegment ist das genau richtig; bei einer Routine, dieDSändert, erfassen Siedsgleich mit und prüfen Sie es.Nur der Chain-4-Linearmodus 13h wird aus dem Videospeicher ausgelesen. Für alles andere ist
source="window"erforderlich.Ein blinder Framebuffer-Scan ist ein Hinweis, keine Antwort, und wird als unbestätigt gemeldet. Geben Sie einen Referenzframe an.
Entwicklung
pip install -e ".[dev,all]"
pytestDie Suite ist vollständig offline: ein DOS-Gast, eine Speicherkette, ein Chain-4-Framebuffer und ein verfolgbares Code-Segment werden alle in einem bytearray aufgebaut, sodass sie ohne Emulator und ohne Spiel auf jeder solchen Plattform läuft. Was sie nicht abdeckt, sind die beiden Systemaufrufe ganz unten – das Lesen und das Schreiben eines anderen Prozesses – sowie das Fenster.
Lizenz
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