Apply AI file exclusions to add_commit MCP partial-edit reads
What does this MR do and why?
This is the second follow-up hardening the add_commit MCP server tool's partial-edit path (old_str/new_str).
Related to #622860 (closed).
Problem
Partial edits read the target file's full content through an internal helper, BlobsTool. BlobsTool reused the get_repository_file GraphQL query, but not GetRepositoryFileTool, so it skipped that tool's file_excluded? check. In EE, that check delegates to Ai::FileExclusionService, which enforces a project's Duo context-exclusion rules (files an admin has excluded from AI processing).
As a result, the partial-edit path could read the content of an excluded file server-side (to expand the edit), even though get_repository_file refuses to read it directly. GraphQL still enforced read_code, so this was not a raw permission escalation, but it defeated the AI context-exclusion control specifically.
Fix
BlobsTool#execute now checks the requested paths against exclusion rules before reading, via a new excluded_paths hook:
- CE has no exclusions (returns none).
- The EE override calls
Ai::FileExclusionService— the same serviceGetRepositoryFileTooluses. - If any requested path is excluded,
BlobsToolreturns an error response naming the excluded path(s), andAddCommitServicesurfaces that as a partial-edit error instead of reading and committing the file.
The exclusion applies only to the partial-edit read path. Full-content commits (content) are unchanged — they overwrite without reading, so they were never in scope.
Scope of changes
app/services/mcp/tools/repositories/blobs_tool.rb— exclusion gate inexecute, CE stubexcluded_paths,prepend_modee/app/services/ee/mcp/tools/repositories/blobs_tool.rb— EEexcluded_pathsoverride usingAi::FileExclusionServiceee/spec/services/ee/mcp/tools/repositories/blobs_tool_spec.rb— exclusion behavior (no rules, matched rule, negation re-include, partial match of multiple paths)ee/spec/services/ee/mcp/tools/repositories/add_commit_service_spec.rb— end-to-end: partial edit on an excluded file does not commit and returns an error
How to set up and validate locally
- Configure a Duo context-exclusion rule for a file path in a project.
- Call
add_commitwith a partial edit (old_str/new_str) targeting that path. - Confirm the tool returns an error and no commit is created.
30 examples pass across the CE/EE blobs and add_commit specs.