Skip to content

Commit 94c3b13

Browse files
Copilotpelikhangithub-actions[bot]claude
authored
Refactor MCP setup generation to eliminate generateMCPSetup architecture violation (#28114)
* Initial plan * refactor: split generateMCPSetup into focused helpers Agent-Logs-Url: https://github.com/github/gh-aw/sessions/da890753-4f2d-411f-b47e-0f848335b3ea Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> * chore: address review feedback in mcp setup refactor Agent-Logs-Url: https://github.com/github/gh-aw/sessions/da890753-4f2d-411f-b47e-0f848335b3ea Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> * chore: finalize mcp setup helper naming Agent-Logs-Url: https://github.com/github/gh-aw/sessions/da890753-4f2d-411f-b47e-0f848335b3ea Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> * chore: polish mcp setup helper naming and errors Agent-Logs-Url: https://github.com/github/gh-aw/sessions/da890753-4f2d-411f-b47e-0f848335b3ea Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> * docs(adr): add draft ADR-28114 for MCP setup generator decomposition Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> Co-authored-by: Peli de Halleux <pelikhan@users.noreply.github.com>
1 parent 7ac9dc6 commit 94c3b13

2 files changed

Lines changed: 544 additions & 628 deletions

File tree

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# ADR-28114: Decompose MCP Setup Generator into Single-Responsibility Helpers
2+
3+
**Date**: 2026-04-23
4+
**Status**: Draft
5+
**Deciders**: pelikhan
6+
7+
---
8+
9+
## Part 1 — Narrative (Human-Friendly)
10+
11+
### Context
12+
13+
`pkg/workflow/mcp_setup_generator.go` contains a single orchestration function, `generateMCPSetup`, that had grown to approximately 852 lines. It handled MCP tool discovery, conditional safe-outputs config generation, agentic-workflows install step emission, safe-outputs setup, mcp-scripts setup, and MCP gateway step/env/export/container-command assembly — all inlined within one function body. The Architecture Guardian flagged this as a critical function-size violation. The function's size made individual concerns hard to navigate, test in isolation, or extend without risk of unintended side effects on adjacent logic.
14+
15+
### Decision
16+
17+
We will decompose `generateMCPSetup` into a thin coordinator that delegates each distinct concern to a focused helper function. `generateMCPSetup` itself becomes a sequencing orchestrator that calls `collectMCPTools`, `generateSafeOutputsConfigIfEnabled`, `generateAgenticWorkflowsInstallStep`, `generateSafeOutputsSetup`, `generateMCPScriptsSetup`, and `generateMCPGatewaySetup`. All helpers remain in `mcp_setup_generator.go`; no new packages are introduced. External behavior and output structure are preserved identically.
18+
19+
### Alternatives Considered
20+
21+
#### Alternative 1: Retain the Monolithic Function with Inline Comments
22+
23+
Add section comments and godoc cross-references to document the structure of `generateMCPSetup` without splitting it. This approach has zero structural diff risk. It was rejected because documentation describes structure but does not enforce it — the function remains a single unit that cannot be tested or reviewed by concern, and the comments will drift as the function evolves. The root problem is co-mingled responsibilities, which only decomposition fixes.
24+
25+
#### Alternative 2: Extract MCP Setup Concerns into Separate Files or a Sub-Package
26+
27+
Move each concern into a dedicated file (e.g., `mcp_tool_collector.go`, `mcp_gateway_setup.go`) or a new `pkg/workflow/mcpsetup` sub-package. This maximises navigability at the directory level. It was not chosen because the helpers are small and tightly coupled to `WorkflowData` and `Compiler` types that live in `pkg/workflow`. A sub-package would add import indirection without meaningful boundary enforcement — all code changes together in the same PR. File-level decomposition within `mcp_setup_generator.go` is sufficient to resolve the function-size violation while keeping locality of reference.
28+
29+
### Consequences
30+
31+
#### Positive
32+
- `generateMCPSetup` is now a readable four-line coordinator; the intent of the setup sequence is visible at a glance.
33+
- Each helper (`collectMCPTools`, `generateMCPGatewaySetup`, etc.) can be reviewed, tested, and extended independently.
34+
- Higher-context error wrapping at orchestration boundaries (`"safe outputs setup preparation failed: %w"`) improves diagnostic clarity when errors surface.
35+
- The deduplication set for forwarded env vars and the gateway command construction are now isolated, reducing the risk of accidental mutation when either concern changes.
36+
37+
#### Negative
38+
- The refactor produces a large diff (470 additions, 628 deletions across a single file) with no functional change, which increases reviewer burden to verify behavioral equivalence.
39+
- Adding function call boundaries introduces a small indirection cost: understanding the full setup sequence now requires reading multiple function signatures rather than one linear flow.
40+
41+
#### Neutral
42+
- All helpers are package-private (`func`, not exported), so no public API surface changes.
43+
- The `hasGhAwSharedImport` helper extracted here may be reused by other generators in `pkg/workflow/` as a shared import-detection utility.
44+
- Existing tests continue to exercise the behavior through `generateMCPSetup`; unit tests targeting individual helpers can be added incrementally.
45+
46+
---
47+
48+
## Part 2 — Normative Specification (RFC 2119)
49+
50+
> The key words **MUST**, **MUST NOT**, **REQUIRED**, **SHALL**, **SHALL NOT**, **SHOULD**, **SHOULD NOT**, **RECOMMENDED**, **MAY**, and **OPTIONAL** in this section are to be interpreted as described in [RFC 2119](https://www.rfc-editor.org/rfc/rfc2119).
51+
52+
### Function Decomposition
53+
54+
1. `generateMCPSetup` **MUST** act as a coordinator only: it **MUST NOT** contain inline logic for tool discovery, config generation, or YAML emission beyond delegating to named helpers.
55+
2. Each concern in the MCP setup pipeline (tool collection, safe-outputs config, install step emission, gateway assembly) **MUST** be implemented in a dedicated helper function with a name that describes its single responsibility.
56+
3. New logic added to the MCP setup pipeline **MUST** be placed in an appropriately scoped helper rather than inlined into `generateMCPSetup`.
57+
58+
### File Ownership
59+
60+
1. All MCP setup helpers **MUST** reside in `pkg/workflow/mcp_setup_generator.go` unless a helper is broadly reusable across the `pkg/workflow` package, in which case it **SHOULD** be moved to a shared file within the same package.
61+
2. MCP setup helpers **MUST NOT** be placed in a separate sub-package unless the sub-package is justified by an independent ADR.
62+
63+
### Error Handling
64+
65+
1. Errors returned from helpers called within `generateMCPSetup` **MUST** be wrapped with a context phrase that identifies the failing phase (e.g., `"safe outputs setup preparation failed: %w"`).
66+
2. Helper functions **SHOULD NOT** wrap errors internally when the caller can provide richer context.
67+
68+
### Conformance
69+
70+
An implementation is considered conformant with this ADR if it satisfies all **MUST** and **MUST NOT** requirements above. Failure to meet any **MUST** or **MUST NOT** requirement constitutes non-conformance.
71+
72+
---
73+
74+
*This is a DRAFT ADR generated by the [Design Decision Gate](https://github.com/github/gh-aw/actions/runs/24844753173) workflow. The PR author must review, complete, and finalize this document before the PR can merge.*

0 commit comments

Comments
 (0)