coder: let the omp harness drive workspaces over Coders MCP server

Coder ships `coder exp mcp server` and omp is an MCP client, so the two compose
with no custom code. The agent stays on the host where its credentials already
live and reaches into the workspace, rather than shipping secrets into a
container.

- scripts/coder-mcp.sh wraps the server, passing a dedicated `omp-mcp` token via
  `docker exec --env-file` (mode 600 temp file, shredded by an EXIT trap) so the
  token never appears in argv or ps
- allow-list exposes 26 of 32 tools; template mutation is excluded because
  pushing a template is the one real path from a Coder principal to the host
  docker socket
- scripts/coder-token-rotate.sh handles the 168h token lifetime cap: mint,
  verify against the API, then revoke the predecessors
- .omp/mcp.json registers it project-scoped so 26 tools do not load into every
  unrelated omp session

The docker exec must stay in the foreground: backgrounding it makes bash
redirect stdin from /dev/null with job control disabled, and the MCP transport
dies on EOF with "MCP tool load failed ... Transport closed".

Verified: fresh omp session in this directory answered from the tools -
coder_get_authenticated_user returned loca, workspace ws1 running.
This commit is contained in:
Antigravity
2026-08-20 17:46:51 +02:00
parent 0e54b86dac
commit 3478e7b913
8 changed files with 185 additions and 2 deletions

View File

@@ -164,6 +164,22 @@ sudo -n gunzip -t $D/coder-db.sql.gz && sudo -n ls -l $D
- artifacts are root-owned; retention keeps 14 dated directories
- `.env`, `.admin-credentials` and `.ai-credentials` are deliberately excluded — they are keys, not data; verify with `sudo -n tar tzf $D/stack-configs.tgz | grep -c credentials` returning `0`
## 1️⃣5️⃣ omp harness reaches Coder over MCP
```bash
printf '%s\n' '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"probe","version":"1"}}}' \
| /home/loca/dev/coder/scripts/coder-mcp.sh | head -1
ls /tmp/tmp.* 2>/dev/null | wc -l
cd /home/loca/dev/coder && omp -p 'Call coder_get_authenticated_user and coder_list_workspaces. Report the username and each workspace name plus status.'
```
- expect the first line to contain `"serverInfo":{"name":"Coder Agent","version":"v2.35.3+..."}`
- expect the temp-file count to be unchanged, proving the wrapper's EXIT trap shredded the mode-600 env file holding the token
- expect the harness to answer from tools, not guesses: username `loca`, workspace `ws1` `running`
- if the harness reports no tools, check `~/.omp/logs/omp.<date>.<pid>.log` for `MCP tool load failed ... Transport closed`, which means the wrapper backgrounded the server and its stdin was redirected from `/dev/null`
- token expiry is the most likely 401 cause: the `omp-mcp` token lasts 168h maximum. Rotate with `scripts/coder-token-rotate.sh` and confirm with `sudo -n docker exec coder /opt/coder tokens list`
- 26 of 32 tools are exposed by design; template mutation is excluded. Confirm with a `tools/list` request and check that no `coder_create_template*`, `coder_update_template_active_version`, `coder_delete_template`, `coder_delete_task` or `coder_upload_tar_file` appears
## 🧹 Pre-publish wiki lint gate
Run this before every `build.sh` invocation, so before item 7 above. It is a gate, not a smoke test: it exits non-zero and publishes nothing.