Skip to content

refactor(files): CQRS consolidation - 5 tools → 2 tools #12

@polaz

Description

@polaz

Summary

Consolidate 5 file tools into 2 CQRS-aligned tools for better MCP client compatibility and cleaner read/write separation.

Current State (5 tools)

Tool Type Description
get_repository_tree READ List files/folders in repository
get_file_contents READ Get file content
create_or_update_file WRITE Single file commit
push_files WRITE Batch file commit
upload_markdown WRITE Upload attachment for markdown

Target State (2 tools)

browse_files (Query)

Consolidates all READ operations:

{
  action: "tree" | "content",
  
  // Common
  projectId: string,
  ref?: string,              // Branch, tag, or commit SHA
  
  // For "tree" action
  path?: string,             // Directory path
  recursive?: boolean,
  per_page?: number,
  page?: number,
  
  // For "content" action
  file_path: string          // File path to read
}

Read-only mode: Always allowed

manage_files (Command)

Consolidates all WRITE operations:

{
  action: "single" | "batch" | "upload",
  
  // Common
  projectId: string,
  
  // For "single" action (create_or_update_file)
  file_path?: string,
  content?: string,          // Base64 encoded
  commit_message?: string,
  branch?: string,
  start_branch?: string,
  author_email?: string,
  author_name?: string,
  
  // For "batch" action (push_files)
  files?: Array<{
    file_path: string,
    content?: string,        // Base64 encoded (for create/update)
    action: "create" | "update" | "delete" | "move",
    previous_path?: string   // For move action
  }>,
  
  // For "upload" action (upload_markdown)
  file?: string,             // Base64 encoded file
  filename?: string
}

Read-only mode: Blocked entirely

Implementation Tasks

  • Create new browse_files handler with action dispatch
  • Create new manage_files handler with action dispatch
  • Update Zod schemas with discriminated union pattern
  • Update registry to export new tool names
  • Update read-only tools list (only browse_files)
  • Remove old handlers after migration
  • Update unit tests
  • Update integration tests

Schema Pattern

const ManageFilesSchema = z.discriminatedUnion("action", [
  z.object({
    action: z.literal("single"),
    projectId: z.string(),
    file_path: z.string(),
    content: z.string(),      // Base64
    commit_message: z.string(),
    branch: z.string().optional(),
    // ...
  }),
  z.object({
    action: z.literal("batch"),
    projectId: z.string(),
    branch: z.string(),
    commit_message: z.string(),
    files: z.array(FileActionSchema),
  }),
  z.object({
    action: z.literal("upload"),
    projectId: z.string(),
    file: z.string(),         // Base64
    filename: z.string(),
  }),
]);

Breaking Changes

Old Tool Migration Path
get_repository_tree browse_files with action: "tree"
get_file_contents browse_files with action: "content"
create_or_update_file manage_files with action: "single"
push_files manage_files with action: "batch"
upload_markdown manage_files with action: "upload"

Feature Flag

Existing USE_FILES flag continues to control entire files entity visibility.

Testing Requirements

  • Unit tests for discriminated union schema validation
  • Test tree listing with pagination
  • Test file content retrieval
  • Test single file create/update
  • Test batch file operations
  • Test markdown upload
  • Test read-only mode blocks manage_files entirely
  • Integration tests for all operations

Acceptance Criteria

  • Total tools reduced from 5 to 2
  • All existing functionality preserved
  • Base64 encoding/decoding works correctly
  • Batch operations atomic (all-or-nothing)
  • Read-only mode correctly gates write operations
  • Clear error messages for invalid action/parameter combinations

Metadata

Metadata

Assignees

No one assigned

    Labels

    refactorCode restructuring without behavior change

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions