From aa0dbc3d920c0d0072aa58d35ded464900b19ecc Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 24 Aug 2026 12:29:13 +0000 Subject: [PATCH 1/5] Initial plan From 0784675e73642084da2a2a41be81df5bf8347d3a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 24 Aug 2026 12:43:16 +0000 Subject: [PATCH 2/5] Add raw MCP canary to auth test workflow Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .../github-remote-mcp-auth-test.lock.yml | 110 +++++++++++++++++- .../workflows/github-remote-mcp-auth-test.md | 95 +++++++++++++++ 2 files changed, 203 insertions(+), 2 deletions(-) diff --git a/.github/workflows/github-remote-mcp-auth-test.lock.yml b/.github/workflows/github-remote-mcp-auth-test.lock.yml index 5ba0513ca42..475d24778b1 100644 --- a/.github/workflows/github-remote-mcp-auth-test.lock.yml +++ b/.github/workflows/github-remote-mcp-auth-test.lock.yml @@ -1,4 +1,4 @@ -# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"d855efd256c75de6ca1d2f20bac63d0f238aec7201c304bd6dbe4013ed348a76","body_hash":"56f9950ffdb46afae7ca16c12844a211460e171090d34f04b8cfe4ac9ab2e754","strict":true,"agent_id":"copilot","agent_model":"gpt-4.1","engine_versions":{"copilot":"1.0.80"}} +# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"aab2313d2f4b6685e281a7950470e34ebaa7c015545b93b1215883caab732bce","body_hash":"56f9950ffdb46afae7ca16c12844a211460e171090d34f04b8cfe4ac9ab2e754","strict":true,"agent_id":"copilot","agent_model":"gpt-4.1","engine_versions":{"copilot":"1.0.80"}} # gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GH_AW_OTEL_GRAFANA_AUTHORIZATION","GH_AW_OTEL_GRAFANA_ENDPOINT","GH_AW_OTEL_SENTRY_AUTHORIZATION","GH_AW_OTEL_SENTRY_ENDPOINT","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache/restore","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/checkout","sha":"3d3c42e5aac5ba805825da76410c181273ba90b1","version":"v7.0.1"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.28.6","digest":"sha256:e3924f943a55ebf362db12500c69f2ef0717661f363baecd95caa50a93380dc8","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.28.6@sha256:e3924f943a55ebf362db12500c69f2ef0717661f363baecd95caa50a93380dc8"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.28.6","digest":"sha256:18f81ac0941a06b931e27f8a7ba70e7d4d7fda8178eb8fe2ea3c6a46d6b63daa","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.28.6@sha256:18f81ac0941a06b931e27f8a7ba70e7d4d7fda8178eb8fe2ea3c6a46d6b63daa"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.28.6","digest":"sha256:b80770265199ce518e3983256782e1ad41aee51fe29a3392e2694e056d6b1c98","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.28.6@sha256:b80770265199ce518e3983256782e1ad41aee51fe29a3392e2694e056d6b1c98"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.10","digest":"sha256:08bb5fa417aed94b40a14e2b7b3ae457531a5f22b143a32fe58317139d9b8f42","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.10@sha256:08bb5fa417aed94b40a14e2b7b3ae457531a5f22b143a32fe58317139d9b8f42"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:bac2192f6374d6262116399b34fc5e143d576f82719e90a18261cae7480f4d4e","pinned_image":"ghcr.io/github/gh-aw-node@sha256:bac2192f6374d6262116399b34fc5e143d576f82719e90a18261cae7480f4d4e"}],"mcp_servers":[{"name":"github","tools":["get_repository","issue_read","list_issues"]},{"name":"safeoutputs","tools":["create_discussion","missing_data","missing_tool","noop"]}]} # This file was automatically generated by gh-aw. DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md # @@ -381,7 +381,9 @@ jobs: retention-days: 1 agent: - needs: activation + needs: + - activation + - raw_mcp_canary if: needs.activation.outputs.daily_ai_credits_exceeded != 'true' runs-on: ubuntu-latest permissions: @@ -1100,6 +1102,7 @@ jobs: - activation - agent - detection + - raw_mcp_canary - safe_outputs if: > always() && (needs.agent.result != 'skipped' || needs.activation.outputs.lockdown_check_failed == 'true' || @@ -1653,6 +1656,109 @@ jobs: run: | bash "${RUNNER_TEMP}/gh-aw/actions/conclude_threat_detection.sh" /tmp/gh-aw/threat-detection/detection_result.json + raw_mcp_canary: + runs-on: ubuntu-latest + permissions: + contents: read + discussions: read + issues: read + steps: + - name: Configure GH_HOST for enterprise compatibility + id: ghes-host-config + shell: bash + run: | # zizmor: ignore[github-env] - GITHUB_SERVER_URL is set by GitHub Actions, not user input. + # Derive GH_HOST from GITHUB_SERVER_URL so the gh CLI targets the correct + # GitHub instance (GHES/GHEC). On github.com this is a harmless no-op. + GH_HOST="${GITHUB_SERVER_URL#https://}" + GH_HOST="${GH_HOST#http://}" + echo "GH_HOST=${GH_HOST}" >> "$GITHUB_ENV" + - name: Verify raw GitHub remote MCP handshake + run: | + set -euo pipefail + + if [ -z "${GITHUB_MCP_SERVER_TOKEN}" ]; then + echo "No GitHub MCP token is available." + exit 1 + fi + echo "::add-mask::${GITHUB_MCP_SERVER_TOKEN}" + + server_url="https://api.githubcopilot.com/mcp/" + headers_file="$(mktemp)" + body_file="$(mktemp)" + json_file="$(mktemp)" + error_file="$(mktemp)" + trap 'rm -f "$headers_file" "$body_file" "$json_file" "$error_file"' EXIT + + mcp_post() { + local payload="$1" + shift + local auth_scheme="Bearer" + local http_code + if ! http_code="$(curl -sS -D "$headers_file" -o "$body_file" -w "%{http_code}" --max-time 20 \ + -X POST "$server_url" \ + -H "Authorization: ${auth_scheme} ${GITHUB_MCP_SERVER_TOKEN}" \ + -H "Content-Type: application/json" \ + -H "Accept: application/json, text/event-stream" \ + -H "X-MCP-Readonly: true" \ + -H "X-MCP-Toolsets: repos,issues,discussions" \ + "$@" \ + -d "$payload" 2>"$error_file")"; then + http_code="000" + fi + printf '%s' "$http_code" + } + + read_json_response() { + if jq -e . "$body_file" >/dev/null 2>&1; then + cp "$body_file" "$json_file" + else + awk '/^data: / { print substr($0, 7) }' "$body_file" | tail -n 1 > "$json_file" + fi + } + + assert_success_response() { + local label="$1" + local http_code="$2" + if [ "$http_code" != "200" ]; then + echo "$label failed with HTTP $http_code." + if [ -s "$error_file" ]; then + echo "curl error: $(head -c 200 "$error_file")" + fi + exit 1 + fi + + read_json_response + if ! jq -e . "$json_file" >/dev/null 2>&1; then + echo "$label did not return a JSON response." + exit 1 + fi + if jq -e '.error' "$json_file" >/dev/null 2>&1; then + error_message="$(jq -r '.error.message // "unknown JSON-RPC error"' "$json_file")" + echo "$label returned JSON-RPC error: $error_message" + exit 1 + fi + } + + ping_code="$(mcp_post '{"jsonrpc":"2.0","id":1,"method":"ping"}')" + assert_success_response "MCP ping" "$ping_code" + + initialize_code="$(mcp_post '{"jsonrpc":"2.0","id":2,"method":"initialize","params":{"capabilities":{},"clientInfo":{"name":"gh-aw-raw-mcp-canary","version":"1.0.0"},"protocolVersion":"2024-11-05"}}')" + assert_success_response "MCP initialize" "$initialize_code" + + session_id="$(awk 'BEGIN{IGNORECASE=1} /^Mcp-Session-Id:/ { gsub(/\r/, "", $2); print $2; exit }' "$headers_file")" + session_args=() + if [ -n "$session_id" ]; then + session_args=(-H "Mcp-Session-Id: $session_id") + fi + + tools_code="$(mcp_post '{"jsonrpc":"2.0","id":3,"method":"tools/list"}' "${session_args[@]}")" + assert_success_response "MCP tools/list" "$tools_code" + + tool_count="$(jq '.result.tools | length // 0' "$json_file")" + echo "Raw GitHub remote MCP handshake succeeded with $tool_count tools available." + env: + GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} + safe_outputs: needs: - activation diff --git a/.github/workflows/github-remote-mcp-auth-test.md b/.github/workflows/github-remote-mcp-auth-test.md index e43e8b8e476..552184130d6 100644 --- a/.github/workflows/github-remote-mcp-auth-test.md +++ b/.github/workflows/github-remote-mcp-auth-test.md @@ -30,6 +30,101 @@ imports: - shared/otlp.md +jobs: + raw_mcp_canary: + needs: [] + runs-on: ubuntu-latest + permissions: + contents: read + issues: read + discussions: read + steps: + - name: Verify raw GitHub remote MCP handshake + env: + GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} + run: | + set -euo pipefail + + if [ -z "${GITHUB_MCP_SERVER_TOKEN}" ]; then + echo "No GitHub MCP token is available." + exit 1 + fi + echo "::add-mask::${GITHUB_MCP_SERVER_TOKEN}" + + server_url="https://api.githubcopilot.com/mcp/" + headers_file="$(mktemp)" + body_file="$(mktemp)" + json_file="$(mktemp)" + error_file="$(mktemp)" + trap 'rm -f "$headers_file" "$body_file" "$json_file" "$error_file"' EXIT + + mcp_post() { + local payload="$1" + shift + local auth_scheme="Bearer" + local http_code + if ! http_code="$(curl -sS -D "$headers_file" -o "$body_file" -w "%{http_code}" --max-time 20 \ + -X POST "$server_url" \ + -H "Authorization: ${auth_scheme} ${GITHUB_MCP_SERVER_TOKEN}" \ + -H "Content-Type: application/json" \ + -H "Accept: application/json, text/event-stream" \ + -H "X-MCP-Readonly: true" \ + -H "X-MCP-Toolsets: repos,issues,discussions" \ + "$@" \ + -d "$payload" 2>"$error_file")"; then + http_code="000" + fi + printf '%s' "$http_code" + } + + read_json_response() { + if jq -e . "$body_file" >/dev/null 2>&1; then + cp "$body_file" "$json_file" + else + awk '/^data: / { print substr($0, 7) }' "$body_file" | tail -n 1 > "$json_file" + fi + } + + assert_success_response() { + local label="$1" + local http_code="$2" + if [ "$http_code" != "200" ]; then + echo "$label failed with HTTP $http_code." + if [ -s "$error_file" ]; then + echo "curl error: $(head -c 200 "$error_file")" + fi + exit 1 + fi + + read_json_response + if ! jq -e . "$json_file" >/dev/null 2>&1; then + echo "$label did not return a JSON response." + exit 1 + fi + if jq -e '.error' "$json_file" >/dev/null 2>&1; then + error_message="$(jq -r '.error.message // "unknown JSON-RPC error"' "$json_file")" + echo "$label returned JSON-RPC error: $error_message" + exit 1 + fi + } + + ping_code="$(mcp_post '{"jsonrpc":"2.0","id":1,"method":"ping"}')" + assert_success_response "MCP ping" "$ping_code" + + initialize_code="$(mcp_post '{"jsonrpc":"2.0","id":2,"method":"initialize","params":{"capabilities":{},"clientInfo":{"name":"gh-aw-raw-mcp-canary","version":"1.0.0"},"protocolVersion":"2024-11-05"}}')" + assert_success_response "MCP initialize" "$initialize_code" + + session_id="$(awk 'BEGIN{IGNORECASE=1} /^Mcp-Session-Id:/ { gsub(/\r/, "", $2); print $2; exit }' "$headers_file")" + session_args=() + if [ -n "$session_id" ]; then + session_args=(-H "Mcp-Session-Id: $session_id") + fi + + tools_code="$(mcp_post '{"jsonrpc":"2.0","id":3,"method":"tools/list"}' "${session_args[@]}")" + assert_success_response "MCP tools/list" "$tools_code" + + tool_count="$(jq '.result.tools | length // 0' "$json_file")" + echo "Raw GitHub remote MCP handshake succeeded with $tool_count tools available." features: gh-aw-detection: true sandbox: From 2186f793e268fe3ebe5bf55ca0e72c8c0db7448a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 24 Aug 2026 12:55:34 +0000 Subject: [PATCH 3/5] Harden raw MCP canary job Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .../github-remote-mcp-auth-test.lock.yml | 40 +++++++++++-------- .../workflows/github-remote-mcp-auth-test.md | 35 +++++++++------- 2 files changed, 44 insertions(+), 31 deletions(-) diff --git a/.github/workflows/github-remote-mcp-auth-test.lock.yml b/.github/workflows/github-remote-mcp-auth-test.lock.yml index 475d24778b1..7b21471ec9d 100644 --- a/.github/workflows/github-remote-mcp-auth-test.lock.yml +++ b/.github/workflows/github-remote-mcp-auth-test.lock.yml @@ -1,4 +1,4 @@ -# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"aab2313d2f4b6685e281a7950470e34ebaa7c015545b93b1215883caab732bce","body_hash":"56f9950ffdb46afae7ca16c12844a211460e171090d34f04b8cfe4ac9ab2e754","strict":true,"agent_id":"copilot","agent_model":"gpt-4.1","engine_versions":{"copilot":"1.0.80"}} +# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"ced15ca5c8eb6e7ad124eba047e0e6dbb8f0aea504afb8584ba3de20ec8fed6d","body_hash":"56f9950ffdb46afae7ca16c12844a211460e171090d34f04b8cfe4ac9ab2e754","strict":true,"agent_id":"copilot","agent_model":"gpt-4.1","engine_versions":{"copilot":"1.0.80"}} # gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GH_AW_OTEL_GRAFANA_AUTHORIZATION","GH_AW_OTEL_GRAFANA_ENDPOINT","GH_AW_OTEL_SENTRY_AUTHORIZATION","GH_AW_OTEL_SENTRY_ENDPOINT","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache/restore","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/checkout","sha":"3d3c42e5aac5ba805825da76410c181273ba90b1","version":"v7.0.1"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.28.6","digest":"sha256:e3924f943a55ebf362db12500c69f2ef0717661f363baecd95caa50a93380dc8","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.28.6@sha256:e3924f943a55ebf362db12500c69f2ef0717661f363baecd95caa50a93380dc8"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.28.6","digest":"sha256:18f81ac0941a06b931e27f8a7ba70e7d4d7fda8178eb8fe2ea3c6a46d6b63daa","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.28.6@sha256:18f81ac0941a06b931e27f8a7ba70e7d4d7fda8178eb8fe2ea3c6a46d6b63daa"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.28.6","digest":"sha256:b80770265199ce518e3983256782e1ad41aee51fe29a3392e2694e056d6b1c98","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.28.6@sha256:b80770265199ce518e3983256782e1ad41aee51fe29a3392e2694e056d6b1c98"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.10","digest":"sha256:08bb5fa417aed94b40a14e2b7b3ae457531a5f22b143a32fe58317139d9b8f42","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.10@sha256:08bb5fa417aed94b40a14e2b7b3ae457531a5f22b143a32fe58317139d9b8f42"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:bac2192f6374d6262116399b34fc5e143d576f82719e90a18261cae7480f4d4e","pinned_image":"ghcr.io/github/gh-aw-node@sha256:bac2192f6374d6262116399b34fc5e143d576f82719e90a18261cae7480f4d4e"}],"mcp_servers":[{"name":"github","tools":["get_repository","issue_read","list_issues"]},{"name":"safeoutputs","tools":["create_discussion","missing_data","missing_tool","noop"]}]} # This file was automatically generated by gh-aw. DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md # @@ -381,9 +381,7 @@ jobs: retention-days: 1 agent: - needs: - - activation - - raw_mcp_canary + needs: activation if: needs.activation.outputs.daily_ai_credits_exceeded != 'true' runs-on: ubuntu-latest permissions: @@ -1657,6 +1655,8 @@ jobs: bash "${RUNNER_TEMP}/gh-aw/actions/conclude_threat_detection.sh" /tmp/gh-aw/threat-detection/detection_result.json raw_mcp_canary: + needs: agent + if: always() && !cancelled() runs-on: ubuntu-latest permissions: contents: read @@ -1676,27 +1676,29 @@ jobs: run: | set -euo pipefail - if [ -z "${GITHUB_MCP_SERVER_TOKEN}" ]; then + if [ -z "${GITHUB_MCP_SERVER_TOKEN:-}" ]; then echo "No GitHub MCP token is available." exit 1 fi echo "::add-mask::${GITHUB_MCP_SERVER_TOKEN}" server_url="https://api.githubcopilot.com/mcp/" - headers_file="$(mktemp)" + ping_headers_file="$(mktemp)" + initialize_headers_file="$(mktemp)" + tools_headers_file="$(mktemp)" body_file="$(mktemp)" json_file="$(mktemp)" error_file="$(mktemp)" - trap 'rm -f "$headers_file" "$body_file" "$json_file" "$error_file"' EXIT + trap 'rm -f "$ping_headers_file" "$initialize_headers_file" "$tools_headers_file" "$body_file" "$json_file" "$error_file"' EXIT mcp_post() { local payload="$1" - shift - local auth_scheme="Bearer" + local response_headers_file="$2" + shift 2 local http_code - if ! http_code="$(curl -sS -D "$headers_file" -o "$body_file" -w "%{http_code}" --max-time 20 \ + if ! http_code="$(curl -sS -D "$response_headers_file" -o "$body_file" -w "%{http_code}" --max-time 20 \ -X POST "$server_url" \ - -H "Authorization: ${auth_scheme} ${GITHUB_MCP_SERVER_TOKEN}" \ + --oauth2-bearer "$GITHUB_MCP_SERVER_TOKEN" \ -H "Content-Type: application/json" \ -H "Accept: application/json, text/event-stream" \ -H "X-MCP-Readonly: true" \ @@ -1712,7 +1714,7 @@ jobs: if jq -e . "$body_file" >/dev/null 2>&1; then cp "$body_file" "$json_file" else - awk '/^data: / { print substr($0, 7) }' "$body_file" | tail -n 1 > "$json_file" + awk '/^data:/ { sub(/^data: ?/, ""); print }' "$body_file" | tail -n 1 > "$json_file" fi } @@ -1739,22 +1741,26 @@ jobs: fi } - ping_code="$(mcp_post '{"jsonrpc":"2.0","id":1,"method":"ping"}')" + ping_code="$(mcp_post '{"jsonrpc":"2.0","id":1,"method":"ping"}' "$ping_headers_file")" assert_success_response "MCP ping" "$ping_code" - initialize_code="$(mcp_post '{"jsonrpc":"2.0","id":2,"method":"initialize","params":{"capabilities":{},"clientInfo":{"name":"gh-aw-raw-mcp-canary","version":"1.0.0"},"protocolVersion":"2024-11-05"}}')" + initialize_code="$(mcp_post '{"jsonrpc":"2.0","id":2,"method":"initialize","params":{"capabilities":{},"clientInfo":{"name":"gh-aw-raw-mcp-canary","version":"1.0.0"},"protocolVersion":"2024-11-05"}}' "$initialize_headers_file")" assert_success_response "MCP initialize" "$initialize_code" - session_id="$(awk 'BEGIN{IGNORECASE=1} /^Mcp-Session-Id:/ { gsub(/\r/, "", $2); print $2; exit }' "$headers_file")" + session_id="$(awk 'BEGIN{IGNORECASE=1} /^Mcp-Session-Id:/ { gsub(/\r/, "", $2); print $2; exit }' "$initialize_headers_file")" session_args=() if [ -n "$session_id" ]; then session_args=(-H "Mcp-Session-Id: $session_id") fi - tools_code="$(mcp_post '{"jsonrpc":"2.0","id":3,"method":"tools/list"}' "${session_args[@]}")" + tools_code="$(mcp_post '{"jsonrpc":"2.0","id":3,"method":"tools/list"}' "$tools_headers_file" "${session_args[@]}")" assert_success_response "MCP tools/list" "$tools_code" - tool_count="$(jq '.result.tools | length // 0' "$json_file")" + tool_count="$(jq -r 'if (.result.tools | type) == "array" then (.result.tools | length) else 0 end' "$json_file")" + if [ "$tool_count" -eq 0 ]; then + echo "MCP tools/list did not return any tools." + exit 1 + fi echo "Raw GitHub remote MCP handshake succeeded with $tool_count tools available." env: GITHUB_MCP_SERVER_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/github-remote-mcp-auth-test.md b/.github/workflows/github-remote-mcp-auth-test.md index 552184130d6..99f5d2169fa 100644 --- a/.github/workflows/github-remote-mcp-auth-test.md +++ b/.github/workflows/github-remote-mcp-auth-test.md @@ -32,7 +32,8 @@ imports: - shared/otlp.md jobs: raw_mcp_canary: - needs: [] + needs: agent + if: always() && !cancelled() runs-on: ubuntu-latest permissions: contents: read @@ -45,27 +46,29 @@ jobs: run: | set -euo pipefail - if [ -z "${GITHUB_MCP_SERVER_TOKEN}" ]; then + if [ -z "${GITHUB_MCP_SERVER_TOKEN:-}" ]; then echo "No GitHub MCP token is available." exit 1 fi echo "::add-mask::${GITHUB_MCP_SERVER_TOKEN}" server_url="https://api.githubcopilot.com/mcp/" - headers_file="$(mktemp)" + ping_headers_file="$(mktemp)" + initialize_headers_file="$(mktemp)" + tools_headers_file="$(mktemp)" body_file="$(mktemp)" json_file="$(mktemp)" error_file="$(mktemp)" - trap 'rm -f "$headers_file" "$body_file" "$json_file" "$error_file"' EXIT + trap 'rm -f "$ping_headers_file" "$initialize_headers_file" "$tools_headers_file" "$body_file" "$json_file" "$error_file"' EXIT mcp_post() { local payload="$1" - shift - local auth_scheme="Bearer" + local response_headers_file="$2" + shift 2 local http_code - if ! http_code="$(curl -sS -D "$headers_file" -o "$body_file" -w "%{http_code}" --max-time 20 \ + if ! http_code="$(curl -sS -D "$response_headers_file" -o "$body_file" -w "%{http_code}" --max-time 20 \ -X POST "$server_url" \ - -H "Authorization: ${auth_scheme} ${GITHUB_MCP_SERVER_TOKEN}" \ + --oauth2-bearer "$GITHUB_MCP_SERVER_TOKEN" \ -H "Content-Type: application/json" \ -H "Accept: application/json, text/event-stream" \ -H "X-MCP-Readonly: true" \ @@ -81,7 +84,7 @@ jobs: if jq -e . "$body_file" >/dev/null 2>&1; then cp "$body_file" "$json_file" else - awk '/^data: / { print substr($0, 7) }' "$body_file" | tail -n 1 > "$json_file" + awk '/^data:/ { sub(/^data: ?/, ""); print }' "$body_file" | tail -n 1 > "$json_file" fi } @@ -108,22 +111,26 @@ jobs: fi } - ping_code="$(mcp_post '{"jsonrpc":"2.0","id":1,"method":"ping"}')" + ping_code="$(mcp_post '{"jsonrpc":"2.0","id":1,"method":"ping"}' "$ping_headers_file")" assert_success_response "MCP ping" "$ping_code" - initialize_code="$(mcp_post '{"jsonrpc":"2.0","id":2,"method":"initialize","params":{"capabilities":{},"clientInfo":{"name":"gh-aw-raw-mcp-canary","version":"1.0.0"},"protocolVersion":"2024-11-05"}}')" + initialize_code="$(mcp_post '{"jsonrpc":"2.0","id":2,"method":"initialize","params":{"capabilities":{},"clientInfo":{"name":"gh-aw-raw-mcp-canary","version":"1.0.0"},"protocolVersion":"2024-11-05"}}' "$initialize_headers_file")" assert_success_response "MCP initialize" "$initialize_code" - session_id="$(awk 'BEGIN{IGNORECASE=1} /^Mcp-Session-Id:/ { gsub(/\r/, "", $2); print $2; exit }' "$headers_file")" + session_id="$(awk 'BEGIN{IGNORECASE=1} /^Mcp-Session-Id:/ { gsub(/\r/, "", $2); print $2; exit }' "$initialize_headers_file")" session_args=() if [ -n "$session_id" ]; then session_args=(-H "Mcp-Session-Id: $session_id") fi - tools_code="$(mcp_post '{"jsonrpc":"2.0","id":3,"method":"tools/list"}' "${session_args[@]}")" + tools_code="$(mcp_post '{"jsonrpc":"2.0","id":3,"method":"tools/list"}' "$tools_headers_file" "${session_args[@]}")" assert_success_response "MCP tools/list" "$tools_code" - tool_count="$(jq '.result.tools | length // 0' "$json_file")" + tool_count="$(jq -r 'if (.result.tools | type) == "array" then (.result.tools | length) else 0 end' "$json_file")" + if [ "$tool_count" -eq 0 ]; then + echo "MCP tools/list did not return any tools." + exit 1 + fi echo "Raw GitHub remote MCP handshake succeeded with $tool_count tools available." features: gh-aw-detection: true From 061cc354e2fe20dba5137e858d78ffae03996f9e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 24 Aug 2026 16:46:25 +0000 Subject: [PATCH 4/5] Complete raw MCP canary validation Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com> --- .github/workflows/github-remote-mcp-auth-test.lock.yml | 4 ++-- .github/workflows/github-remote-mcp-auth-test.md | 2 +- .github/workflows/smoke-claude.lock.yml | 6 +++++- .github/workflows/step-name-alignment.lock.yml | 6 +++++- 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/.github/workflows/github-remote-mcp-auth-test.lock.yml b/.github/workflows/github-remote-mcp-auth-test.lock.yml index f178d129a53..e61ded5db4e 100644 --- a/.github/workflows/github-remote-mcp-auth-test.lock.yml +++ b/.github/workflows/github-remote-mcp-auth-test.lock.yml @@ -1,4 +1,4 @@ -# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"798c821f9b5ed6be7e4f3c7bad1eb4a640b83ae1598d9b498377238cd4fa7b14","body_hash":"56f9950ffdb46afae7ca16c12844a211460e171090d34f04b8cfe4ac9ab2e754","strict":true,"agent_id":"copilot","agent_model":"gpt-4.1","engine_versions":{"copilot":"1.0.80"}} +# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"835aa876ed88e123c9634e0275b5b4a625a39bcc85dda3760d3a387fe6635a09","body_hash":"56f9950ffdb46afae7ca16c12844a211460e171090d34f04b8cfe4ac9ab2e754","strict":true,"agent_id":"copilot","agent_model":"gpt-4.1","engine_versions":{"copilot":"1.0.80"}} # gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GH_AW_OTEL_GRAFANA_AUTHORIZATION","GH_AW_OTEL_GRAFANA_ENDPOINT","GH_AW_OTEL_SENTRY_AUTHORIZATION","GH_AW_OTEL_SENTRY_ENDPOINT","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache/restore","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/checkout","sha":"3d3c42e5aac5ba805825da76410c181273ba90b1","version":"v7.0.1"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.28.7","digest":"sha256:40a1e30b1b8d70642d4292485146cd5af612730d7a6a2e12706ddd13df375059","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.28.7@sha256:40a1e30b1b8d70642d4292485146cd5af612730d7a6a2e12706ddd13df375059"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.28.7","digest":"sha256:4f209dd4cbc74d47a6c7379956143de293429d1b1b2fb2647776cdcbf65836a1","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.28.7@sha256:4f209dd4cbc74d47a6c7379956143de293429d1b1b2fb2647776cdcbf65836a1"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.28.7","digest":"sha256:fb362a08d4d2f0da6c036e3f5d3b2fd87931e857fec3ca4a241cd2f2b61131f9","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.28.7@sha256:fb362a08d4d2f0da6c036e3f5d3b2fd87931e857fec3ca4a241cd2f2b61131f9"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.10","digest":"sha256:08bb5fa417aed94b40a14e2b7b3ae457531a5f22b143a32fe58317139d9b8f42","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.10@sha256:08bb5fa417aed94b40a14e2b7b3ae457531a5f22b143a32fe58317139d9b8f42"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:bac2192f6374d6262116399b34fc5e143d576f82719e90a18261cae7480f4d4e","pinned_image":"ghcr.io/github/gh-aw-node@sha256:bac2192f6374d6262116399b34fc5e143d576f82719e90a18261cae7480f4d4e"}],"mcp_servers":[{"name":"github","tools":["get_repository","issue_read","list_issues"]},{"name":"safeoutputs","tools":["create_discussion","missing_data","missing_tool","noop"]}]} # This file was automatically generated by gh-aw. DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md # @@ -1797,7 +1797,7 @@ jobs: call_code="$(mcp_post "$call_payload" "$response_headers_file" "${session_args[@]}")" assert_success_response "MCP get_repository" "$call_code" if jq -e '.result.isError == true' "$json_file" >/dev/null; then - tool_error="$(jq -r '[.result.content[]?.text] | join(" ")' "$json_file" | head -c 200)" + tool_error="$(jq -r '([.result.content[]?.text] | join(" "))[0:200]' "$json_file")" echo "MCP get_repository returned a tool error: $tool_error" echo "- ❌ MCP get_repository: tool error \`$tool_error\`" >> "$GITHUB_STEP_SUMMARY" exit 1 diff --git a/.github/workflows/github-remote-mcp-auth-test.md b/.github/workflows/github-remote-mcp-auth-test.md index b0e306c500d..7f37febf7b6 100644 --- a/.github/workflows/github-remote-mcp-auth-test.md +++ b/.github/workflows/github-remote-mcp-auth-test.md @@ -167,7 +167,7 @@ jobs: call_code="$(mcp_post "$call_payload" "$response_headers_file" "${session_args[@]}")" assert_success_response "MCP get_repository" "$call_code" if jq -e '.result.isError == true' "$json_file" >/dev/null; then - tool_error="$(jq -r '[.result.content[]?.text] | join(" ")' "$json_file" | head -c 200)" + tool_error="$(jq -r '([.result.content[]?.text] | join(" "))[0:200]' "$json_file")" echo "MCP get_repository returned a tool error: $tool_error" echo "- ❌ MCP get_repository: tool error \`$tool_error\`" >> "$GITHUB_STEP_SUMMARY" exit 1 diff --git a/.github/workflows/smoke-claude.lock.yml b/.github/workflows/smoke-claude.lock.yml index 5df0a0ba4ad..bd609de57f0 100644 --- a/.github/workflows/smoke-claude.lock.yml +++ b/.github/workflows/smoke-claude.lock.yml @@ -1549,6 +1549,7 @@ jobs: # - Bash # - BashOutput # - Edit + # - Edit(/tmp/*) # - Edit(/tmp/gh-aw/agent/*) # - Edit(/tmp/gh-aw/cache-memory/*) # - ExitPlanMode @@ -1557,16 +1558,19 @@ jobs: # - KillBash # - LS # - MultiEdit + # - MultiEdit(/tmp/*) # - MultiEdit(/tmp/gh-aw/agent/*) # - MultiEdit(/tmp/gh-aw/cache-memory/*) # - NotebookEdit # - NotebookRead # - Read + # - Read(/tmp/*) # - Read(/tmp/gh-aw/agent/*) # - Read(/tmp/gh-aw/cache-memory/*) # - Task # - TodoWrite # - Write + # - Write(/tmp/*) # - Write(/tmp/gh-aw/agent/*) # - Write(/tmp/gh-aw/cache-memory/*) # - mcp__agenticworkflows @@ -1667,7 +1671,7 @@ jobs: fi # shellcheck disable=SC1003,SC2016,SC2086 awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} --tty --env-all --exclude-env ACTIONS_ID_TOKEN_REQUEST_TOKEN --exclude-env ACTIONS_ID_TOKEN_REQUEST_URL --exclude-env ANTHROPIC_API_KEY --exclude-env GH_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --exclude-env TAVILY_API_KEY --mount /tmp/gh-aw:/tmp/gh-aw:rw --log-level info --skip-pull --difc-proxy-host awmg-cli-proxy:18443 --difc-proxy-ca-cert /tmp/gh-aw/difc-proxy-tls/ca.crt \ - -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/claude_harness.cjs claude --print --no-chrome --max-turns 100 --allowed-tools '\''Bash,BashOutput,Edit,Edit(/tmp/gh-aw/agent/*),Edit(/tmp/gh-aw/cache-memory/*),ExitPlanMode,Glob,Grep,KillBash,LS,MultiEdit,MultiEdit(/tmp/gh-aw/agent/*),MultiEdit(/tmp/gh-aw/cache-memory/*),NotebookEdit,NotebookRead,Read,Read(/tmp/gh-aw/agent/*),Read(/tmp/gh-aw/cache-memory/*),Task,TodoWrite,Write,Write(/tmp/gh-aw/agent/*),Write(/tmp/gh-aw/cache-memory/*),mcp__agenticworkflows,mcp__github__actions_get,mcp__github__actions_list,mcp__github__get_code_scanning_alert,mcp__github__get_commit,mcp__github__get_dependabot_alert,mcp__github__get_discussion,mcp__github__get_discussion_comments,mcp__github__get_file_contents,mcp__github__get_job_logs,mcp__github__get_label,mcp__github__get_latest_release,mcp__github__get_me,mcp__github__get_notification_details,mcp__github__get_pull_request,mcp__github__get_pull_request_comments,mcp__github__get_pull_request_diff,mcp__github__get_pull_request_files,mcp__github__get_pull_request_review_comments,mcp__github__get_pull_request_reviews,mcp__github__get_pull_request_status,mcp__github__get_release_by_tag,mcp__github__get_secret_scanning_alert,mcp__github__get_tag,mcp__github__issue_read,mcp__github__list_branches,mcp__github__list_code_scanning_alerts,mcp__github__list_commits,mcp__github__list_dependabot_alerts,mcp__github__list_discussion_categories,mcp__github__list_discussions,mcp__github__list_issue_types,mcp__github__list_issues,mcp__github__list_label,mcp__github__list_notifications,mcp__github__list_pull_requests,mcp__github__list_releases,mcp__github__list_secret_scanning_alerts,mcp__github__list_starred_repositories,mcp__github__list_tags,mcp__github__pull_request_read,mcp__github__search_code,mcp__github__search_issues,mcp__github__search_orgs,mcp__github__search_pull_requests,mcp__github__search_repositories,mcp__github__search_users,mcp__mcpscripts,mcp__playwright__browser_click,mcp__playwright__browser_close,mcp__playwright__browser_console_messages,mcp__playwright__browser_drag,mcp__playwright__browser_evaluate,mcp__playwright__browser_file_upload,mcp__playwright__browser_fill_form,mcp__playwright__browser_handle_dialog,mcp__playwright__browser_hover,mcp__playwright__browser_install,mcp__playwright__browser_navigate,mcp__playwright__browser_navigate_back,mcp__playwright__browser_network_requests,mcp__playwright__browser_press_key,mcp__playwright__browser_resize,mcp__playwright__browser_select_option,mcp__playwright__browser_snapshot,mcp__playwright__browser_tabs,mcp__playwright__browser_take_screenshot,mcp__playwright__browser_type,mcp__playwright__browser_wait_for,mcp__safeoutputs,mcp__tavily'\'' --debug-file /tmp/gh-aw/agent/claude-debug.log --verbose --permission-mode acceptEdits --output-format stream-json --bare --mcp-config "${RUNNER_TEMP}/gh-aw/mcp-config/mcp-servers.json" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log + -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/claude_harness.cjs claude --print --no-chrome --max-turns 100 --allowed-tools '\''Bash,BashOutput,Edit,Edit(/tmp/*),Edit(/tmp/gh-aw/agent/*),Edit(/tmp/gh-aw/cache-memory/*),ExitPlanMode,Glob,Grep,KillBash,LS,MultiEdit,MultiEdit(/tmp/*),MultiEdit(/tmp/gh-aw/agent/*),MultiEdit(/tmp/gh-aw/cache-memory/*),NotebookEdit,NotebookRead,Read,Read(/tmp/*),Read(/tmp/gh-aw/agent/*),Read(/tmp/gh-aw/cache-memory/*),Task,TodoWrite,Write,Write(/tmp/*),Write(/tmp/gh-aw/agent/*),Write(/tmp/gh-aw/cache-memory/*),mcp__agenticworkflows,mcp__github__actions_get,mcp__github__actions_list,mcp__github__get_code_scanning_alert,mcp__github__get_commit,mcp__github__get_dependabot_alert,mcp__github__get_discussion,mcp__github__get_discussion_comments,mcp__github__get_file_contents,mcp__github__get_job_logs,mcp__github__get_label,mcp__github__get_latest_release,mcp__github__get_me,mcp__github__get_notification_details,mcp__github__get_pull_request,mcp__github__get_pull_request_comments,mcp__github__get_pull_request_diff,mcp__github__get_pull_request_files,mcp__github__get_pull_request_review_comments,mcp__github__get_pull_request_reviews,mcp__github__get_pull_request_status,mcp__github__get_release_by_tag,mcp__github__get_secret_scanning_alert,mcp__github__get_tag,mcp__github__issue_read,mcp__github__list_branches,mcp__github__list_code_scanning_alerts,mcp__github__list_commits,mcp__github__list_dependabot_alerts,mcp__github__list_discussion_categories,mcp__github__list_discussions,mcp__github__list_issue_types,mcp__github__list_issues,mcp__github__list_label,mcp__github__list_notifications,mcp__github__list_pull_requests,mcp__github__list_releases,mcp__github__list_secret_scanning_alerts,mcp__github__list_starred_repositories,mcp__github__list_tags,mcp__github__pull_request_read,mcp__github__search_code,mcp__github__search_issues,mcp__github__search_orgs,mcp__github__search_pull_requests,mcp__github__search_repositories,mcp__github__search_users,mcp__mcpscripts,mcp__playwright__browser_click,mcp__playwright__browser_close,mcp__playwright__browser_console_messages,mcp__playwright__browser_drag,mcp__playwright__browser_evaluate,mcp__playwright__browser_file_upload,mcp__playwright__browser_fill_form,mcp__playwright__browser_handle_dialog,mcp__playwright__browser_hover,mcp__playwright__browser_install,mcp__playwright__browser_navigate,mcp__playwright__browser_navigate_back,mcp__playwright__browser_network_requests,mcp__playwright__browser_press_key,mcp__playwright__browser_resize,mcp__playwright__browser_select_option,mcp__playwright__browser_snapshot,mcp__playwright__browser_tabs,mcp__playwright__browser_take_screenshot,mcp__playwright__browser_type,mcp__playwright__browser_wait_for,mcp__safeoutputs,mcp__tavily'\'' --debug-file /tmp/gh-aw/agent/claude-debug.log --verbose --permission-mode acceptEdits --output-format stream-json --bare --mcp-config "${RUNNER_TEMP}/gh-aw/mcp-config/mcp-servers.json" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log env: ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} ANTHROPIC_MAX_RETRIES: 0 diff --git a/.github/workflows/step-name-alignment.lock.yml b/.github/workflows/step-name-alignment.lock.yml index 79ea464dff2..621b8c694a6 100644 --- a/.github/workflows/step-name-alignment.lock.yml +++ b/.github/workflows/step-name-alignment.lock.yml @@ -871,6 +871,7 @@ jobs: # - Bash(yq*) # - BashOutput # - Edit + # - Edit(/tmp/*) # - Edit(/tmp/gh-aw/agent/*) # - Edit(/tmp/gh-aw/cache-memory/*) # - ExitPlanMode @@ -879,16 +880,19 @@ jobs: # - KillBash # - LS # - MultiEdit + # - MultiEdit(/tmp/*) # - MultiEdit(/tmp/gh-aw/agent/*) # - MultiEdit(/tmp/gh-aw/cache-memory/*) # - NotebookEdit # - NotebookRead # - Read + # - Read(/tmp/*) # - Read(/tmp/gh-aw/agent/*) # - Read(/tmp/gh-aw/cache-memory/*) # - Task # - TodoWrite # - Write + # - Write(/tmp/*) # - Write(/tmp/gh-aw/agent/*) # - Write(/tmp/gh-aw/cache-memory/*) # - mcp__github__actions_get @@ -965,7 +969,7 @@ jobs: fi # shellcheck disable=SC1003,SC2016,SC2086 awf --config "${RUNNER_TEMP}/gh-aw/awf-config.json" --container-workdir "${GITHUB_WORKSPACE}" --mount "${RUNNER_TEMP}/gh-aw:${RUNNER_TEMP}/gh-aw:ro" --mount "${RUNNER_TEMP}/gh-aw:/host${RUNNER_TEMP}/gh-aw:ro" ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} --tty --env-all --exclude-env ACTIONS_ID_TOKEN_REQUEST_TOKEN --exclude-env ACTIONS_ID_TOKEN_REQUEST_URL --exclude-env ANTHROPIC_API_KEY --exclude-env GH_TOKEN --exclude-env GITHUB_MCP_SERVER_TOKEN --exclude-env MCP_GATEWAY_API_KEY --mount /tmp/gh-aw:/tmp/gh-aw:rw --log-level info --skip-pull --difc-proxy-host awmg-cli-proxy:18443 --difc-proxy-ca-cert /tmp/gh-aw/difc-proxy-tls/ca.crt \ - -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/claude_harness.cjs claude --print --no-chrome --max-turns 50 --allowed-tools '\''Bash(cat /tmp/gh-aw/agent/step-alignment-input.json),Bash(cat /tmp/gh-aw/cache-memory/),Bash(cat > /tmp/gh-aw/cache-memory/),Bash(cat docs/src/content/docs/reference/glossary.md),Bash(cat),Bash(date),Bash(echo),Bash(find .github/workflows -name "*.lock.yml" -type f),Bash(gh:*),Bash(git log --since="24 hours ago" --oneline --name-only -- ".github/workflows/*.lock.yml"),Bash(grep),Bash(head),Bash(jq* /tmp/gh-aw/agent/step-alignment-input.json),Bash(ls),Bash(mkdir -p /tmp/gh-aw/cache-memory/),Bash(mv /tmp/gh-aw/cache-memory/),Bash(printf),Bash(pwd),Bash(safeoutputs:*),Bash(sort),Bash(tail),Bash(uniq),Bash(wc),Bash(yq),Bash(yq*),BashOutput,Edit,Edit(/tmp/gh-aw/agent/*),Edit(/tmp/gh-aw/cache-memory/*),ExitPlanMode,Glob,Grep,KillBash,LS,MultiEdit,MultiEdit(/tmp/gh-aw/agent/*),MultiEdit(/tmp/gh-aw/cache-memory/*),NotebookEdit,NotebookRead,Read,Read(/tmp/gh-aw/agent/*),Read(/tmp/gh-aw/cache-memory/*),Task,TodoWrite,Write,Write(/tmp/gh-aw/agent/*),Write(/tmp/gh-aw/cache-memory/*),mcp__github__actions_get,mcp__github__actions_list,mcp__github__get_code_scanning_alert,mcp__github__get_commit,mcp__github__get_dependabot_alert,mcp__github__get_discussion,mcp__github__get_discussion_comments,mcp__github__get_file_contents,mcp__github__get_job_logs,mcp__github__get_label,mcp__github__get_latest_release,mcp__github__get_me,mcp__github__get_notification_details,mcp__github__get_pull_request,mcp__github__get_pull_request_comments,mcp__github__get_pull_request_diff,mcp__github__get_pull_request_files,mcp__github__get_pull_request_review_comments,mcp__github__get_pull_request_reviews,mcp__github__get_pull_request_status,mcp__github__get_release_by_tag,mcp__github__get_secret_scanning_alert,mcp__github__get_tag,mcp__github__issue_read,mcp__github__list_branches,mcp__github__list_code_scanning_alerts,mcp__github__list_commits,mcp__github__list_dependabot_alerts,mcp__github__list_discussion_categories,mcp__github__list_discussions,mcp__github__list_issue_types,mcp__github__list_issues,mcp__github__list_label,mcp__github__list_notifications,mcp__github__list_pull_requests,mcp__github__list_releases,mcp__github__list_secret_scanning_alerts,mcp__github__list_starred_repositories,mcp__github__list_tags,mcp__github__pull_request_read,mcp__github__search_code,mcp__github__search_issues,mcp__github__search_orgs,mcp__github__search_pull_requests,mcp__github__search_repositories,mcp__github__search_users,mcp__safeoutputs'\'' --debug-file /tmp/gh-aw/agent/claude-debug.log --verbose --permission-mode acceptEdits --output-format stream-json --mcp-config "${RUNNER_TEMP}/gh-aw/mcp-config/mcp-servers.json" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt${GH_AW_MODEL_AGENT_CLAUDE:+ --model "$GH_AW_MODEL_AGENT_CLAUDE"}' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log + -- /bin/bash -c 'set +o histexpand; export PATH="${RUNNER_TEMP}/gh-aw/mcp-cli/bin:$PATH" && : "${RUNNER_TOOL_CACHE:?RUNNER_TOOL_CACHE must be set}"; GH_AW_TOOL_CACHE="$RUNNER_TOOL_CACHE"; export PATH="$(find "$GH_AW_TOOL_CACHE" -maxdepth 5 -type d -name bin 2>/dev/null | tr '\''\n'\'' '\'':'\'')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true; [ -n "$ERLANG_HOME" ] && export PATH="$ERLANG_HOME/bin:$PATH" || true && GH_AW_NODE_EXEC="${GH_AW_NODE_BIN:-}"; if [ -z "$GH_AW_NODE_EXEC" ] || [ ! -x "$GH_AW_NODE_EXEC" ]; then GH_AW_NODE_EXEC="$(command -v node 2>/dev/null || true)"; fi; if [ -z "$GH_AW_NODE_EXEC" ]; then echo "node runtime missing on this runner — check runtimes.node in workflow YAML" >&2; exit 127; fi; GH_AW_NPM_GLOBAL_ROOT="$(npm root -g 2>/dev/null || true)"; if [ -n "$GH_AW_NPM_GLOBAL_ROOT" ]; then export NODE_PATH="${GH_AW_NPM_GLOBAL_ROOT}${NODE_PATH:+:${NODE_PATH}}"; fi; "$GH_AW_NODE_EXEC" ${RUNNER_TEMP}/gh-aw/actions/claude_harness.cjs claude --print --no-chrome --max-turns 50 --allowed-tools '\''Bash(cat /tmp/gh-aw/agent/step-alignment-input.json),Bash(cat /tmp/gh-aw/cache-memory/),Bash(cat > /tmp/gh-aw/cache-memory/),Bash(cat docs/src/content/docs/reference/glossary.md),Bash(cat),Bash(date),Bash(echo),Bash(find .github/workflows -name "*.lock.yml" -type f),Bash(gh:*),Bash(git log --since="24 hours ago" --oneline --name-only -- ".github/workflows/*.lock.yml"),Bash(grep),Bash(head),Bash(jq* /tmp/gh-aw/agent/step-alignment-input.json),Bash(ls),Bash(mkdir -p /tmp/gh-aw/cache-memory/),Bash(mv /tmp/gh-aw/cache-memory/),Bash(printf),Bash(pwd),Bash(safeoutputs:*),Bash(sort),Bash(tail),Bash(uniq),Bash(wc),Bash(yq),Bash(yq*),BashOutput,Edit,Edit(/tmp/*),Edit(/tmp/gh-aw/agent/*),Edit(/tmp/gh-aw/cache-memory/*),ExitPlanMode,Glob,Grep,KillBash,LS,MultiEdit,MultiEdit(/tmp/*),MultiEdit(/tmp/gh-aw/agent/*),MultiEdit(/tmp/gh-aw/cache-memory/*),NotebookEdit,NotebookRead,Read,Read(/tmp/*),Read(/tmp/gh-aw/agent/*),Read(/tmp/gh-aw/cache-memory/*),Task,TodoWrite,Write,Write(/tmp/*),Write(/tmp/gh-aw/agent/*),Write(/tmp/gh-aw/cache-memory/*),mcp__github__actions_get,mcp__github__actions_list,mcp__github__get_code_scanning_alert,mcp__github__get_commit,mcp__github__get_dependabot_alert,mcp__github__get_discussion,mcp__github__get_discussion_comments,mcp__github__get_file_contents,mcp__github__get_job_logs,mcp__github__get_label,mcp__github__get_latest_release,mcp__github__get_me,mcp__github__get_notification_details,mcp__github__get_pull_request,mcp__github__get_pull_request_comments,mcp__github__get_pull_request_diff,mcp__github__get_pull_request_files,mcp__github__get_pull_request_review_comments,mcp__github__get_pull_request_reviews,mcp__github__get_pull_request_status,mcp__github__get_release_by_tag,mcp__github__get_secret_scanning_alert,mcp__github__get_tag,mcp__github__issue_read,mcp__github__list_branches,mcp__github__list_code_scanning_alerts,mcp__github__list_commits,mcp__github__list_dependabot_alerts,mcp__github__list_discussion_categories,mcp__github__list_discussions,mcp__github__list_issue_types,mcp__github__list_issues,mcp__github__list_label,mcp__github__list_notifications,mcp__github__list_pull_requests,mcp__github__list_releases,mcp__github__list_secret_scanning_alerts,mcp__github__list_starred_repositories,mcp__github__list_tags,mcp__github__pull_request_read,mcp__github__search_code,mcp__github__search_issues,mcp__github__search_orgs,mcp__github__search_pull_requests,mcp__github__search_repositories,mcp__github__search_users,mcp__safeoutputs'\'' --debug-file /tmp/gh-aw/agent/claude-debug.log --verbose --permission-mode acceptEdits --output-format stream-json --mcp-config "${RUNNER_TEMP}/gh-aw/mcp-config/mcp-servers.json" --prompt-file /tmp/gh-aw/aw-prompts/prompt.txt${GH_AW_MODEL_AGENT_CLAUDE:+ --model "$GH_AW_MODEL_AGENT_CLAUDE"}' 2>&1 | tee -a /tmp/gh-aw/agent-stdio.log env: ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} ANTHROPIC_MAX_RETRIES: 0 From facef8e9f32b79d616eb722b3e69589c7872c704 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 24 Aug 2026 16:50:01 +0000 Subject: [PATCH 5/5] Verify raw MCP repository result Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com> --- .github/workflows/github-remote-mcp-auth-test.lock.yml | 8 +++++++- .github/workflows/github-remote-mcp-auth-test.md | 6 ++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/.github/workflows/github-remote-mcp-auth-test.lock.yml b/.github/workflows/github-remote-mcp-auth-test.lock.yml index e61ded5db4e..298424d2818 100644 --- a/.github/workflows/github-remote-mcp-auth-test.lock.yml +++ b/.github/workflows/github-remote-mcp-auth-test.lock.yml @@ -1,4 +1,4 @@ -# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"835aa876ed88e123c9634e0275b5b4a625a39bcc85dda3760d3a387fe6635a09","body_hash":"56f9950ffdb46afae7ca16c12844a211460e171090d34f04b8cfe4ac9ab2e754","strict":true,"agent_id":"copilot","agent_model":"gpt-4.1","engine_versions":{"copilot":"1.0.80"}} +# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"23c768d340eb1d7e43465f9dc097f91d94cd3b62dd1692e46d796cdce017ad65","body_hash":"56f9950ffdb46afae7ca16c12844a211460e171090d34f04b8cfe4ac9ab2e754","strict":true,"agent_id":"copilot","agent_model":"gpt-4.1","engine_versions":{"copilot":"1.0.80"}} # gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GH_AW_OTEL_GRAFANA_AUTHORIZATION","GH_AW_OTEL_GRAFANA_ENDPOINT","GH_AW_OTEL_SENTRY_AUTHORIZATION","GH_AW_OTEL_SENTRY_ENDPOINT","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache/restore","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/checkout","sha":"3d3c42e5aac5ba805825da76410c181273ba90b1","version":"v7.0.1"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.28.7","digest":"sha256:40a1e30b1b8d70642d4292485146cd5af612730d7a6a2e12706ddd13df375059","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.28.7@sha256:40a1e30b1b8d70642d4292485146cd5af612730d7a6a2e12706ddd13df375059"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.28.7","digest":"sha256:4f209dd4cbc74d47a6c7379956143de293429d1b1b2fb2647776cdcbf65836a1","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.28.7@sha256:4f209dd4cbc74d47a6c7379956143de293429d1b1b2fb2647776cdcbf65836a1"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.28.7","digest":"sha256:fb362a08d4d2f0da6c036e3f5d3b2fd87931e857fec3ca4a241cd2f2b61131f9","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.28.7@sha256:fb362a08d4d2f0da6c036e3f5d3b2fd87931e857fec3ca4a241cd2f2b61131f9"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.10","digest":"sha256:08bb5fa417aed94b40a14e2b7b3ae457531a5f22b143a32fe58317139d9b8f42","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.10@sha256:08bb5fa417aed94b40a14e2b7b3ae457531a5f22b143a32fe58317139d9b8f42"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:bac2192f6374d6262116399b34fc5e143d576f82719e90a18261cae7480f4d4e","pinned_image":"ghcr.io/github/gh-aw-node@sha256:bac2192f6374d6262116399b34fc5e143d576f82719e90a18261cae7480f4d4e"}],"mcp_servers":[{"name":"github","tools":["get_repository","issue_read","list_issues"]},{"name":"safeoutputs","tools":["create_discussion","missing_data","missing_tool","noop"]}]} # This file was automatically generated by gh-aw. DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md # @@ -1802,6 +1802,12 @@ jobs: echo "- ❌ MCP get_repository: tool error \`$tool_error\`" >> "$GITHUB_STEP_SUMMARY" exit 1 fi + repository_content="$(jq -r '[.result.content[]? | select(.type == "text") | .text] | join(" ")' "$json_file")" + if [[ "$repository_content" != *"$GITHUB_REPOSITORY"* ]]; then + echo "MCP get_repository did not return the requested repository." + echo "- ❌ MCP get_repository: result did not identify \`$GITHUB_REPOSITORY\`" >> "$GITHUB_STEP_SUMMARY" + exit 1 + fi echo "- ✅ MCP get_repository: retrieved \`$GITHUB_REPOSITORY\`" >> "$GITHUB_STEP_SUMMARY" echo "Raw GitHub remote MCP handshake succeeded with $tool_count tools available." env: diff --git a/.github/workflows/github-remote-mcp-auth-test.md b/.github/workflows/github-remote-mcp-auth-test.md index 7f37febf7b6..8ddd49f22fd 100644 --- a/.github/workflows/github-remote-mcp-auth-test.md +++ b/.github/workflows/github-remote-mcp-auth-test.md @@ -172,6 +172,12 @@ jobs: echo "- ❌ MCP get_repository: tool error \`$tool_error\`" >> "$GITHUB_STEP_SUMMARY" exit 1 fi + repository_content="$(jq -r '[.result.content[]? | select(.type == "text") | .text] | join(" ")' "$json_file")" + if [[ "$repository_content" != *"$GITHUB_REPOSITORY"* ]]; then + echo "MCP get_repository did not return the requested repository." + echo "- ❌ MCP get_repository: result did not identify \`$GITHUB_REPOSITORY\`" >> "$GITHUB_STEP_SUMMARY" + exit 1 + fi echo "- ✅ MCP get_repository: retrieved \`$GITHUB_REPOSITORY\`" >> "$GITHUB_STEP_SUMMARY" echo "Raw GitHub remote MCP handshake succeeded with $tool_count tools available." features: