Inspiration
Every developer has felt it: you push, CI goes red, and you context-switch to dig through logs for a fix you'll make in thirty seconds — once you find it. We wanted an agent that does the finding, drafts the fix, and hands it to you to approve, so a broken build becomes a single tap instead of a detour.
What it does
ShipMate is a mobile DevOps repair agent. When a GitLab CI pipeline fails, ShipMate:
- reads the failed job's log and diagnoses the root cause in plain English,
- drafts the minimal fix on a new branch and opens a merge request with its reasoning,
- notifies you so you can review and approve from your phone — it never merges on its own,
- retries the pipeline once you approve. The human stays in control by design: the agent can only diagnose and draft; the pipeline-retry is triggered exclusively by the Approve button.
How we built it
- Agent: Gemini (
gemini-3-flash-preview) on Google Cloud Agent Builder using the Agent Development Kit (ADK), deployed on Cloud Run. - Trigger: a GitLab pipeline webhook hits a FastAPI endpoint; the server resolves the failed job + log and invokes the agent.
- Partner integration — GitLab MCP server: the agent integrates GitLab's official MCP server (
gitlab.com/api/v4/mcp) forget_pipeline_jobs,get_job_log,get_merge_request,create_merge_request,manage_pipeline(pipeline retry), andsearch. We connect throughmcp-remote, which manages the OAuth 2.0 lifecycle.agent/mcp_demo.pyshows a live round-trip: ShipMate's MCP client connects, lists the GitLab tools, and fetches the very merge request the agent created. - State + notifications: Firestore for run state, Expo push for the phone alert.
- App: React Native + Expo — iOS, Android, and a web export, with a diagnosis card and an approve/reject control.
- Guardrails (in code, not just prompts): never touches protected branches, max 3 files per commit, branch names restricted to
shipmate/*, and a hard "no merge" rule. ## Challenges we ran into - CI gating: GitLab requires account verification before shared runners will run pipelines — until we verified, pipelines failed with zero jobs and (correctly) no logs for the agent to read.
- Stateless OAuth: GitLab's MCP server uses OAuth with rotating refresh tokens. Keeping a token alive inside a stateless Cloud Run container is awkward, so the always-on service uses GitLab's REST API for the same actions, while the agent's MCP integration runs through
mcp-remote(which owns token refresh). Both paths exercise the same GitLab capabilities. - Agent convergence: early runs wandered through config files instead of fixing the source file named in the log. We fixed this by pre-resolving the failure log on the server, trimming the agent's tool surface, and tightening the instruction so it reads exactly the implicated file and acts.
- Cloud Run gotchas: fresh
run.appURLs 404 at the edge for a few minutes after deploy (not broken — just propagating), and CPU is throttled after the HTTP response unless you set--no-cpu-throttling, which matters for an agent that runs as a background task. ## Accomplishments we're proud of A real, end-to-end loop: break a build → pipeline fails → webhook → Gemini diagnoses → fix branch + merge request opened with reasoning → human approves from the app → pipeline goes green. And a genuine GitLab MCP integration demonstrated against the live server.
What we learned
- Pre-feeding the agent the exact failure context (the log) and trimming its tools is more effective than a bigger model for getting reliable, fast convergence.
- "Human-in-the-loop" is most trustworthy when enforced in code (only the Approve endpoint can retry), not just asked for in the prompt.
- GitLab's MCP tools are plain REST under an OAuth token, so they don't consume Duo credits — the model reasoning does. That distinction unblocked our integration.
What's next
Self-refreshing MCP tokens for an always-on MCP path in production, support for more failure classes (dependency conflicts, config errors), multi-repo support, and learning from which fixes get approved vs rejected.
Built With
- adk
- agent-builder
- cloud-run
- expo.io
- fastapi
- firestore
- gemini
- gitlab
- gitlab-mcp
- google-cloud
- model-context-protocol
- python
- react-native
Log in or sign up for Devpost to join the conversation.