Accept plain iids for link_work_items MCP tool targets

What does this MR do and why?

The link_work_items MCP tool required two different ID formats in the same call: the source work item is identified by project_id/group_id + work_item_iid (a plain integer), but work_items_ids (the targets) had to be global IDs (gid://gitlab/WorkItem/<id>). Mixing formats confused agents, and a failed lookup returned a single generic "No matching work item found" error that didn't say which id was the problem.

This MR lets work_items_ids accept plain iids (integers or numeric strings) alongside global IDs, and makes resolution errors name the failing id. Cross-project and cross-group targets still require global IDs, per the issue's scoping discussion.

Changes:

  • An iid in work_items_ids resolves in the source work item's project or group, i.e. the same scope already used to resolve work_item_iid.
  • An unresolvable iid returns: Target work item with iid '<value>' not found in <parent path>. Use a global ID (gid://gitlab/WorkItem/<id>) for work items in other projects or groups.
  • An unrecognized id format returns: Invalid target work item ID format: '<value>'. Expected an iid (integer) or a global ID (gid://gitlab/WorkItem/<id>).
  • Widened the items.type input schema to ["integer", "string"] and updated the schema and tool descriptions in doc/user/model_context_protocol/mcp_server_tools.md.
  • No GraphQL changes: the tool still calls workItemAddLinkedItems with resolved global IDs.

The numeric-id normalization approach follows the one already used in !250475 (merged).

References

How to verify locally

  1. bundle exec rubocop — clean.
  2. Run the CE and EE specs for the link_work_items tool and its service (54 examples, all green).
  3. Against a running GDK, call POST /api/v4/mcp with a link_work_items JSON-RPC request:
    • Mix one plain iid and one global ID in work_items_ids — both links should be created (IssueLink records in the database).
    • Pass an iid that doesn't exist in the source's project/group — expect the parent-scoped "not found" error naming that iid.
    • Pass a malformed value (e.g. a non-numeric string) — expect the format error naming both accepted id forms.

Merge request reports

Loading
Loading