Files
Gitea-Tools/docs/architecture/mcp-refactor-compatibility-matrix.md
T
2026-07-02 15:01:44 -05:00

8.6 KiB

MCP Gitea Server Refactor: Compatibility Matrix & Staged Plan

  • Status: Staging/Design (First phase of #65)
  • Issue: #65 (Staged refactor of mcp_server.py into a modular package)
  • Date: 2026-07-02

1. Overview and Refactoring Contract

The goal of this refactor is to split the monolith mcp_server.py (~1689 lines) into a clean, maintainable, and modular Python package (gitea_tools).

To ensure complete backward compatibility, we establish a strict contract:

  • No functional changes: Code behaviour, API endpoint targets, parameter sets, and return formats must remain identical.
  • No gate bypasses: Allowed operations, forbidden operations, identity resolving, and audit logging must continue to execute exactly as they do in the monolith.
  • Independent testing: The full pytest suite must pass with 100% success after every single stage.

2. Compatibility Matrix

The following table documents every MCP tool's expected signature, parameters, return payload shape, and error behavior that must be preserved.

2.1 Issue & Label Management Tools

Tool Name Parameters Return Payload Shape Error Behavior / Edge Cases
gitea_create_issue title: str, body: str, remote: str, host: str | None, org: str | None, repo: str | None Dict containing issue details (number, title, body, state, labels, assignee, url) Raises error on auth failure, missing parameters, or Gitea API validation error.
gitea_close_issue issue_number: int, remote: str, host: str | None, org: str | None, repo: str | None Dict detailing the closed issue. Raises 404 if issue doesn't exist; fails closed if user has insufficient permission.
gitea_list_issues state: str, label: str | None, limit: int, remote: str, host: str | None, org: str | None, repo: str | None List of dicts representing matched issues. Limits pagination per page and overall maximum caps.
gitea_view_issue issue_number: int, remote: str, host: str | None, org: str | None, repo: str | None Dict of detailed issue attributes. Returns clear 404 error if not found.
gitea_mark_issue issue_number: int, action: str, remote: str, host: str | None, org: str | None, repo: str | None Dict indicating current label states (presence of status:in-progress). Rejects unknown actions; fails if label doesn't exist on Gitea.
gitea_list_labels remote: str, host: str | None, org: str | None, repo: str | None List of dicts representing labels. Basic auth error fallback behavior.
gitea_create_label name: str, color: str, description: str, remote: str, host: str | None, org: str | None, repo: str | None Dict of created label properties. Fails on duplicate names or invalid color hex formats.
gitea_set_issue_labels issue_number: int, labels: list[str], remote: str, host: str | None, org: str | None, repo: str | None List of all labels currently applied to the issue. Fails closed if any label name does not exist.

2.2 PR & Review Management Tools

Tool Name Parameters Return Payload Shape Error Behavior / Edge Cases
gitea_create_pr title: str, head: str, base: str, body: str, remote: str, host: str | None, org: str | None, repo: str | None Dict detailing the created PR. Fails on missing branches, existing duplicate PR, or invalid base branch.
gitea_list_prs state: str, remote: str, host: str | None, org: str | None, repo: str | None List of dicts representing open/closed PRs. Standard limits apply.
gitea_view_pr pr_number: int, remote: str, host: str | None, org: str | None, repo: str | None Dict of detailed PR attributes. Fails if PR does not exist.
gitea_check_pr_eligibility pr_number: int, action: str, remote: str, host: str | None, org: str | None, repo: str | None Dict: {"eligible": bool, "reasons": list[str]} Non-gated, safe, read-only. Fails on invalid actions.
gitea_submit_pr_review pr_number: int, action: str, body: str, expected_head_sha: str | None, remote: str, host: str | None, org: str | None, repo: str | None Dict of submitted review properties. Rejects self-review; fails if head SHA has changed in the meantime.
gitea_edit_pr pr_number: int, title: str | None, body: str | None, state: str | None, base: str | None, remote: str, host: str | None, org: str | None, repo: str | None Dict of updated PR attributes. Fails on invalid fields or if PR state transition is blocked.
gitea_merge_pr pr_number: int, confirmation: str, expected_head_sha: str | None, expected_changed_files: list[str] | None, do: str, title: str | None, message: str | None, remote: str, host: str | None, org: str | None, repo: str | None Dict of merge result details. Fails if any gating eligibility checks fail (e.g. self-merge, wrong confirmation, SHA mismatch).
gitea_review_pr pr_number: int, event: str, body: str, merge: bool, merge_method: str, remote: str, host: str | None, org: str | None, repo: str | None Dict representing legacy review output. Backward compatibility wrapper; delegates to review/merge logic.
gitea_delete_branch branch: str, remote: str, host: str | None, org: str | None, repo: str | None Dict indicating branch deletion status. Fails on protected branches or non-existent refs.

2.3 File, Identity, and Utility Tools

Tool Name Parameters Return Payload Shape Error Behavior / Edge Cases
gitea_get_file filepath: str, ref: str, remote: str, host: str | None, org: str | None, repo: str | None Dict containing metadata and Base64 content of the target file. Fails if path or reference branch does not exist.
gitea_commit_files files: list[dict], message: str, branch: str | None, new_branch: str | None, remote: str, host: str | None, org: str | None, repo: str | None Dict describing commit hash and ref state. Fails on file path conflicts or commit collisions.
gitea_whoami remote: str, host: str | None Dict detailing verified login user (e.g., sysadmin). Alias targets: gitea_get_authenticated_user, gitea_get_current_user must be preserved.
gitea_get_profile remote: str, host: str | None, resolve_identity: bool Dict of loaded profile constraints and active configuration details. Fails closed on invalid/missing profile specs.
gitea_mirror_refs apply: bool, force: bool Dict summarizing mirrored branch/tag logs. Fails on Git CLI mirror action exceptions.

3. Staged Refactoring Plan

We will perform the refactoring in five discrete stages. Each stage will land as its own independent PR to master, verifying that the codebase compiles and passes the complete test suite at each step.

Stage 1: API and Client Core Extraction

  • Goal: Extract common network request wrappers, pagination handlers, and HTTP exception conversions.
  • Target File: gitea_tools/client.py
  • Contents: api_request, api_get_all, HTTP error maps, and token/credential redaction helper _redact.

Stage 2: Auth and Configuration Extraction

  • Goal: Extract Gitea profile parsers, credential loading logic, and helper scripts.
  • Target File: gitea_tools/config.py
  • Contents: get_auth_header, get_profile, repo_api_url, and profile config schemas.

Stage 3: Audit Logging and Security Gates

  • Goal: Extract security filters, audit logging mechanisms, and metadata decorators.
  • Target File: gitea_tools/audit.py
  • Contents: AuditSink, _audited, and audit message templates.

Stage 4: Tool Implementations (Domain-Driven Modules)

  • Goal: Group and move the core implementation logic of the 24 tools out of mcp_server.py.
  • Target Files:
    • gitea_tools/issues.py — Issues, labels, and mark status tools.
    • gitea_tools/prs.py — PRs, reviews, merge gating, and branch delete.
    • gitea_tools/files.py — File retrieval and atomic commits.
    • gitea_tools/identity.py — whoami and runtime profile descriptions.
    • gitea_tools/utilities.py — Mirroring scripts and miscellaneous tasks.

Stage 5: Final Tool Registration Layer

  • Goal: Clean up the root mcp_server.py to be a pure registration layer.
  • Contents: Imports the modular functions from the gitea_tools package and wraps them inside the standard FastMCP @mcp.tool() decorators.