chore(plans): archive completed notes

This commit is contained in:
Guillaume ARM 2026-06-11 05:43:30 +02:00
parent f44aebf5d5
commit 316d561f4b
2 changed files with 0 additions and 248 deletions

View File

@ -1,248 +0,0 @@
# MCP Computer Lua Plan
Depends on the implemented host bridge in `tools/mcp-bridge/`.
## 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:
```text
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 implemented local/dev bridge link default is `ws://<host>:3001` (`CC_LINK_PORT`, default `3001`). Production/public bridge deployments use `ws://<host>:4243` with `CC_LINK_PORT=4243`; see [`../docs/public-ports.md`](../docs/public-ports.md).
- The host-side MCP tool is named `probe-computers` and 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.
- The implemented bridge accepts WebSocket connections on any path, so a bare local/dev URL such as `ws://<host>:3001` is sufficient.
## 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:
```text
[ CC computer ] --outbound WebSocket--> [ tools/mcp-bridge link listener :3001 local/dev, :4243 production ]
```
Production deployments use the public ComputerCraft bridge WebSocket port `4243` instead of the local/dev default `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. The host bridge is already implemented and exposes MCP over plain HTTP JSON-RPC on `MCP_PORT` while this Lua program only speaks the ComputerCraft WebSocket link protocol.
## User Interface
Program usage:
```text
mcp-computer <ws-url>
mcp-computer -url <ws-url>
mcp-computer --version
mcp-computer --help
```
Examples:
```text
mcp-computer ws://192.168.1.20:3001
mcp-computer -url ws://mcp-bridge.local:3001
mcp-computer ws://public.example.com:4243
```
The program should print clear status lines:
```text
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:
```json
{
"type": "hello",
"computerId": 12,
"computerLabel": "base-turtle"
}
```
Lua fields:
- `computerId`: `os.getComputerID()`.
- `computerLabel`: `os.getComputerLabel()`, or `nil` encoded as JSON null/omitted depending on `textutils.serializeJSON` behavior. The bridge treats missing, empty, or non-string labels as `null`.
### Hello OK
Expected from bridge:
```json
{
"type": "hello-ok"
}
```
The bridge sends `hello-ok` immediately after a valid `hello`. The Lua program should wait briefly for this frame so connection or protocol problems are obvious, then proceed only after receiving it.
### Probe Request
Received from bridge:
```json
{
"type": "request",
"id": "req-123",
"method": "ping"
}
```
### Probe Response
Sent back by Lua:
```json
{
"type": "response",
"id": "req-123",
"ok": true,
"result": "pong from 12 (Label: base-turtle)"
}
```
Unknown method response:
```json
{
"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`, and `version`.
- 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 `http` exists.
- Check `http.websocket` exists.
- Call `http.websocket(url)`.
- On failure, print the returned error and exit non-zero if possible.
- Send `hello` frame.
- Optionally wait up to a short timeout for `hello-ok`.
### 3. Request Loop
- Receive websocket messages in a loop.
- Decode JSON with `textutils.unserializeJSON` inside `pcall`.
- Ignore or respond with error for malformed messages.
- Handle `terminate` cleanly if using `parallel.waitForAny` around websocket receive and terminate watcher.
- For `request` with `method = 'ping'`, send success response.
- For unknown request methods, send error response.
- Close websocket on exit.
### 4. Pong Formatting
Implement a local function:
```lua
local function formatPong()
local label = os.getComputerLabel();
if not label or label == '' then
label = 'null';
end
return 'pong from ' .. tostring(os.getComputerID()) .. ' (Label: ' .. tostring(label) .. ')';
end
```
Keep the output aligned with the implemented bridge's `formatComputer` fallback (`null` for missing labels) and the MCP tool's expected successful pong lines.
### 5. Packaging
- Add `programs/mcp-computer.lua` to `packages/trapos-sandbox/ccpm.json`.
- Bump `trapos-sandbox` version.
- Mirror the version bump in `packages/index.json`.
- Do not add it to `autostart` in the first pass.
- Do not add `trapos-sandbox` as a `trapos` dependency 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/decode` helpers 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:
```bash
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. The bridge already includes integration-test Lua clients under `tools/mcp-bridge/test-integration/lua/` that can be used as protocol references. 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 check`
- `just test` if tests are added or changed.
## Manual Validation
1. Start the TypeScript bridge.
2. On one ComputerCraft computer, run `mcp-computer ws://<bridge-host>:3001` for local/dev, or `mcp-computer ws://<public-host>:4243` for public production.
3. Confirm the bridge logs the computer registration.
4. Connect an MCP client to the bridge MCP port.
5. Call `probe-computers`.
6. Confirm response includes the computer id and label.
7. 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.lua` in `trapos-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 `ping` requests.