GitMCP

permite que assistentes de IA explorem repositórios do GitHub, código-fonte, issues, pull requests e commits por meio de 14 ferramentas validadas e somente leitura, além de 4 ferramentas de escrita opcionais que ficam desativadas por padrão.

Documentação

GitMCP

Um servidor GitHub para assistentes de IA: permite que Claude e outros clientes MCP leiam repositórios, issues, pull requests e commits por meio de ferramentas validadas, com gravações desabilitadas, a menos que você opte por ativá-las.

Release Python Tests

  • 14 ferramentas somente leitura, além de 4 ferramentas de gravação opcionais, cada uma com um esquema de entrada Pydantic estrito
  • Falhas transitórias (429, 5xx, timeouts) são repetidas dentro de um orçamento rígido; erros de autenticação, permissão e 404 nunca são repetidos
  • Seguro por padrão: gravações desativadas, token nunca é registrado ou retornado, tamanhos de resposta limitados, sem acesso arbitrário a URL/shell
  • Funciona com Claude Code e Claude Desktop via stdio; repositórios públicos não precisam de token

Expectativas honestas: apenas stdio, então cada usuário executa sua própria cópia local. Pesquisa de código e repositórios privados precisam de um token GitHub. Leituras de arquivos são somente texto UTF-8.

O que eu construí

