diff --git a/.github/workflows/smoke-codex.lock.yml b/.github/workflows/smoke-codex.lock.yml index 4f77b05a37c..f484b97b7e2 100644 --- a/.github/workflows/smoke-codex.lock.yml +++ b/.github/workflows/smoke-codex.lock.yml @@ -28,7 +28,7 @@ # - shared/gh.md # - shared/reporting.md # -# gh-aw-metadata: {"schema_version":"v1","frontmatter_hash":"7d48bac6df7757e4815d5c43bf8bc9072daed18816f793b91d734c6b752705f2"} +# gh-aw-metadata: {"schema_version":"v1","frontmatter_hash":"fbb9ed29477ed621b1c3827b01a8f7bf0052063618b2900bb1e739453a3aa770"} name: "Smoke Codex" "on": @@ -418,7 +418,7 @@ jobs: const determineAutomaticLockdown = require('/opt/gh-aw/actions/determine_automatic_lockdown.cjs'); await determineAutomaticLockdown(github, context, core); - name: Download container images - run: bash /opt/gh-aw/actions/download_docker_images.sh ghcr.io/github/gh-aw-firewall/agent:0.20.2 ghcr.io/github/gh-aw-firewall/api-proxy:0.20.2 ghcr.io/github/gh-aw-firewall/squid:0.20.2 ghcr.io/github/gh-aw-mcpg:v0.1.5 ghcr.io/github/github-mcp-server:v0.31.0 ghcr.io/github/serena-mcp-server:latest mcr.microsoft.com/playwright/mcp node:lts-alpine + run: bash /opt/gh-aw/actions/download_docker_images.sh ghcr.io/github/gh-aw-firewall/agent:0.20.2 ghcr.io/github/gh-aw-firewall/api-proxy:0.20.2 ghcr.io/github/gh-aw-firewall/squid:0.20.2 ghcr.io/github/gh-aw-mcpg:v0.1.5 ghcr.io/github/github-mcp-server:v0.31.0 ghcr.io/github/serena-mcp-server:latest mcp/fetch mcr.microsoft.com/playwright/mcp node:lts-alpine - name: Write Safe Outputs Config run: | mkdir -p /opt/gh-aw/safeoutputs @@ -1091,6 +1091,9 @@ jobs: "${GITHUB_WORKSPACE}" ] mounts = ["${GITHUB_WORKSPACE}:${GITHUB_WORKSPACE}:rw"] + + [mcp_servers."web-fetch"] + container = "mcp/fetch" GH_AW_MCP_CONFIG_EOF # Generate JSON config for MCP gateway @@ -1153,6 +1156,9 @@ jobs: "\${GITHUB_WORKSPACE}" ], "mounts": ["\${GITHUB_WORKSPACE}:\${GITHUB_WORKSPACE}:rw"] + }, + "web-fetch": { + "container": "mcp/fetch" } }, "gateway": { diff --git a/.github/workflows/smoke-codex.md b/.github/workflows/smoke-codex.md index 3862f548b24..3da0d8c2b0a 100644 --- a/.github/workflows/smoke-codex.md +++ b/.github/workflows/smoke-codex.md @@ -33,6 +33,7 @@ tools: serena: languages: go: {} + web-fetch: runtimes: go: version: "1.25" @@ -78,9 +79,10 @@ timeout-minutes: 15 - Use the Serena MCP server tool `activate_project` to initialize the workspace at `${{ github.workspace }}` and verify it succeeds (do NOT use bash to run go commands) - After initialization, use the `find_symbol` tool to search for symbols and verify that at least 3 symbols are found in the results 3. **Playwright Testing**: Use the playwright tools to navigate to https://github.com and verify the page title contains "GitHub" (do NOT try to install playwright - use the provided MCP tools) -4. **File Writing Testing**: Create a test file `/tmp/gh-aw/agent/smoke-test-codex-${{ github.run_id }}.txt` with content "Smoke test passed for Codex at $(date)" (create the directory if it doesn't exist) -5. **Bash Tool Testing**: Execute bash commands to verify file creation was successful (use `cat` to read the file back) -6. **Build gh-aw**: Run `GOCACHE=/tmp/go-cache GOMODCACHE=/tmp/go-mod make build` to verify the agent can successfully build the gh-aw project (both caches must be set to /tmp because the default cache locations are not writable). If the command fails, mark this test as ❌ and report the failure. +4. **Web Fetch Testing**: Use the web-fetch MCP tool to fetch https://github.com and verify the response contains "GitHub" (do NOT use bash or playwright for this test - use the web-fetch MCP tool directly) +5. **File Writing Testing**: Create a test file `/tmp/gh-aw/agent/smoke-test-codex-${{ github.run_id }}.txt` with content "Smoke test passed for Codex at $(date)" (create the directory if it doesn't exist) +6. **Bash Tool Testing**: Execute bash commands to verify file creation was successful (use `cat` to read the file back) +7. **Build gh-aw**: Run `GOCACHE=/tmp/go-cache GOMODCACHE=/tmp/go-mod make build` to verify the agent can successfully build the gh-aw project (both caches must be set to /tmp because the default cache locations are not writable). If the command fails, mark this test as ❌ and report the failure. ## Output diff --git a/.github/workflows/smoke-copilot.md b/.github/workflows/smoke-copilot.md index cda289dab9b..ce3ce7f9cc6 100644 --- a/.github/workflows/smoke-copilot.md +++ b/.github/workflows/smoke-copilot.md @@ -122,16 +122,17 @@ strict: true - Use the Serena MCP server tool `activate_project` to initialize the workspace at `${{ github.workspace }}` and verify it succeeds (do NOT use bash to run go commands - use Serena's MCP tools) - After initialization, use the `find_symbol` tool to search for symbols (find which tool to call) and verify that at least 3 symbols are found in the results 4. **Playwright Testing**: Use the playwright tools to navigate to and verify the page title contains "GitHub" (do NOT try to install playwright - use the provided MCP tools) -5. **File Writing Testing**: Create a test file `/tmp/gh-aw/agent/smoke-test-copilot-${{ github.run_id }}.txt` with content "Smoke test passed for Copilot at $(date)" (create the directory if it doesn't exist) -6. **Bash Tool Testing**: Execute bash commands to verify file creation was successful (use `cat` to read the file back) -7. **Discussion Interaction Testing**: +5. **Web Fetch Testing**: Use the web-fetch tool to fetch https://github.com and verify the response contains "GitHub" (do NOT use bash or playwright for this test - use the web-fetch tool directly) +6. **File Writing Testing**: Create a test file `/tmp/gh-aw/agent/smoke-test-copilot-${{ github.run_id }}.txt` with content "Smoke test passed for Copilot at $(date)" (create the directory if it doesn't exist) +7. **Bash Tool Testing**: Execute bash commands to verify file creation was successful (use `cat` to read the file back) +8. **Discussion Interaction Testing**: - Use the `github-discussion-query` safe-input tool with params: `limit=1, jq=".[0]"` to get the latest discussion from ${{ github.repository }} - Extract the discussion number from the result (e.g., if the result is `{"number": 123, "title": "...", ...}`, extract 123) - Use the `add_comment` tool with `discussion_number: ` to add a fun, playful comment stating that the smoke test agent was here -8. **Build gh-aw**: Run `GOCACHE=/tmp/go-cache GOMODCACHE=/tmp/go-mod make build` to verify the agent can successfully build the gh-aw project (both caches must be set to /tmp because the default cache locations are not writable). If the command fails, mark this test as ❌ and report the failure. -9. **Discussion Creation Testing**: Use the `create_discussion` safe-output tool to create a discussion in the announcements category titled "copilot was here" with the label "ai-generated" -10. **Workflow Dispatch Testing**: Use the `dispatch_workflow` safe output tool to trigger the `haiku-printer` workflow with a haiku as the message input. Create an original, creative haiku about software testing or automation. -11. **PR Review Testing**: Review the diff of the current pull request. Leave 1-2 inline `create_pull_request_review_comment` comments on specific lines, then call `submit_pull_request_review` with a brief body summarizing your review and event `COMMENT`. +9. **Build gh-aw**: Run `GOCACHE=/tmp/go-cache GOMODCACHE=/tmp/go-mod make build` to verify the agent can successfully build the gh-aw project (both caches must be set to /tmp because the default cache locations are not writable). If the command fails, mark this test as ❌ and report the failure. +10. **Discussion Creation Testing**: Use the `create_discussion` safe-output tool to create a discussion in the announcements category titled "copilot was here" with the label "ai-generated" +11. **Workflow Dispatch Testing**: Use the `dispatch_workflow` safe output tool to trigger the `haiku-printer` workflow with a haiku as the message input. Create an original, creative haiku about software testing or automation. +12. **PR Review Testing**: Review the diff of the current pull request. Leave 1-2 inline `create_pull_request_review_comment` comments on specific lines, then call `submit_pull_request_review` with a brief body summarizing your review and event `COMMENT`. ## Output @@ -150,7 +151,7 @@ strict: true - Overall status: PASS or FAIL - Mention the pull request author and any assignees -3. Use the `add_comment` tool to add a **fun and creative comment** to the latest discussion (using the `discussion_number` you extracted in step 7) - be playful and entertaining in your comment +3. Use the `add_comment` tool to add a **fun and creative comment** to the latest discussion (using the `discussion_number` you extracted in step 8) - be playful and entertaining in your comment 4. Use the `send_slack_message` tool to send a brief summary message (e.g., "Smoke test ${{ github.run_id }}: All tests passed! ✅") diff --git a/.github/workflows/smoke-gemini.lock.yml b/.github/workflows/smoke-gemini.lock.yml index a8e8042f250..127409c822c 100644 --- a/.github/workflows/smoke-gemini.lock.yml +++ b/.github/workflows/smoke-gemini.lock.yml @@ -28,7 +28,7 @@ # - shared/gh.md # - shared/reporting.md # -# gh-aw-metadata: {"schema_version":"v1","frontmatter_hash":"c1cc854ca4445238a9a3d11e58860d2a8930fdfa740d6380d512db7b4b7e64bb"} +# gh-aw-metadata: {"schema_version":"v1","frontmatter_hash":"95345f5bec2e20786d333877824bb16c47b438ecab2077f421fe38aeb01123d4"} name: "Smoke Gemini" "on": @@ -409,7 +409,7 @@ jobs: const determineAutomaticLockdown = require('/opt/gh-aw/actions/determine_automatic_lockdown.cjs'); await determineAutomaticLockdown(github, context, core); - name: Download container images - run: bash /opt/gh-aw/actions/download_docker_images.sh ghcr.io/github/gh-aw-firewall/agent:0.20.2 ghcr.io/github/gh-aw-firewall/api-proxy:0.20.2 ghcr.io/github/gh-aw-firewall/squid:0.20.2 ghcr.io/github/gh-aw-mcpg:v0.1.5 ghcr.io/github/github-mcp-server:v0.31.0 node:lts-alpine + run: bash /opt/gh-aw/actions/download_docker_images.sh ghcr.io/github/gh-aw-firewall/agent:0.20.2 ghcr.io/github/gh-aw-firewall/api-proxy:0.20.2 ghcr.io/github/gh-aw-firewall/squid:0.20.2 ghcr.io/github/gh-aw-mcpg:v0.1.5 ghcr.io/github/github-mcp-server:v0.31.0 mcp/fetch node:lts-alpine - name: Write Safe Outputs Config run: | mkdir -p /opt/gh-aw/safeoutputs @@ -898,6 +898,9 @@ jobs: "headers": { "Authorization": "$GH_AW_SAFE_OUTPUTS_API_KEY" } + }, + "web-fetch": { + "container": "mcp/fetch" } }, "gateway": { diff --git a/.github/workflows/smoke-gemini.md b/.github/workflows/smoke-gemini.md index cbd78128a55..1154f57445c 100644 --- a/.github/workflows/smoke-gemini.md +++ b/.github/workflows/smoke-gemini.md @@ -30,6 +30,7 @@ tools: edit: bash: - "*" + web-fetch: safe-outputs: add-comment: hide-older-comments: true @@ -58,9 +59,10 @@ timeout-minutes: 10 ## Test Requirements 1. **GitHub MCP Testing**: Use GitHub MCP tools to fetch details of exactly 2 merged pull requests from ${{ github.repository }} (title and number only) -2. **File Writing Testing**: Create a test file `/tmp/gh-aw/agent/smoke-test-gemini-${{ github.run_id }}.txt` with content "Smoke test passed for Gemini at $(date)" (create the directory if it doesn't exist) -3. **Bash Tool Testing**: Execute bash commands to verify file creation was successful (use `cat` to read the file back) -4. **Build gh-aw**: Run `GOCACHE=/tmp/go-cache GOMODCACHE=/tmp/go-mod make build` to verify the agent can successfully build the gh-aw project. If the command fails, mark this test as ❌ and report the failure. +2. **Web Fetch Testing**: Use the web-fetch MCP tool to fetch https://github.com and verify the response contains "GitHub" (do NOT use bash or playwright for this test - use the web-fetch MCP tool directly) +3. **File Writing Testing**: Create a test file `/tmp/gh-aw/agent/smoke-test-gemini-${{ github.run_id }}.txt` with content "Smoke test passed for Gemini at $(date)" (create the directory if it doesn't exist) +4. **Bash Tool Testing**: Execute bash commands to verify file creation was successful (use `cat` to read the file back) +5. **Build gh-aw**: Run `GOCACHE=/tmp/go-cache GOMODCACHE=/tmp/go-mod make build` to verify the agent can successfully build the gh-aw project. If the command fails, mark this test as ❌ and report the failure. ## Output diff --git a/pkg/workflow/fetch.go b/pkg/workflow/fetch.go index 8b82a6a55b4..b92d2c8a8d4 100644 --- a/pkg/workflow/fetch.go +++ b/pkg/workflow/fetch.go @@ -59,16 +59,9 @@ func renderMCPFetchServerConfig(yaml *strings.Builder, format string, indent str switch format { case "json": // JSON format (for Claude, Copilot, Custom engines) + // Use container key per MCP Gateway schema (container-based stdio server) yaml.WriteString(indent + "\"web-fetch\": {\n") - yaml.WriteString(indent + " \"command\": \"docker\",\n") - yaml.WriteString(indent + " \"args\": [\n") - yaml.WriteString(indent + " \"run\",\n") - yaml.WriteString(indent + " \"-i\",\n") - yaml.WriteString(indent + " \"--rm\",\n") - yaml.WriteString(indent + " \"mcp/fetch\"\n") - yaml.WriteString(indent + " ]\n") - // Note: tools field is NOT included here - the converter script adds it back - // for Copilot. This keeps the gateway config compatible with the schema. + yaml.WriteString(indent + " \"container\": \"mcp/fetch\"\n") if isLast { yaml.WriteString(indent + "}\n") } else { @@ -76,14 +69,9 @@ func renderMCPFetchServerConfig(yaml *strings.Builder, format string, indent str } case "toml": // TOML format (for Codex engine) + // Use container key per MCP Gateway schema (container-based stdio server) yaml.WriteString(indent + "\n") yaml.WriteString(indent + "[mcp_servers.\"web-fetch\"]\n") - yaml.WriteString(indent + "command = \"docker\"\n") - yaml.WriteString(indent + "args = [\n") - yaml.WriteString(indent + " \"run\",\n") - yaml.WriteString(indent + " \"-i\",\n") - yaml.WriteString(indent + " \"--rm\",\n") - yaml.WriteString(indent + " \"mcp/fetch\"\n") - yaml.WriteString(indent + "]\n") + yaml.WriteString(indent + "container = \"mcp/fetch\"\n") } } diff --git a/pkg/workflow/fetch_integration_test.go b/pkg/workflow/fetch_integration_test.go index 97cc76f1eed..832a0244856 100644 --- a/pkg/workflow/fetch_integration_test.go +++ b/pkg/workflow/fetch_integration_test.go @@ -65,14 +65,9 @@ Fetch content from the web. t.Errorf("Expected compiled workflow to contain web-fetch MCP server configuration, but it didn't") } - // Verify the Docker command is present - if !strings.Contains(lockContent, `"mcp/fetch"`) { - t.Errorf("Expected web-fetch MCP server to use the mcp/fetch Docker image, but it didn't") - } - - // Verify that the MCP server is configured with Docker - if !strings.Contains(lockContent, `command = "docker"`) { - t.Errorf("Expected web-fetch MCP server to have Docker command") + // Verify the container image is present (MCP Gateway schema: container key) + if !strings.Contains(lockContent, `container = "mcp/fetch"`) { + t.Errorf("Expected web-fetch MCP server to use the mcp/fetch container image, but it didn't") } } @@ -124,13 +119,13 @@ Fetch content from the web. lockContent := string(lockData) // Claude uses JSON format, check that web-fetch is NOT configured as an MCP server - // Look for the MCP server configuration pattern with "command": "docker" + // Look for the MCP server configuration pattern with "container": "mcp/fetch" // We can't simply search for "web-fetch" because Claude will have it in the allowed tools - if strings.Contains(lockContent, `"web-fetch": {`) && strings.Contains(lockContent, `"command": "docker"`) { + if strings.Contains(lockContent, `"web-fetch": {`) && strings.Contains(lockContent, `"container": "mcp/fetch"`) { // Check if both appear close together (indicating MCP server config) - dockerIdx := strings.Index(lockContent, `"command": "docker"`) + containerIdx := strings.Index(lockContent, `"container": "mcp/fetch"`) webFetchIdx := strings.Index(lockContent, `"web-fetch": {`) - if dockerIdx > 0 && webFetchIdx > 0 && dockerIdx-webFetchIdx < 200 { + if containerIdx > 0 && webFetchIdx > 0 && containerIdx-webFetchIdx < 200 { t.Errorf("Expected Claude workflow NOT to contain web-fetch MCP server (since Claude has native web-fetch support), but it did") } } @@ -194,10 +189,10 @@ Fetch content from the web. } // Also check for JSON format MCP server config - if strings.Contains(lockContent, `"web-fetch": {`) && strings.Contains(lockContent, `"command": "docker"`) { - dockerIdx := strings.Index(lockContent, `"command": "docker"`) + if strings.Contains(lockContent, `"web-fetch": {`) && strings.Contains(lockContent, `"container": "mcp/fetch"`) { + containerIdx := strings.Index(lockContent, `"container": "mcp/fetch"`) webFetchIdx := strings.Index(lockContent, `"web-fetch": {`) - if dockerIdx > 0 && webFetchIdx > 0 && dockerIdx-webFetchIdx < 200 { + if containerIdx > 0 && webFetchIdx > 0 && containerIdx-webFetchIdx < 200 { t.Errorf("Expected Copilot workflow NOT to contain web-fetch MCP server, but it did") } } diff --git a/pkg/workflow/fetch_test.go b/pkg/workflow/fetch_test.go index f79e461cc31..8a12f10311e 100644 --- a/pkg/workflow/fetch_test.go +++ b/pkg/workflow/fetch_test.go @@ -132,8 +132,7 @@ func TestRenderMCPFetchServerConfig(t *testing.T) { includeTools: false, expectSubstr: []string{ `"web-fetch": {`, - `"command": "docker"`, - `"mcp/fetch"`, + `"container": "mcp/fetch"`, `},`, }, }, @@ -145,8 +144,7 @@ func TestRenderMCPFetchServerConfig(t *testing.T) { includeTools: false, expectSubstr: []string{ `"web-fetch": {`, - `"command": "docker"`, - `"mcp/fetch"`, + `"container": "mcp/fetch"`, `}`, // No comma }, }, @@ -158,8 +156,7 @@ func TestRenderMCPFetchServerConfig(t *testing.T) { includeTools: true, expectSubstr: []string{ `"web-fetch": {`, - `"command": "docker"`, - `"mcp/fetch"`, + `"container": "mcp/fetch"`, `},`, }, }, @@ -171,8 +168,7 @@ func TestRenderMCPFetchServerConfig(t *testing.T) { includeTools: true, expectSubstr: []string{ `"web-fetch": {`, - `"command": "docker"`, - `"mcp/fetch"`, + `"container": "mcp/fetch"`, `}`, // No comma }, }, @@ -184,8 +180,7 @@ func TestRenderMCPFetchServerConfig(t *testing.T) { includeTools: false, expectSubstr: []string{ `[mcp_servers."web-fetch"]`, - `command = "docker"`, - `"mcp/fetch"`, + `container = "mcp/fetch"`, }, }, } diff --git a/smoke-test-claude-22292196576.md b/smoke-test-claude-22292196576.md new file mode 100644 index 00000000000..d439147f58d --- /dev/null +++ b/smoke-test-claude-22292196576.md @@ -0,0 +1 @@ +Smoke test file - Run 22292196576