Lock the full input schema of every MCP tool in specs
What does this MR do and why?
Spec-only change. Every tool the GitLab MCP server serves (CE and EE, including unlisted and REST-backed tools) now has a spec that compares its entire input_schema with eq. Any change to the agent-facing contract (new property, maxItems, required, description, enum) fails CI until someone updates the expected hash on purpose.
Motivation: ee/spec/services/mcp/tools/security/attach_scan_profile_service_spec.rb only checked types, so maxItems: 100 was added in !258207 (merged) without any spec failing. No changelog entry because the change is spec-only.
Sweep and coverage details
-
Sweep method: built the list of served tools from
Mcp::Tools::Manager.new.toolsin bothFOSS_ONLY=1and EE, and dumped each tool'sinput_schemaper registered version. Cross-checked withregister_version/def input_schemainapp/services/mcp/toolsandee/app/services/mcp/tools, the EE prepend modules inee/app/services/ee/mcp/tools, and everyroute_setting :mcpinlib/apiandee/lib/api. -
Counts from the first sweep (master) and the second sweep (this branch):
Sweep Tools served CE Tools served EE Without full eqmaster 46 56 19 this branch 46 56 0 The 19 distinct tools on master without a full
eq:- 7 class-based tools with no full
eq:get_repository_file,list_tags,search,attach_scan_profile,start_duo_session,send_duo_session_input, andsave_vulnerability(version 0.2.0). - 3 more tools whose EE-served schema was only partly checked:
link_work_items,list_work_items,save_work_item. - 9 REST-backed tools with no per-tool schema spec:
fork_repository,get_issue,create_issue,get_merge_request_commits,get_merge_request_diffs,get_merge_request_pipelines,list_pipelines,get_pipeline_jobs,list_branches.
- 7 class-based tools with no full
-
Differences from the initial gap list, which was built by grepping specs for partial schema checks:
- Added
save_vulnerability0.2.0. Only 0.1.0 was locked. Both versions share one schema, so one literal is checked against both. - Added the EE-served schemas of
link_work_items,list_work_items,save_work_itemandsearch. EE adds properties, and the EE specs checked them piecemeal. list_wiki_pageswas already fully covered.- The other REST routes with
route_setting :mcp(create_merge_request,update_merge_request,gitlab_search_in_instance/group/project,update_pipeline,delete_pipeline,create_duo_workflow,resume_duo_workflow) are not served directly. They sit behind the aggregated toolssearch,save_merge_request,manage_pipeline,start_duo_sessionandsend_duo_session_input, whose schemas are locked in those tools' specs.
- Added
-
What changed:
- Replaced partial schema examples with a full
eqin the class-based tool specs listed above. Removed the partial checks the fulleqreplaces, and kept the behavior examples. searchin EE: its schema depends on the advanced search and exact code search settings. All four combinations are locked from a base literal plus the added properties. The CEsearchexample runs only in FOSS (unless: Gitlab.ee?).- REST-backed tools: one example per tool in the request spec of its route, next to the Grape
paramsthat define the schema.fork_repositoryinspec/requests/api/projects_spec.rb;get_merge_request_commits,get_merge_request_diffsandget_merge_request_pipelinesinspec/requests/api/merge_requests_spec.rb;list_pipelinesandget_pipeline_jobsinspec/requests/api/ci/pipelines_spec.rb;list_branchesinspec/requests/api/branches_spec.rb;get_issueinspec/requests/api/issues/get_project_issues_spec.rb. create_issueis the only REST tool whose schema differs in EE:ee/lib/ee/api/helpers/issues_helpers.rbaddsepic_idwhen the route is defined, whatever the license. Following the EE spec guidelines, the CE example inspec/requests/api/issues/post_projects_issues_spec.rbruns only in FOSS (unless: Gitlab.ee?), andee/spec/requests/api/issues_spec.rblocks the EE schema. EE is CE plusepic_id, so the EE example also catches CE param changes in regular pipelines.- Checked that the specs catch a change: adding
maxItems: 100toattach_scan_profile's source makes its spec fail.
- Replaced partial schema examples with a full
-
Known exception: the existing
accept_merge_requestspec builds thestrategyenum fromAutoMergeService.all_strategies_ordered_by_preferenceinstead of a literal, because EE adds merge train strategies. Left as is.
References
Expected conflict: that MR adds maxItems: 100 (and a combined-limit description) to attach_scan_profile. This MR asserts master's schema, so whichever merges second updates the expected hash in ee/spec/services/mcp/tools/security/attach_scan_profile_service_spec.rb.
Screenshots or screen recordings
No UI changes.
How to set up and validate locally
The change is spec-only, so running the specs is the validation.
-
Run the changed specs in EE:
bundle exec rspec \ spec/requests/api/projects_spec.rb \ spec/requests/api/merge_requests_spec.rb \ spec/requests/api/ci/pipelines_spec.rb \ spec/requests/api/branches_spec.rb \ spec/requests/api/issues/get_project_issues_spec.rb \ spec/requests/api/issues/post_projects_issues_spec.rb \ ee/spec/requests/api/issues_spec.rb \ spec/services/mcp/tools/search/search_service_spec.rb \ ee/spec/services/ee/mcp/tools/search/search_service_spec.rb \ spec/services/mcp/tools/repositories/get_repository_file_service_spec.rb \ spec/services/mcp/tools/repositories/tags/list_tags_service_spec.rb \ ee/spec/services/mcp/tools/security/attach_scan_profile_service_spec.rb \ ee/spec/services/mcp/tools/security/save_vulnerability_service_spec.rb \ ee/spec/services/mcp/tools/duo_workflows/start_duo_session_service_spec.rb \ ee/spec/services/mcp/tools/duo_workflows/send_duo_session_input_service_spec.rb \ ee/spec/services/ee/mcp/tools/work_items/link_work_items_service_spec.rb \ ee/spec/services/ee/mcp/tools/work_items/list_work_items_service_spec.rb \ ee/spec/services/ee/mcp/tools/work_items/save_work_item_service_spec.rb -
Run the CE ones (paths starting with
spec/) withFOSS_ONLY=1. -
Optional: add
maxItems: 100to a property inee/app/services/mcp/tools/security/attach_scan_profile_service.rband confirm its spec fails.
Local results: every changed spec passes in EE and in FOSS. For the large request specs, only the new MCP tool input schemas blocks were run locally.
MR acceptance checklist
Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.