Contributing to GitLab & MCP: Lessons from a Week of Upstream Open-Source Engineering A developer contributed a series of upstream merge requests to GitLab and the GitLab Language Server (gitlab-lsp), extending GitLab's Model Context Protocol (MCP) tooling that connects AI agents and IDE assistants like GitLab Duo to GitLab's API. The changes added an update_note method to the save_note tool so agents can edit and resolve comments in place, introduced a list_user_events tool with pagination and date filters, folded merge-request pipeline creation into save_pipeline via an optional merge_request_iid, and added parent_iid support to list_work_items. The developer also fixed a race condition in gitlab-lsp where stale microtasks could dispatch messages to a newly created session, and documented two pitfalls: the false.blank? trap for boolean arguments and an invalid "date" JSON Schema type that broke strict MCP clients. Over the past sprint, I contributed a series of upstream enhancements and bug fixes to GitLab gitlab-org/gitlab and the GitLab Language Server gitlab-org/editor-extensions/gitlab-lsp . Most of these changes focus on GitLab’s implementation of the Model Context Protocol MCP —the protocol connecting AI agents and IDE assistants like GitLab Duo to GitLab's API—as well as race-condition resilience in Language Server protocols. Here is a comprehensive retrospective on what was built, the architectural decisions behind them, and lessons learned getting complex merge requests to 100% green pipelines under GitLab's rigorous review standards. save note Tool 264854 The MCP save note tool allowed AI agents to post comments, reply to discussion threads, and resolve discussions on merge requests and work items. However, agents could not edit their existing comments or refine feedback in-place, leading to comment sprawl. We introduced the update note method to save note : Mutations::Notes::Update::Base updateNote with proper authorization checks and quick-action guards. gid://gitlab/Note/123 . We updated the tool schema to accept oneOf: { type: 'string' }, { type: 'integer' } and automatically coerce them. project , so we ensured the governance container resolver properly fell back to note.namespace to enforce project/group tool policies. false.blank? Trap: true . When validating method arguments for boolean fields like resolved: false , a naive .blank? check erroneously flagged the parameter as missing. We implemented strict string-blankness checking val.nil? || val.is a? String && val.blank? to guarantee boolean stability. Agents needed visibility into recent user activity to assist with sprint summaries and standups. While /users/:id/events existed as a REST endpoint, it was not exposed as an MCP tool. list user events in the :core toolset with pagination, action, and target-type filters. ApiTool::TYPE CONVERSIONS : before and after with type: Date . Grape's MCP tool mapper previously lacked a mapping for Date , emitting "type": "date" in the generated JSON Schema—which is invalid according to the JSON Schema meta-schema and caused strict MCP clients to reject the tool catalog. We added 'Date' = 'string' to map dates cleanly to ISO 8601 strings. mcp server tools.md . save pipeline 264858 An earlier draft introduced a separate tool to create merge request pipelines. Reviewers pointed out that having both save pipeline and a dedicated merge request pipeline tool introduced fragmentation and API redundancy. SavePipelineService using an optional merge request iid parameter. parent iid support to the list work items MCP tool, enabling agents to query tasks and child items belonging to a specific parent issue or epic. gitlab-lsp 4539 In the GitLab Language Server gitlab-lsp , when a user ran /new to initiate a clean session while pending wake messages were queued, old microtasks could resolve and dispatch messages to the newly instantiated session, causing stale state corruption. await flushMicrotasks during session teardown. false.blank? == true . Always check .nil? or type-check when accepting booleans. "date" will break tool discovery across ecosystems. All Merge Requests linked above are open or merged in GitLab's official repositories. Happy hacking