From 08e13973dd7db5f055fff91e3f0bc89f4c972165 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 20 May 2026 06:38:43 +0000 Subject: [PATCH 1/3] Initial plan From 47b32641f1e9e11d482f79a170b6e3cbd08e7448 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 20 May 2026 06:46:28 +0000 Subject: [PATCH 2/3] Initial plan: extract renderDefaultJSONMCPConfig helper Agent-Logs-Url: https://github.com/github/gh-aw/sessions/834767ce-37aa-4118-aee2-700213987ab3 Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com> --- .github/workflows/design-decision-gate.lock.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/design-decision-gate.lock.yml b/.github/workflows/design-decision-gate.lock.yml index 2f16f2869d5..d433e109a87 100644 --- a/.github/workflows/design-decision-gate.lock.yml +++ b/.github/workflows/design-decision-gate.lock.yml @@ -64,6 +64,8 @@ on: # names: # Label filtering applied via job conditions # - implementation # Label filtering applied via job conditions types: + - ready_for_review + - review_requested - labeled workflow_dispatch: inputs: From b6636a3cebef4f457574b2a0731089dc929eb0f8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 20 May 2026 06:51:53 +0000 Subject: [PATCH 3/3] refactor: extract renderDefaultJSONMCPConfig to eliminate duplicated MCP wrapper logic Agent-Logs-Url: https://github.com/github/gh-aw/sessions/834767ce-37aa-4118-aee2-700213987ab3 Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com> --- pkg/workflow/claude_mcp.go | 16 +--------------- pkg/workflow/crush_mcp.go | 10 +--------- pkg/workflow/gemini_mcp.go | 10 +--------- pkg/workflow/mcp_rendering.go | 21 +++++++++++++++++++++ pkg/workflow/opencode_mcp.go | 10 +--------- 5 files changed, 25 insertions(+), 42 deletions(-) diff --git a/pkg/workflow/claude_mcp.go b/pkg/workflow/claude_mcp.go index 65781c5c9fe..459a6cabf94 100644 --- a/pkg/workflow/claude_mcp.go +++ b/pkg/workflow/claude_mcp.go @@ -13,19 +13,5 @@ func (e *ClaudeEngine) RenderMCPConfig(yaml *strings.Builder, tools map[string]a claudeMCPLog.Printf("Rendering MCP config for Claude: tool_count=%d, mcp_tool_count=%d", len(tools), len(mcpTools)) // Claude uses JSON format without Copilot-specific fields and multi-line args - return renderStandardJSONMCPConfig(yaml, renderStandardJSONMCPConfigOptions{ - tools: tools, - mcpTools: mcpTools, - workflowData: workflowData, - configPath: "${RUNNER_TEMP}/gh-aw/mcp-config/mcp-servers.json", - renderCustom: func(yaml *strings.Builder, toolName string, toolConfig map[string]any, isLast bool) error { - return e.renderClaudeMCPConfigWithContext(yaml, toolName, toolConfig, isLast, workflowData) - }, - }) -} - -// renderClaudeMCPConfigWithContext generates custom MCP server configuration for a single tool in Claude workflow mcp-servers.json -// This version includes workflowData to determine if localhost URLs should be rewritten -func (e *ClaudeEngine) renderClaudeMCPConfigWithContext(yaml *strings.Builder, toolName string, toolConfig map[string]any, isLast bool, workflowData *WorkflowData) error { - return renderCustomMCPConfigWrapperWithContext(yaml, toolName, toolConfig, isLast, workflowData) + return renderDefaultJSONMCPConfig(yaml, tools, mcpTools, workflowData, "${RUNNER_TEMP}/gh-aw/mcp-config/mcp-servers.json") } diff --git a/pkg/workflow/crush_mcp.go b/pkg/workflow/crush_mcp.go index 89d7cd54e17..dcb15cc8d80 100644 --- a/pkg/workflow/crush_mcp.go +++ b/pkg/workflow/crush_mcp.go @@ -13,13 +13,5 @@ func (e *CrushEngine) RenderMCPConfig(sb *strings.Builder, tools map[string]any, crushMCPLog.Printf("Rendering MCP config for Crush: tool_count=%d, mcp_tool_count=%d", len(tools), len(mcpTools)) // Crush uses JSON format without Copilot-specific fields and multi-line args - return renderStandardJSONMCPConfig(sb, renderStandardJSONMCPConfigOptions{ - tools: tools, - mcpTools: mcpTools, - workflowData: workflowData, - configPath: "/tmp/gh-aw/mcp-config/mcp-servers.json", - renderCustom: func(builder *strings.Builder, toolName string, toolConfig map[string]any, isLast bool) error { - return renderCustomMCPConfigWrapperWithContext(builder, toolName, toolConfig, isLast, workflowData) - }, - }) + return renderDefaultJSONMCPConfig(sb, tools, mcpTools, workflowData, "/tmp/gh-aw/mcp-config/mcp-servers.json") } diff --git a/pkg/workflow/gemini_mcp.go b/pkg/workflow/gemini_mcp.go index 283addd467e..444c51e78ff 100644 --- a/pkg/workflow/gemini_mcp.go +++ b/pkg/workflow/gemini_mcp.go @@ -13,13 +13,5 @@ func (e *GeminiEngine) RenderMCPConfig(yaml *strings.Builder, tools map[string]a geminiMCPLog.Printf("Rendering MCP config for Gemini: tool_count=%d, mcp_tool_count=%d", len(tools), len(mcpTools)) // Gemini uses JSON format without Copilot-specific fields and multi-line args - return renderStandardJSONMCPConfig(yaml, renderStandardJSONMCPConfigOptions{ - tools: tools, - mcpTools: mcpTools, - workflowData: workflowData, - configPath: "${RUNNER_TEMP}/gh-aw/mcp-config/mcp-servers.json", - renderCustom: func(yaml *strings.Builder, toolName string, toolConfig map[string]any, isLast bool) error { - return renderCustomMCPConfigWrapperWithContext(yaml, toolName, toolConfig, isLast, workflowData) - }, - }) + return renderDefaultJSONMCPConfig(yaml, tools, mcpTools, workflowData, "${RUNNER_TEMP}/gh-aw/mcp-config/mcp-servers.json") } diff --git a/pkg/workflow/mcp_rendering.go b/pkg/workflow/mcp_rendering.go index e7e7bc6dece..9e90051f712 100644 --- a/pkg/workflow/mcp_rendering.go +++ b/pkg/workflow/mcp_rendering.go @@ -89,6 +89,27 @@ type renderStandardJSONMCPConfigOptions struct { filterTool func(string) bool } +// renderDefaultJSONMCPConfig is a convenience wrapper for renderStandardJSONMCPConfig used by +// simple JSON engines (Claude, Gemini, Crush, OpenCode) that share the standard +// renderCustomMCPConfigWrapperWithContext callback and differ only in their config path. +func renderDefaultJSONMCPConfig( + sb *strings.Builder, + tools map[string]any, + mcpTools []string, + workflowData *WorkflowData, + configPath string, +) error { + return renderStandardJSONMCPConfig(sb, renderStandardJSONMCPConfigOptions{ + tools: tools, + mcpTools: mcpTools, + workflowData: workflowData, + configPath: configPath, + renderCustom: func(builder *strings.Builder, toolName string, toolConfig map[string]any, isLast bool) error { + return renderCustomMCPConfigWrapperWithContext(builder, toolName, toolConfig, isLast, workflowData) + }, + }) +} + // renderStandardJSONMCPConfig is a shared helper for JSON MCP config rendering used by // Claude, Gemini, Copilot, and Codex engines. It consolidates the repeated sequence of: // buildMCPRendererFactory → buildMCPGatewayConfig → buildStandardJSONMCPRenderers → RenderJSONMCPConfig. diff --git a/pkg/workflow/opencode_mcp.go b/pkg/workflow/opencode_mcp.go index 74dede13d0e..169c9669635 100644 --- a/pkg/workflow/opencode_mcp.go +++ b/pkg/workflow/opencode_mcp.go @@ -12,13 +12,5 @@ var openCodeMCPLog = logger.New("workflow:opencode_mcp") func (e *OpenCodeEngine) RenderMCPConfig(sb *strings.Builder, tools map[string]any, mcpTools []string, workflowData *WorkflowData) error { openCodeMCPLog.Printf("Rendering MCP config for OpenCode: tool_count=%d, mcp_tool_count=%d", len(tools), len(mcpTools)) - return renderStandardJSONMCPConfig(sb, renderStandardJSONMCPConfigOptions{ - tools: tools, - mcpTools: mcpTools, - workflowData: workflowData, - configPath: "/tmp/gh-aw/mcp-config/mcp-servers.json", - renderCustom: func(builder *strings.Builder, toolName string, toolConfig map[string]any, isLast bool) error { - return renderCustomMCPConfigWrapperWithContext(builder, toolName, toolConfig, isLast, workflowData) - }, - }) + return renderDefaultJSONMCPConfig(sb, tools, mcpTools, workflowData, "/tmp/gh-aw/mcp-config/mcp-servers.json") }