From 6d3f153dd966fb4e9c11490c6f7fc09b81571471 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Wed, 12 Aug 2026 06:24:56 +0000 Subject: [PATCH 1/3] Add Cloud Agent dev environment config Co-authored-by: Satori-Bot --- .cursor/environment.json | 10 +++++++++ .cursor/install.sh | 44 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 .cursor/environment.json create mode 100755 .cursor/install.sh diff --git a/.cursor/environment.json b/.cursor/environment.json new file mode 100644 index 0000000..58bd95f --- /dev/null +++ b/.cursor/environment.json @@ -0,0 +1,10 @@ +{ + "name": "coding-tools-mcp", + "install": "./.cursor/install.sh", + "ports": [ + { + "name": "MCP HTTP server", + "port": 8765 + } + ] +} diff --git a/.cursor/install.sh b/.cursor/install.sh new file mode 100755 index 0000000..f2c3b4f --- /dev/null +++ b/.cursor/install.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash +# Idempotent Cloud Agent bootstrap for coding-tools-mcp. +# +# The repository is a Python >=3.11 MCP server whose canonical dev loop is +# `python -m pip install -e ".[dev]"` followed by `make ci` (lint, typecheck, +# unittest discovery, protocol/integration/docs/schema gates, dogfood, and +# benchmark smokes). This script prepares that loop on the default Cursor image. +set -euo pipefail + +cd "$(dirname "$0")/.." + +# 1. The compliance fixtures invoke a bare `python` (e.g. `python -m pytest`, +# `python repl.py`). Ubuntu ships only `python3`, so provide the alias. +if ! command -v python >/dev/null 2>&1; then + sudo apt-get update -y + sudo apt-get install -y --no-install-recommends python-is-python3 +fi + +# 2. Grant the runtime's Landlock exec sandbox access to the Node toolchain. +# The safe/trusted permission modes confine exec_command to system prefixes +# (/usr, /bin, ...). On the Cursor image, Node/npm live under nvm +# (~/.nvm) and the agent's exec daemon (/exec-daemon), so the golden/e2e +# suites that shell out to `npm test`/`node --test` are otherwise blocked +# with LANDLOCK_READ_ROOT_BLOCKED. This mirrors how the project's own +# Dockerfile keeps the toolchain under system-readable roots. +# The export is placed in ~/.bashrc alongside the image's nvm init so it +# reaches the exec daemon that spawns the MCP server during `make test`. +BASHRC="${HOME}/.bashrc" +MARKER="# coding-tools-mcp: allow Landlock exec of the nvm/exec-daemon Node toolchain" +if ! grep -qF "$MARKER" "$BASHRC" 2>/dev/null; then + { + echo "" + echo "$MARKER" + echo 'export CODING_TOOLS_MCP_EXEC_ALLOW_ROOTS="/exec-daemon:${HOME}/.nvm${CODING_TOOLS_MCP_EXEC_ALLOW_ROOTS:+:$CODING_TOOLS_MCP_EXEC_ALLOW_ROOTS}"' + } >> "$BASHRC" +fi + +# 3. Install the package plus dev tooling (ruff, mypy, PyYAML, typing_extensions) +# in editable mode. Ubuntu 24.04's system interpreter is PEP 668 managed; +# this is a disposable agent VM, so install directly into it (mirrors CI's +# `pip install -e ".[dev]"`). +python3 -m pip install --break-system-packages -e ".[dev]" + +echo "coding-tools-mcp environment ready." From a94e2c3ada8fc0d596a7f3e67d4593b31edc94b0 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Wed, 12 Aug 2026 06:47:22 +0000 Subject: [PATCH 2/3] Grant Landlock read access to python sitecustomize dir; make bashrc block replace-idempotent Co-authored-by: Satori-Bot --- .cursor/install.sh | 45 +++++++++++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 16 deletions(-) diff --git a/.cursor/install.sh b/.cursor/install.sh index f2c3b4f..79a95dd 100755 --- a/.cursor/install.sh +++ b/.cursor/install.sh @@ -16,24 +16,37 @@ if ! command -v python >/dev/null 2>&1; then sudo apt-get install -y --no-install-recommends python-is-python3 fi -# 2. Grant the runtime's Landlock exec sandbox access to the Node toolchain. -# The safe/trusted permission modes confine exec_command to system prefixes -# (/usr, /bin, ...). On the Cursor image, Node/npm live under nvm -# (~/.nvm) and the agent's exec daemon (/exec-daemon), so the golden/e2e -# suites that shell out to `npm test`/`node --test` are otherwise blocked -# with LANDLOCK_READ_ROOT_BLOCKED. This mirrors how the project's own -# Dockerfile keeps the toolchain under system-readable roots. -# The export is placed in ~/.bashrc alongside the image's nvm init so it -# reaches the exec daemon that spawns the MCP server during `make test`. +# 2. Grant the runtime's Landlock exec sandbox access to toolchain paths that +# live outside the system prefixes (/usr, /bin, ...) it allows by default. +# On the Cursor image: +# - Node/npm live under nvm (~/.nvm) and the agent exec daemon +# (/exec-daemon), so suites that shell out to `npm test` / `node --test` +# are otherwise blocked with LANDLOCK_READ_ROOT_BLOCKED. +# - Debian symlinks /usr/lib/pythonX.Y/sitecustomize.py into +# /etc/pythonX.Y, so on stricter Landlock kernels a sandboxed `python` +# fails to read it and pollutes stderr; grant the /etc python config dir. +# This mirrors how the project's own Dockerfile keeps the toolchain under +# system-readable roots. The export is placed in ~/.bashrc alongside the +# image's nvm init so it reaches the exec daemon that spawns the MCP server +# during `make test`. BASHRC="${HOME}/.bashrc" -MARKER="# coding-tools-mcp: allow Landlock exec of the nvm/exec-daemon Node toolchain" -if ! grep -qF "$MARKER" "$BASHRC" 2>/dev/null; then - { - echo "" - echo "$MARKER" - echo 'export CODING_TOOLS_MCP_EXEC_ALLOW_ROOTS="/exec-daemon:${HOME}/.nvm${CODING_TOOLS_MCP_EXEC_ALLOW_ROOTS:+:$CODING_TOOLS_MCP_EXEC_ALLOW_ROOTS}"' - } >> "$BASHRC" +MARKER_TAG="coding-tools-mcp: allow Landlock" +MARKER="# ${MARKER_TAG} exec/read of the nvm + exec-daemon + python toolchain" +PY_ETC="/etc/python$(python3 -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")')" +# Replace any previously-managed block (any marker variant) so re-runs and +# rebuilds from an older snapshot pick up an updated value without duplicating. +if grep -qF "$MARKER_TAG" "$BASHRC" 2>/dev/null || grep -qF 'CODING_TOOLS_MCP_EXEC_ALLOW_ROOTS' "$BASHRC" 2>/dev/null; then + tmp_bashrc="$(mktemp)" + grep -vF "$MARKER_TAG" "$BASHRC" | grep -vF 'CODING_TOOLS_MCP_EXEC_ALLOW_ROOTS' > "$tmp_bashrc" || true + # collapse any trailing blank lines left behind, then move back + sed -e :a -e '/^\n*$/{$d;N;ba}' "$tmp_bashrc" > "$BASHRC" + rm -f "$tmp_bashrc" fi +{ + echo "" + echo "$MARKER" + echo "export CODING_TOOLS_MCP_EXEC_ALLOW_ROOTS=\"/exec-daemon:\${HOME}/.nvm:${PY_ETC}\${CODING_TOOLS_MCP_EXEC_ALLOW_ROOTS:+:\$CODING_TOOLS_MCP_EXEC_ALLOW_ROOTS}\"" +} >> "$BASHRC" # 3. Install the package plus dev tooling (ruff, mypy, PyYAML, typing_extensions) # in editable mode. Ubuntu 24.04's system interpreter is PEP 668 managed; From 9151630ad19b86de64adffef71d51b2fca67ba2a Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Wed, 12 Aug 2026 07:00:30 +0000 Subject: [PATCH 3/3] Use stable (non-appending) allow-roots assignment in bashrc Co-authored-by: Satori-Bot --- .cursor/install.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.cursor/install.sh b/.cursor/install.sh index 79a95dd..18ac173 100755 --- a/.cursor/install.sh +++ b/.cursor/install.sh @@ -45,7 +45,9 @@ fi { echo "" echo "$MARKER" - echo "export CODING_TOOLS_MCP_EXEC_ALLOW_ROOTS=\"/exec-daemon:\${HOME}/.nvm:${PY_ETC}\${CODING_TOOLS_MCP_EXEC_ALLOW_ROOTS:+:\$CODING_TOOLS_MCP_EXEC_ALLOW_ROOTS}\"" + # Fixed assignment (not self-appending) so re-sourcing ~/.bashrc in nested + # shells keeps the value stable instead of growing on each source. + echo "export CODING_TOOLS_MCP_EXEC_ALLOW_ROOTS=\"/exec-daemon:\${HOME}/.nvm:${PY_ETC}\"" } >> "$BASHRC" # 3. Install the package plus dev tooling (ruff, mypy, PyYAML, typing_extensions)