Skip to content

[file-diet] Refactor pkg/workflow/mcp_renderer.go (1053 lines) into focused modules #20799

@github-actions

Description

@github-actions

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

  1. Format Router (6×) — if Format=="toml" { renderXxxTOML() } else { renderXxxJSON() }
  2. Env Var Sorting (3×) — create slice, append keys, sort, iterate
  3. TOML Section Building (6×) — [mcp_servers.xxx] with entrypointArgs
  4. Guard Policy Conditional (3×) — if len(GuardPolicies) > 0 { renderGuardPolicies* }
  5. 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

  1. 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
  2. mcp_renderer_github.go

    • Functions: RenderGitHubMCP, renderGitHubTOML (split into renderGitHubTOMLRemote + renderGitHubTOMLLocal), RenderGitHubMCPDockerConfig, RenderGitHubMCPRemoteConfig
    • Responsibility: All GitHub MCP rendering (the largest single concern in the file)
    • Estimated LOC: ~310
  3. 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
  4. mcp_renderer_guard.go

    • Functions: renderGuardPoliciesJSON, renderGuardPoliciesToml
    • Responsibility: Guard / access-control policy rendering (used across multiple renderers)
    • Estimated LOC: ~65
  5. mcp_renderer.go (trimmed)

    • Functions: NewMCPConfigRenderer, HandleCustomMCPToolInSwitch, RenderJSONMCPConfig
    • Responsibility: Factory, custom-tool switch handling, and the top-level JSON orchestrator
    • Estimated LOC: ~140

Shared Utilities to Extract

  • sortedMapKeys(m map[string]string) []string — deduplicate the 3× env-var-sorting pattern; add to mcp_renderer.go or a maputil package.
  • hasGuardPolicies(policies []string) bool — small inline helper to replace 3× guard-policy conditionals.

Interface Abstractions

  • Consider a MCPFormatRenderer interface with RenderTOML() string and RenderJSON() string to 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:

  1. 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%
  2. mcp_renderer_builtin_test.go

    • Test cases: Playwright/Serena/SafeOutputs/MCPScripts/AgenticWorkflows TOML generation, dev vs release mode for agentic workflows
    • Target coverage: ≥80%
  3. mcp_renderer_guard_test.go

    • Test cases: Empty policies, single policy, multiple policies, TOML vs JSON format
    • Target coverage: ≥80%
  4. mcp_renderer_test.go (trimmed)

    • Test cases: Factory creation, HandleCustomMCPToolInSwitch, RenderJSONMCPConfig orchestration
    • Target coverage: ≥80%

Implementation Guidelines

  1. Preserve Behavior: Ensure all existing functionality works identically after the split
  2. Maintain Exports: Keep all public API signatures unchanged (Render*, Handle*, struct types)
  3. Add Tests First: Verify existing tests pass, then expand coverage per the plan above
  4. Incremental Changes: Move one group (e.g., guard policies first — smallest) at a time
  5. Run Tests Frequently: Verify make test-unit passes after each split
  6. Update Imports: All files remain in package workflow — no import path changes needed
  7. Document Boundaries: Add a package-doc comment block in mcp_renderer.go explaining the module split

Acceptance Criteria

  • mcp_renderer.go is 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-finish passes 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 !integration build 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

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions