Add start_duo_session MCP tool

What does this MR do and why?

Adds the start_duo_session MCP tool. It starts a Duo Agent Platform session running an AI Catalog flow. Closes #607619 (closed). It's route-backed: route_setting :mcp on POST /ai/duo_workflows/workflows plus a Base::AggregatedService, the same pattern as save_merge_request and semantic_search. No ApiTool changes.

References

Closes #607619 (closed). Related: #617171 (closed), !254765 (merged), #627559 (closed).

Screenshots or screen recordings

Before After

How to set up and validate locally

  1. Create a token with the mcp scope. There's no checkbox for it in the UI yet, so make it in rails console:
PersonalAccessToken.create!(
  user: User.find_by_username('root'), name: 'mcp', scopes: [:mcp],
  expires_at: 7.days.from_now,
  organization: Organizations::Organization.default_organization
).token
  1. Find a project with an AI Catalog consumer and Duo enabled. gitlab:duo:setup seeds one:
project = Project.find_by_full_path('gitlab-duo/test')
Ai::Catalog::ItemConsumer.where(project: project).map { |c| [c.id, c.item&.name] }
# => [[723, "Developer"], ...]
  1. Confirm the tool is listed and the underlying route tool is hidden:
curl -s -X POST http://gdk.test:3000/api/v4/mcp \
  -H "PRIVATE-TOKEN: $TOKEN" -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","method":"tools/list","id":1}' \
  | jq '.result.tools[].name' | grep duo

start_duo_session should appear, create_duo_workflow should not.

  1. Start a session. Note the model sends no start_workflow:
curl -s -X POST http://gdk.test:3000/api/v4/mcp \
  -H "PRIVATE-TOKEN: $TOKEN" -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","method":"tools/call","id":2,"params":{"name":"start_duo_session",
       "arguments":{"project_id":"1000000","ai_catalog_item_consumer_id":723,
                    "goal":"Add a line to README saying hello"}}}' | jq '.result.structuredContent'

What I got:

{"workflow_id": 972, "status": "created", "workload_id": 499, "poll_after_seconds": 30}
  1. Check the session in rails console. This is the bit that shows the tool did more than create a record:
w = Ai::DuoWorkflows::Workflow.find(972)
[w.source_type, w.workflows_workloads.count, w.ai_catalog_item_version_id]
# => ["mcp", 1, 66]

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.

Edited by Fred de Gier

Merge request reports

Loading
Loading