---
id: w2/m8/t005
title: GraphQL (gitConnection/repos + mutations) and MCP (list_repos, get_git_connection)
worker: worker2
status: done
estimate: 40m
depends_on: [w2/m8/t004]
---

## Objective

Mirror the REST surface on the other two adapters over the same t003 verbs: GraphQL queries `gitConnection` + `repos` and mutations `connectGit` (returns install URL) / `disconnectGit`; MCP tools `list_repos` and `get_git_connection` (connection status + install URL so an agent can tell the human what to click).

## Context

- One core, thin adapters ([docs/ADR006-bex-api.md](../../../docs/ADR006-bex-api.md)); follow the `envgroups`/`keyvalue` graphql.go + mcp.go layout in `internal/github`.
- Both are **bex extensions** (Render's dashboard GraphQL for repos is uncaptured; Render's MCP has no repo tools) — flag in-code like `createService` does, and name tools in Render's MCP style (`list_*`/`get_*`).
- MCP `list_repos` is the agent-facing payoff: "which repos can I deploy?"

## Steps

1. GraphQL schema + resolvers; field shapes identical to REST (fullName, private, defaultBranch, cloneURL…).
2. MCP tool registrations with descriptions that tell an agent when to use them and what to do when 503/no-connection (point at the connect flow).
3. Adapter tests: resolver + tool round-trips against a fake core; identical field sets across REST/GraphQL/MCP asserted.

## Files

- `lego/backend/internal/github/graphql.go`, `mcp.go` (new) + tests
- GraphQL schema registration in `internal/api`

## Acceptance criteria

- [ ] Same fields/semantics/error shapes as REST on both adapters
- [ ] MCP tools return actionable guidance when unconfigured or disconnected
- [ ] Cross-surface consistency asserted by a test

## Out of scope

- Dashboard (t006)
