-- MCP computer server: reacts to sandbox gateway requests. -- -- No longer owns a websocket. It registers `exec-lua` / `write-file` handlers on the -- sandbox daemon's event bus (apis/libsandbox.serve), so requests arrive over the one -- gateway connection owned by servers/sandbox.lua and replies are sent back through it. -- It only handles requests while a sandbox is configured, so exec stays gated behind -- the same trusted, authenticated connection as the rest of the gateway. local createSandbox = require('/apis/libsandbox'); local createMcpComputer = require('/apis/libmcpcomputer'); local createVersion = require('/apis/libversion'); local URL_SETTING = 'sandbox.url'; local url = settings.get(URL_SETTING); if type(url) ~= 'string' or url == '' then print('mcp-computer-server: ' .. URL_SETTING .. ' not set, exec/write handlers inactive.'); return; end local el = _G.bootEventLoop; if not el then print('mcp-computer-server: no boot eventloop, handlers inactive.'); return; end local sandbox = createSandbox(); local mcp = createMcpComputer(); -- A code error or a failed file write is a *successful* round-trip that carries an -- ok:false result (so captured output survives the reply); only a thrown handler or -- a dropped connection becomes a transport-level failure. sandbox.serve('exec-lua', function(payload) local result = mcp.executeLua(payload and payload.code); return true, { ok = result.ok, returns = result.returns or {}, output = result.output or '', error = result.error, }; end, { eventloop = el }); sandbox.serve('write-file', function(payload) local result = mcp.writeFile(payload and payload.path, payload and payload.content); return true, { ok = result.ok, path = result.path, bytes = result.bytes, error = result.error, }; end, { eventloop = el }); print('mcp-computer-server v' .. createVersion().forSelf() .. ' started (serving exec-lua/write-file over sandbox).');