GitMCP é um servidor MCP em Python que adapta a API REST do GitHub em 18 ferramentas que um assistente de IA pode descobrir e chamar. A lógica do GitHub (github/*.py) é independente do MCP, então é testada sem um servidor em execução; uma camada fina server.py registra as ferramentas e transforma cada falha em uma mensagem curta, segura e acionável. Foi construído com o SDK oficial atual do MCP Python (2.x) e verificado com um cliente MCP stdio real.

Resultados em resumo

Medido em um laptop Windows 11, Python 3.14, anônimo (sem token) contra a API GitHub ao vivo.

MétricaResultado
Testes automatizados112 passando, 1 ignorado (teste de integração ao vivo, precisa de token), ~13 s
Lint / tiposruff limpo, mypy --strict limpo (18 arquivos de origem)
Início a frio: processo de spawn, handshake MCP, listar 14 ferramentas1,3 s
Latência github_get_repository0,6 s na primeira chamada (configuração TLS), ~0,02 s mediana em conexão reutilizada
Tamanho do código~2.100 linhas em src/, ~1.400 linhas de testes

A latência é dominada pelo GitHub e pela rede, não pelo servidor. As decisões de design estão em DECISIONS.md.

Arquitetura

flowchart LR
    Client["MCP client<br/>(Claude Code / Desktop)"] -- "stdio JSON-RPC" --> Server["server.py<br/>tool registration + error guard"]
    Server --> Repos["github/repositories.py"]
    Server --> Issues["github/issues.py"]
    Server --> PRs["github/pull_requests.py"]
    Server --> Commits["github/commits.py"]
    Repos & Issues & PRs & Commits --> GH["github/client.py<br/>auth, errors, size limit"]
    GH --> Retry["retry.py<br/>backoff + jitter + Retry-After"]
    GH -- HTTPS --> API[("GitHub REST API")]
    Server -. validates with .-> Schemas["schemas/<br/>Pydantic in/out models"]
    Config["config.py<br/>env settings"] --> Server
MóduloResponsabilidade
server.pyCria o MCPServer, registra ferramentas, converte erros em erros seguros de ferramenta, fecha o cliente HTTP no encerramento
github/*.pyLógica de negócio. Sem imports MCP, então é testável sem um servidor
github/client.pyCliente httpx autenticado, mapeamento de status HTTP → erro tipado, limite de tamanho de resposta
retry.pyPolítica de repetição (429 / 5xx / rede), tratamento de Retry-After e cabeçalho de reset
schemas/Modelos de entrada Pydantic estritos (extra="forbid") e modelos de saída
errors.pyExceções tipadas com mensagens seguras e dicas
logging_utils.pyRegistro em stderr com redação de segredos

Por que foi construído assim: veja DECISIONS.md.

Início rápido

Requer Python 3.11+. Repositório: https://github.com/wablevaibhav/gitmcp

python -m pip install git+https://github.com/wablevaibhav/gitmcp
python -m gitmcp          # starts the server (waits silently for an MCP client)

Depois, conecte-o ao seu cliente de IA: veja Claude Code ou Claude Desktop. Você não precisa clonar o repositório para usar o GitMCP.

Última versão: v0.1.0. Para instalar exatamente essa versão:

python -m pip install git+https://github.com/wablevaibhav/gitmcp@v0.1.0

Para atualizar depois:

python -m pip install --upgrade --force-reinstall git+https://github.com/wablevaibhav/gitmcp

Alternativas (não obrigatórias): pipx install git+https://github.com/wablevaibhav/gitmcp, ou com uv: uvx --from git+https://github.com/wablevaibhav/gitmcp gitmcp.

Instalação para desenvolvimento (contribuidores)

git clone https://github.com/wablevaibhav/gitmcp.git
cd gitmcp
python -m venv .venv
# Windows (PowerShell):  .venv\Scripts\Activate.ps1
# macOS / Linux:         source .venv/bin/activate
pip install -e ".[dev]"

requirements-lock.txt fixa as versões exatas com as quais o projeto foi testado (pip install -r requirements-lock.txt, depois pip install -e . --no-deps).

Configuração do token GitHub

O token é opcional para repositórios públicos (limite anônimo: 60 requisições/hora), mas obrigatório para repositórios privados, pesquisa de código e ferramentas de gravação.

Crie um token de acesso pessoal de granularidade fina em GitHub → Configurações → Configurações de desenvolvedor → Tokens de acesso pessoal → Tokens de granularidade fina, restrito apenas aos repositórios que você quer que o assistente veja.

CapacidadePermissão do repositório
Repositórios, conteúdos, leitura de arquivos, commitsConteúdos: Leitura (Metadados: Leitura é implícita)
Issues e comentáriosIssues: Leitura
Pull requests, arquivos, revisõesPull requests: Leitura
github_create_issue, github_add_issue_commentIssues: Leitura e gravação
github_create_branchConteúdos: Leitura e gravação
github_create_pull_requestPull requests: Leitura e gravação

Comece com permissões somente leitura. Adicione permissões de gravação apenas se você ativar as ferramentas de gravação.

Público vs. autenticado: sem token, apenas dados públicos são visíveis e o GitHub retorna 404 para recursos privados. Com um token, você vê exatamente o que o token pode ver, nada mais; o GitMCP nunca contorna a autorização do GitHub.

Configuração

Variáveis de ambiente (ou um arquivo .env no diretório de trabalho; copie .env.example):

VariávelPadrãoSignificado
GITHUB_TOKEN(nenhum)Token de acesso pessoal
GITHUB_API_URLhttps://api.github.comBase da API (GitHub Enterprise: https://HOST/api/v3)
GITHUB_API_VERSION2022-11-28Cabeçalho X-GitHub-Api-Version
GITHUB_REQUEST_TIMEOUT30Tempo limite por requisição, em segundos
GITHUB_MAX_RETRIES3Repetições após a primeira tentativa (0–10)
GITHUB_MAX_RATE_LIMIT_WAIT60Maior espera por limite de taxa que o GitMCP vai aguardar, em segundos
GITHUB_ENABLE_WRITE_TOOLSfalseRegistrar ferramentas de gravação
GITMCP_LOG_LEVELINFODEBUG/INFO/WARNING/ERROR (stderr)
GITMCP_MAX_FILE_BYTES200000Maior arquivo que github_get_file_contents retorna
GITMCP_MAX_PATCH_CHARS8000Truncamento de diff por arquivo
GITMCP_MAX_COMMENT_CHARS4000Truncamento de corpo de comentário/revisão
GITMCP_MAX_RESPONSE_BYTES5000000Limite rígido em qualquer corpo de resposta do GitHub

Executando o servidor

python -m gitmcp          # or simply: gitmcp

O servidor fala MCP via stdio, então, por conta própria, ele imprime uma linha "pronto" no stderr e aguarda. Ele foi feito para ser iniciado por um cliente MCP. Para confirmar que ele é detectável e chamável usando um cliente MCP stdio real (a partir de um clone deste repositório):

python scripts/verify_tools.py                       # lists the tools
python scripts/verify_tools.py octocat/Hello-World   # also calls github_get_repository

Mantenha seu token em segredo. Nunca cole em chats, issues, capturas de tela ou faça commit. Se um token for exposto, revogue-o imediatamente em https://github.com/settings/personal-access-tokens e crie um novo.

Claude Code

macOS / Linux / Git Bash:

claude mcp add gitmcp --scope user -e GITHUB_TOKEN="$GITHUB_TOKEN" -- python -m gitmcp

Windows PowerShell (o Windows PowerShell 5.1 engole o separador --, então execute via cmd):

$env:GITHUB_TOKEN = "your-token"       # type it in your own terminal only
cmd /c "claude mcp add gitmcp --scope user -e GITHUB_TOKEN=%GITHUB_TOKEN% -- python -m gitmcp"

Verifique com claude mcp list (ou /mcp dentro do Claude Code). Se python não for o interpretador no qual você instalou o GitMCP, use o caminho completo (where python / which python), por exemplo, C:\Users\you\AppData\Local\Programs\Python\Python312\python.exe.

Você também pode compartilhar um .mcp.json em nível de projeto, referenciando a variável de ambiente de cada pessoa (nunca escreva o token no arquivo):

{
  "mcpServers": {
    "gitmcp": {
      "command": "python",
      "args": ["-m", "gitmcp"],
      "env": { "GITHUB_TOKEN": "${GITHUB_TOKEN}" }
    }
  }
}

Claude Desktop

Edite claude_desktop_config.json (Windows: %APPDATA%\Claude\, macOS: ~/Library/Application Support/Claude/) e reinicie o Claude Desktop:

{
  "mcpServers": {
    "gitmcp": {
      "command": "python",
      "args": ["-m", "gitmcp"],
      "env": {
        "GITHUB_TOKEN": "your-token",
        "GITHUB_ENABLE_WRITE_TOOLS": "false"
      }
    }
  }
}

Se o Claude Desktop não conseguir encontrar python, defina command para o caminho completo do interpretador, com barras invertidas duplicadas no Windows ("C:\\Users\\you\\AppData\\Local\\Programs\\Python\\Python312\\python.exe").

Usando com outras pessoas

Cada pessoa executa sua própria cópia local; nenhum servidor é compartilhado e tokens nunca são compartilhados. Todos fazem:

  1. python -m pip install git+https://github.com/wablevaibhav/gitmcp
  2. Cria seu próprio token GitHub de granularidade fina (veja abaixo).
  3. Adiciona o servidor ao seu cliente usando uma das configurações acima.

Repositórios públicos funcionam sem token (60 requisições/hora); repositórios privados, pesquisa de código e ferramentas de gravação exigem um.

Instalar o pacote não faz o servidor aparecer em um cliente por conta própria; o cliente deve ser configurado como acima. O servidor e o comando foram verificados com scripts/verify_tools.py (um cliente MCP stdio real). Os trechos do Claude Code / Desktop seguem os formatos documentados desses produtos.

Uso

Saída real de python scripts/verify_tools.py octocat/Hello-World (um cliente MCP conversando com o servidor via stdio, sem token):

Connected. 14 tools:
  - github_search_repositories
  - github_get_repository
  - github_list_repository_contents
  - github_get_file_contents
  ...
is_error: False
{'full_name': 'octocat/Hello-World', 'owner': 'octocat', 'name': 'Hello-World',
 'visibility': 'public', 'stars': 3842, 'default_branch': 'master', ...}

Erros são curtos, tipados e acionáveis (saída real, anônima):

github_get_repository  -> NotFoundError: Resource not found. Hint: Check owner, repo, path and ref.
                          Private resources also return 404 when the token lacks access.
                          No GITHUB_TOKEN is configured, so only public data is visible.
github_search_code     -> AuthenticationError: GitHub code search requires authentication.
                          Hint: Set GITHUB_TOKEN, and scope the query with repo:, org: or user:.

Ferramentas

Cada ferramenta aceita um argumento de objeto chamado params. Todas as entradas rejeitam campos desconhecidos. Ferramentas de listagem aceitam page (1–1000) e per_page (1–100, padrão 30) e retornam has_next_page. owner/repo/ref/path são validados (sem travessia, sem caracteres de referência inválidos).

FerramentaArgumentos principaisRetorna
github_search_repositoriesquery, language, topic, min_stars, sort, order, paginaçãocontagem total; itens com nome completo, proprietário, descrição, URL, visibilidade, linguagem, estrelas, branch padrão
github_get_repositoryowner, reporesumo + licença, forks, issues abertas, tópicos, URLs de clone/API, carimbos de data/hora
github_list_repository_contentsowner, repo, path, refentradas: nome, caminho, tipo, tamanho, sha, URLs web/API/download
github_get_file_contentsowner, repo, path, refcontent UTF-8, sha, tamanho. Erros para diretórios, binários, > limite de tamanho
github_search_codequery (precisa de repo:/org:/user:), paginaçãoitens: caminho, repositório, URL, trechos. Requer token
github_list_issuesowner, repo, state, labels, assignee, include_pull_requests, paginaçãoresumos com flag is_pull_request
github_get_issueowner, repo, issue_numberdetalhes: corpo, rótulos, responsáveis, marco, carimbos de data/hora, URL
github_list_issue_commentsowner, repo, issue_number, paginaçãocomentários (corpos truncados, sinalizados)
github_list_pull_requestsowner, repo, state, base, head (owner:branch), paginaçãoresumos de PR
github_get_pull_requestowner, repo, pull_numberbranches, SHAs, autor, rascunho/mesclado/mesclável, tamanho, revisores
github_list_pull_request_filesowner, repo, pull_number, paginaçãoarquivos: status, +/−, patch (truncado, sinalizado)
github_list_pull_request_reviewsowner, repo, pull_number, paginaçãorevisões: autor, APPROVED/CHANGES_REQUESTED/…, corpo
github_list_commitsowner, repo, ref, path, author, paginaçãoresumos de commits
github_get_commitowner, repo, refmensagem, autor, pais, estatísticas, arquivos (máx. 100, patches truncados)
github_create_issue ⚠owner, repo, title, body, labels, assigneesnúmero, URL
github_add_issue_comment ⚠owner, repo, issue_number, bodyid do comentário, URL
github_create_branch ⚠owner, repo, branch, from_refnova referência, SHA
github_create_pull_request ⚠owner, repo, title, head, base, body, draftnúmero, URL

⚠ Ferramenta de gravação: registrada apenas quando GITHUB_ENABLE_WRITE_TOOLS=true.

Exemplos de prompts

  • Exploração de repositório: "Veja octocat/Hello-World. Qual é o branch padrão, o que está na raiz e o que o README diz?"
  • Pesquisa de código: "Encontre onde parse_config está definido em acme/api." (precisa de token)
  • Investigação de issue: "Liste issues abertas rotuladas como bug em acme/api, depois resuma a discussão na mais comentada."
  • Revisão de PR: "Revise o PR 482 em acme/api: mostre os metadados, os arquivos alterados e patches, revisões existentes e aponte mudanças arriscadas."
  • Histórico: "Quem tocou src/auth.py por último em acme/api e o que esses commits mudaram?"

Limites de taxa e tratamento de erros

SituaçãoComportamento
429, ou 403 com sinais de limite de taxaRepetido, respeitando Retry-After / x-ratelimit-reset. Se a espera exceder GITHUB_MAX_RATE_LIMIT_WAIT, falha imediatamente com RateLimitError informando a espera. Nunca dorme além desse limite
500/502/503/504, timeouts, erros de conexãoRepetido até GITHUB_MAX_RETRIES com backoff exponencial e jitter total (base de 0,5 s, teto de 8 s)
401AuthenticationError — sem repetição
403 (permissão)AuthorizationError — sem repetição; a dica nomeia a permissão a conceder
404NotFoundError — sem repetição; a dica observa que recursos privados também retornam 404
400/409/422InputValidationError — sem repetição
Corpo malformado / muito grande / não-JSONGitHubAPIError

Requisições de escrita (POST) nunca são repetidas após timeout ou 5xx, pois a escrita pode ter sido concluída; elas só são repetidas quando o GitHub as rejeitou por limite de taxa.

Os clientes recebem ErrorType: message Hint: .... Tracebacks, corpos de resposta e tokens nunca chegam ao cliente.

Segurança

  • O token vem apenas do ambiente, é mantido como SecretStr e é ocultado de logs e erros (correspondência exata mais padrões de ghp_…/github_pat_…/Authorization:).
  • Ferramentas de escrita não são registradas a menos que GITHUB_ENABLE_WRITE_TOOLS=true, e cada método de serviço de escrita recusa independentemente se a flag estiver desligada. O GitHub ainda aplica as permissões próprias do token.
  • Sem execução de shell, sem busca arbitrária de URLs, sem GraphQL, sem proxy genérico de API: cada ferramenta mapeia para um endpoint REST fixo e os argumentos da ferramenta são codificados em percentual no caminho.
  • Tamanhos de arquivo, patch, comentário e resposta total são limitados; logs nunca contêm código-fonte ou respostas completas.
  • Use um token de granularidade fina com escopo para repositórios específicos e defina uma expiração.
  • Transporte HTTP Streamable é intencionalmente não implementado; um servidor exposto à rede precisaria de sua própria autenticação, o que está fora do escopo desta versão.

Desenvolvimento

A partir de uma instalação de desenvolvimento:

pytest                       # unit + MCP tests (no token, no network)
ruff check . && ruff format --check .
mypy                         # strict, on src/

Testes ao vivo opcionais (somente leitura, ignorados a menos que configurados):

GITMCP_TEST_TOKEN=github_pat_xxx GITMCP_TEST_REPO=owner/repo pytest -m integration

Solução de problemas

SintomaCausa provável / correção
Cliente não mostra ferramentasPython errado na configuração do cliente. Execute python -m gitmcp com esse interpretador exato; use o caminho completo dele na configuração
error: unknown option '-m' (PowerShell)PowerShell 5.1 descarta --. Use a forma cmd /c "claude mcp add ..." acima
No module named gitmcpInstalado em um Python/venv diferente do que o cliente inicia
NotFoundError em um repositório que você pode abrir no navegadorRepositório privado e token ausente/com escopo insuficiente
AuthorizationErrorO token não tem a permissão da tabela acima ou o repositório não está selecionado para o token
RateLimitError imediatamenteA redefinição está mais distante que GITHUB_MAX_RATE_LIMIT_WAIT; defina um token ou aguarde
github_search_code falhaPrecisa de GITHUB_TOKEN e um qualificador repo:/org:/user:
Ferramentas de escrita ausentesIntencional: defina GITHUB_ENABLE_WRITE_TOOLS=true e reinicie o cliente
invalid configuration na inicializaçãoUma configuração falhou na validação; os nomes dos campos são impressos em stderr
Saída de protocolo distorcidaAlgo escreveu em stdout; use stderr para qualquer depuração

Limitações e roteiro

  • As ferramentas de leitura retornam a primeira fatia de um resultado (paginação é explícita); não há acompanhamento automático de todas as páginas.
  • O conteúdo dos arquivos é somente texto UTF-8; arquivos binários e arquivos acima de GITMCP_MAX_FILE_BYTES são recusados.
  • A busca de código depende do índice de busca do GitHub e de seus limites (máximo de 1000 resultados, consulta ≤ 256 caracteres).
  • github_get_commit limita arquivos a 100 e não pagina a paginação de arquivos de commit do GitHub.
  • GitHub Actions, releases, comentários de revisão (inline) e Projects não são cobertos.
  • Somente stdio; planejado: HTTP Streamable autenticado, cache de requisição condicional (ETag), ferramenta de árvore de repositório.
  • Python 3.14 e mcp 2.3 foram usados no desenvolvimento; o código tem como alvo Python ≥ 3.11.