GitPrism

GitPrism é um pipeline rápido, eficiente em tokens e sem estado que converte repositórios públicos do GitHub em Markdown pronto para LLMs.

Documentação

GitPrism

Dashboard

Um pipeline rápido, eficiente em tokens e sem estado que converte repositórios públicos do GitHub em Markdown pronto para LLM. Implantado como um único Cloudflare Worker atendendo humanos, agentes de IA e clientes MCP a partir de um núcleo compartilhado.

                    ┌─────────────────────────────────────────────┐
                    │          Single Cloudflare Worker            │
                    │               (gitprism)                    │
                    │                                             │
   Humans ────────► │  /              → Astro Static UI           │
                    │                   (Workers Static Assets)   │
                    │                                             │
   AI Agents ─────► │  /ingest?...    → REST API                  │
                    │  /<github-url>  → URL Proxy (shorthand)     │
                    │                                             │
   MCP Clients ───► │  /mcp           → Stateless MCP Server      │
                    │                   (createMcpHandler)        │
                    │                                             │
                    │         ┌───────────────────┐               │
                    │         │   Core Engine      │               │
                    │         │  URL Parser        │               │
                    │         │  Zipball Fetch     │               │
                    │         │  fflate Decomp     │               │
                    │         │  Filter/Ignore     │               │
                    │         │  MD Formatter      │               │
                    │         └───────────────────┘               │
                    └─────────────────────────────────────────────┘
                                       │
                                       ▼
                              GitHub Zipball API
                          (authenticated via secret)

Autenticação

O GitPrism suporta tokens de acesso pessoal do GitHub opcionais para contornar limites de taxa compartilhados e usar sua cota pessoal da API do GitHub.

Limites de taxa padrão

  • Sem autenticação: 30 solicitações por minuto por endereço IP
  • Com token do servidor: Compartilhado entre todos os usuários (5.000 req/h para o IP do Worker)
  • Com token do usuário: Sua cota pessoal do GitHub (5.000 solicitações por hora)

Usando seu próprio token

API REST:

curl -H "X-GitHub-Token: ghp_xxxx" https://gitprism.cloudemo.org/ingest?repo=owner/repo

Interface Web: Clique no ícone de configurações ⚙️ na barra de pesquisa para abrir o painel de configurações do token. Seu token é armazenado em localStorage e nunca é enviado a nenhum servidor além do GitHub por meio deste Worker.

Ferramenta MCP:

{
  "url": "https://github.com/owner/repo",
  "detail": "full",
  "github_token": "ghp_xxxx"
}

Requisitos do token

Cabeçalhos de resposta

O cabeçalho X-Token-Source indica qual token foi usado:

  • user — Seu token pessoal (via cabeçalho X-GitHub-Token)
  • server — O token compartilhado do Worker
  • none — Nenhum token disponível

Uso

Interface Web

Visite https://gitprism.cloudemo.org/ e cole qualquer URL do GitHub. Use o painel de configurações (⚙️) para configurar seu token do GitHub.

API REST

Forma canônica (recomendada para uso programático):

GET /ingest?repo=owner/repo&ref=main&path=src&detail=full

Atalho anexado à URL (amigável para humanos):

GET /https://github.com/owner/repo/tree/main/src

Branch, ref e subdiretório são extraídos automaticamente da URL do GitHub. Acrescente um atalho de detalhe para controlar a saída:

GET /https://github.com/owner/repo?summary
GET /https://github.com/owner/repo/tree/main/src?file-list

Parâmetros (forma canônica):

ParâmetroObrigatórioPadrãoDescrição
repoSim (canônico)owner/repo, e.g. cloudflare/workers-sdk
refNãobranch padrãoBranch, tag ou SHA do commit
pathNãoSubdiretório para limitar os resultados
detailNãofullNível de saída: summary, structure, file-list ou full
no-cacheNãofalseDefina como true para ignorar o cache de resposta

Atalho de nível de detalhe — em vez de ?detail=<level>, acrescente o nível como uma chave simples. Funciona tanto na forma canônica quanto na forma de proxy de URL:

/ingest?repo=owner/repo&summary
/https://github.com/owner/repo?structure

Níveis de detalhe:

NívelAtalhoRetorna
summary?summaryfront-matter YAML com nome do repositório, ref, contagem de arquivos, tamanho total
structure?structureResumo + árvore de diretórios ASCII
file-list?file-listEstrutura + tabela de cada arquivo incluído com tamanho em bytes e contagem de linhas
full?fullResumo + estrutura + conteúdo completo dos arquivos em blocos de código cercados. Transmitido em fluxo.

Cabeçalhos de resposta:

CabeçalhoDescrição
Content-Typetext/markdown; charset=utf-8
X-Repoowner/repo
X-RefRef original solicitada (branch, tag ou SHA)
X-Commit-ShaSHA do commit resolvido usado para a chave de cache
X-File-CountNúmero de arquivos incluídos
X-Total-SizeTamanho total dos arquivos incluídos em bytes
X-Truncatedtrue se a saída foi truncada
X-RateLimit-RemainingLimite de taxa da API do GitHub restante
X-RateLimit-ResetTimestamp de redefinição do limite de taxa da API do GitHub
X-CacheHIT ou MISS

Respostas de erro (JSON):

StatusCondição
400Entrada malformada
404Repositório não encontrado ou privado
413Arquivo excede o limite de 50 MB
429Limite de taxa (30 req/min por IP, ignorado com X-GitHub-Token)
502Erro da API do GitHub

Ferramenta MCP

Conecte qualquer cliente compatível com MCP a https://gitprism.cloudemo.org/mcp.

Ferramenta disponível: ingest_repo

ArgumentoObrigatórioPadrãoDescrição
urlSimURL do GitHub ou atalho owner/repo
detailNãofullsummary, structure, file-list ou full
github_tokenNãoSeu PAT do GitHub para ignorar limites de taxa
{
  "url": "https://github.com/owner/repo",
  "detail": "summary",
  "github_token": "ghp_xxxx"
}

A ferramenta é totalmente compatível com agentes Code Mode — o esquema de entrada Zod fortemente tipado e as anotações descritivas permitem que o createCodeTool() do lado do cliente a envolva automaticamente.

Implantação

Opção A — Workers Builds (recomendado)

Workers Builds conecta seu repositório GitHub ao Cloudflare e implanta automaticamente a cada push para main. A interface Astro é compilada durante a etapa de build; ui/dist/ é intencionalmente não commitado no git.

Passos:

  1. Vá para o painel do CloudflareWorkers & PagesCriarImportar um repositório Git

  2. Conecte sua conta do GitHub e selecione este repositório

  3. Configure Configurações de build:

    ConfiguraçãoValor
    Branchmain
    Comando de buildnpm install && npm run build
    Comando de implantaçãonpx wrangler deploy (padrão)
  4. Clique em Salvar e Implantar — o primeiro build será executado imediatamente

  5. Após a implantação, vá para seu Worker → ConfiguraçõesVariáveis e SegredosAdicionar um segredo:

    NomeValor
    GITHUB_TOKENPAT de granularidade fina com escopo repositório público somente leitura

    Sem este segredo, o Worker ainda funciona, mas os limites de taxa da API do GitHub caem de 5.000 para 60 solicitações/hora (compartilhados entre todas as solicitações do IP de saída do Worker).

  6. Opcional — Domínio personalizado: Worker → ConfiguraçõesDomínios personalizados → adicione seu domínio. Isso ativa a Workers Cache API. Sem um domínio personalizado, o Worker implanta em <name>.<subdomain>.workers.dev e o cache não opera silenciosamente (o código lida com isso de forma graciosa). Para habilitar o roteamento quando você tiver um domínio, descomente e atualize o bloco routes em wrangler.jsonc:

    "routes": [
      { "pattern": "yourdomain.com/*", "custom_domain": true }
    ],
    

