6.6 KiB
MCP Computer Lua Plan
Goal
Add a TrapOS sandbox program that links a ComputerCraft computer to the host-side MCP bridge over WebSocket.
The first supported command is ping, used by the bridge's MCP tool probe-computers. The Lua program answers:
pong from <computerId> (Label: <computerLabel>)
Decisions
- Lua program path:
programs/mcp-computer.lua. - Package:
trapos-sandbox. - The program connects outbound to the bridge's ComputerCraft link port.
- The bridge link default is
ws://<host>:3001. - The host-side MCP tool is named
probe-computersand broadcasts to every connected computer. - No link auth for the first version.
- Keep the first Lua implementation as a program, not an autostart server, until the bridge loop is proven.
Background
CC:Tweaked cannot listen on real HTTP/TCP ports with standard APIs. It can connect outward using http.websocket. This program is therefore the in-game half of the bridge:
[ CC computer ] --outbound WebSocket--> [ tools/mcp-bridge link port :3001 ]
The Lua program is effectively an agent. It identifies itself to the bridge, waits for JSON request frames, executes supported methods, and sends JSON response frames.
User Interface
Program usage:
mcp-computer <ws-url>
mcp-computer -url <ws-url>
mcp-computer --version
mcp-computer --help
Examples:
mcp-computer ws://192.168.1.20:3001
mcp-computer -url ws://mcp-bridge.local:3001
The program should print clear status lines:
mcp-computer v0.1.1 connecting to ws://192.168.1.20:3001
linked as 12 (Label: base-turtle)
waiting for requests... Press Ctrl+T to stop.
If http or http.websocket is unavailable, print a clear error explaining that CC:Tweaked HTTP/WebSocket must be enabled.
Link Protocol
All frames are JSON strings compatible with textutils.serializeJSON and textutils.unserializeJSON.
Computer Hello
Sent immediately after opening the websocket:
{
"type": "hello",
"computerId": 12,
"computerLabel": "base-turtle"
}
Lua fields:
computerId:os.getComputerID().computerLabel:os.getComputerLabel(), ornilencoded as JSON null/omitted depending ontextutils.serializeJSONbehavior.
Hello OK
Expected from bridge:
{
"type": "hello-ok"
}
The first version may continue even if hello-ok is not received immediately, but implementation should prefer waiting briefly so connection problems are obvious.
Probe Request
Received from bridge:
{
"type": "request",
"id": "req-123",
"method": "ping"
}
Probe Response
Sent back by Lua:
{
"type": "response",
"id": "req-123",
"ok": true,
"result": "pong from 12 (Label: base-turtle)"
}
Unknown method response:
{
"type": "response",
"id": "req-123",
"ok": false,
"error": "unknown method"
}
Implementation Sections
1. Program Skeleton
- Add
programs/mcp-computer.lua. - Support
--help,-help,help,--version,-version, andversion. - Version output uses
require('/apis/libversion')().forSelf(). - Parse URL from first positional argument or
-url <ws-url>. - Reject missing URL with usage.
2. Connection Handling
- Check
httpexists. - Check
http.websocketexists. - Call
http.websocket(url). - On failure, print the returned error and exit non-zero if possible.
- Send
helloframe. - Optionally wait up to a short timeout for
hello-ok.
3. Request Loop
- Receive websocket messages in a loop.
- Decode JSON with
textutils.unserializeJSONinsidepcall. - Ignore or respond with error for malformed messages.
- Handle
terminatecleanly if usingparallel.waitForAnyaround websocket receive and terminate watcher. - For
requestwithmethod = 'ping', send success response. - For unknown request methods, send error response.
- Close websocket on exit.
4. Pong Formatting
Implement a local function:
local function formatPong()
local label = os.getComputerLabel();
if not label or label == '' then
label = 'nil';
end
return 'pong from ' .. tostring(os.getComputerID()) .. ' (Label: ' .. tostring(label) .. ')';
end
Keep the output exactly aligned with the bridge plan.
5. Packaging
- Add
programs/mcp-computer.luatopackages/trapos-sandbox/ccpm.json. - Bump
trapos-sandboxversion. - Mirror the version bump in
packages/index.json. - Do not add it to
autostartin the first pass. - Do not add
trapos-sandboxas atraposdependency unless explicitly desired later.
Testing Strategy
Unit-Style Lua Tests
Prefer moving deterministic protocol helpers into apis/libmcpcomputer.lua only if testing the program directly becomes awkward. The minimal testable API could expose:
formatPong(osLike).handleRequest(request, osLike).encode/decodehelpers if needed.
If a helper API is added, include it in trapos-sandbox and add tests under tests/ using /apis/libtest.lua.
If keeping everything in one program, at least verify syntax and help/version behavior with CraftOS-PC probes.
CraftOS-PC Probes
Use automated probes only; do not run just repl.
Examples after implementation:
just trapos-exec 'shell.run("/programs/mcp-computer.lua", "--help")'
just trapos-exec 'shell.run("/programs/mcp-computer.lua", "--version")'
For an end-to-end probe, run the TS bridge on localhost and use CraftOS-PC with HTTP local access enabled if the harness permits it. If localhost access is blocked by CC:Tweaked config, document the limitation and rely on an in-game/manual validation for the WebSocket connection.
Required Repo Checks
After editing Lua or package descriptors:
just checkjust testif tests are added or changed.
Manual Validation
- Start the TypeScript bridge.
- On one ComputerCraft computer, run
mcp-computer ws://<bridge-host>:3001. - Confirm the bridge logs the computer registration.
- Connect an MCP client to the bridge MCP port.
- Call
probe-computers. - Confirm response includes the computer id and label.
- Connect a second computer and confirm the tool returns two lines.
Out Of Scope For First Pass
- Autostart server behavior.
- Reconnect/backoff loop.
- Authentication.
- Commands that mutate the world.
- Turtle/peripheral control.
- MCP protocol implementation inside Lua. Lua only speaks the simple bridge link protocol.
Deliverables
programs/mcp-computer.luaintrapos-sandbox.- Package version bump for
trapos-sandbox. - Optional helper API and tests if implementation benefits from unit coverage.
- Working WebSocket link to
tools/mcp-bridge. - Correct response to bridge
pingrequests.