jdBasic

AI-Pair Coding
on a live BASIC VM

Most code-exec MCP servers fork and die per call. jdBasic keeps a persistent VM, hands the AI a cited language reference so it stops hallucinating, and can compile your script to a redistributable EXE via LLVM — all from inside one tool call.

90-second demo video — landing on launch day

What makes this different

Four things you don't get from a sandboxed Python REPL or a forking shell-exec MCP.

Persistent VM — state carries

One jdBasic VM lives across every tool call in your session. Variables, FUNCs, IMPORTed modules — all stick around. The AI can iterate like a human at the REPL.

# call 1
jdb_eval "DIM x = SUM(IOTA(100))"
# call 2 (an hour later)
jdb_eval "PRINT x" ' → 5050

jdb_doc — anti-hallucination

The AI can substring-search jdBasic's own language spec (doc/languages.md) before it writes code. "Does jdBasic have REDUCE?" stops being a guess.

jdb_doc query="FOLD"
→ "Use REDUCE (lambda, array). FOLD is
  not a jdBasic keyword."

jdb_run_native — compile & ship

jdBasic ships an LLVM-18 native compiler in the same binary. jdb_run_native lets the AI turn your script into a standalone EXE — no Docker, no pip install, no toolchain on the user's machine.

# 218 KB EXE, runs anywhere
jdb_run_native code="..."
→ stdout + dropped .exe path

STOP / RESUME — live-tweak

Loaded a game loop or long-running agent via jdb_load? jdb_stop pauses the VM, your AI mutates state or rewrites a FUNC, jdb_resume continues — without losing world state.

jdb_stop
jdb_eval "hud_colour = RGB(255,0,128)"
jdb_resume ' game keeps running

Setup in 60 seconds

Works with Claude Code, Claude Desktop, Cursor, Cline, Continue, Zed, Windsurf — every MCP-aware client.

  1. 1

    Grab a binary

    Download the latest release for your platform — or build from source with build.sh MCPSERVER=1 (build.bat MCPSERVER HTTP on Windows).

  2. 2

    Drop this into .mcp.json

    Project root (Claude Code) or your client's MCP config (Claude Desktop, Cursor, Cline, …). Replace the path with the absolute path to your jdBasic binary.

    {
      "mcpServers": {
        "jdbasic": {
          "command": "/absolute/path/to/jdbasic",
          "args": ["--mcp"]
        }
      }
    }

    doc/languages.md ships next to the binary on purpose — jdb_doc resolves it relative to the EXE first, so no cwd setting is needed.

  3. 3

    Restart the client

    Ask the agent to call jdb_eval with code: "PRINT SUM(IOTA(20))". You should see 210. You're paired up.

5-minute walkthrough

Live-tweaking a running space-shooter while it's mid-frame. Same shape works for agents, simulations, training loops.

1

Load the game into the VM

jdb_load reads space_shooter.jdb into the persistent VM and starts it on a worker thread. The MCP server keeps responding to tool calls while the game loop spins.

jdb_load path="jdb/space_shooter.jdb"
2

Pause it

Mid-game, you decide the HUD colour is off. Ask the AI to jdb_stop. The VM enters a deterministic pause point — frame thread parked, world state frozen.

jdb_stop
3

Inspect & tweak

jdb_vars shows what's bound; jdb_eval mutates it. Or rewrite a FUNC on the fly:

jdb_eval code="hud_colour = RGB(255, 0, 128)"
jdb_eval code="FUNC enemy_speed() : RETURN 4 : ENDFUNC"
4

Resume

jdb_resume hands control back to the worker. Sprites keep moving from exactly where they were — only with the new HUD colour and new enemy speed in effect.

jdb_resume
5

Ship a binary (optional)

Happy with where the game ended up? Ask the AI to call jdb_run_native with the same source. You get a standalone Windows or Linux EXE — drop on a USB stick, hand it to anyone, no jdBasic install on the target.

jdb_run_native code="PRINT 'Hello from a fresh EXE'"

Tool reference

Every tool shares one persistent VM. Full schemas are advertised by the server itself — your client will surface them automatically.

Tool Purpose
jdb_evalExecute jdBasic statements. Captured stdout is returned. State persists across calls.
jdb_checkLint without running. Faster than the --lint subprocess; keeps the VM warm.
jdb_loadLoad a .jdb file into the VM so subsequent jdb_eval can call its functions.
jdb_varsList currently-bound variables with their tags / shapes.
jdb_funcsList user-defined FUNC / SUB / ASYNC FUNC with signatures.
jdb_docSubstring lookup against doc/languages.md. The authoritative answer for "does jdBasic have X" — kills hallucination.
jdb_stopPause a script loaded via jdb_load at a deterministic safe point. World state preserved.
jdb_resumeResume a paused script. Picks up exactly where it stopped, with any mutations you made in between in effect.
jdb_recompileRe-parse + re-compile the loaded source after edits. FUNC bodies get swapped; module state survives.
jdb_statusWhere is the VM right now — running / stopped / idle? Useful gate before jdb_resume / jdb_stop.
jdb_run_nativeCompile a snippet via the LLVM-18 backend, run the produced binary, capture stdout. Requires the Full build (NATIVEC=1).

Full client-config (Claude Desktop / Cursor / Cline / Continue / Zed / Windsurf) and a deeper protocol breakdown live in doc/MCP.md.

⚠ Security

Every tool here can execute arbitrary jdBasic code, which means arbitrary process actions inside the jdBasic VM. Treat the MCP server like a local shell. The stdio transport is safe by default (your client launches the process directly). The HTTP transport (--mcp-http) binds to 127.0.0.1 only — never expose it on a public interface without auth in front.

Ready to pair up?

Grab a release, paste the .mcp.json snippet, and ask your AI to call jdb_eval. That's the whole setup.