Gemini-Cloud-Agent-MCP
by JOAO2666
README.md
# Gemini Cloud Agent
Aplicação web completa para operar um computador Linux remoto com modelos via OpenRouter, OpenCode Zen, Google Gemini ou TokenRouter: chat multi-etapas, Vercel Sandbox persistente, terminal, arquivos, uploads privados, artefatos verificáveis, Git, previews e servidor MCP Streamable HTTP.
O agente não devolve apenas comandos para o usuário executar. Quando a tarefa exige código ou arquivos, ele usa ferramentas reais no sandbox, lê `stdout`/`stderr`, corrige falhas, valida o resultado e publica o arquivo para download.
## O que está implementado
- Next.js 16, React 19, TypeScript, Tailwind CSS 4 e shadcn/ui.
- Interface mobile/desktop com sidebar, chat, tool cards, logs, upload, STOP, continuar, histórico, artefatos e downloads.
- OpenRouter Free Models Router como opção recomendada, OpenCode Zen/Google Gemini/TokenRouter selecionáveis, function calling e `ToolLoopAgent` do AI SDK 7.
- Loop multi-etapas limitado por `MAX_AGENT_STEPS`.
- Vercel Sandbox 3 com microVM isolada, filesystem persistente e sandbox nomeada por usuário/workspace.
- Shell, filesystem, Git, web/download, processos, archives, artifacts e preview de portas reais.
- Supabase Auth com Google, Postgres/RLS e Storage privado.
- Upload direto por URL assinada, sem atravessar o limite de body da Vercel Function.
- Artefatos com tamanho, SHA-256, MIME, registro no banco e URL assinada curta.
- MCP remoto stateless em `/mcp`, Streamable HTTP atual, OAuth 2.1 + PKCE/DCR e Bearer de compatibilidade.
- MegaBrain Skills com catálogo progressivo de 19 capacidades Claude-compatible, recursos instaláveis no sandbox e origem/licença auditáveis.
- Cancelamento do navegador propagado ao modelo/comando e interrupção da sandbox.
- Testes locais de segurança e suíte cloud real para os cinco cenários obrigatórios.
## Arquitetura
```text
Browser / celular
│
├── Supabase Auth (Google)
▼
Next.js UI + Route Handlers
├── Postgres/RLS ─ mensagens, runs, tools, workspaces
├── Storage privado ─ uploads e artifacts
▼
ToolLoopAgent (AI SDK) ─ OpenRouter / OpenCode Zen / Google / TokenRouter
│ tool ▲ resultado real
▼ │
Tool layer ─ Vercel Sandbox (microVM Linux persistente)
├── /workspace/uploads
├── /workspace/source
├── /workspace/output
├── /workspace/temp
├── /workspace/logs
└── /workspace/metadata
Clientes MCP ─ OAuth/Bearer ─ POST /mcp ─ Vercel Sandbox persistente
```
Cada workspace recebe um nome derivado por SHA-256 de `user_id + workspace_id`. `persistent: true` permite restaurar o filesystem depois que a sessão para. Secrets da aplicação não são injetados no sandbox.
## Pré-requisitos
- Node.js 22+.
- Projeto Supabase.
- Pelo menos uma API key compatível: OpenRouter, OpenCode Zen, Google Gemini ou TokenRouter.
- Projeto Vercel com acesso ao Sandbox.
- Localmente: token, team ID e project ID Vercel. No deploy, OIDC é automático.
O computador do usuário final não participa da execução. Depois do deploy, tarefas e builds rodam na nuvem.
## Instalação
```bash
git clone <seu-repositorio>
cd gemini-cloud-agent
npm install
cp .env.example .env.local
```
Preencha `.env.local`, aplique a migration e rode:
```bash
npm run dev
```
A aplicação abre em `http://localhost:3000`.
## Variáveis de ambiente
Use `.env.example` como fonte completa.
| Variável | Uso |
|---|---|
| `AI_PROVIDER` | `auto`, `openrouter`, `opencode`, `google` ou `tokenrouter`. |
| `OPENROUTER_API_KEY` | Chave OpenRouter somente no servidor. |
| `OPENROUTER_MODEL` | Padrão `openrouter/free`, que escolhe um modelo gratuito compatível. |
| `OPENCODE_ZEN_API_KEY` | Chave OpenCode Zen somente no servidor. |
| `OPENCODE_ZEN_MODEL` | Padrão `nemotron-3-ultra-free`. |
| `TOKENROUTER_API_KEY` | Chave TokenRouter somente no servidor. |
| `TOKENROUTER_MODEL` | Padrão `kimi-k2p6`. |
| `GEMINI_API_KEY` | Chave Gemini opcional. |
| `GEMINI_MODEL` | Model ID usado quando o provider é `google`. |
| `NEXT_PUBLIC_SUPABASE_URL` | URL do Supabase. |
| `NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY` | Chave publicável atual. |
| `NEXT_PUBLIC_SUPABASE_ANON_KEY` | Alternativa para chave anon legada. |
| `SUPABASE_SERVICE_ROLE_KEY` | Somente servidor para a interface web e smoke tests legados. |
| `VERCEL_TOKEN`, `VERCEL_TEAM_ID`, `VERCEL_PROJECT_ID` | Acesso local ao Sandbox. |
| `MCP_SECRET` | Senha OAuth e Bearer de compatibilidade, com no mínimo 24 caracteres. |
| `MCP_USER_ID` | UUID estável usado como namespace isolado das sandboxes MCP. |
| `MAX_AGENT_STEPS` | Máximo de gerações/tool rounds. |
| `MAX_EXECUTION_SECONDS` | Timeout máximo por comando. |
| `MAX_SANDBOX_MINUTES` | Tempo máximo da sessão. |
| `MAX_UPLOAD_SIZE` | Máximo por upload em bytes. |
| `MAX_ARTIFACT_SIZE` | Máximo por artifact em bytes. |
| `MAX_WORKSPACE_DISK_BYTES` | Limite verificado antes/depois das operações. |
| `MAX_TOOL_OUTPUT_CHARS` | Corte de stdout/stderr para modelo/log. |
| `SANDBOX_VCPUS` | vCPUs; memória é vinculada às vCPUs. |
| `SANDBOX_EXPOSED_PORTS` | Até 15 portas de preview. |
`DEV_AUTH_BYPASS=true` é apenas para desenvolvimento, exige service role e é ignorado em produção.
## Supabase
### Banco e Storage
Vincule o projeto e aplique a migration:
```bash
npx supabase login
npx supabase link --project-ref <project-ref>
npx supabase db push
```
A migration cria `workspaces`, `conversations`, `messages`, `agent_runs`, `tool_calls`, `files`, `artifacts`, `sandboxes`, índices, constraints, triggers e os buckets privados `uploads`/`artifacts`.
As tabelas recebem grants explícitos para `authenticated`, pois projetos atuais podem não expor tabelas novas automaticamente. RLS continua exigindo `(select auth.uid()) = user_id` em SELECT, INSERT, UPDATE e DELETE.
### Google Auth
1. No Supabase: Authentication → Providers → Google.
2. Configure Client ID/Secret do Google.
3. Adicione a callback indicada pelo Supabase no Google Cloud Console.
4. Inclua `http://localhost:3000/auth/callback` e a URL de produção nas redirect URLs.
O servidor autoriza com `supabase.auth.getClaims()`, não com `getSession()`.
### Uploads
Os buckets são privados; o primeiro segmento do object path é sempre `auth.uid()`. O navegador usa `createSignedUploadUrl` + `uploadToSignedUrl`; depois o servidor baixa o objeto autenticado e o materializa na sandbox. Assim, uploads de até 50 MB não entram no body da Vercel Function.
## Modelo e agent loop
Por padrão, configure `OPENROUTER_API_KEY` e mantenha `OPENROUTER_MODEL=openrouter/free`. Essa rota escolhe um modelo gratuito que suporte os requisitos da chamada, inclusive tools. Modelos gratuitos têm disponibilidade variável e limites baixos; para fixar um modelo, use um ID `:free` atual do catálogo OpenRouter.
`AI_PROVIDER=auto` seleciona a primeira chave presente nesta ordem: OpenRouter, OpenCode Zen, Google e TokenRouter. Para fixar uma integração, use o nome correspondente. O OpenCode Zen usa o endpoint OpenAI-compatible oficial e um modelo gratuito por padrão. Google Gemini aceita os modelos configurados em `GEMINI_MODEL`. TokenRouter usa seu endpoint OpenAI-compatible.
A seleção fica em `src/lib/ai/provider.ts` e nenhuma chave é enviada ao navegador ou à sandbox.
O system prompt obriga o agente a usar o computador remoto, inspecionar resultados, tratar stderr, corrigir falhas, validar arquivos, chamar `artifact_publish`, ocultar raciocínio privado e não fazer push externo sem autorização.
O loop termina quando o modelo conclui, ocorre condição impossível/cancelamento ou chega a `MAX_AGENT_STEPS`.
## MegaBrain Skills
O agente e o MCP expõem um catálogo de skills carregado sob demanda. Só nome e descrição ficam sempre no contexto; `skill_read` carrega as instruções relevantes, `skill_resources` consulta scripts/referências/assets e `skill_install` copia o pacote completo para `/workspace/metadata/skills/<nome>` quando ele precisa ser executado na microVM.
Um manifesto versionado registra caminho, tamanho e SHA-256 de cada um dos 234 recursos. As 14 skills oficiais são obtidas do commit fixado da Anthropic apenas quando usadas e cada byte é verificado contra o manifesto; as 5 skills nativas ficam no próprio deployment. Isso mantém o deploy leve sem aceitar mudanças futuras do branch upstream. Regenere o manifesto após atualizar as fontes com `npm run skills:manifest`.
O catálogo foi fixado em 24/08/2026 no commit `3b3fad96af16a10759d930941b4520ba0c40edae` de `anthropics/skills`:
- 14 skills oficiais Apache 2.0: `academy-guide`, `algorithmic-art`, `brand-guidelines`, `canvas-design`, `claude-api`, `discernment-nudge`, `frontend-design`, `internal-comms`, `mcp-builder`, `skill-creator`, `slack-gif-creator`, `theme-factory`, `web-artifacts-builder` e `webapp-testing`.
- 5 implementações nativas equivalentes: `doc-coauthoring`, `docx`, `pdf`, `pptx` e `xlsx`.
As quatro skills documentais oficiais são apenas source-available e proíbem cópia/redistribuição fora dos serviços Anthropic; `doc-coauthoring` não publica licença de redistribuição. Por isso essas cinco foram reimplementadas originalmente para o MegaBrain, mantendo a cobertura sem incorporar material restrito. A auditoria está em `skills/PROVENANCE.json`, e cada pacote oficial mantém seu `LICENSE.txt` e avisos de terceiros.
## Vercel Sandbox
O projeto usa a imagem universal atual do SDK, sandbox persistente e `/workspace`. A criação configura vCPU, timeout e portas. O isolamento é uma microVM Firecracker; limites do plano Vercel prevalecem sobre a configuração da aplicação.
Em desenvolvimento, preencha as três credenciais Vercel. No deploy Vercel, o SDK usa OIDC automaticamente.
Para Android/toolchains pesadas, use uma imagem OCI/VCR própria com JDK, Android command-line tools, SDK e Gradle já instalados. Sem imagem customizada, o agente pode instalar dependências na sandbox persistente, sujeito a tempo e disco.
## Ferramentas
- `skill_list`, `skill_read`, `skill_resources`, `skill_install`
- `workspace_info`
- `shell_execute`
- `file_list`, `file_read`, `file_write`, `file_edit`, `file_delete`
- `mkdir`, `move_file`, `copy_file`
- `artifact_list`, `artifact_publish`
- `git_clone`, `git_status`, `git_diff`
- `download_url`, `web_fetch`
- `create_archive`, `extract_archive`
- `process_list`, `process_kill`
- `expose_port`
`shell_execute` chama `bash -lc` na microVM, nunca no processo Next.js. Suporta ferramentas presentes/instaladas como Python, pip, Node, npm, Git, curl, zip, Java e Gradle.
## Artefatos
`artifact_publish(path)` resolve/protege o path, lê o arquivo real, rejeita vazio/tamanho excessivo, calcula SHA-256, detecta MIME, envia ao bucket privado, registra no Postgres e retorna `/api/artifacts/:id/download`. O download valida o usuário e cria URL assinada por 60 segundos.
O painel só oferece Download para registros reais de `artifacts`.
### APKG
Não existe gerador falso. O agente instala uma biblioteca real, como `genanki`, gera o pacote, verifica ZIP/banco/tamanho/hash e publica. A suíte cloud cobre um deck `Teste` com três cards.
### APK Android
O agente pode instalar JDK/Gradle/Android SDK e executar `./gradlew assembleDebug`. Uma imagem VCR pré-aquecida é recomendada. Push e fallback GitHub Actions não são automáticos: exigem credenciais e autorização explícita para branch/push. O MVP oferece clone/status/diff público sem mutação externa.
## Preview
Inicie o servidor no sandbox em background/detached e use `expose_port`. A porta precisa constar em `SANDBOX_EXPOSED_PORTS`. O link usa `sandbox.domain(port)` e existe enquanto a sessão está ativa.
## Cancelamento
STOP cancela o HTTP stream. `vercel.json` habilita `supportsCancellation`; o AbortSignal chega ao modelo e ao comando. A aplicação chama `sandbox.stop()`, matando processos da sessão. O filesystem persistente pode ser restaurado depois.
## MCP remoto
Endpoint desta instalação: `https://gemini-cloud-agent.vercel.app/mcp`.
O transporte é Streamable HTTP stateless. POST é suportado; GET/DELETE retornam 405. O servidor publica descoberta OAuth, registro dinâmico de cliente, Authorization Code + PKCE e refresh token. Isso permite adicionar apenas a URL no Gemini Spark.
No Gemini Spark:
1. Abra `Settings & help` → `Connected Apps`.
2. Em `Custom apps for Spark`, escolha `Add a custom app`.
3. Cole `https://gemini-cloud-agent.vercel.app/mcp` e avance.
4. Na tela `Autorizar Gemini Cloud Agent`, informe o valor de `MCP_SECRET`.
A conexão não é ativada automaticamente apenas por existir na lista. Depois de conectá-la, use `/goal` ou `/meta` e descreva o resultado completo. Os dois prompts encaminham a solicitação para `goal_run`, que cria/reutiliza o computador, escolhe skills, executa comandos, verifica a entrega e publica os arquivos em uma única chamada composta. Se o menu de prompts não aparecer, peça em linguagem natural: `@Gemini Cloud Agent use goal_run para ...`.
O Gemini/Google controla a confirmação de segurança mostrada antes de usar uma ferramenta. O servidor não pode clicar em **Allow** nem desativar essa proteção. O fluxo composto reduz uma tarefa inteira a uma confirmação inicial; ações destrutivas continuam explícitas.
Clientes antigos também podem usar o Bearer diretamente:
```http
Authorization: Bearer SEU_MCP_SECRET
```
Configuração de compatibilidade:
```json
{
"name": "CloudComputer",
"url": "https://SEU-DOMINIO/mcp",
"headers": { "Authorization": "Bearer SEU_MCP_SECRET" }
}
```
Tools: `goal_run`, `skill_list`, `skill_read`, `skill_resources`, `skill_install`, `workspace_create`, `workspace_delete`, `workspace_info`, `shell_execute`, `file_list`, `file_read`, `file_write`, `file_edit`, `git_clone`, `artifact_list`, `artifact_publish`.
Todas operam com `workspace_id`. Cada ID mapeia para uma sandbox nomeada dentro do namespace de `MCP_USER_ID`. O MCP não depende do Supabase para terminal e arquivos, e o segredo nunca é enviado à microVM ou ao modelo.
`goal_run` usa somente os provedores/modelos gratuitos configurados quando `ZERO_COST_MODE=true`. Arquivos novos ou alterados em `/workspace/output` são publicados automaticamente. O resultado traz um `download_url` assinado, válido por 24 horas; depois do vencimento, execute `artifact_publish` novamente para gerar outro link. `workspace_delete` encerra e apaga o computador indicado, portanto só deve ser usado quando essa exclusão for realmente desejada.
Para validar a instalação pública de ponta a ponta — OAuth, catálogo MCP, Linux real, goal autônomo, conteúdo do arquivo, download assinado e limpeza — execute:
```bash
npm run test:cloud
```
## Deploy Vercel
1. Envie o repositório para seu provedor Git.
2. Importe no Dashboard Vercel.
3. Configure as variáveis de produção.
4. Confirme acesso ao Sandbox.
5. Configure a callback de produção no Supabase/Google.
6. Faça deploy.
Validação local equivalente:
```bash
npm run typecheck
npm run lint
npm test
npm run build
```
As rotas declaram duração estendida, mas o limite efetivo depende do plano. Comandos rodam na sandbox; a função web permanece viva durante o loop/stream.
## Segurança
- Código arbitrário apenas no Vercel Sandbox.
- Nenhum env/secret da aplicação é injetado na sandbox.
- RLS em todas as tabelas e Storage por usuário.
- Service role apenas no servidor.
- `shell_execute` exige sessão Supabase na interface web ou OAuth/Bearer no MCP.
- MCP secret comparado em tempo constante.
- Paths normalizados/restritos a `/workspace`; exclusão do root bloqueada.
- URLs de tools bloqueiam localhost, link-local e IPs privados.
- ZIP/TAR é validado contra traversal antes de extrair.
- Timeouts, steps, vCPU/memória, upload, artifact, disco, leitura e output limitados.
- Logs truncam conteúdo e redigem token/secret/password/API key.
- Push/commit remoto não é exposto por padrão.
O disco é verificado antes/depois das operações; o limite físico do Sandbox é a barreira durante um comando que cresce rapidamente. Em produção de alto risco, restrinja também a `networkPolicy` a domínios necessários.
## Custos e free tiers
- O painel mostra os limites ativos.
- Steps/timeouts evitam loops e sessões abandonadas.
- Output/leitura limitados reduzem o contexto enviado ao modelo.
- Supabase Free atualmente inclui quotas de banco, storage e egress; upload máximo por arquivo é 50 MB. Confirme a tabela atual.
- OpenRouter Free Models tem limite compartilhado baixo e não é indicado para produção; disponibilidade de cada modelo varia.
- Gemini, quando usado, tem quotas por projeto/modelo visíveis no AI Studio.
- Vercel Sandbox cobra CPU ativa e planos limitam duração/recursos. Confirme quotas antes de abrir a aplicação ao público.
Fontes: [OpenRouter free models](https://openrouter.ai/collections/free-models), [Supabase pricing](https://supabase.com/pricing), [Gemini rate limits](https://ai.google.dev/gemini-api/docs/rate-limits), [Vercel Sandbox](https://vercel.com/sandbox).
## Testes
Locais, sem cloud:
```bash
npm test
```
Verificam traversal, URLs privadas, sanitização e redação.
Cloud real:
```bash
npm run test:cloud
```
O comando usa o endpoint público de produção e realiza OAuth, inicialização MCP, leitura/instalação de skill, criação de workspace, escrita e leitura de arquivo, comando Linux, `goal_run` autônomo, publicação automática, download assinado e comparação exata dos bytes. Ao final, remove somente o workspace temporário que ele próprio criou.
A suíte administrativa antiga, que depende de `TEST_USER_ID` e credenciais locais adicionais, continua disponível como `npm run test:cloud:extended`.
## Limitações conhecidas
- `shell_execute` transmite `stdout` e `stderr` progressivamente para o event log e para o terminal da interface. O terminal é de acompanhamento e não expõe uma PTY interativa para entrada manual.
- Filesystem persistente depende do recurso/snapshots do plano Vercel.
- Android SDK não é garantido na imagem universal; use VCR própria para previsibilidade.
- GitHub autenticado/push/Actions requer fluxo explícito de autorização.
- PDFs são processados por bibliotecas instaladas dentro da sandbox, mantendo conteúdo não confiável fora do processo web.
- Smoke tests cloud não rodam no CI sem secrets para evitar custo/escrita externa inesperada.
## Troubleshooting
### Supabase não configurado
Confira URL e chave publicável/anon, aplique a migration e reinicie o servidor.
### Login Google volta à tela inicial
Confira provider, redirect URL Supabase e callback Google. Em produção use exatamente `https://SEU-DOMINIO/auth/callback`.
### 401/403 ou tabelas vazias
Rode a migration. Confirme grants do Data API, policies RLS e que o JWT possui o mesmo `user_id`.
### Upload assinado falha
Confira buckets/policies, limite do plano e `MAX_UPLOAD_SIZE`. O primeiro segmento do path deve ser o UUID do usuário.
### Sandbox não autentica localmente
Confira token/team/project Vercel. No deploy, prefira OIDC e não copie tokens desnecessariamente.
### Comando expira
Aumente `MAX_EXECUTION_SECONDS` dentro do limite do plano ou use imagem com dependências pré-instaladas.
### MCP retorna 401/503
401: conclua o OAuth ou envie o Bearer correto. 503: `MCP_SECRET` ou `MCP_USER_ID` está ausente. O UUID é apenas o namespace das sandboxes MCP e não precisa existir em `auth.users`.
### Artifact não aparece
O agente precisa chamar `artifact_publish`. Verifique `tool_calls`, policy do bucket e `MAX_ARTIFACT_SIZE`.
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues