From 1782612e6f855376e6f80d3438d7abc412f6e4ea Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 13 Jan 2026 02:44:36 +0000 Subject: [PATCH 1/7] Initial plan From c57d2b5eb9a21a5b7cc6f37df0e356471f4b9e9a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 13 Jan 2026 02:55:52 +0000 Subject: [PATCH 2/7] Update Serena to use uvx with HTTP transport - Modified MCP config rendering to use HTTP URL (http://localhost:9121) - Added runtime dependency detection for Serena languages - Created language-to-runtime mapping for supported languages - Added uvx startup step with HTTP server - Updated tests to reflect HTTP-based configuration - All Serena tests passing Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- pkg/workflow/importable_tools_test.go | 39 +++--- pkg/workflow/mcp-config.go | 49 +------- pkg/workflow/mcp_config_comprehensive_test.go | 36 +++--- pkg/workflow/mcp_renderer.go | 34 +----- pkg/workflow/mcp_servers.go | 62 ++++++++++ pkg/workflow/runtime_detection.go | 115 +++++++++++++++++- 6 files changed, 227 insertions(+), 108 deletions(-) diff --git a/pkg/workflow/importable_tools_test.go b/pkg/workflow/importable_tools_test.go index edf29a89034..c82ecd2eb89 100644 --- a/pkg/workflow/importable_tools_test.go +++ b/pkg/workflow/importable_tools_test.go @@ -153,13 +153,19 @@ Uses imported serena tool. t.Error("Expected compiled workflow to contain serena tool") } - // Verify serena container (now using Docker instead of uvx) - if !strings.Contains(workflowData, "ghcr.io/oraios/serena:latest") { - t.Error("Expected compiled workflow to contain serena Docker container") + // Verify serena HTTP server setup (now using uvx with HTTP transport) + if !strings.Contains(workflowData, "Start Serena MCP HTTP Server") { + t.Error("Expected compiled workflow to contain Serena HTTP server startup step") + } + if !strings.Contains(workflowData, "uvx --from git+https://github.com/oraios/serena") { + t.Error("Expected compiled workflow to use uvx to start Serena") + } + if !strings.Contains(workflowData, "http://localhost:9121") { + t.Error("Expected compiled workflow to contain Serena HTTP URL") } - // Verify that language service setup steps are NOT present - // since Serena now runs in a container with language services included + // Verify that language service setup steps ARE present + // since Serena now runs with uvx on the host and needs language runtimes if strings.Contains(workflowData, "Install Go language service") { t.Error("Did not expect Go language service installation step (Serena runs in container)") } @@ -318,8 +324,8 @@ Uses all imported tools. if !strings.Contains(workflowData, "mcr.microsoft.com/playwright/mcp") { t.Error("Expected compiled workflow to contain playwright Docker image") } - if !strings.Contains(workflowData, "ghcr.io/oraios/serena:latest") { - t.Error("Expected compiled workflow to contain serena Docker container") + if !strings.Contains(workflowData, "http://localhost:9121") { + t.Error("Expected compiled workflow to contain Serena HTTP URL") } if !strings.Contains(workflowData, "example.com") { t.Error("Expected compiled workflow to contain example.com domain for playwright") @@ -391,19 +397,18 @@ Uses imported serena with language config. t.Error("Expected compiled workflow to contain serena tool") } - // Verify that language runtime setup steps are NOT present - // since Serena now runs in a container with language services included - if strings.Contains(workflowData, "Setup Go") { - t.Error("Did not expect Go setup step (Serena runs in container)") + // Verify that runtime setup steps ARE present for Serena languages + // since Serena now runs with uvx on the host and needs language runtimes + if !strings.Contains(workflowData, "Setup Go") { + t.Error("Expected Go setup step (Serena needs Go runtime)") } - - if strings.Contains(workflowData, "Setup Node.js") { - t.Error("Did not expect Node.js setup step (Serena runs in container)") + if !strings.Contains(workflowData, "Setup Node.js") { + t.Error("Expected Node.js setup step (Serena needs Node for TypeScript)") } - // Verify serena container is present - if !strings.Contains(workflowData, "ghcr.io/oraios/serena") { - t.Error("Expected serena to use Docker container") + // Verify serena HTTP server is started with uvx + if !strings.Contains(workflowData, "uvx --from git+https://github.com/oraios/serena") { + t.Error("Expected serena to use uvx for HTTP server") } } diff --git a/pkg/workflow/mcp-config.go b/pkg/workflow/mcp-config.go index eb1851ef586..792826b06ad 100644 --- a/pkg/workflow/mcp-config.go +++ b/pkg/workflow/mcp-config.go @@ -146,55 +146,18 @@ func renderPlaywrightMCPConfigWithOptions(yaml *strings.Builder, playwrightTool } // renderSerenaMCPConfigWithOptions generates the Serena MCP server configuration with engine-specific options -// Per MCP Gateway Specification v1.0.0 section 3.2.1, stdio-based MCP servers MUST be containerized. -// Uses Docker container format as specified by Serena: ghcr.io/oraios/serena:latest +// Serena now runs using uvx with HTTP transport in the agent job (not containerized) +// The HTTP server is started in a background step and accessed via http://localhost:9121 func renderSerenaMCPConfigWithOptions(yaml *strings.Builder, serenaTool any, isLast bool, includeCopilotFields bool, inlineArgs bool) { - customArgs := getSerenaCustomArgs(serenaTool) - yaml.WriteString(" \"serena\": {\n") - // Add type field for Copilot (per MCP Gateway Specification v1.0.0, use "stdio" for containerized servers) + // Add type field for Copilot (HTTP transport) if includeCopilotFields { - yaml.WriteString(" \"type\": \"stdio\",\n") - } - - // Use Serena's Docker container image - yaml.WriteString(" \"container\": \"ghcr.io/oraios/serena:latest\",\n") - - // Docker runtime args (--network host for network access) - if inlineArgs { - yaml.WriteString(" \"args\": [\"--network\", \"host\"],\n") - } else { - yaml.WriteString(" \"args\": [\n") - yaml.WriteString(" \"--network\",\n") - yaml.WriteString(" \"host\"\n") - yaml.WriteString(" ],\n") - } - - // Serena entrypoint - yaml.WriteString(" \"entrypoint\": \"serena\",\n") - - // Entrypoint args for Serena MCP server - if inlineArgs { - yaml.WriteString(" \"entrypointArgs\": [\"start-mcp-server\", \"--context\", \"codex\", \"--project\", \"${{ github.workspace }}\"") - // Append custom args if present - writeArgsToYAMLInline(yaml, customArgs) - yaml.WriteString("],\n") - } else { - yaml.WriteString(" \"entrypointArgs\": [\n") - yaml.WriteString(" \"start-mcp-server\",\n") - yaml.WriteString(" \"--context\",\n") - yaml.WriteString(" \"codex\",\n") - yaml.WriteString(" \"--project\",\n") - yaml.WriteString(" \"${{ github.workspace }}\"") - // Append custom args if present - writeArgsToYAML(yaml, customArgs, " ") - yaml.WriteString("\n") - yaml.WriteString(" ],\n") + yaml.WriteString(" \"type\": \"http\",\n") } - // Add volume mount for workspace access - yaml.WriteString(" \"mounts\": [\"${{ github.workspace }}:${{ github.workspace }}:rw\"]\n") + // HTTP URL for Serena MCP server running on host + yaml.WriteString(" \"url\": \"http://localhost:9121\"\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. diff --git a/pkg/workflow/mcp_config_comprehensive_test.go b/pkg/workflow/mcp_config_comprehensive_test.go index 12c2aa8f57e..e896758fb5d 100644 --- a/pkg/workflow/mcp_config_comprehensive_test.go +++ b/pkg/workflow/mcp_config_comprehensive_test.go @@ -574,15 +574,15 @@ func TestRenderSerenaMCPConfigWithOptions(t *testing.T) { inlineArgs: false, expectedContent: []string{ `"serena": {`, - `"container": "ghcr.io/oraios/serena:latest"`, - `"entrypoint": "serena"`, - `"entrypointArgs"`, - `"start-mcp-server"`, + `"url": "http://localhost:9121"`, ` },`, }, unexpectedContent: []string{ `"type"`, `"tools"`, + `"container"`, + `"entrypoint"`, + `"entrypointArgs"`, }, }, { @@ -593,12 +593,13 @@ func TestRenderSerenaMCPConfigWithOptions(t *testing.T) { inlineArgs: false, expectedContent: []string{ `"serena": {`, - `"container": "ghcr.io/oraios/serena:latest"`, + `"url": "http://localhost:9121"`, ` }`, }, unexpectedContent: []string{ `"type"`, `"tools"`, + `"container"`, ` },`, }, }, @@ -610,10 +611,12 @@ func TestRenderSerenaMCPConfigWithOptions(t *testing.T) { inlineArgs: false, expectedContent: []string{ `"serena": {`, - `"type": "stdio"`, - `"container": "ghcr.io/oraios/serena:latest"`, + `"type": "http"`, + `"url": "http://localhost:9121"`, + }, + unexpectedContent: []string{ + `"container"`, }, - unexpectedContent: []string{}, }, { name: "Serena config with inline args format", @@ -623,11 +626,13 @@ func TestRenderSerenaMCPConfigWithOptions(t *testing.T) { inlineArgs: true, expectedContent: []string{ `"serena": {`, - `"type": "stdio"`, - `"container": "ghcr.io/oraios/serena:latest"`, - `"entrypointArgs": ["start-mcp-server", "--context", "codex", "--project", "${{ github.workspace }}"]`, + `"type": "http"`, + `"url": "http://localhost:9121"`, + }, + unexpectedContent: []string{ + `"container"`, + `"entrypointArgs"`, }, - unexpectedContent: []string{}, }, { name: "Serena config with custom args", @@ -639,11 +644,14 @@ func TestRenderSerenaMCPConfigWithOptions(t *testing.T) { inlineArgs: false, expectedContent: []string{ `"serena": {`, - `"container": "ghcr.io/oraios/serena:latest"`, + `"url": "http://localhost:9121"`, + }, + unexpectedContent: []string{ + `"container"`, + // Note: custom args are now used in the startup step, not in MCP config `"--verbose"`, `"--debug"`, }, - unexpectedContent: []string{}, }, } diff --git a/pkg/workflow/mcp_renderer.go b/pkg/workflow/mcp_renderer.go index e93f445dfb4..2cce44fb0e0 100644 --- a/pkg/workflow/mcp_renderer.go +++ b/pkg/workflow/mcp_renderer.go @@ -185,40 +185,12 @@ func (r *MCPConfigRendererUnified) RenderSerenaMCP(yaml *strings.Builder, serena } // renderSerenaTOML generates Serena MCP configuration in TOML format -// Per MCP Gateway Specification v1.0.0 section 3.2.1, stdio-based MCP servers MUST be containerized. -// Uses Docker container format as specified by Serena: ghcr.io/oraios/serena:latest +// Serena now runs using uvx with HTTP transport in the agent job (not containerized) +// The HTTP server is started in a background step and accessed via http://localhost:9121 func (r *MCPConfigRendererUnified) renderSerenaTOML(yaml *strings.Builder, serenaTool any) { - customArgs := getSerenaCustomArgs(serenaTool) - yaml.WriteString(" \n") yaml.WriteString(" [mcp_servers.serena]\n") - yaml.WriteString(" container = \"ghcr.io/oraios/serena:latest\"\n") - - // Docker runtime args (--network host for network access) - yaml.WriteString(" args = [\n") - yaml.WriteString(" \"--network\",\n") - yaml.WriteString(" \"host\",\n") - yaml.WriteString(" ]\n") - - // Serena entrypoint - yaml.WriteString(" entrypoint = \"serena\"\n") - - // Entrypoint args for Serena MCP server - yaml.WriteString(" entrypointArgs = [\n") - yaml.WriteString(" \"start-mcp-server\",\n") - yaml.WriteString(" \"--context\",\n") - yaml.WriteString(" \"codex\",\n") - yaml.WriteString(" \"--project\",\n") - yaml.WriteString(" \"${{ github.workspace }}\"") - - // Append custom args if present - writeArgsToYAML(yaml, customArgs, " ") - - yaml.WriteString("\n") - yaml.WriteString(" ]\n") - - // Add volume mount for workspace access - yaml.WriteString(" mounts = [\"${{ github.workspace }}:${{ github.workspace }}:rw\"]\n") + yaml.WriteString(" url = \"http://localhost:9121\"\n") } // RenderSafeOutputsMCP generates the Safe Outputs MCP server configuration diff --git a/pkg/workflow/mcp_servers.go b/pkg/workflow/mcp_servers.go index 1cb84a42e9b..a49d3828777 100644 --- a/pkg/workflow/mcp_servers.go +++ b/pkg/workflow/mcp_servers.go @@ -442,6 +442,68 @@ func (c *Compiler) generateMCPSetup(yaml *strings.Builder, tools map[string]any, yaml.WriteString(" \n") } + // Start Serena MCP HTTP server if serena tool is enabled + hasSerena := false + for _, toolName := range mcpTools { + if toolName == "serena" { + hasSerena = true + break + } + } + if hasSerena { + // Get Serena tool configuration for custom args + serenaTool := tools["serena"] + customArgs := getSerenaCustomArgs(serenaTool) + + yaml.WriteString(" - name: Start Serena MCP HTTP Server\n") + yaml.WriteString(" id: serena-start\n") + yaml.WriteString(" run: |\n") + yaml.WriteString(" set -eo pipefail\n") + yaml.WriteString(" mkdir -p /tmp/gh-aw/mcp-logs/serena\n") + yaml.WriteString(" \n") + yaml.WriteString(" echo \"Starting Serena MCP HTTP server on port 9121...\"\n") + yaml.WriteString(" \n") + yaml.WriteString(" # Start Serena MCP server in background with uvx\n") + yaml.WriteString(" uvx --from git+https://github.com/oraios/serena \\\n") + yaml.WriteString(" serena start-mcp-server \\\n") + yaml.WriteString(" --transport streamable-http \\\n") + yaml.WriteString(" --port 9121 \\\n") + yaml.WriteString(" --project \"${{ github.workspace }}\"") + + // Append custom args if present + if len(customArgs) > 0 { + yaml.WriteString(" \\\n") + for i, arg := range customArgs { + yaml.WriteString(" " + arg) + if i < len(customArgs)-1 { + yaml.WriteString(" \\\n") + } + } + } + yaml.WriteString(" \\\n") + yaml.WriteString(" > /tmp/gh-aw/mcp-logs/serena/server.log 2>&1 &\n") + yaml.WriteString(" \n") + yaml.WriteString(" # Save PID for potential cleanup\n") + yaml.WriteString(" echo $! > /tmp/gh-aw/serena-mcp-server.pid\n") + yaml.WriteString(" \n") + yaml.WriteString(" # Wait for server to start (max 30 seconds)\n") + yaml.WriteString(" echo \"Waiting for Serena MCP server to start...\"\n") + yaml.WriteString(" for i in {1..30}; do\n") + yaml.WriteString(" if curl -s http://localhost:9121/health > /dev/null 2>&1; then\n") + yaml.WriteString(" echo \"Serena MCP server is ready\"\n") + yaml.WriteString(" break\n") + yaml.WriteString(" fi\n") + yaml.WriteString(" if [ $i -eq 30 ]; then\n") + yaml.WriteString(" echo \"ERROR: Serena MCP server failed to start within 30 seconds\"\n") + yaml.WriteString(" echo \"Server logs:\"\n") + yaml.WriteString(" cat /tmp/gh-aw/mcp-logs/serena/server.log || true\n") + yaml.WriteString(" exit 1\n") + yaml.WriteString(" fi\n") + yaml.WriteString(" sleep 1\n") + yaml.WriteString(" done\n") + yaml.WriteString(" \n") + } + // Skip gateway setup if sandbox is disabled // When sandbox: false, MCP servers are configured without the gateway if !isSandboxDisabled(workflowData) { diff --git a/pkg/workflow/runtime_detection.go b/pkg/workflow/runtime_detection.go index a45fb6cd02e..b4384d4ad12 100644 --- a/pkg/workflow/runtime_detection.go +++ b/pkg/workflow/runtime_detection.go @@ -24,6 +24,11 @@ func DetectRuntimeRequirements(workflowData *WorkflowData) []RuntimeRequirement detectFromMCPConfigs(workflowData.ParsedTools, requirements) } + // Detect from Serena language configuration + if workflowData.ParsedTools != nil && workflowData.ParsedTools.Serena != nil { + detectFromSerenaLanguages(workflowData.ParsedTools.Serena, requirements) + } + // Detect from engine requirements if workflowData.EngineConfig != nil && len(workflowData.EngineConfig.Steps) > 0 { detectFromEngineSteps(workflowData.EngineConfig.Steps, requirements) @@ -129,9 +134,6 @@ func detectFromMCPConfigs(tools *ToolsConfig, requirements map[string]*RuntimeRe allTools := tools.ToMap() log.Printf("Scanning %d MCP configurations for runtime commands", len(allTools)) - // Note: Serena and other built-in MCP servers now run in containers and do not - // require runtime detection. Language services are provided inside the containers. - // Scan custom MCP tools for runtime commands // Skip containerized MCP servers as they don't need host runtime setup for _, tool := range tools.Custom { @@ -150,6 +152,113 @@ func detectFromMCPConfigs(tools *ToolsConfig, requirements map[string]*RuntimeRe } } +// detectFromSerenaLanguages detects runtime requirements based on Serena language configuration +// Serena now runs using uvx with HTTP transport in the agent job, requiring language runtimes +// to be installed on the host system +func detectFromSerenaLanguages(serenaConfig *SerenaToolConfig, requirements map[string]*RuntimeRequirement) { + if serenaConfig == nil { + return + } + + // uvx is always required to run Serena + uvRuntime := findRuntimeByID("uv") + if uvRuntime != nil { + runtimeSetupLog.Print("Serena detected, adding uv runtime requirement") + updateRequiredRuntime(uvRuntime, "", requirements) + } + + // Map to track which languages we need to process + languagesToProcess := make(map[string]string) // language name -> version + + // Check short syntax (array of language names) + if len(serenaConfig.ShortSyntax) > 0 { + runtimeSetupLog.Printf("Detecting runtimes from Serena short syntax: %v", serenaConfig.ShortSyntax) + for _, lang := range serenaConfig.ShortSyntax { + languagesToProcess[lang] = "" // No version specified in short syntax + } + } + + // Check long syntax (detailed language configuration) + if len(serenaConfig.Languages) > 0 { + runtimeSetupLog.Printf("Detecting runtimes from Serena long syntax: %d languages", len(serenaConfig.Languages)) + for lang, langConfig := range serenaConfig.Languages { + version := "" + if langConfig != nil && langConfig.Version != "" { + version = langConfig.Version + } + languagesToProcess[lang] = version + } + } + + // Map Serena languages to runtime IDs and add requirements + for lang, version := range languagesToProcess { + runtimeID := mapSerenaLanguageToRuntime(lang) + if runtimeID == "" { + // Language doesn't map to a known runtime (e.g., bash, markdown, yaml) + runtimeSetupLog.Printf("Skipping Serena language '%s' - no runtime mapping", lang) + continue + } + + runtime := findRuntimeByID(runtimeID) + if runtime != nil { + runtimeSetupLog.Printf("Adding runtime requirement for Serena language '%s' -> %s (version=%s)", lang, runtimeID, version) + updateRequiredRuntime(runtime, version, requirements) + } + } +} + +// mapSerenaLanguageToRuntime maps a Serena language identifier to a runtime ID +// Returns empty string if the language doesn't require a runtime setup +func mapSerenaLanguageToRuntime(serenaLang string) string { + // Mapping based on .serena/project.yml language list and available runtimes + languageMap := map[string]string{ + // Direct mappings + "go": "go", + "typescript": "node", // JavaScript/TypeScript use Node.js + "python": "python", + "java": "java", + "ruby": "ruby", + "haskell": "haskell", + "elixir": "elixir", + "rust": "rust", + + // Alternative names or variants + "python_jedi": "python", + "typescript_vts": "node", + "ruby_solargraph": "ruby", + "kotlin": "java", // Kotlin runs on JVM + "scala": "java", // Scala runs on JVM + "csharp": "dotnet", + "csharp_omnisharp": "dotnet", + "erlang": "elixir", // Erlang uses same runtime setup + + // Languages that don't need runtime setup (return empty string) + "bash": "", + "markdown": "", + "yaml": "", + + // Languages not in our runtime definitions (return empty string) + "cpp": "", + "clojure": "", + "dart": "", + "elm": "", + "fortran": "", + "julia": "", + "lua": "", + "nix": "", + "perl": "", + "php": "", + "r": "", + "rego": "", + "swift": "", + "terraform": "", + "zig": "", + "al": "", + } + + return languageMap[serenaLang] +} + // detectFromEngineSteps scans engine steps for runtime commands func detectFromEngineSteps(steps []map[string]any, requirements map[string]*RuntimeRequirement) { for _, step := range steps { From 4450186f6cb77262c053f685a1fd02a8af238673 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 13 Jan 2026 02:59:42 +0000 Subject: [PATCH 3/7] Recompile all workflows with Serena HTTP transport changes Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .github/workflows/archie.lock.yml | 53 +++++++++++-- .github/workflows/cloclo.lock.yml | 65 +++++++++++----- .github/workflows/daily-file-diet.lock.yml | 53 +++++++++++-- .../developer-docs-consolidator.lock.yml | 60 +++++++++++---- .../duplicate-code-detector.lock.yml | 75 ++++++++++++------- .../workflows/glossary-maintainer.lock.yml | 53 +++++++++++-- .github/workflows/go-fan.lock.yml | 60 +++++++++++---- .github/workflows/jsweep.lock.yml | 49 ++++++++++-- .github/workflows/mcp-inspector.lock.yml | 52 ++++++++++--- .github/workflows/q.lock.yml | 58 +++++++++++--- .../repository-quality-improver.lock.yml | 53 +++++++++++-- .github/workflows/smoke-claude.lock.yml | 60 +++++++++++---- .github/workflows/smoke-codex.lock.yml | 75 ++++++++++++------- .github/workflows/smoke-copilot.lock.yml | 53 +++++++++++-- .github/workflows/terminal-stylist.lock.yml | 53 +++++++++++-- .github/workflows/typist.lock.yml | 60 +++++++++++---- 16 files changed, 737 insertions(+), 195 deletions(-) diff --git a/.github/workflows/archie.lock.yml b/.github/workflows/archie.lock.yml index addce637fa0..e270fea9063 100644 --- a/.github/workflows/archie.lock.yml +++ b/.github/workflows/archie.lock.yml @@ -153,6 +153,16 @@ jobs: uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 with: persist-credentials: false + - name: Setup Go + uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 + with: + go-version: '1.25' + - name: Setup Python + uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 + with: + python-version: '3.12' + - name: Setup uv + uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5.4.2 - name: Create gh-aw temp directory run: bash /opt/gh-aw/actions/create_gh_aw_tmp_dir.sh - name: Configure Git credentials @@ -370,6 +380,41 @@ jobs: } } EOF + - name: Start Serena MCP HTTP Server + id: serena-start + run: | + set -eo pipefail + mkdir -p /tmp/gh-aw/mcp-logs/serena + + echo "Starting Serena MCP HTTP server on port 9121..." + + # Start Serena MCP server in background with uvx + uvx --from git+https://github.com/oraios/serena \ + serena start-mcp-server \ + --transport streamable-http \ + --port 9121 \ + --project "${{ github.workspace }}" \ + > /tmp/gh-aw/mcp-logs/serena/server.log 2>&1 & + + # Save PID for potential cleanup + echo $! > /tmp/gh-aw/serena-mcp-server.pid + + # Wait for server to start (max 30 seconds) + echo "Waiting for Serena MCP server to start..." + for i in {1..30}; do + if curl -s http://localhost:9121/health > /dev/null 2>&1; then + echo "Serena MCP server is ready" + break + fi + if [ $i -eq 30 ]; then + echo "ERROR: Serena MCP server failed to start within 30 seconds" + echo "Server logs:" + cat /tmp/gh-aw/mcp-logs/serena/server.log || true + exit 1 + fi + sleep 1 + done + - name: Start MCP gateway id: start-mcp-gateway env: @@ -426,12 +471,8 @@ jobs: } }, "serena": { - "type": "stdio", - "container": "ghcr.io/oraios/serena:latest", - "args": ["--network", "host"], - "entrypoint": "serena", - "entrypointArgs": ["start-mcp-server", "--context", "codex", "--project", "${{ github.workspace }}"], - "mounts": ["${{ github.workspace }}:${{ github.workspace }}:rw"] + "type": "http", + "url": "http://localhost:9121" } }, "gateway": { diff --git a/.github/workflows/cloclo.lock.yml b/.github/workflows/cloclo.lock.yml index 9c8226e6bde..f0092cccb37 100644 --- a/.github/workflows/cloclo.lock.yml +++ b/.github/workflows/cloclo.lock.yml @@ -181,13 +181,18 @@ jobs: uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 with: persist-credentials: false - - name: Create gh-aw temp directory - run: bash /opt/gh-aw/actions/create_gh_aw_tmp_dir.sh - - name: Set up Go + - name: Setup Go uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 with: - cache: true - go-version-file: go.mod + go-version: '1.25' + - name: Setup Python + uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 + with: + python-version: '3.12' + - name: Setup uv + uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5.4.2 + - name: Create gh-aw temp directory + run: bash /opt/gh-aw/actions/create_gh_aw_tmp_dir.sh - name: Install dependencies run: make deps-dev - env: @@ -485,6 +490,41 @@ jobs: } } EOF + - name: Start Serena MCP HTTP Server + id: serena-start + run: | + set -eo pipefail + mkdir -p /tmp/gh-aw/mcp-logs/serena + + echo "Starting Serena MCP HTTP server on port 9121..." + + # Start Serena MCP server in background with uvx + uvx --from git+https://github.com/oraios/serena \ + serena start-mcp-server \ + --transport streamable-http \ + --port 9121 \ + --project "${{ github.workspace }}" \ + > /tmp/gh-aw/mcp-logs/serena/server.log 2>&1 & + + # Save PID for potential cleanup + echo $! > /tmp/gh-aw/serena-mcp-server.pid + + # Wait for server to start (max 30 seconds) + echo "Waiting for Serena MCP server to start..." + for i in {1..30}; do + if curl -s http://localhost:9121/health > /dev/null 2>&1; then + echo "Serena MCP server is ready" + break + fi + if [ $i -eq 30 ]; then + echo "ERROR: Serena MCP server failed to start within 30 seconds" + echo "Server logs:" + cat /tmp/gh-aw/mcp-logs/serena/server.log || true + exit 1 + fi + sleep 1 + done + - name: Start MCP gateway id: start-mcp-gateway env: @@ -559,20 +599,7 @@ jobs: } }, "serena": { - "container": "ghcr.io/oraios/serena:latest", - "args": [ - "--network", - "host" - ], - "entrypoint": "serena", - "entrypointArgs": [ - "start-mcp-server", - "--context", - "codex", - "--project", - "${{ github.workspace }}" - ], - "mounts": ["${{ github.workspace }}:${{ github.workspace }}:rw"] + "url": "http://localhost:9121" } }, "gateway": { diff --git a/.github/workflows/daily-file-diet.lock.yml b/.github/workflows/daily-file-diet.lock.yml index 79a0c1dbade..1ff7104cfe7 100644 --- a/.github/workflows/daily-file-diet.lock.yml +++ b/.github/workflows/daily-file-diet.lock.yml @@ -113,6 +113,16 @@ jobs: uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 with: persist-credentials: false + - name: Setup Go + uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 + with: + go-version: '1.25' + - name: Setup Python + uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 + with: + python-version: '3.12' + - name: Setup uv + uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5.4.2 - name: Create gh-aw temp directory run: bash /opt/gh-aw/actions/create_gh_aw_tmp_dir.sh - name: Configure Git credentials @@ -368,6 +378,41 @@ jobs: } } EOF + - name: Start Serena MCP HTTP Server + id: serena-start + run: | + set -eo pipefail + mkdir -p /tmp/gh-aw/mcp-logs/serena + + echo "Starting Serena MCP HTTP server on port 9121..." + + # Start Serena MCP server in background with uvx + uvx --from git+https://github.com/oraios/serena \ + serena start-mcp-server \ + --transport streamable-http \ + --port 9121 \ + --project "${{ github.workspace }}" \ + > /tmp/gh-aw/mcp-logs/serena/server.log 2>&1 & + + # Save PID for potential cleanup + echo $! > /tmp/gh-aw/serena-mcp-server.pid + + # Wait for server to start (max 30 seconds) + echo "Waiting for Serena MCP server to start..." + for i in {1..30}; do + if curl -s http://localhost:9121/health > /dev/null 2>&1; then + echo "Serena MCP server is ready" + break + fi + if [ $i -eq 30 ]; then + echo "ERROR: Serena MCP server failed to start within 30 seconds" + echo "Server logs:" + cat /tmp/gh-aw/mcp-logs/serena/server.log || true + exit 1 + fi + sleep 1 + done + - name: Start MCP gateway id: start-mcp-gateway env: @@ -424,12 +469,8 @@ jobs: } }, "serena": { - "type": "stdio", - "container": "ghcr.io/oraios/serena:latest", - "args": ["--network", "host"], - "entrypoint": "serena", - "entrypointArgs": ["start-mcp-server", "--context", "codex", "--project", "${{ github.workspace }}"], - "mounts": ["${{ github.workspace }}:${{ github.workspace }}:rw"] + "type": "http", + "url": "http://localhost:9121" } }, "gateway": { diff --git a/.github/workflows/developer-docs-consolidator.lock.yml b/.github/workflows/developer-docs-consolidator.lock.yml index 3fa5a9c990d..6fb984d9785 100644 --- a/.github/workflows/developer-docs-consolidator.lock.yml +++ b/.github/workflows/developer-docs-consolidator.lock.yml @@ -112,6 +112,16 @@ jobs: uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 with: persist-credentials: false + - name: Setup Go + uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 + with: + go-version: '1.25' + - name: Setup Python + uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 + with: + python-version: '3.12' + - name: Setup uv + uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5.4.2 - name: Create gh-aw temp directory run: bash /opt/gh-aw/actions/create_gh_aw_tmp_dir.sh # Cache memory file share configuration from frontmatter processed below @@ -415,6 +425,41 @@ jobs: } } EOF + - name: Start Serena MCP HTTP Server + id: serena-start + run: | + set -eo pipefail + mkdir -p /tmp/gh-aw/mcp-logs/serena + + echo "Starting Serena MCP HTTP server on port 9121..." + + # Start Serena MCP server in background with uvx + uvx --from git+https://github.com/oraios/serena \ + serena start-mcp-server \ + --transport streamable-http \ + --port 9121 \ + --project "${{ github.workspace }}" \ + > /tmp/gh-aw/mcp-logs/serena/server.log 2>&1 & + + # Save PID for potential cleanup + echo $! > /tmp/gh-aw/serena-mcp-server.pid + + # Wait for server to start (max 30 seconds) + echo "Waiting for Serena MCP server to start..." + for i in {1..30}; do + if curl -s http://localhost:9121/health > /dev/null 2>&1; then + echo "Serena MCP server is ready" + break + fi + if [ $i -eq 30 ]; then + echo "ERROR: Serena MCP server failed to start within 30 seconds" + echo "Server logs:" + cat /tmp/gh-aw/mcp-logs/serena/server.log || true + exit 1 + fi + sleep 1 + done + - name: Start MCP gateway id: start-mcp-gateway env: @@ -468,20 +513,7 @@ jobs: } }, "serena": { - "container": "ghcr.io/oraios/serena:latest", - "args": [ - "--network", - "host" - ], - "entrypoint": "serena", - "entrypointArgs": [ - "start-mcp-server", - "--context", - "codex", - "--project", - "${{ github.workspace }}" - ], - "mounts": ["${{ github.workspace }}:${{ github.workspace }}:rw"] + "url": "http://localhost:9121" } }, "gateway": { diff --git a/.github/workflows/duplicate-code-detector.lock.yml b/.github/workflows/duplicate-code-detector.lock.yml index 57a925b7812..49c5451becd 100644 --- a/.github/workflows/duplicate-code-detector.lock.yml +++ b/.github/workflows/duplicate-code-detector.lock.yml @@ -106,6 +106,16 @@ jobs: uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 with: persist-credentials: false + - name: Setup Go + uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 + with: + go-version: '1.25' + - name: Setup Python + uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 + with: + python-version: '3.12' + - name: Setup uv + uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5.4.2 - name: Create gh-aw temp directory run: bash /opt/gh-aw/actions/create_gh_aw_tmp_dir.sh - name: Configure Git credentials @@ -356,6 +366,41 @@ jobs: } } EOF + - name: Start Serena MCP HTTP Server + id: serena-start + run: | + set -eo pipefail + mkdir -p /tmp/gh-aw/mcp-logs/serena + + echo "Starting Serena MCP HTTP server on port 9121..." + + # Start Serena MCP server in background with uvx + uvx --from git+https://github.com/oraios/serena \ + serena start-mcp-server \ + --transport streamable-http \ + --port 9121 \ + --project "${{ github.workspace }}" \ + > /tmp/gh-aw/mcp-logs/serena/server.log 2>&1 & + + # Save PID for potential cleanup + echo $! > /tmp/gh-aw/serena-mcp-server.pid + + # Wait for server to start (max 30 seconds) + echo "Waiting for Serena MCP server to start..." + for i in {1..30}; do + if curl -s http://localhost:9121/health > /dev/null 2>&1; then + echo "Serena MCP server is ready" + break + fi + if [ $i -eq 30 ]; then + echo "ERROR: Serena MCP server failed to start within 30 seconds" + echo "Server logs:" + cat /tmp/gh-aw/mcp-logs/serena/server.log || true + exit 1 + fi + sleep 1 + done + - name: Start MCP gateway id: start-mcp-gateway env: @@ -400,20 +445,7 @@ jobs: env_vars = ["GH_AW_MCP_LOG_DIR", "GH_AW_SAFE_OUTPUTS", "GH_AW_SAFE_OUTPUTS_CONFIG_PATH", "GH_AW_SAFE_OUTPUTS_TOOLS_PATH", "GH_AW_ASSETS_BRANCH", "GH_AW_ASSETS_MAX_SIZE_KB", "GH_AW_ASSETS_ALLOWED_EXTS", "GITHUB_REPOSITORY", "GITHUB_SERVER_URL", "GITHUB_SHA", "GITHUB_WORKSPACE", "DEFAULT_BRANCH"] [mcp_servers.serena] - container = "ghcr.io/oraios/serena:latest" - args = [ - "--network", - "host", - ] - entrypoint = "serena" - entrypointArgs = [ - "start-mcp-server", - "--context", - "codex", - "--project", - "${{ github.workspace }}" - ] - mounts = ["${{ github.workspace }}:${{ github.workspace }}:rw"] + url = "http://localhost:9121" EOF # Generate JSON config for MCP gateway @@ -450,20 +482,7 @@ jobs: } }, "serena": { - "container": "ghcr.io/oraios/serena:latest", - "args": [ - "--network", - "host" - ], - "entrypoint": "serena", - "entrypointArgs": [ - "start-mcp-server", - "--context", - "codex", - "--project", - "${{ github.workspace }}" - ], - "mounts": ["${{ github.workspace }}:${{ github.workspace }}:rw"] + "url": "http://localhost:9121" } }, "gateway": { diff --git a/.github/workflows/glossary-maintainer.lock.yml b/.github/workflows/glossary-maintainer.lock.yml index 3e2bc00d5a1..8000cb0a729 100644 --- a/.github/workflows/glossary-maintainer.lock.yml +++ b/.github/workflows/glossary-maintainer.lock.yml @@ -112,6 +112,16 @@ jobs: uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 with: persist-credentials: false + - name: Setup Go + uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 + with: + go-version: '1.25' + - name: Setup Python + uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 + with: + python-version: '3.12' + - name: Setup uv + uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5.4.2 - name: Create gh-aw temp directory run: bash /opt/gh-aw/actions/create_gh_aw_tmp_dir.sh # Cache memory file share configuration from frontmatter processed below @@ -367,6 +377,41 @@ jobs: } } EOF + - name: Start Serena MCP HTTP Server + id: serena-start + run: | + set -eo pipefail + mkdir -p /tmp/gh-aw/mcp-logs/serena + + echo "Starting Serena MCP HTTP server on port 9121..." + + # Start Serena MCP server in background with uvx + uvx --from git+https://github.com/oraios/serena \ + serena start-mcp-server \ + --transport streamable-http \ + --port 9121 \ + --project "${{ github.workspace }}" \ + > /tmp/gh-aw/mcp-logs/serena/server.log 2>&1 & + + # Save PID for potential cleanup + echo $! > /tmp/gh-aw/serena-mcp-server.pid + + # Wait for server to start (max 30 seconds) + echo "Waiting for Serena MCP server to start..." + for i in {1..30}; do + if curl -s http://localhost:9121/health > /dev/null 2>&1; then + echo "Serena MCP server is ready" + break + fi + if [ $i -eq 30 ]; then + echo "ERROR: Serena MCP server failed to start within 30 seconds" + echo "Server logs:" + cat /tmp/gh-aw/mcp-logs/serena/server.log || true + exit 1 + fi + sleep 1 + done + - name: Start MCP gateway id: start-mcp-gateway env: @@ -423,12 +468,8 @@ jobs: } }, "serena": { - "type": "stdio", - "container": "ghcr.io/oraios/serena:latest", - "args": ["--network", "host"], - "entrypoint": "serena", - "entrypointArgs": ["start-mcp-server", "--context", "codex", "--project", "${{ github.workspace }}"], - "mounts": ["${{ github.workspace }}:${{ github.workspace }}:rw"] + "type": "http", + "url": "http://localhost:9121" } }, "gateway": { diff --git a/.github/workflows/go-fan.lock.yml b/.github/workflows/go-fan.lock.yml index 2e92b7109d5..e2f2e1ee79b 100644 --- a/.github/workflows/go-fan.lock.yml +++ b/.github/workflows/go-fan.lock.yml @@ -111,6 +111,16 @@ jobs: uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 with: persist-credentials: false + - name: Setup Go + uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 + with: + go-version: '1.25' + - name: Setup Python + uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 + with: + python-version: '3.12' + - name: Setup uv + uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5.4.2 - name: Create gh-aw temp directory run: bash /opt/gh-aw/actions/create_gh_aw_tmp_dir.sh # Cache memory file share configuration from frontmatter processed below @@ -351,6 +361,41 @@ jobs: } } EOF + - name: Start Serena MCP HTTP Server + id: serena-start + run: | + set -eo pipefail + mkdir -p /tmp/gh-aw/mcp-logs/serena + + echo "Starting Serena MCP HTTP server on port 9121..." + + # Start Serena MCP server in background with uvx + uvx --from git+https://github.com/oraios/serena \ + serena start-mcp-server \ + --transport streamable-http \ + --port 9121 \ + --project "${{ github.workspace }}" \ + > /tmp/gh-aw/mcp-logs/serena/server.log 2>&1 & + + # Save PID for potential cleanup + echo $! > /tmp/gh-aw/serena-mcp-server.pid + + # Wait for server to start (max 30 seconds) + echo "Waiting for Serena MCP server to start..." + for i in {1..30}; do + if curl -s http://localhost:9121/health > /dev/null 2>&1; then + echo "Serena MCP server is ready" + break + fi + if [ $i -eq 30 ]; then + echo "ERROR: Serena MCP server failed to start within 30 seconds" + echo "Server logs:" + cat /tmp/gh-aw/mcp-logs/serena/server.log || true + exit 1 + fi + sleep 1 + done + - name: Start MCP gateway id: start-mcp-gateway env: @@ -404,20 +449,7 @@ jobs: } }, "serena": { - "container": "ghcr.io/oraios/serena:latest", - "args": [ - "--network", - "host" - ], - "entrypoint": "serena", - "entrypointArgs": [ - "start-mcp-server", - "--context", - "codex", - "--project", - "${{ github.workspace }}" - ], - "mounts": ["${{ github.workspace }}:${{ github.workspace }}:rw"] + "url": "http://localhost:9121" } }, "gateway": { diff --git a/.github/workflows/jsweep.lock.yml b/.github/workflows/jsweep.lock.yml index 17d81e2a915..610a759ed53 100644 --- a/.github/workflows/jsweep.lock.yml +++ b/.github/workflows/jsweep.lock.yml @@ -113,6 +113,12 @@ jobs: with: node-version: '20' package-manager-cache: false + - name: Setup Python + uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 + with: + python-version: '3.12' + - name: Setup uv + uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5.4.2 - name: Create gh-aw temp directory run: bash /opt/gh-aw/actions/create_gh_aw_tmp_dir.sh - name: Install Node.js dependencies @@ -372,6 +378,41 @@ jobs: } } EOF + - name: Start Serena MCP HTTP Server + id: serena-start + run: | + set -eo pipefail + mkdir -p /tmp/gh-aw/mcp-logs/serena + + echo "Starting Serena MCP HTTP server on port 9121..." + + # Start Serena MCP server in background with uvx + uvx --from git+https://github.com/oraios/serena \ + serena start-mcp-server \ + --transport streamable-http \ + --port 9121 \ + --project "${{ github.workspace }}" \ + > /tmp/gh-aw/mcp-logs/serena/server.log 2>&1 & + + # Save PID for potential cleanup + echo $! > /tmp/gh-aw/serena-mcp-server.pid + + # Wait for server to start (max 30 seconds) + echo "Waiting for Serena MCP server to start..." + for i in {1..30}; do + if curl -s http://localhost:9121/health > /dev/null 2>&1; then + echo "Serena MCP server is ready" + break + fi + if [ $i -eq 30 ]; then + echo "ERROR: Serena MCP server failed to start within 30 seconds" + echo "Server logs:" + cat /tmp/gh-aw/mcp-logs/serena/server.log || true + exit 1 + fi + sleep 1 + done + - name: Start MCP gateway id: start-mcp-gateway env: @@ -428,12 +469,8 @@ jobs: } }, "serena": { - "type": "stdio", - "container": "ghcr.io/oraios/serena:latest", - "args": ["--network", "host"], - "entrypoint": "serena", - "entrypointArgs": ["start-mcp-server", "--context", "codex", "--project", "${{ github.workspace }}"], - "mounts": ["${{ github.workspace }}:${{ github.workspace }}:rw"] + "type": "http", + "url": "http://localhost:9121" } }, "gateway": { diff --git a/.github/workflows/mcp-inspector.lock.yml b/.github/workflows/mcp-inspector.lock.yml index 4c88d041636..f8fb3b18c0c 100644 --- a/.github/workflows/mcp-inspector.lock.yml +++ b/.github/workflows/mcp-inspector.lock.yml @@ -127,6 +127,10 @@ jobs: uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 with: persist-credentials: false + - name: Setup Go + uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 + with: + go-version: '1.25' - name: Setup Node.js uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0 with: @@ -140,11 +144,6 @@ jobs: uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5.4.2 - name: Create gh-aw temp directory run: bash /opt/gh-aw/actions/create_gh_aw_tmp_dir.sh - - name: Set up Go - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 - with: - cache: true - go-version-file: go.mod - name: Install dependencies run: make deps-dev - env: @@ -435,6 +434,41 @@ jobs: } } EOF + - name: Start Serena MCP HTTP Server + id: serena-start + run: | + set -eo pipefail + mkdir -p /tmp/gh-aw/mcp-logs/serena + + echo "Starting Serena MCP HTTP server on port 9121..." + + # Start Serena MCP server in background with uvx + uvx --from git+https://github.com/oraios/serena \ + serena start-mcp-server \ + --transport streamable-http \ + --port 9121 \ + --project "${{ github.workspace }}" \ + > /tmp/gh-aw/mcp-logs/serena/server.log 2>&1 & + + # Save PID for potential cleanup + echo $! > /tmp/gh-aw/serena-mcp-server.pid + + # Wait for server to start (max 30 seconds) + echo "Waiting for Serena MCP server to start..." + for i in {1..30}; do + if curl -s http://localhost:9121/health > /dev/null 2>&1; then + echo "Serena MCP server is ready" + break + fi + if [ $i -eq 30 ]; then + echo "ERROR: Serena MCP server failed to start within 30 seconds" + echo "Server logs:" + cat /tmp/gh-aw/mcp-logs/serena/server.log || true + exit 1 + fi + sleep 1 + done + - name: Start MCP gateway id: start-mcp-gateway env: @@ -726,12 +760,8 @@ jobs: } }, "serena": { - "type": "stdio", - "container": "ghcr.io/oraios/serena:latest", - "args": ["--network", "host"], - "entrypoint": "serena", - "entrypointArgs": ["start-mcp-server", "--context", "codex", "--project", "${{ github.workspace }}"], - "mounts": ["${{ github.workspace }}:${{ github.workspace }}:rw"] + "type": "http", + "url": "http://localhost:9121" }, "tavily": { "type": "http", diff --git a/.github/workflows/q.lock.yml b/.github/workflows/q.lock.yml index 833a85b5d4d..8351976f553 100644 --- a/.github/workflows/q.lock.yml +++ b/.github/workflows/q.lock.yml @@ -176,13 +176,18 @@ jobs: uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 with: persist-credentials: false - - name: Create gh-aw temp directory - run: bash /opt/gh-aw/actions/create_gh_aw_tmp_dir.sh - - name: Set up Go + - name: Setup Go uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 with: - cache: true - go-version-file: go.mod + go-version: '1.25' + - name: Setup Python + uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 + with: + python-version: '3.12' + - name: Setup uv + uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5.4.2 + - name: Create gh-aw temp directory + run: bash /opt/gh-aw/actions/create_gh_aw_tmp_dir.sh - name: Install dependencies run: make deps-dev - env: @@ -482,6 +487,41 @@ jobs: } } EOF + - name: Start Serena MCP HTTP Server + id: serena-start + run: | + set -eo pipefail + mkdir -p /tmp/gh-aw/mcp-logs/serena + + echo "Starting Serena MCP HTTP server on port 9121..." + + # Start Serena MCP server in background with uvx + uvx --from git+https://github.com/oraios/serena \ + serena start-mcp-server \ + --transport streamable-http \ + --port 9121 \ + --project "${{ github.workspace }}" \ + > /tmp/gh-aw/mcp-logs/serena/server.log 2>&1 & + + # Save PID for potential cleanup + echo $! > /tmp/gh-aw/serena-mcp-server.pid + + # Wait for server to start (max 30 seconds) + echo "Waiting for Serena MCP server to start..." + for i in {1..30}; do + if curl -s http://localhost:9121/health > /dev/null 2>&1; then + echo "Serena MCP server is ready" + break + fi + if [ $i -eq 30 ]; then + echo "ERROR: Serena MCP server failed to start within 30 seconds" + echo "Server logs:" + cat /tmp/gh-aw/mcp-logs/serena/server.log || true + exit 1 + fi + sleep 1 + done + - name: Start MCP gateway id: start-mcp-gateway env: @@ -545,12 +585,8 @@ jobs: } }, "serena": { - "type": "stdio", - "container": "ghcr.io/oraios/serena:latest", - "args": ["--network", "host"], - "entrypoint": "serena", - "entrypointArgs": ["start-mcp-server", "--context", "codex", "--project", "${{ github.workspace }}"], - "mounts": ["${{ github.workspace }}:${{ github.workspace }}:rw"] + "type": "http", + "url": "http://localhost:9121" }, "tavily": { "type": "http", diff --git a/.github/workflows/repository-quality-improver.lock.yml b/.github/workflows/repository-quality-improver.lock.yml index ec464cc1dc8..3918d29b9d9 100644 --- a/.github/workflows/repository-quality-improver.lock.yml +++ b/.github/workflows/repository-quality-improver.lock.yml @@ -111,6 +111,16 @@ jobs: uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 with: persist-credentials: false + - name: Setup Go + uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 + with: + go-version: '1.25' + - name: Setup Python + uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 + with: + python-version: '3.12' + - name: Setup uv + uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5.4.2 - name: Create gh-aw temp directory run: bash /opt/gh-aw/actions/create_gh_aw_tmp_dir.sh # Cache memory file share configuration from frontmatter processed below @@ -358,6 +368,41 @@ jobs: } } EOF + - name: Start Serena MCP HTTP Server + id: serena-start + run: | + set -eo pipefail + mkdir -p /tmp/gh-aw/mcp-logs/serena + + echo "Starting Serena MCP HTTP server on port 9121..." + + # Start Serena MCP server in background with uvx + uvx --from git+https://github.com/oraios/serena \ + serena start-mcp-server \ + --transport streamable-http \ + --port 9121 \ + --project "${{ github.workspace }}" \ + > /tmp/gh-aw/mcp-logs/serena/server.log 2>&1 & + + # Save PID for potential cleanup + echo $! > /tmp/gh-aw/serena-mcp-server.pid + + # Wait for server to start (max 30 seconds) + echo "Waiting for Serena MCP server to start..." + for i in {1..30}; do + if curl -s http://localhost:9121/health > /dev/null 2>&1; then + echo "Serena MCP server is ready" + break + fi + if [ $i -eq 30 ]; then + echo "ERROR: Serena MCP server failed to start within 30 seconds" + echo "Server logs:" + cat /tmp/gh-aw/mcp-logs/serena/server.log || true + exit 1 + fi + sleep 1 + done + - name: Start MCP gateway id: start-mcp-gateway env: @@ -414,12 +459,8 @@ jobs: } }, "serena": { - "type": "stdio", - "container": "ghcr.io/oraios/serena:latest", - "args": ["--network", "host"], - "entrypoint": "serena", - "entrypointArgs": ["start-mcp-server", "--context", "codex", "--project", "${{ github.workspace }}"], - "mounts": ["${{ github.workspace }}:${{ github.workspace }}:rw"] + "type": "http", + "url": "http://localhost:9121" } }, "gateway": { diff --git a/.github/workflows/smoke-claude.lock.yml b/.github/workflows/smoke-claude.lock.yml index 4b0e3038b99..40e911933ec 100644 --- a/.github/workflows/smoke-claude.lock.yml +++ b/.github/workflows/smoke-claude.lock.yml @@ -138,6 +138,16 @@ jobs: uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 with: persist-credentials: false + - name: Setup Go + uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 + with: + go-version: '1.25' + - name: Setup Python + uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 + with: + python-version: '3.12' + - name: Setup uv + uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5.4.2 - name: Create gh-aw temp directory run: bash /opt/gh-aw/actions/create_gh_aw_tmp_dir.sh # Cache memory file share configuration from frontmatter processed below @@ -572,6 +582,41 @@ jobs: bash /opt/gh-aw/actions/start_safe_inputs_server.sh + - name: Start Serena MCP HTTP Server + id: serena-start + run: | + set -eo pipefail + mkdir -p /tmp/gh-aw/mcp-logs/serena + + echo "Starting Serena MCP HTTP server on port 9121..." + + # Start Serena MCP server in background with uvx + uvx --from git+https://github.com/oraios/serena \ + serena start-mcp-server \ + --transport streamable-http \ + --port 9121 \ + --project "${{ github.workspace }}" \ + > /tmp/gh-aw/mcp-logs/serena/server.log 2>&1 & + + # Save PID for potential cleanup + echo $! > /tmp/gh-aw/serena-mcp-server.pid + + # Wait for server to start (max 30 seconds) + echo "Waiting for Serena MCP server to start..." + for i in {1..30}; do + if curl -s http://localhost:9121/health > /dev/null 2>&1; then + echo "Serena MCP server is ready" + break + fi + if [ $i -eq 30 ]; then + echo "ERROR: Serena MCP server failed to start within 30 seconds" + echo "Server logs:" + cat /tmp/gh-aw/mcp-logs/serena/server.log || true + exit 1 + fi + sleep 1 + done + - name: Start MCP gateway id: start-mcp-gateway env: @@ -653,20 +698,7 @@ jobs: } }, "serena": { - "container": "ghcr.io/oraios/serena:latest", - "args": [ - "--network", - "host" - ], - "entrypoint": "serena", - "entrypointArgs": [ - "start-mcp-server", - "--context", - "codex", - "--project", - "${{ github.workspace }}" - ], - "mounts": ["${{ github.workspace }}:${{ github.workspace }}:rw"] + "url": "http://localhost:9121" }, "tavily": { "type": "http", diff --git a/.github/workflows/smoke-codex.lock.yml b/.github/workflows/smoke-codex.lock.yml index 76f57c2f770..d54648acc41 100644 --- a/.github/workflows/smoke-codex.lock.yml +++ b/.github/workflows/smoke-codex.lock.yml @@ -137,6 +137,16 @@ jobs: uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 with: persist-credentials: false + - name: Setup Go + uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 + with: + go-version: '1.25' + - name: Setup Python + uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 + with: + python-version: '3.12' + - name: Setup uv + uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5.4.2 - name: Create gh-aw temp directory run: bash /opt/gh-aw/actions/create_gh_aw_tmp_dir.sh # Cache memory file share configuration from frontmatter processed below @@ -599,6 +609,41 @@ jobs: bash /opt/gh-aw/actions/start_safe_inputs_server.sh + - name: Start Serena MCP HTTP Server + id: serena-start + run: | + set -eo pipefail + mkdir -p /tmp/gh-aw/mcp-logs/serena + + echo "Starting Serena MCP HTTP server on port 9121..." + + # Start Serena MCP server in background with uvx + uvx --from git+https://github.com/oraios/serena \ + serena start-mcp-server \ + --transport streamable-http \ + --port 9121 \ + --project "${{ github.workspace }}" \ + > /tmp/gh-aw/mcp-logs/serena/server.log 2>&1 & + + # Save PID for potential cleanup + echo $! > /tmp/gh-aw/serena-mcp-server.pid + + # Wait for server to start (max 30 seconds) + echo "Waiting for Serena MCP server to start..." + for i in {1..30}; do + if curl -s http://localhost:9121/health > /dev/null 2>&1; then + echo "Serena MCP server is ready" + break + fi + if [ $i -eq 30 ]; then + echo "ERROR: Serena MCP server failed to start within 30 seconds" + echo "Server logs:" + cat /tmp/gh-aw/mcp-logs/serena/server.log || true + exit 1 + fi + sleep 1 + done + - name: Start MCP gateway id: start-mcp-gateway env: @@ -669,20 +714,7 @@ jobs: env_vars = ["GH_AW_MCP_LOG_DIR", "GH_AW_SAFE_OUTPUTS", "GH_AW_SAFE_OUTPUTS_CONFIG_PATH", "GH_AW_SAFE_OUTPUTS_TOOLS_PATH", "GH_AW_ASSETS_BRANCH", "GH_AW_ASSETS_MAX_SIZE_KB", "GH_AW_ASSETS_ALLOWED_EXTS", "GITHUB_REPOSITORY", "GITHUB_SERVER_URL", "GITHUB_SHA", "GITHUB_WORKSPACE", "DEFAULT_BRANCH"] [mcp_servers.serena] - container = "ghcr.io/oraios/serena:latest" - args = [ - "--network", - "host", - ] - entrypoint = "serena" - entrypointArgs = [ - "start-mcp-server", - "--context", - "codex", - "--project", - "${{ github.workspace }}" - ] - mounts = ["${{ github.workspace }}:${{ github.workspace }}:rw"] + url = "http://localhost:9121" [mcp_servers.tavily] url = "https://mcp.tavily.com/mcp/" @@ -747,20 +779,7 @@ jobs: } }, "serena": { - "container": "ghcr.io/oraios/serena:latest", - "args": [ - "--network", - "host" - ], - "entrypoint": "serena", - "entrypointArgs": [ - "start-mcp-server", - "--context", - "codex", - "--project", - "${{ github.workspace }}" - ], - "mounts": ["${{ github.workspace }}:${{ github.workspace }}:rw"] + "url": "http://localhost:9121" }, "tavily": { "type": "http", diff --git a/.github/workflows/smoke-copilot.lock.yml b/.github/workflows/smoke-copilot.lock.yml index 494be2fcebe..76293d69588 100644 --- a/.github/workflows/smoke-copilot.lock.yml +++ b/.github/workflows/smoke-copilot.lock.yml @@ -132,6 +132,16 @@ jobs: uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 with: persist-credentials: false + - name: Setup Go + uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 + with: + go-version: '1.25' + - name: Setup Python + uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 + with: + python-version: '3.12' + - name: Setup uv + uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5.4.2 - name: Create gh-aw temp directory run: bash /opt/gh-aw/actions/create_gh_aw_tmp_dir.sh # Cache memory file share configuration from frontmatter processed below @@ -472,6 +482,41 @@ jobs: } } EOF + - name: Start Serena MCP HTTP Server + id: serena-start + run: | + set -eo pipefail + mkdir -p /tmp/gh-aw/mcp-logs/serena + + echo "Starting Serena MCP HTTP server on port 9121..." + + # Start Serena MCP server in background with uvx + uvx --from git+https://github.com/oraios/serena \ + serena start-mcp-server \ + --transport streamable-http \ + --port 9121 \ + --project "${{ github.workspace }}" \ + > /tmp/gh-aw/mcp-logs/serena/server.log 2>&1 & + + # Save PID for potential cleanup + echo $! > /tmp/gh-aw/serena-mcp-server.pid + + # Wait for server to start (max 30 seconds) + echo "Waiting for Serena MCP server to start..." + for i in {1..30}; do + if curl -s http://localhost:9121/health > /dev/null 2>&1; then + echo "Serena MCP server is ready" + break + fi + if [ $i -eq 30 ]; then + echo "ERROR: Serena MCP server failed to start within 30 seconds" + echo "Server logs:" + cat /tmp/gh-aw/mcp-logs/serena/server.log || true + exit 1 + fi + sleep 1 + done + - name: Start MCP gateway id: start-mcp-gateway env: @@ -535,12 +580,8 @@ jobs: } }, "serena": { - "type": "stdio", - "container": "ghcr.io/oraios/serena:latest", - "args": ["--network", "host"], - "entrypoint": "serena", - "entrypointArgs": ["start-mcp-server", "--context", "codex", "--project", "${{ github.workspace }}"], - "mounts": ["${{ github.workspace }}:${{ github.workspace }}:rw"] + "type": "http", + "url": "http://localhost:9121" } }, "gateway": { diff --git a/.github/workflows/terminal-stylist.lock.yml b/.github/workflows/terminal-stylist.lock.yml index 96de1f3d874..ae3c8b52771 100644 --- a/.github/workflows/terminal-stylist.lock.yml +++ b/.github/workflows/terminal-stylist.lock.yml @@ -102,6 +102,16 @@ jobs: uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 with: persist-credentials: false + - name: Setup Go + uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 + with: + go-version: '1.25' + - name: Setup Python + uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 + with: + python-version: '3.12' + - name: Setup uv + uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5.4.2 - name: Create gh-aw temp directory run: bash /opt/gh-aw/actions/create_gh_aw_tmp_dir.sh - name: Configure Git credentials @@ -336,6 +346,41 @@ jobs: } } EOF + - name: Start Serena MCP HTTP Server + id: serena-start + run: | + set -eo pipefail + mkdir -p /tmp/gh-aw/mcp-logs/serena + + echo "Starting Serena MCP HTTP server on port 9121..." + + # Start Serena MCP server in background with uvx + uvx --from git+https://github.com/oraios/serena \ + serena start-mcp-server \ + --transport streamable-http \ + --port 9121 \ + --project "${{ github.workspace }}" \ + > /tmp/gh-aw/mcp-logs/serena/server.log 2>&1 & + + # Save PID for potential cleanup + echo $! > /tmp/gh-aw/serena-mcp-server.pid + + # Wait for server to start (max 30 seconds) + echo "Waiting for Serena MCP server to start..." + for i in {1..30}; do + if curl -s http://localhost:9121/health > /dev/null 2>&1; then + echo "Serena MCP server is ready" + break + fi + if [ $i -eq 30 ]; then + echo "ERROR: Serena MCP server failed to start within 30 seconds" + echo "Server logs:" + cat /tmp/gh-aw/mcp-logs/serena/server.log || true + exit 1 + fi + sleep 1 + done + - name: Start MCP gateway id: start-mcp-gateway env: @@ -392,12 +437,8 @@ jobs: } }, "serena": { - "type": "stdio", - "container": "ghcr.io/oraios/serena:latest", - "args": ["--network", "host"], - "entrypoint": "serena", - "entrypointArgs": ["start-mcp-server", "--context", "codex", "--project", "${{ github.workspace }}"], - "mounts": ["${{ github.workspace }}:${{ github.workspace }}:rw"] + "type": "http", + "url": "http://localhost:9121" } }, "gateway": { diff --git a/.github/workflows/typist.lock.yml b/.github/workflows/typist.lock.yml index 8f7f167f995..409750c4be7 100644 --- a/.github/workflows/typist.lock.yml +++ b/.github/workflows/typist.lock.yml @@ -109,6 +109,16 @@ jobs: uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 with: persist-credentials: false + - name: Setup Go + uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 + with: + go-version: '1.25' + - name: Setup Python + uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 + with: + python-version: '3.12' + - name: Setup uv + uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5.4.2 - name: Create gh-aw temp directory run: bash /opt/gh-aw/actions/create_gh_aw_tmp_dir.sh - name: Configure Git credentials @@ -338,6 +348,41 @@ jobs: } } EOF + - name: Start Serena MCP HTTP Server + id: serena-start + run: | + set -eo pipefail + mkdir -p /tmp/gh-aw/mcp-logs/serena + + echo "Starting Serena MCP HTTP server on port 9121..." + + # Start Serena MCP server in background with uvx + uvx --from git+https://github.com/oraios/serena \ + serena start-mcp-server \ + --transport streamable-http \ + --port 9121 \ + --project "${{ github.workspace }}" \ + > /tmp/gh-aw/mcp-logs/serena/server.log 2>&1 & + + # Save PID for potential cleanup + echo $! > /tmp/gh-aw/serena-mcp-server.pid + + # Wait for server to start (max 30 seconds) + echo "Waiting for Serena MCP server to start..." + for i in {1..30}; do + if curl -s http://localhost:9121/health > /dev/null 2>&1; then + echo "Serena MCP server is ready" + break + fi + if [ $i -eq 30 ]; then + echo "ERROR: Serena MCP server failed to start within 30 seconds" + echo "Server logs:" + cat /tmp/gh-aw/mcp-logs/serena/server.log || true + exit 1 + fi + sleep 1 + done + - name: Start MCP gateway id: start-mcp-gateway env: @@ -391,20 +436,7 @@ jobs: } }, "serena": { - "container": "ghcr.io/oraios/serena:latest", - "args": [ - "--network", - "host" - ], - "entrypoint": "serena", - "entrypointArgs": [ - "start-mcp-server", - "--context", - "codex", - "--project", - "${{ github.workspace }}" - ], - "mounts": ["${{ github.workspace }}:${{ github.workspace }}:rw"] + "url": "http://localhost:9121" } }, "gateway": { From be9ca85b3a193db4568dbc2e29c2b4f06e8dd218 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 13 Jan 2026 06:48:41 +0000 Subject: [PATCH 4/7] Fix Copilot MCP config converter to handle stdio to local conversion The converter script now properly converts type: "stdio" to type: "local" for Copilot CLI compatibility. HTTP servers remain unchanged as type: "http". This fixes the Serena configuration for Copilot where Serena MCP server runs with HTTP transport and should keep type: "http" in the output. Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .github/aw/actions-lock.json | 5 +++++ .github/workflows/audit-workflows.lock.yml | 2 +- .github/workflows/ci-coach.lock.yml | 2 +- .../daily-copilot-token-report.lock.yml | 2 +- .github/workflows/daily-firewall-report.lock.yml | 2 +- .github/workflows/deep-report.lock.yml | 2 +- .github/workflows/dev-hawk.lock.yml | 2 +- .github/workflows/go-logger.lock.yml | 2 +- .github/workflows/hourly-ci-cleaner.lock.yml | 2 +- .github/workflows/portfolio-analyst.lock.yml | 2 +- .../prompt-clustering-analysis.lock.yml | 2 +- .github/workflows/release.lock.yml | 2 +- .github/workflows/safe-output-health.lock.yml | 2 +- .../workflows/static-analysis-report.lock.yml | 2 +- .github/workflows/tidy.lock.yml | 2 +- .../setup/sh/convert_gateway_config_copilot.sh | 13 +++++++++---- pkg/workflow/runtime_detection.go | 16 ++++++++-------- 17 files changed, 36 insertions(+), 26 deletions(-) diff --git a/.github/aw/actions-lock.json b/.github/aw/actions-lock.json index 0ef7d9d9063..705bdeb0b60 100644 --- a/.github/aw/actions-lock.json +++ b/.github/aw/actions-lock.json @@ -60,6 +60,11 @@ "version": "v4.3.1", "sha": "67a3573c9a986a3f9c594539f4ab511d57bb3ce9" }, + "actions/setup-go@v6": { + "repo": "actions/setup-go", + "version": "v6", + "sha": "7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5" + }, "actions/setup-go@v6.1.0": { "repo": "actions/setup-go", "version": "v6.1.0", diff --git a/.github/workflows/audit-workflows.lock.yml b/.github/workflows/audit-workflows.lock.yml index bc313fc5085..c2957c53a5b 100644 --- a/.github/workflows/audit-workflows.lock.yml +++ b/.github/workflows/audit-workflows.lock.yml @@ -118,7 +118,7 @@ jobs: - name: Create gh-aw temp directory run: bash /opt/gh-aw/actions/create_gh_aw_tmp_dir.sh - name: Set up Go - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 + uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6 with: cache: true go-version-file: go.mod diff --git a/.github/workflows/ci-coach.lock.yml b/.github/workflows/ci-coach.lock.yml index 2df155ace86..5a0a95e9c1b 100644 --- a/.github/workflows/ci-coach.lock.yml +++ b/.github/workflows/ci-coach.lock.yml @@ -128,7 +128,7 @@ jobs: name: Download CI workflow runs from last 7 days run: "# Download workflow runs for the ci workflow\ngh run list --repo ${{ github.repository }} --workflow=ci.yml --limit 100 --json databaseId,status,conclusion,createdAt,updatedAt,displayTitle,headBranch,event,url,workflowDatabaseId,number > /tmp/ci-runs.json\n\n# Create directory for artifacts\nmkdir -p /tmp/ci-artifacts\n\n# Download artifacts from recent runs (last 5 successful runs)\necho \"Downloading artifacts from recent CI runs...\"\ngh run list --repo ${{ github.repository }} --workflow=ci.yml --status success --limit 5 --json databaseId | jq -r '.[].databaseId' | while read -r run_id; do\n echo \"Processing run $run_id\"\n gh run download \"$run_id\" --repo ${{ github.repository }} --dir \"/tmp/ci-artifacts/$run_id\" 2>/dev/null || echo \"No artifacts for run $run_id\"\ndone\n\necho \"CI runs data saved to /tmp/ci-runs.json\"\necho \"Artifacts saved to /tmp/ci-artifacts/\"\n\n# Summarize downloaded artifacts\necho \"## Downloaded Artifacts\" >> $GITHUB_STEP_SUMMARY\nfind /tmp/ci-artifacts -type f -name \"*.txt\" -o -name \"*.html\" -o -name \"*.json\" | head -20 | while read -r f; do\n echo \"- $(basename $f)\" >> $GITHUB_STEP_SUMMARY\ndone\n" - name: Set up Go - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 + uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6 with: cache: true go-version-file: go.mod diff --git a/.github/workflows/daily-copilot-token-report.lock.yml b/.github/workflows/daily-copilot-token-report.lock.yml index 92563113eeb..c1d477006c1 100644 --- a/.github/workflows/daily-copilot-token-report.lock.yml +++ b/.github/workflows/daily-copilot-token-report.lock.yml @@ -137,7 +137,7 @@ jobs: /tmp/gh-aw/python/data/* retention-days: 30 - name: Set up Go - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 + uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6 with: cache: true go-version-file: go.mod diff --git a/.github/workflows/daily-firewall-report.lock.yml b/.github/workflows/daily-firewall-report.lock.yml index fef351b14bd..85052f8a746 100644 --- a/.github/workflows/daily-firewall-report.lock.yml +++ b/.github/workflows/daily-firewall-report.lock.yml @@ -117,7 +117,7 @@ jobs: - name: Create gh-aw temp directory run: bash /opt/gh-aw/actions/create_gh_aw_tmp_dir.sh - name: Set up Go - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 + uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6 with: cache: true go-version-file: go.mod diff --git a/.github/workflows/deep-report.lock.yml b/.github/workflows/deep-report.lock.yml index 9de01df6c7b..73cbe12c501 100644 --- a/.github/workflows/deep-report.lock.yml +++ b/.github/workflows/deep-report.lock.yml @@ -128,7 +128,7 @@ jobs: name: Fetch weekly issues data run: "# Create output directories\nmkdir -p /tmp/gh-aw/weekly-issues-data\nmkdir -p /tmp/gh-aw/cache-memory\n\n# Get today's date for cache identification\nTODAY=$(date '+%Y-%m-%d')\nCACHE_DIR=\"/tmp/gh-aw/cache-memory\"\n\n# Check if cached data exists from today\nif [ -f \"$CACHE_DIR/weekly-issues-${TODAY}.json\" ] && [ -s \"$CACHE_DIR/weekly-issues-${TODAY}.json\" ]; then\n echo \"✓ Found cached weekly issues data from ${TODAY}\"\n cp \"$CACHE_DIR/weekly-issues-${TODAY}.json\" /tmp/gh-aw/weekly-issues-data/issues.json\n \n # Regenerate schema if missing\n if [ ! -f \"$CACHE_DIR/weekly-issues-${TODAY}-schema.json\" ]; then\n /tmp/gh-aw/jqschema.sh < /tmp/gh-aw/weekly-issues-data/issues.json > \"$CACHE_DIR/weekly-issues-${TODAY}-schema.json\"\n fi\n cp \"$CACHE_DIR/weekly-issues-${TODAY}-schema.json\" /tmp/gh-aw/weekly-issues-data/issues-schema.json\n \n echo \"Using cached data from ${TODAY}\"\n echo \"Total issues in cache: $(jq 'length' /tmp/gh-aw/weekly-issues-data/issues.json)\"\nelse\n echo \"⬇ Downloading fresh weekly issues data...\"\n \n # Calculate date 7 days ago (cross-platform: GNU date first, BSD fallback)\n DATE_7_DAYS_AGO=$(date -d '7 days ago' '+%Y-%m-%d' 2>/dev/null || date -v-7d '+%Y-%m-%d')\n \n echo \"Fetching issues created or updated since ${DATE_7_DAYS_AGO}...\"\n \n # Fetch issues from the last 7 days using gh CLI\n # Using --search with updated filter to get recent activity\n gh issue list --repo ${{ github.repository }} \\\n --search \"updated:>=${DATE_7_DAYS_AGO}\" \\\n --state all \\\n --json number,title,author,createdAt,state,url,body,labels,updatedAt,closedAt,milestone,assignees,comments \\\n --limit 500 \\\n > /tmp/gh-aw/weekly-issues-data/issues.json\n\n # Generate schema for reference\n /tmp/gh-aw/jqschema.sh < /tmp/gh-aw/weekly-issues-data/issues.json > /tmp/gh-aw/weekly-issues-data/issues-schema.json\n\n # Store in cache with today's date\n cp /tmp/gh-aw/weekly-issues-data/issues.json \"$CACHE_DIR/weekly-issues-${TODAY}.json\"\n cp /tmp/gh-aw/weekly-issues-data/issues-schema.json \"$CACHE_DIR/weekly-issues-${TODAY}-schema.json\"\n\n echo \"✓ Weekly issues data saved to cache: weekly-issues-${TODAY}.json\"\n echo \"Total issues found: $(jq 'length' /tmp/gh-aw/weekly-issues-data/issues.json)\"\nfi\n\n# Always ensure data is available at expected locations for backward compatibility\necho \"Weekly issues data available at: /tmp/gh-aw/weekly-issues-data/issues.json\"\necho \"Schema available at: /tmp/gh-aw/weekly-issues-data/issues-schema.json\"" - name: Set up Go - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 + uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6 with: cache: true go-version-file: go.mod diff --git a/.github/workflows/dev-hawk.lock.yml b/.github/workflows/dev-hawk.lock.yml index 2ec4a572759..129f4f0bfaa 100644 --- a/.github/workflows/dev-hawk.lock.yml +++ b/.github/workflows/dev-hawk.lock.yml @@ -123,7 +123,7 @@ jobs: - name: Create gh-aw temp directory run: bash /opt/gh-aw/actions/create_gh_aw_tmp_dir.sh - name: Set up Go - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 + uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6 with: cache: true go-version-file: go.mod diff --git a/.github/workflows/go-logger.lock.yml b/.github/workflows/go-logger.lock.yml index cb6822cd018..5d5bcfe33d0 100644 --- a/.github/workflows/go-logger.lock.yml +++ b/.github/workflows/go-logger.lock.yml @@ -116,7 +116,7 @@ jobs: - name: Create gh-aw temp directory run: bash /opt/gh-aw/actions/create_gh_aw_tmp_dir.sh - name: Set up Go - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 + uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6 with: cache: true go-version-file: go.mod diff --git a/.github/workflows/hourly-ci-cleaner.lock.yml b/.github/workflows/hourly-ci-cleaner.lock.yml index 776490b07e5..1dc345f9218 100644 --- a/.github/workflows/hourly-ci-cleaner.lock.yml +++ b/.github/workflows/hourly-ci-cleaner.lock.yml @@ -128,7 +128,7 @@ jobs: sudo apt-get update sudo apt-get install -y make - name: Setup Go - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 + uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6 with: cache: true go-version-file: go.mod diff --git a/.github/workflows/portfolio-analyst.lock.yml b/.github/workflows/portfolio-analyst.lock.yml index c6ee1e01791..58128114049 100644 --- a/.github/workflows/portfolio-analyst.lock.yml +++ b/.github/workflows/portfolio-analyst.lock.yml @@ -118,7 +118,7 @@ jobs: - name: Create gh-aw temp directory run: bash /opt/gh-aw/actions/create_gh_aw_tmp_dir.sh - name: Set up Go - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 + uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6 with: cache: true go-version-file: go.mod diff --git a/.github/workflows/prompt-clustering-analysis.lock.yml b/.github/workflows/prompt-clustering-analysis.lock.yml index 6f8f4b1c922..fdbc22a0e67 100644 --- a/.github/workflows/prompt-clustering-analysis.lock.yml +++ b/.github/workflows/prompt-clustering-analysis.lock.yml @@ -123,7 +123,7 @@ jobs: - name: Set up jq utilities directory run: "mkdir -p /tmp/gh-aw\ncat > /tmp/gh-aw/jqschema.sh << 'EOF'\n#!/usr/bin/env bash\n# jqschema.sh\njq -c '\ndef walk(f):\n . as $in |\n if type == \"object\" then\n reduce keys[] as $k ({}; . + {($k): ($in[$k] | walk(f))})\n elif type == \"array\" then\n if length == 0 then [] else [.[0] | walk(f)] end\n else\n type\n end;\nwalk(.)\n'\nEOF\nchmod +x /tmp/gh-aw/jqschema.sh" - name: Set up Go - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 + uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6 with: cache: true go-version-file: go.mod diff --git a/.github/workflows/release.lock.yml b/.github/workflows/release.lock.yml index ce8d4a55d9c..b66b59cb120 100644 --- a/.github/workflows/release.lock.yml +++ b/.github/workflows/release.lock.yml @@ -1225,7 +1225,7 @@ jobs: - name: Checkout repository uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 - name: Set up Go - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 + uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6 with: cache: false go-version-file: go.mod diff --git a/.github/workflows/safe-output-health.lock.yml b/.github/workflows/safe-output-health.lock.yml index 120464489f0..df7a8c5f86c 100644 --- a/.github/workflows/safe-output-health.lock.yml +++ b/.github/workflows/safe-output-health.lock.yml @@ -117,7 +117,7 @@ jobs: - name: Create gh-aw temp directory run: bash /opt/gh-aw/actions/create_gh_aw_tmp_dir.sh - name: Set up Go - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 + uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6 with: cache: true go-version-file: go.mod diff --git a/.github/workflows/static-analysis-report.lock.yml b/.github/workflows/static-analysis-report.lock.yml index 99bd6115f91..9deb84b0871 100644 --- a/.github/workflows/static-analysis-report.lock.yml +++ b/.github/workflows/static-analysis-report.lock.yml @@ -116,7 +116,7 @@ jobs: - name: Create gh-aw temp directory run: bash /opt/gh-aw/actions/create_gh_aw_tmp_dir.sh - name: Set up Go - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 + uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6 with: cache: true go-version-file: go.mod diff --git a/.github/workflows/tidy.lock.yml b/.github/workflows/tidy.lock.yml index 27d69710830..5d7ef7ddf8f 100644 --- a/.github/workflows/tidy.lock.yml +++ b/.github/workflows/tidy.lock.yml @@ -149,7 +149,7 @@ jobs: cache-dependency-path: actions/setup/js/package-lock.json node-version: "24" - name: Set up Go - uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 + uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6 with: cache: true go-version-file: go.mod diff --git a/actions/setup/sh/convert_gateway_config_copilot.sh b/actions/setup/sh/convert_gateway_config_copilot.sh index d3721ba55d0..73c7ca9244c 100755 --- a/actions/setup/sh/convert_gateway_config_copilot.sh +++ b/actions/setup/sh/convert_gateway_config_copilot.sh @@ -26,7 +26,7 @@ echo "Input: $MCP_GATEWAY_OUTPUT" # { # "mcpServers": { # "server-name": { -# "type": "http", +# "type": "http" or "stdio", # "url": "http://domain:port/mcp/server-name", # "headers": { # "Authorization": "apiKey" @@ -39,7 +39,7 @@ echo "Input: $MCP_GATEWAY_OUTPUT" # { # "mcpServers": { # "server-name": { -# "type": "http", +# "type": "http" or "local", # "url": "http://domain:port/mcp/server-name", # "headers": { # "Authorization": "apiKey" @@ -49,12 +49,17 @@ echo "Input: $MCP_GATEWAY_OUTPUT" # } # } # -# The main difference is that Copilot requires the "tools" field. -# We also need to ensure headers use the actual API key value, not a placeholder. +# The main differences for Copilot: +# 1. Copilot requires the "tools" field +# 2. Copilot uses "local" instead of "stdio" for containerized servers +# 3. HTTP servers keep "type": "http" and don't need conversion jq ' .mcpServers |= with_entries( .value |= ( + # Convert stdio to local for Copilot compatibility + if .type == "stdio" then .type = "local" else . end | + # Add tools field if not present if .tools then . else . + {"tools": ["*"]} end ) ) diff --git a/pkg/workflow/runtime_detection.go b/pkg/workflow/runtime_detection.go index b4384d4ad12..e290fa80ac2 100644 --- a/pkg/workflow/runtime_detection.go +++ b/pkg/workflow/runtime_detection.go @@ -223,14 +223,14 @@ func mapSerenaLanguageToRuntime(serenaLang string) string { "rust": "rust", // Alternative names or variants - "python_jedi": "python", - "typescript_vts": "node", - "ruby_solargraph": "ruby", - "kotlin": "java", // Kotlin runs on JVM - "scala": "java", // Scala runs on JVM - "csharp": "dotnet", - "csharp_omnisharp": "dotnet", - "erlang": "elixir", // Erlang uses same runtime setup + "python_jedi": "python", + "typescript_vts": "node", + "ruby_solargraph": "ruby", + "kotlin": "java", // Kotlin runs on JVM + "scala": "java", // Scala runs on JVM + "csharp": "dotnet", + "csharp_omnisharp": "dotnet", + "erlang": "elixir", // Erlang uses same runtime setup // Languages that don't need runtime setup (return empty string) "bash": "", From ba137a94f6f643f8ae20f45f3a0bd6e12b45e631 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 13 Jan 2026 06:50:57 +0000 Subject: [PATCH 5/7] Merge main and recompile all workflows - Merged main branch with conflict resolution - Combined stdio-to-local conversion with URL rewriting in converter - Recompiled all 119 workflows successfully Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .github/workflows/cloclo.lock.yml | 65 +++++++++++++++++------- .github/workflows/mcp-inspector.lock.yml | 52 +++++++++++++++---- .github/workflows/q.lock.yml | 58 +++++++++++++++++---- 3 files changed, 134 insertions(+), 41 deletions(-) diff --git a/.github/workflows/cloclo.lock.yml b/.github/workflows/cloclo.lock.yml index 5a31212caf4..687f69b9c03 100644 --- a/.github/workflows/cloclo.lock.yml +++ b/.github/workflows/cloclo.lock.yml @@ -181,13 +181,18 @@ jobs: uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 with: persist-credentials: false + - name: Setup Go + uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 + with: + go-version: '1.25' + - name: Setup Python + uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 + with: + python-version: '3.12' + - name: Setup uv + uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5.4.2 - name: Create gh-aw temp directory run: bash /opt/gh-aw/actions/create_gh_aw_tmp_dir.sh - - name: Set up Go - uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6 - with: - cache: true - go-version-file: go.mod - name: Install dependencies run: make deps-dev - env: @@ -485,6 +490,41 @@ jobs: } } EOF + - name: Start Serena MCP HTTP Server + id: serena-start + run: | + set -eo pipefail + mkdir -p /tmp/gh-aw/mcp-logs/serena + + echo "Starting Serena MCP HTTP server on port 9121..." + + # Start Serena MCP server in background with uvx + uvx --from git+https://github.com/oraios/serena \ + serena start-mcp-server \ + --transport streamable-http \ + --port 9121 \ + --project "${{ github.workspace }}" \ + > /tmp/gh-aw/mcp-logs/serena/server.log 2>&1 & + + # Save PID for potential cleanup + echo $! > /tmp/gh-aw/serena-mcp-server.pid + + # Wait for server to start (max 30 seconds) + echo "Waiting for Serena MCP server to start..." + for i in {1..30}; do + if curl -s http://localhost:9121/health > /dev/null 2>&1; then + echo "Serena MCP server is ready" + break + fi + if [ $i -eq 30 ]; then + echo "ERROR: Serena MCP server failed to start within 30 seconds" + echo "Server logs:" + cat /tmp/gh-aw/mcp-logs/serena/server.log || true + exit 1 + fi + sleep 1 + done + - name: Start MCP gateway id: start-mcp-gateway env: @@ -559,20 +599,7 @@ jobs: } }, "serena": { - "container": "ghcr.io/oraios/serena:latest", - "args": [ - "--network", - "host" - ], - "entrypoint": "serena", - "entrypointArgs": [ - "start-mcp-server", - "--context", - "codex", - "--project", - "${{ github.workspace }}" - ], - "mounts": ["${{ github.workspace }}:${{ github.workspace }}:rw"] + "url": "http://localhost:9121" } }, "gateway": { diff --git a/.github/workflows/mcp-inspector.lock.yml b/.github/workflows/mcp-inspector.lock.yml index b78d5ed5621..70b94395543 100644 --- a/.github/workflows/mcp-inspector.lock.yml +++ b/.github/workflows/mcp-inspector.lock.yml @@ -127,6 +127,10 @@ jobs: uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 with: persist-credentials: false + - name: Setup Go + uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 + with: + go-version: '1.25' - name: Setup Node.js uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0 with: @@ -140,11 +144,6 @@ jobs: uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5.4.2 - name: Create gh-aw temp directory run: bash /opt/gh-aw/actions/create_gh_aw_tmp_dir.sh - - name: Set up Go - uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6 - with: - cache: true - go-version-file: go.mod - name: Install dependencies run: make deps-dev - env: @@ -435,6 +434,41 @@ jobs: } } EOF + - name: Start Serena MCP HTTP Server + id: serena-start + run: | + set -eo pipefail + mkdir -p /tmp/gh-aw/mcp-logs/serena + + echo "Starting Serena MCP HTTP server on port 9121..." + + # Start Serena MCP server in background with uvx + uvx --from git+https://github.com/oraios/serena \ + serena start-mcp-server \ + --transport streamable-http \ + --port 9121 \ + --project "${{ github.workspace }}" \ + > /tmp/gh-aw/mcp-logs/serena/server.log 2>&1 & + + # Save PID for potential cleanup + echo $! > /tmp/gh-aw/serena-mcp-server.pid + + # Wait for server to start (max 30 seconds) + echo "Waiting for Serena MCP server to start..." + for i in {1..30}; do + if curl -s http://localhost:9121/health > /dev/null 2>&1; then + echo "Serena MCP server is ready" + break + fi + if [ $i -eq 30 ]; then + echo "ERROR: Serena MCP server failed to start within 30 seconds" + echo "Server logs:" + cat /tmp/gh-aw/mcp-logs/serena/server.log || true + exit 1 + fi + sleep 1 + done + - name: Start MCP gateway id: start-mcp-gateway env: @@ -726,12 +760,8 @@ jobs: } }, "serena": { - "type": "stdio", - "container": "ghcr.io/oraios/serena:latest", - "args": ["--network", "host"], - "entrypoint": "serena", - "entrypointArgs": ["start-mcp-server", "--context", "codex", "--project", "${{ github.workspace }}"], - "mounts": ["${{ github.workspace }}:${{ github.workspace }}:rw"] + "type": "http", + "url": "http://localhost:9121" }, "tavily": { "type": "http", diff --git a/.github/workflows/q.lock.yml b/.github/workflows/q.lock.yml index 420c2c52d2e..c00427aa87b 100644 --- a/.github/workflows/q.lock.yml +++ b/.github/workflows/q.lock.yml @@ -176,13 +176,18 @@ jobs: uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 with: persist-credentials: false + - name: Setup Go + uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 + with: + go-version: '1.25' + - name: Setup Python + uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 + with: + python-version: '3.12' + - name: Setup uv + uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5.4.2 - name: Create gh-aw temp directory run: bash /opt/gh-aw/actions/create_gh_aw_tmp_dir.sh - - name: Set up Go - uses: actions/setup-go@7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5 # v6 - with: - cache: true - go-version-file: go.mod - name: Install dependencies run: make deps-dev - env: @@ -482,6 +487,41 @@ jobs: } } EOF + - name: Start Serena MCP HTTP Server + id: serena-start + run: | + set -eo pipefail + mkdir -p /tmp/gh-aw/mcp-logs/serena + + echo "Starting Serena MCP HTTP server on port 9121..." + + # Start Serena MCP server in background with uvx + uvx --from git+https://github.com/oraios/serena \ + serena start-mcp-server \ + --transport streamable-http \ + --port 9121 \ + --project "${{ github.workspace }}" \ + > /tmp/gh-aw/mcp-logs/serena/server.log 2>&1 & + + # Save PID for potential cleanup + echo $! > /tmp/gh-aw/serena-mcp-server.pid + + # Wait for server to start (max 30 seconds) + echo "Waiting for Serena MCP server to start..." + for i in {1..30}; do + if curl -s http://localhost:9121/health > /dev/null 2>&1; then + echo "Serena MCP server is ready" + break + fi + if [ $i -eq 30 ]; then + echo "ERROR: Serena MCP server failed to start within 30 seconds" + echo "Server logs:" + cat /tmp/gh-aw/mcp-logs/serena/server.log || true + exit 1 + fi + sleep 1 + done + - name: Start MCP gateway id: start-mcp-gateway env: @@ -545,12 +585,8 @@ jobs: } }, "serena": { - "type": "stdio", - "container": "ghcr.io/oraios/serena:latest", - "args": ["--network", "host"], - "entrypoint": "serena", - "entrypointArgs": ["start-mcp-server", "--context", "codex", "--project", "${{ github.workspace }}"], - "mounts": ["${{ github.workspace }}:${{ github.workspace }}:rw"] + "type": "http", + "url": "http://localhost:9121" }, "tavily": { "type": "http", From a332056e316331ccf736fe28bf3b274b66f6925c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 13 Jan 2026 07:00:55 +0000 Subject: [PATCH 6/7] Fix gateway converters to preserve direct HTTP server URLs Updated all three MCP gateway converters (Copilot, Claude, Codex) to properly handle direct HTTP servers like Serena: - Copilot: Added clearer comments about URL rewriting logic - Claude: Added comments clarifying gateway-proxied vs direct HTTP servers - Codex: Fixed URL construction to preserve original URL for direct HTTP servers (previously always rewrote URLs to gateway format) The regex pattern ^http://[^/]+/mcp/ only matches gateway-proxied URLs, so Serena's http://localhost:9121 passes through unchanged. Codex converter now uses conditional logic instead of always constructing gateway URLs. Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- actions/setup/sh/convert_gateway_config_claude.sh | 4 +++- actions/setup/sh/convert_gateway_config_codex.sh | 10 +++++++++- actions/setup/sh/convert_gateway_config_copilot.sh | 5 +++-- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/actions/setup/sh/convert_gateway_config_claude.sh b/actions/setup/sh/convert_gateway_config_claude.sh index 639147cafe1..8ad92e3d935 100755 --- a/actions/setup/sh/convert_gateway_config_claude.sh +++ b/actions/setup/sh/convert_gateway_config_claude.sh @@ -74,7 +74,9 @@ jq --arg urlPrefix "$URL_PREFIX" ' .value |= ( (.type = "http") | (del(.tools)) | - # Fix the URL to use the correct domain + # Fix the URL to use the correct domain for gateway-proxied servers only + # URLs with /mcp/ prefix are gateway-proxied and need rewriting + # Direct HTTP servers (like Serena on localhost) should pass through unchanged .url |= (. | sub("^http://[^/]+/mcp/"; $urlPrefix + "/mcp/")) ) ) diff --git a/actions/setup/sh/convert_gateway_config_codex.sh b/actions/setup/sh/convert_gateway_config_codex.sh index 14c8107340a..833058e6b06 100755 --- a/actions/setup/sh/convert_gateway_config_codex.sh +++ b/actions/setup/sh/convert_gateway_config_codex.sh @@ -73,7 +73,15 @@ TOML_EOF jq -r --arg urlPrefix "$URL_PREFIX" ' .mcpServers | to_entries[] | "[mcp_servers.\(.key)]\n" + - "url = \"" + ($urlPrefix + "/mcp/" + .key) + "\"\n" + + # Use original URL if it doesn'\''t contain /mcp/ (direct HTTP servers like Serena) + # Otherwise construct gateway URL + "url = \"" + ( + if (.value.url | contains("/mcp/")) then + $urlPrefix + "/mcp/" + .key + else + .value.url + end + ) + "\"\n" + "http_headers = { Authorization = \"\(.value.headers.Authorization)\" }\n" ' "$MCP_GATEWAY_OUTPUT" >> /tmp/gh-aw/mcp-config/config.toml diff --git a/actions/setup/sh/convert_gateway_config_copilot.sh b/actions/setup/sh/convert_gateway_config_copilot.sh index bc8dd942285..b601581b19a 100755 --- a/actions/setup/sh/convert_gateway_config_copilot.sh +++ b/actions/setup/sh/convert_gateway_config_copilot.sh @@ -79,8 +79,9 @@ jq --arg urlPrefix "$URL_PREFIX" ' (if .type == "stdio" then .type = "local" else . end) | # Add tools field if not present (if .tools then . else . + {"tools": ["*"]} end) | - # Fix the URL to use the correct domain - # Replace http://anything:port/mcp/ with http://domain:port/mcp/ + # Fix the URL to use the correct domain for gateway-proxied servers only + # URLs with /mcp/ prefix are gateway-proxied and need rewriting + # Direct HTTP servers (like Serena on localhost) should pass through unchanged .url |= (. | sub("^http://[^/]+/mcp/"; $urlPrefix + "/mcp/")) ) ) From dbab4959389e83e3a2891d6b3ba2d55552716a2d Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Tue, 13 Jan 2026 04:25:07 -0800 Subject: [PATCH 7/7] Fix Serena MCP server URL to use host.docker.internal (#9817) --- .github/workflows/archie.lock.yml | 2 +- .github/workflows/cloclo.lock.yml | 2 +- .github/workflows/daily-file-diet.lock.yml | 2 +- .github/workflows/developer-docs-consolidator.lock.yml | 2 +- .github/workflows/duplicate-code-detector.lock.yml | 4 ++-- .github/workflows/glossary-maintainer.lock.yml | 2 +- .github/workflows/go-fan.lock.yml | 2 +- .github/workflows/jsweep.lock.yml | 2 +- .github/workflows/mcp-inspector.lock.yml | 2 +- .github/workflows/q.lock.yml | 2 +- .github/workflows/repository-quality-improver.lock.yml | 2 +- .github/workflows/smoke-claude.lock.yml | 2 +- .github/workflows/smoke-codex.lock.yml | 4 ++-- .github/workflows/smoke-copilot.lock.yml | 2 +- .github/workflows/terminal-stylist.lock.yml | 2 +- .github/workflows/typist.lock.yml | 2 +- pkg/workflow/importable_tools_test.go | 8 ++++---- pkg/workflow/mcp-config.go | 6 ++++-- pkg/workflow/mcp_config_comprehensive_test.go | 10 +++++----- pkg/workflow/mcp_renderer.go | 5 +++-- 20 files changed, 34 insertions(+), 31 deletions(-) diff --git a/.github/workflows/archie.lock.yml b/.github/workflows/archie.lock.yml index 374c889b955..b88d79f9b10 100644 --- a/.github/workflows/archie.lock.yml +++ b/.github/workflows/archie.lock.yml @@ -472,7 +472,7 @@ jobs: }, "serena": { "type": "http", - "url": "http://localhost:9121" + "url": "http://host.docker.internal:9121" } }, "gateway": { diff --git a/.github/workflows/cloclo.lock.yml b/.github/workflows/cloclo.lock.yml index 687f69b9c03..f6cafa6558e 100644 --- a/.github/workflows/cloclo.lock.yml +++ b/.github/workflows/cloclo.lock.yml @@ -599,7 +599,7 @@ jobs: } }, "serena": { - "url": "http://localhost:9121" + "url": "http://host.docker.internal:9121" } }, "gateway": { diff --git a/.github/workflows/daily-file-diet.lock.yml b/.github/workflows/daily-file-diet.lock.yml index 6c75554cdf0..c18e31c79e9 100644 --- a/.github/workflows/daily-file-diet.lock.yml +++ b/.github/workflows/daily-file-diet.lock.yml @@ -470,7 +470,7 @@ jobs: }, "serena": { "type": "http", - "url": "http://localhost:9121" + "url": "http://host.docker.internal:9121" } }, "gateway": { diff --git a/.github/workflows/developer-docs-consolidator.lock.yml b/.github/workflows/developer-docs-consolidator.lock.yml index 53546f3604a..141cb77b520 100644 --- a/.github/workflows/developer-docs-consolidator.lock.yml +++ b/.github/workflows/developer-docs-consolidator.lock.yml @@ -513,7 +513,7 @@ jobs: } }, "serena": { - "url": "http://localhost:9121" + "url": "http://host.docker.internal:9121" } }, "gateway": { diff --git a/.github/workflows/duplicate-code-detector.lock.yml b/.github/workflows/duplicate-code-detector.lock.yml index 423edbc18f4..82a54e65942 100644 --- a/.github/workflows/duplicate-code-detector.lock.yml +++ b/.github/workflows/duplicate-code-detector.lock.yml @@ -445,7 +445,7 @@ jobs: env_vars = ["GH_AW_MCP_LOG_DIR", "GH_AW_SAFE_OUTPUTS", "GH_AW_SAFE_OUTPUTS_CONFIG_PATH", "GH_AW_SAFE_OUTPUTS_TOOLS_PATH", "GH_AW_ASSETS_BRANCH", "GH_AW_ASSETS_MAX_SIZE_KB", "GH_AW_ASSETS_ALLOWED_EXTS", "GITHUB_REPOSITORY", "GITHUB_SERVER_URL", "GITHUB_SHA", "GITHUB_WORKSPACE", "DEFAULT_BRANCH"] [mcp_servers.serena] - url = "http://localhost:9121" + url = "http://host.docker.internal:9121" EOF # Generate JSON config for MCP gateway @@ -482,7 +482,7 @@ jobs: } }, "serena": { - "url": "http://localhost:9121" + "url": "http://host.docker.internal:9121" } }, "gateway": { diff --git a/.github/workflows/glossary-maintainer.lock.yml b/.github/workflows/glossary-maintainer.lock.yml index 6e67d32bc2d..3f3cb4ccf62 100644 --- a/.github/workflows/glossary-maintainer.lock.yml +++ b/.github/workflows/glossary-maintainer.lock.yml @@ -469,7 +469,7 @@ jobs: }, "serena": { "type": "http", - "url": "http://localhost:9121" + "url": "http://host.docker.internal:9121" } }, "gateway": { diff --git a/.github/workflows/go-fan.lock.yml b/.github/workflows/go-fan.lock.yml index de8a398d2b5..81dd77f5212 100644 --- a/.github/workflows/go-fan.lock.yml +++ b/.github/workflows/go-fan.lock.yml @@ -449,7 +449,7 @@ jobs: } }, "serena": { - "url": "http://localhost:9121" + "url": "http://host.docker.internal:9121" } }, "gateway": { diff --git a/.github/workflows/jsweep.lock.yml b/.github/workflows/jsweep.lock.yml index b60db5a2cbd..ddc1c0fd58a 100644 --- a/.github/workflows/jsweep.lock.yml +++ b/.github/workflows/jsweep.lock.yml @@ -470,7 +470,7 @@ jobs: }, "serena": { "type": "http", - "url": "http://localhost:9121" + "url": "http://host.docker.internal:9121" } }, "gateway": { diff --git a/.github/workflows/mcp-inspector.lock.yml b/.github/workflows/mcp-inspector.lock.yml index 70b94395543..59b8b854166 100644 --- a/.github/workflows/mcp-inspector.lock.yml +++ b/.github/workflows/mcp-inspector.lock.yml @@ -761,7 +761,7 @@ jobs: }, "serena": { "type": "http", - "url": "http://localhost:9121" + "url": "http://host.docker.internal:9121" }, "tavily": { "type": "http", diff --git a/.github/workflows/q.lock.yml b/.github/workflows/q.lock.yml index c00427aa87b..0e9138ff724 100644 --- a/.github/workflows/q.lock.yml +++ b/.github/workflows/q.lock.yml @@ -586,7 +586,7 @@ jobs: }, "serena": { "type": "http", - "url": "http://localhost:9121" + "url": "http://host.docker.internal:9121" }, "tavily": { "type": "http", diff --git a/.github/workflows/repository-quality-improver.lock.yml b/.github/workflows/repository-quality-improver.lock.yml index 77b2f0073f1..e47b9daec25 100644 --- a/.github/workflows/repository-quality-improver.lock.yml +++ b/.github/workflows/repository-quality-improver.lock.yml @@ -460,7 +460,7 @@ jobs: }, "serena": { "type": "http", - "url": "http://localhost:9121" + "url": "http://host.docker.internal:9121" } }, "gateway": { diff --git a/.github/workflows/smoke-claude.lock.yml b/.github/workflows/smoke-claude.lock.yml index b157c7c59a8..8fe18650ea5 100644 --- a/.github/workflows/smoke-claude.lock.yml +++ b/.github/workflows/smoke-claude.lock.yml @@ -698,7 +698,7 @@ jobs: } }, "serena": { - "url": "http://localhost:9121" + "url": "http://host.docker.internal:9121" }, "tavily": { "type": "http", diff --git a/.github/workflows/smoke-codex.lock.yml b/.github/workflows/smoke-codex.lock.yml index 6de1b324a25..a30243631fb 100644 --- a/.github/workflows/smoke-codex.lock.yml +++ b/.github/workflows/smoke-codex.lock.yml @@ -714,7 +714,7 @@ jobs: env_vars = ["GH_AW_MCP_LOG_DIR", "GH_AW_SAFE_OUTPUTS", "GH_AW_SAFE_OUTPUTS_CONFIG_PATH", "GH_AW_SAFE_OUTPUTS_TOOLS_PATH", "GH_AW_ASSETS_BRANCH", "GH_AW_ASSETS_MAX_SIZE_KB", "GH_AW_ASSETS_ALLOWED_EXTS", "GITHUB_REPOSITORY", "GITHUB_SERVER_URL", "GITHUB_SHA", "GITHUB_WORKSPACE", "DEFAULT_BRANCH"] [mcp_servers.serena] - url = "http://localhost:9121" + url = "http://host.docker.internal:9121" [mcp_servers.tavily] url = "https://mcp.tavily.com/mcp/" @@ -779,7 +779,7 @@ jobs: } }, "serena": { - "url": "http://localhost:9121" + "url": "http://host.docker.internal:9121" }, "tavily": { "type": "http", diff --git a/.github/workflows/smoke-copilot.lock.yml b/.github/workflows/smoke-copilot.lock.yml index c53808edc37..0dd374c97ff 100644 --- a/.github/workflows/smoke-copilot.lock.yml +++ b/.github/workflows/smoke-copilot.lock.yml @@ -581,7 +581,7 @@ jobs: }, "serena": { "type": "http", - "url": "http://localhost:9121" + "url": "http://host.docker.internal:9121" } }, "gateway": { diff --git a/.github/workflows/terminal-stylist.lock.yml b/.github/workflows/terminal-stylist.lock.yml index 24022f4fcd0..db0ffb1230b 100644 --- a/.github/workflows/terminal-stylist.lock.yml +++ b/.github/workflows/terminal-stylist.lock.yml @@ -438,7 +438,7 @@ jobs: }, "serena": { "type": "http", - "url": "http://localhost:9121" + "url": "http://host.docker.internal:9121" } }, "gateway": { diff --git a/.github/workflows/typist.lock.yml b/.github/workflows/typist.lock.yml index a9196d96bee..0b7b8a9c5a2 100644 --- a/.github/workflows/typist.lock.yml +++ b/.github/workflows/typist.lock.yml @@ -436,7 +436,7 @@ jobs: } }, "serena": { - "url": "http://localhost:9121" + "url": "http://host.docker.internal:9121" } }, "gateway": { diff --git a/pkg/workflow/importable_tools_test.go b/pkg/workflow/importable_tools_test.go index c82ecd2eb89..932fe922f0a 100644 --- a/pkg/workflow/importable_tools_test.go +++ b/pkg/workflow/importable_tools_test.go @@ -160,8 +160,8 @@ Uses imported serena tool. if !strings.Contains(workflowData, "uvx --from git+https://github.com/oraios/serena") { t.Error("Expected compiled workflow to use uvx to start Serena") } - if !strings.Contains(workflowData, "http://localhost:9121") { - t.Error("Expected compiled workflow to contain Serena HTTP URL") + if !strings.Contains(workflowData, "http://host.docker.internal:9121") { + t.Error("Expected compiled workflow to contain Serena HTTP URL with host.docker.internal") } // Verify that language service setup steps ARE present @@ -324,8 +324,8 @@ Uses all imported tools. if !strings.Contains(workflowData, "mcr.microsoft.com/playwright/mcp") { t.Error("Expected compiled workflow to contain playwright Docker image") } - if !strings.Contains(workflowData, "http://localhost:9121") { - t.Error("Expected compiled workflow to contain Serena HTTP URL") + if !strings.Contains(workflowData, "http://host.docker.internal:9121") { + t.Error("Expected compiled workflow to contain Serena HTTP URL with host.docker.internal") } if !strings.Contains(workflowData, "example.com") { t.Error("Expected compiled workflow to contain example.com domain for playwright") diff --git a/pkg/workflow/mcp-config.go b/pkg/workflow/mcp-config.go index 792826b06ad..cf81b5c8d8e 100644 --- a/pkg/workflow/mcp-config.go +++ b/pkg/workflow/mcp-config.go @@ -147,7 +147,8 @@ func renderPlaywrightMCPConfigWithOptions(yaml *strings.Builder, playwrightTool // renderSerenaMCPConfigWithOptions generates the Serena MCP server configuration with engine-specific options // Serena now runs using uvx with HTTP transport in the agent job (not containerized) -// The HTTP server is started in a background step and accessed via http://localhost:9121 +// The HTTP server is started in a background step and accessed via http://host.docker.internal:9121 +// Note: host.docker.internal is used because the MCP gateway runs in a container and needs to reach the host func renderSerenaMCPConfigWithOptions(yaml *strings.Builder, serenaTool any, isLast bool, includeCopilotFields bool, inlineArgs bool) { yaml.WriteString(" \"serena\": {\n") @@ -157,7 +158,8 @@ func renderSerenaMCPConfigWithOptions(yaml *strings.Builder, serenaTool any, isL } // HTTP URL for Serena MCP server running on host - yaml.WriteString(" \"url\": \"http://localhost:9121\"\n") + // Use host.docker.internal so the gateway container can reach the host + yaml.WriteString(" \"url\": \"http://host.docker.internal:9121\"\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. diff --git a/pkg/workflow/mcp_config_comprehensive_test.go b/pkg/workflow/mcp_config_comprehensive_test.go index e896758fb5d..4dba3060fd0 100644 --- a/pkg/workflow/mcp_config_comprehensive_test.go +++ b/pkg/workflow/mcp_config_comprehensive_test.go @@ -574,7 +574,7 @@ func TestRenderSerenaMCPConfigWithOptions(t *testing.T) { inlineArgs: false, expectedContent: []string{ `"serena": {`, - `"url": "http://localhost:9121"`, + `"url": "http://host.docker.internal:9121"`, ` },`, }, unexpectedContent: []string{ @@ -593,7 +593,7 @@ func TestRenderSerenaMCPConfigWithOptions(t *testing.T) { inlineArgs: false, expectedContent: []string{ `"serena": {`, - `"url": "http://localhost:9121"`, + `"url": "http://host.docker.internal:9121"`, ` }`, }, unexpectedContent: []string{ @@ -612,7 +612,7 @@ func TestRenderSerenaMCPConfigWithOptions(t *testing.T) { expectedContent: []string{ `"serena": {`, `"type": "http"`, - `"url": "http://localhost:9121"`, + `"url": "http://host.docker.internal:9121"`, }, unexpectedContent: []string{ `"container"`, @@ -627,7 +627,7 @@ func TestRenderSerenaMCPConfigWithOptions(t *testing.T) { expectedContent: []string{ `"serena": {`, `"type": "http"`, - `"url": "http://localhost:9121"`, + `"url": "http://host.docker.internal:9121"`, }, unexpectedContent: []string{ `"container"`, @@ -644,7 +644,7 @@ func TestRenderSerenaMCPConfigWithOptions(t *testing.T) { inlineArgs: false, expectedContent: []string{ `"serena": {`, - `"url": "http://localhost:9121"`, + `"url": "http://host.docker.internal:9121"`, }, unexpectedContent: []string{ `"container"`, diff --git a/pkg/workflow/mcp_renderer.go b/pkg/workflow/mcp_renderer.go index 2cce44fb0e0..d3d6663654a 100644 --- a/pkg/workflow/mcp_renderer.go +++ b/pkg/workflow/mcp_renderer.go @@ -186,11 +186,12 @@ func (r *MCPConfigRendererUnified) RenderSerenaMCP(yaml *strings.Builder, serena // renderSerenaTOML generates Serena MCP configuration in TOML format // Serena now runs using uvx with HTTP transport in the agent job (not containerized) -// The HTTP server is started in a background step and accessed via http://localhost:9121 +// The HTTP server is started in a background step and accessed via http://host.docker.internal:9121 +// Note: host.docker.internal is used because the MCP gateway runs in a container and needs to reach the host func (r *MCPConfigRendererUnified) renderSerenaTOML(yaml *strings.Builder, serenaTool any) { yaml.WriteString(" \n") yaml.WriteString(" [mcp_servers.serena]\n") - yaml.WriteString(" url = \"http://localhost:9121\"\n") + yaml.WriteString(" url = \"http://host.docker.internal:9121\"\n") } // RenderSafeOutputsMCP generates the Safe Outputs MCP server configuration