In my workflows I often reach for AI agents - Copilot, OpenAI, Gemini, Claude, whichever fits the moment. Each has its place; more on that in another post. Here I want to focus on one particular gap that was keeping me from being as effective as I'd like: getting AI agents to cross-reference my work against Drupal's actual git history on git.drupalcode.org.
git.drupalcode.org is a self-hosted GitLab instance - full read and write API access, same as any GitLab install. Most AI agents today speak MCP (Model Context Protocol), the open standard for connecting AI applications to external systems, so getting an agent to read and write against it should have been a matter of pointing it at the right server.
An open-source project already does most of the work: gitlab-mcp acts as an MCP proxy in front of any self-hosted GitLab instance, including an OAuth proxy mode built specifically for remote MCP clients like claude.ai - you add it as a custom connector, log into GitLab in your browser, and the proxy handles the token exchange. No personal access token to generate or hand around.
I wanted to run it as-is against git.drupalcode.org and hit a wall: every request failed with a 401, even with a freshly issued, valid token. Chasing it down - eventually via tcpdump inside the container - turned up the actual cause, and it's narrower than "GitLab tokens don't work here." git.drupalcode.org sits behind Varnish, and Varnish strips the Authorization header specifically on /oauth/* paths, while passing it through untouched on /api/v4/*. gitlab-mcp's OAuth proxy verifies incoming tokens with a Bearer-header call to /oauth/token/info - exactly the path that gets stripped - so every valid token gets rejected at the verification step, before it ever reaches the part of the API that would have accepted it.
I opened a PR upstream: on a 401 from the Bearer-header call, retry /oauth/token/info once with the token as a query parameter instead, which Doorkeeper (GitLab's OAuth provider) accepts. It's still under review.
Until it lands, I'm running a patched fork, packaged as drupalcode-mcp. It's the same OAuth proxy mode, so the workflow is unchanged: add it to claude.ai as a custom connector, authenticate with your own git.drupalcode.org account, done. I'm also running a hosted instance at drupalcode.piasecki.dev/mcp - best-effort, no SLA for now - if you'd rather not stand up your own. Deployment notes are in the repo if you do.
Drupal's issue queues live on drupal.org, not on git.drupalcode.org, so this project only covers code, merge requests, and CI. For issue and project metadata I built a companion, drupalorg-mcp, against drupal.org's public API - read-only, no auth needed since it's all public data anyway. Between the two, an agent can go from an issue on drupal.org straight to the merge request that fixes it on git.drupalcode.org.
Longer term, I expect one of two things to make this proxy unnecessary: the upstream PR merging, at which point drupalcode-mcp switches back to the stock gitlab-mcp image, or git.drupalcode.org gaining native MCP support, which is currently an open discussion on the Drupal infrastructure issue queue. Whichever comes first.