-
Notifications
You must be signed in to change notification settings - Fork 296
Description
Overview
The file pkg/workflow/mcp_renderer.go has grown to 1053 lines, exceeding the healthy threshold of 800 lines. The file acts as a monolithic renderer for multiple MCP server types across different engines (Claude, Copilot, Codex, Custom) and formats (TOML, JSON). Splitting it into focused modules will improve maintainability, testability, and reduce cognitive load.
Current State
- File:
pkg/workflow/mcp_renderer.go - Size: 1053 lines
- Test file:
pkg/workflow/mcp_renderer_test.go— 510 lines (48% test-to-source ratio) - Complexity: 6 functions over 60 lines; deepest nesting 3+ levels in
renderGitHubTOML
Full File Analysis
Functions & Types (with line numbers)
| Symbol | Lines | Size |
|---|---|---|
MCPRendererOptions (struct) |
93–107 | 15 |
MCPConfigRendererUnified (struct) |
108–111 | 4 |
NewMCPConfigRenderer |
113–122 | 10 |
RenderGitHubMCP |
123–202 | 80 |
RenderPlaywrightMCP |
203–220 | 18 |
renderPlaywrightTOML |
221–259 | 39 |
RenderSerenaMCP |
260–270 | 11 |
renderSerenaTOML |
276–318 | 43 |
RenderSafeOutputsMCP |
320–333 | 14 |
renderSafeOutputsTOML |
334–365 | 32 |
RenderMCPScriptsMCP |
365–376 | 12 |
renderMCPScriptsTOML |
379–399 | 21 |
RenderAgenticWorkflowsMCP |
401–412 | 12 |
renderAgenticWorkflowsTOML |
415–475 | 61 |
renderGitHubTOML |
476–595 | 120 🔴 |
RenderCustomMCPToolConfigHandler (func type) |
597 | 1 |
HandleCustomMCPToolInSwitch |
611–629 | 19 |
MCPToolRenderers (struct) |
631–641 | 11 |
JSONMCPConfigOptions (struct) |
644–657 | 14 |
GitHubMCPDockerOptions (struct) |
660–683 | 24 |
RenderGitHubMCPDockerConfig |
692–786 | 95 |
GitHubMCPRemoteOptions (struct) |
788–809 | 22 |
RenderGitHubMCPRemoteConfig |
817–898 | 82 |
renderGuardPoliciesJSON |
899–916 | 17 |
renderGuardPoliciesToml |
916–957 | 41 |
RenderJSONMCPConfig |
957–1053 | 97 |
Duplicate Patterns
- Format Router (6×) —
if Format=="toml" { renderXxxTOML() } else { renderXxxJSON() } - Env Var Sorting (3×) — create slice, append keys, sort, iterate
- TOML Section Building (6×) —
[mcp_servers.xxx]withentrypointArgs - Guard Policy Conditional (3×) —
if len(GuardPolicies) > 0 { renderGuardPolicies* } - Engine-Specific Field Branching — Copilot vs Claude differences repeated across functions
Logical Groups & Line Distribution
| Group | ~Lines |
|---|---|
| Factory & initialization | 10 |
| Public Render APIs (format routers) | 147 |
| TOML format rendering | 216 |
| Shared GitHub MCP layer | 177 |
| Guard policy rendering | 58 |
Orchestration & routing (RenderJSONMCPConfig) |
116 |
| Type definitions | 110 |
| Documentation & comments | 219 |
Refactoring Strategy
Proposed File Splits
-
mcp_renderer_types.go- Types:
MCPRendererOptions,MCPConfigRendererUnified,RenderCustomMCPToolConfigHandler,MCPToolRenderers,JSONMCPConfigOptions,GitHubMCPDockerOptions,GitHubMCPRemoteOptions - Responsibility: All struct and func-type definitions for the renderer subsystem
- Estimated LOC: ~120
- Types:
-
mcp_renderer_github.go- Functions:
RenderGitHubMCP,renderGitHubTOML(split intorenderGitHubTOMLRemote+renderGitHubTOMLLocal),RenderGitHubMCPDockerConfig,RenderGitHubMCPRemoteConfig - Responsibility: All GitHub MCP rendering (the largest single concern in the file)
- Estimated LOC: ~310
- Functions:
-
mcp_renderer_builtin.go- Functions:
RenderPlaywrightMCP,renderPlaywrightTOML,RenderSerenaMCP,renderSerenaTOML,RenderSafeOutputsMCP,renderSafeOutputsTOML,RenderMCPScriptsMCP,renderMCPScriptsTOML,RenderAgenticWorkflowsMCP,renderAgenticWorkflowsTOML - Responsibility: All non-GitHub built-in MCP server renderers
- Estimated LOC: ~250
- Functions:
-
mcp_renderer_guard.go- Functions:
renderGuardPoliciesJSON,renderGuardPoliciesToml - Responsibility: Guard / access-control policy rendering (used across multiple renderers)
- Estimated LOC: ~65
- Functions:
-
mcp_renderer.go(trimmed)- Functions:
NewMCPConfigRenderer,HandleCustomMCPToolInSwitch,RenderJSONMCPConfig - Responsibility: Factory, custom-tool switch handling, and the top-level JSON orchestrator
- Estimated LOC: ~140
- Functions:
Shared Utilities to Extract
sortedMapKeys(m map[string]string) []string— deduplicate the 3× env-var-sorting pattern; add tomcp_renderer.goor amaputilpackage.hasGuardPolicies(policies []string) bool— small inline helper to replace 3× guard-policy conditionals.
Interface Abstractions
- Consider a
MCPFormatRendererinterface withRenderTOML() stringandRenderJSON() stringto replace the 6×if Format=="toml"pattern; each built-in server becomes a small struct implementing the interface.
Test Coverage Plan
Existing test file (mcp_renderer_test.go, 510 lines, 12 tests) should be split alongside source:
-
mcp_renderer_github_test.go- Test cases: Docker vs Remote mode selection, TOML Local vs Remote branch, Copilot vs Claude field differences, guard policy inclusion/exclusion, env var sort stability
- Target coverage: ≥80%
-
mcp_renderer_builtin_test.go- Test cases: Playwright/Serena/SafeOutputs/MCPScripts/AgenticWorkflows TOML generation, dev vs release mode for agentic workflows
- Target coverage: ≥80%
-
mcp_renderer_guard_test.go- Test cases: Empty policies, single policy, multiple policies, TOML vs JSON format
- Target coverage: ≥80%
-
mcp_renderer_test.go(trimmed)- Test cases: Factory creation,
HandleCustomMCPToolInSwitch,RenderJSONMCPConfigorchestration - Target coverage: ≥80%
- Test cases: Factory creation,
Implementation Guidelines
- Preserve Behavior: Ensure all existing functionality works identically after the split
- Maintain Exports: Keep all public API signatures unchanged (
Render*,Handle*, struct types) - Add Tests First: Verify existing tests pass, then expand coverage per the plan above
- Incremental Changes: Move one group (e.g., guard policies first — smallest) at a time
- Run Tests Frequently: Verify
make test-unitpasses after each split - Update Imports: All files remain in
package workflow— no import path changes needed - Document Boundaries: Add a package-doc comment block in
mcp_renderer.goexplaining the module split
Acceptance Criteria
-
mcp_renderer.gois split into 5 focused files (see above) - Each new file is under 500 lines
- All tests pass (
make test-unit) - Test coverage is ≥80% for each new file
- No breaking changes to public API
- Code passes linting (
make lint) - Build succeeds (
make build) -
make agent-finishpasses with no errors
Additional Context
- Repository Guidelines: Follow patterns in
AGENTS.md— prefer many small files grouped by functionality - Related files:
mcp_config_builtin.go,mcp_config_custom.go,mcp_github_config.go,mcp_setup_generator.go— review for consistency - Testing: Match existing test patterns in
pkg/workflow/*_test.go; every test file needs//go:build !integrationbuild tag - Workflow run: §23053038268
Priority: Medium
Effort: Medium (well-defined split boundaries, existing tests reduce regression risk)
Expected Impact: Improved maintainability, easier targeted testing, reduced cognitive load when navigating MCP rendering logic
Generated by Daily File Diet · ◷
- expires on Mar 15, 2026, 1:39 PM UTC