Opção B — Implantação manual (Wrangler CLI)

git clone https://github.com/cougz/gitprism.git
cd gitprism
npm install
npm run build          # builds ui/dist/
npx wrangler secret put GITHUB_TOKEN
npx wrangler deploy

Variáveis de Ambiente

Configurado em wrangler.jsonc sob vars. Substitua no painel do Cloudflare em Worker → ConfiguraçõesVariáveis e Segredos se necessário:

VariávelPadrãoDescrição
MAX_ZIP_BYTES52428800 (50 MB)Tamanho máximo do arquivo zip antes de rejeitar com 413
MAX_OUTPUT_BYTES10485760 (10 MB)Tamanho máximo da saída antes do truncamento
MAX_FILE_COUNT5000Número máximo de arquivos antes do truncamento
CACHE_TTL_SECONDS86400 (24 horas)TTL de cache para chaves de cache baseadas em SHA

Segredos

SegredoComo definirPropósito
GITHUB_TOKENPainel → Segredos, ou npx wrangler secret put GITHUB_TOKENPAT de granularidade fina, repositório público somente leitura. Aumenta o limite de taxa do GitHub de 60 para 5.000 req/h.

Por que uma etapa de build é necessária

ui/dist/ (o frontend Astro compilado) é excluído do git. O Wrangler lê assets.directory = "./ui/dist" de wrangler.jsonc e envia esses arquivos como ativos estáticos durante a implantação. Se esse diretório não existir no momento da implantação, o Worker será implantado sem interface. A etapa npm run build compila o código-fonte Astro em ui/src/ para ui/dist/ antes de o Wrangler ser executado.

Desenvolvimento

# Build the Astro UI (required before deploying or running wrangler dev)
npm run build

# Run tests (169 tests)
npm test

# Watch mode
npm run test:watch

# Type-check
npm run typecheck

# Local dev server (requires ui/dist/ to exist — run npm run build first)
npm run dev

Arquitetura

Estrutura do Projeto

gitprism/
├── src/
│   ├── index.ts              # Worker entry point, routing
│   ├── types.ts              # Shared interfaces and error classes
│   ├── engine/
│   │   ├── parser.ts         # URL parsing and validation
│   │   ├── fetcher.ts        # GitHub zipball download + size check
│   │   ├── decompressor.ts   # fflate decompression + processing
│   │   ├── filter.ts         # Ignore lists, .gitignore, binary detection
│   │   ├── formatter.ts      # Markdown output generators (4 levels)
│   │   └── ingest.ts         # Shared pipeline (used by API + MCP)
│   ├── mcp/
│   │   └── server.ts         # createMcpHandler setup
│   ├── api/
│   │   ├── handler.ts        # REST API handler, streaming, caching
│   │   └── llmstxt.ts        # /llms.txt endpoint
│   └── utils/
│       ├── cache.ts          # Workers Cache API helpers
│       ├── ratelimit.ts      # Rate limiting helper
│       └── headers.ts        # Response header builder
├── test/                     # Vitest test files (169 tests)
├── ui/
│   ├── src/                  # Astro source
│   ├── dist/                 # Build output (gitignored)
│   └── astro.config.mjs
├── PLAN.md                   # Detailed implementation plan
└── wrangler.jsonc

Decisões-chave

DecisãoJustificativa
Worker único (sem Pages)Workers Static Assets é a abordagem recomendada. Sem CORS, implantação mais simples.
createMcpHandler() (sem Durable Objects)A ferramenta é sem estado. Nenhum estado por sessão é necessário.
fflate em vez de jszipDescompressão em fluxo, pacote menor, menor pico de memória em isolados V8.
GITHUB_TOKEN no lado do servidorAumenta o limite de taxa de 60 para 5.000 req/h sem autenticação do usuário.
Verificação de tamanho pré-vooEvita travamentos OOM em repositórios grandes.
Cache API desde o inícioRepositório+ref+detalhe idênticos produzem saída idêntica. O cache reduz a latência e o uso da API do GitHub.
Transmissão em fluxo de TransformStream para fullReduz o pico de memória, melhora o tempo até o primeiro byte.

