GPT MCP tools fail in DAP due to automatic addition of params

Everyone can contribute. Help move this issue forward while earning points, leveling up and collecting rewards.

Summary

get_workitem_notes fails for GPT-based clients because the tool invocation serializes both mutually exclusive pagination parameters, first and last, even when the LLM only wants to supply one. Apparently, optional fields are still initialized with default values when using GPT LLMs.

The same behavior can be observed across multiple MCP tools in this Langsmith trace, such as gitlab_save_work_item.

The problem can be observed in

  • Agentic Chat
  • Using Agentic Chat endpoint through OpenCode integration + Adding tools yourself
  • for modern (GPT-5.6) as well as legacy (GPT-5.3 codex) models via DAP. Anthropic works fine. Gemini 3.7 Flash works fine.

It is not happening in ChatGPT itself. Codex has not been tested

Reproduction

  • Select GPT model
  • Instruct agent to fetch comments from a supplied work item URL.

Actual behavior

The tool returns:

Can only provide either `first` or `last`, not both

This suggests GPT tool-call serialization includes both fields, likely emitting omitted values as null.

Expected behavior

The MCP tool does not send omitted pagination fields to the backend.

Scope

This appears specific to GPT-based clients. Related: #618673 covers naming confusion for this MCP tool, but not this pagination serialization defect.

Proposal

Fix this with multiple MRs:

  1. !251810 (merged) adds a pagination concern (so we can fix many tools at once)
  2. Add resolve_pagination_direction to the concern as a follow up MR
  3. For save_* tools:
    • save_work_item: add minimum: 1 to work_item_iid schema (replaces description warning), keep .to_i > 0 dispatch fix from !251695 (merged), strip wrong-mode params after dispatch instead of raising (follow-up)
    • save_merge_request: same pattern for its iid field. Already has ignored_params reporting — just reorder so detect_operation doesn't raise on cross-mode params before the slice happens
    • save_merge_request_review: handle old_line: 0 / new_line: 0 and the method-scoped param rejection
    • save_pipeline: add minimum: 1 to pipeline_id schema + .to_i > 0 for dispatch
  4. For tools where the default actually mutates/removes values (like setting labels: [] or weight: 0 on an issue) or where the zero-value is ambiguous (can't use minimum):
    • Schema descriptions that say "omit to leave unchanged" (prompt-engineering the model to not send it)
    • Response-level visibility ("Updated: title. Also cleared: labels, assignees") so the damage is at least noticed
  5. Fix gitlab-org/modelops/applied-ml/code-suggestions/ai-assist#2766 in DWS to strip zero-value arguments in McpTool._execute() before json.dumps. The gateway has the tool's args_schema and can compare argument values against type defaults. Although the root cause is really the model sending optional fields, the gateway forwarding them is not helping.
Edited by 🤖 GitLab Bot 🤖