[Refactor] Look up each governed MCP container once per call

What does this MR do and why?

Governance and the tool each look up the same project or group. A governed call therefore does two lookups per container. Terri asked for one in Blocker 4 of https://gitlab.com/gitlab-org/gitlab/-/work_items/623329#note_3900303533.

This MR adds a per-call store, Mcp::Tools::Concerns::GovernedLookups::Store. It records each container that the tool's own find_project or find_group loads during governance, including misses.

  • GraphqlService adopts the store filled by the tool instance it built for governance. It passes the store to the tool it builds for execution. The second find_project returns the same object with no query.
  • Record lookups are recorded the same way. These cover pipeline, vulnerability, workflow, saved view, scan profile, catalog consumer, and work items. The tools pass the Global ID of the governed record.
  • ApiTool and aggregated services expose the store in request.env. API::Helpers#find_project, #find_group, and #find_namespace read it. Organization-scoped and project-namespace lookups skip it.
  • Manager now dups ApiTool per call so the store never leaks between requests.
  • When no container named in the call is governed, the store is cleared. The tool then runs exactly as on master.

This MR is stacked on !268284 and targets its branch. That MR is the last of three that split !261045, and this MR depends on all three.

After !261045 was rebased onto master, this MR was rebased onto it. The adjustments are in a separate commit:

  1. master now requires an access_token when a tool is built. GraphqlService and the services that build tools pass both the token and the store, and the new specs pass access_token: nil.
  2. check_tool_governance! reads the containers through master's memoized tool_governed_containers, so governance still resolves them once per call.
  3. The labels search tool builds a fresh tool for each term of an array search. It now passes its store along, so every term reuses the project or group that governance already looked up.

How to reproduce the issue

There is no user-facing defect. The before-state is the lookup count.

  1. Check out the parent MR branch.
  2. Make a governed get_merge_request call by URL.
  3. You can see the project loaded twice. Governance loads it once and the tool loads it again at execute time.

How to test the fix

Make a governed get_merge_request call by URL. The project is resolved once.

Run the specs:

bin/rspec spec/services/mcp ee/spec/services/mcp spec/lib/api/helpers_spec.rb ee/spec/lib/ee/api/mcp

References

Edited by Raounak Sharma

Merge request reports

Loading
Loading