Filtragem de Arquivos

Lista de Ignorados Fixa

Os seguintes são sempre excluídos independentemente de .gitignore:

Diretórios: node_modules/, vendor/, .git/, __pycache__/, .venv/, venv/, dist/, build/, .next/, .nuxt/, .svelte-kit/, .output/, .cache/, .parcel-cache/, coverage/, .tox/, .mypy_cache/

Arquivos: package-lock.json, yarn.lock, pnpm-lock.yaml, bun.lockb, Cargo.lock, composer.lock, Gemfile.lock, go.sum, poetry.lock, *.min.js, *.min.css, *.map, *.wasm, *.pb.go, *.pyc, *.pyo

Extensões binárias: .png, .jpg, .jpeg, .gif, .ico, .webp, .bmp, .tiff, .svg, .woff, .woff2, .ttf, .eot, .otf, .pdf, .zip, .tar, .gz, .bz2, .7z, .rar, .exe, .dll, .so, .dylib, .bin, .o, .a, .mp3, .mp4, .avi, .mov, .mkv, .flac, .wav, .ogg, .sqlite, .db, .DS_Store

Detecção de conteúdo binário: Arquivos contendo bytes nulos nos primeiros 8 KB são ignorados independentemente da extensão.

Suporte a .gitignore

O .gitignore raiz do repositório é analisado e aplicado. Suporta:

  • Padrões curinga (*.log, **/*.tmp)
  • Padrões de diretório com barra final (logs/)
  • Padrões enraizados (/build)
  • Padrões de negação (!important.log)
  • Comentários (# this line is ignored)

Limitação: Apenas o .gitignore raiz é avaliado. Arquivos .gitignore aninhados (por exemplo, src/.gitignore) não são suportados na v1.

Compatibilidade com Code Mode

A ferramenta MCP ingest_repo é compatível com agentes Code Mode por design:

  • Nome de ferramenta claro e descritivo (ingest_repo)
  • Descrição de várias frases explicando todos os quatro níveis de detalhe
  • Esquemas Zod fortemente tipados com .describe() em cada parâmetro
  • Nenhuma alteração no lado do servidor necessária — ferramentas MCP padrão com esquemas tipados são inerentemente compatíveis com Code Mode

Limites

LimiteValorConfigurável
Tamanho máximo do arquivo zip50 MBvariável de ambiente MAX_ZIP_BYTES
Tamanho máximo da saída10 MBvariável de ambiente MAX_OUTPUT_BYTES
Número máximo de arquivos5.000variável de ambiente MAX_FILE_COUNT
Limite de taxa (sem token)30 req/min por IPbinding de ratelimits wrangler.jsonc
Limite de taxa (token do usuário)5.000 req/hcota por usuário do GitHub
TTL de cache24 horasvariável de ambiente CACHE_TTL_SECONDS

Comportamento do limite de taxa:

  • Sem X-GitHub-Token: O limitador de taxa do Cloudflare impõe 30 solicitações por minuto por IP
  • Com X-GitHub-Token: O limitador de taxa do Cloudflare é ignorado; sua cota pessoal do GitHub se aplica (5.000 req/h)
  • O cabeçalho de resposta X-Token-Source indica qual token foi usado (user, server ou none)

Comportamento de cache:

As chaves de cache usam SHAs de commit resolvidos para invalidação automática quando os repositórios são atualizados. Entradas de cache antigas expiram naturalmente após o TTL. Se a resolução de SHA falhar, o cache é ignorado e dados frescos são sempre buscados.

Licença

MIT