estudio-aprendizagem
README.md
# Estúdio de Aprendizagem
Projeto pessoal de um aplicativo educacional interativo que funciona no ChatGPT por meio da arquitetura oficial de ChatGPT Apps, Apps SDK e MCP.
## Estado atual
O MVP está implementado e implantado. Ele inclui:
- servidor HTTP local;
- rota de saúde `GET /health`;
- testes automatizados da rota;
- serviço em memória para criar sessões dinâmicas com uma a cinco questões;
- validação, correção e idempotência por `submissionId`;
- testes automatizados da lógica do exercício;
- endpoint MCP local em `http://127.0.0.1:8787/mcp`;
- três ferramentas MCP para preparar uma sessão, iniciar a demonstração fixa e enviar respostas;
- recurso MCP Apps `ui://widget/exercicio.html` com o MIME oficial;
- widget acessível e responsivo em HTML, CSS e JavaScript simples;
- host local de desenvolvimento em `http://127.0.0.1:8787/local`;
- testes automatizados pelo cliente oficial do SDK MCP.
O servidor está implantado no Railway em
`https://inspiring-spirit-production-429d.up.railway.app/mcp`. A versão publicada
continua sendo um MVP sem banco de dados, login ou geração de questões por IA.
## Prova de conceito local
A lógica atual recebe uma definição de sessão com título, matéria ou tema e uma a cinco questões. Cada questão contém enunciado, quatro ou cinco alternativas, alternativa correta e uma explicação interna opcional. O aluno continua informando justificativa obrigatória e confiança de 1 a 5.
Cada sessão recebe um `sessionId` próprio e permanece somente na memória do processo. O servidor entrega uma questão por vez, sem gabarito ou explicação interna, e só avança depois de validar e corrigir a resposta atual. Depois da última resposta, devolve um resumo com acertos, erros, respostas, gabaritos, explicações disponíveis, justificativas e níveis de confiança.
Quando um `submissionId` é repetido com os mesmos dados validados, o serviço devolve o resultado já armazenado sem corrigir novamente. Se o identificador for reutilizado com conteúdo diferente, o serviço rejeita a tentativa e preserva o resultado original.
## Servidor MCP local
O endpoint `/mcp` usa o transporte Streamable HTTP sem sessão. Ele expõe somente estas ferramentas:
- `preparar_sessao_exercicios`: valida a definição recebida, cria a sessão em memória e devolve somente a primeira questão pública;
- `iniciar_exercicio_fixo`: mantém a sessão fixa anterior apenas como demonstração compatível;
- `enviar_resposta_exercicio`: valida e corrige a questão atual, devolvendo a próxima questão pública ou o resumo final.
As ferramentas que preparam sessões referenciam o recurso visual `ui://widget/exercicio.html`. A ferramenta `enviar_resposta_exercicio` permanece sem metadados de UI, para que o envio atualize o widget existente sem solicitar uma nova montagem. O recurso usa `text/html;profile=mcp-app`, conforme o [guia oficial da OpenAI](https://developers.openai.com/plugins/build/mcp-server).
O widget recebe a primeira questão pública pelo resultado da ferramenta inicial e chama somente `enviar_resposta_exercicio` pela ponte MCP Apps. Após cada envio ele avança para a próxima questão e, ao final, mostra o resumo completo. Ele impede o envio incompleto no cliente, mas toda validação, ordem das questões e correção continuam no servidor. O estado visual pode usar `window.openai.widgetState` quando o host oferecer essa extensão; esse recurso é opcional e não substitui o estado em memória do servidor.
Resultados bem-sucedidos seguem o `outputSchema` declarado e usam `structuredContent`. Erros conhecidos usam `isError: true` e mantêm código, mensagem e detalhes no bloco textual de `content`, sem devolver um `structuredContent` incompatível. Falhas internas do transporte recebem uma resposta de erro JSON-RPC 2.0.
## Host local de desenvolvimento
Para testar o MVP sem publicar o plugin nem conectar ao ChatGPT, o servidor expõe `GET /local`. Essa página carrega o mesmo widget do MCP Apps em um iframe e simula a ponte `ui/*` localmente. As chamadas do widget passam pelo servidor em `POST /local/api/tools/call`, usando os mesmos nomes e formatos das ferramentas MCP.
Esse host local existe somente para validação de desenvolvimento. O fluxo MCP real continua em `/mcp`, verificado por `pnpm test:mcp:local`.
## Requisitos
- Node.js 20 ou superior;
- pnpm.
## Comandos locais
- `pnpm start`: inicia o servidor em `http://127.0.0.1:8787`.
- `pnpm test`: executa os testes automatizados.
- `pnpm test:mcp:local`: com o servidor já iniciado, executa uma verificação local pelo cliente oficial MCP.
- Abra `http://127.0.0.1:8787/local` para testar a interação completa no navegador.
A porta pode ser alterada pela variável de ambiente `PORT`. Por padrão, o servidor aceita conexões somente da própria máquina. O endpoint MCP fica disponível em `/mcp` e a rota de saúde permanece em `/health`. Para testar outra porta, defina `MCP_SERVER_URL` antes de executar `pnpm test:mcp:local`.
## Configuração de produção
Toda configuração operacional é recebida por variáveis de ambiente. O projeto
não carrega arquivos `.env` automaticamente; configure os valores no ambiente da
hospedagem ou no gerenciador de segredos da plataforma. O arquivo `.env.example`
contém apenas exemplos sem credenciais.
| Variável | Padrão | Uso |
| --- | --- | --- |
| `NODE_ENV` | `development` | Use `production` na hospedagem. |
| `HOST` | `127.0.0.1`, ou `0.0.0.0` em produção | Interface de rede em que o processo escuta. |
| `PORT` | `8787` | Porta HTTP interna fornecida pela plataforma. |
| `MCP_ALLOWED_ORIGINS` | `*` | Uma origem HTTP(S), uma lista separada por vírgulas ou `*`. |
| `ENABLE_LOCAL_DEV_ROUTES` | ativa fora de produção | Controla somente `/local` e `/local/api/*`; mantenha `false` em produção. |
| `OPENAI_APPS_CHALLENGE_TOKEN` | ausente | Token temporário de verificação de domínio fornecido pelo portal da OpenAI. |
Com `NODE_ENV=production`, as rotas locais de demonstração ficam desativadas. As
rotas públicas são `GET /`, `/suporte`, `/privacidade`, `/termos`, `/site.css`,
`/health`, `/mcp` e, somente quando houver um token configurado,
`GET /.well-known/openai-apps-challenge`. A última devolve o token exato como texto
puro, sem JSON e sem gravá-lo no código ou nos logs.
O site público e as páginas de suporte e políticas ficam no mesmo domínio do MCP:
- site: `https://inspiring-spirit-production-429d.up.railway.app/`;
- suporte: `https://inspiring-spirit-production-429d.up.railway.app/suporte`;
- privacidade: `https://inspiring-spirit-production-429d.up.railway.app/privacidade`;
- termos: `https://inspiring-spirit-production-429d.up.railway.app/termos`.
O CORS de `/mcp` permite os cabeçalhos usados pelo transporte Streamable HTTP e
pode refletir somente as origens configuradas. O valor `*` é compatível com este
MVP público sem credenciais, mas não funciona como controle de acesso. Quando a
origem real de um cliente de navegador for conhecida, prefira uma lista explícita.
O widget é autocontido. Sua política MCP Apps declara listas vazias para conexões,
recursos externos, frames aninhados e URI-base. Se futuramente algum domínio for
necessário, ele deve ser adicionado explicitamente à política e revisado antes da
publicação.
As três ferramentas alteram apenas o estado efêmero da sessão no processo, não
acessam a internet e não apagam ou sobrescrevem dados externos. Por isso todas
declaram `readOnlyHint: false`, `openWorldHint: false` e
`destructiveHint: false`. Todas declaram autenticação `noauth`. A ferramenta de
envio também declara `idempotentHint: true`, de acordo com seu comportamento por
`submissionId`.
## Execução atrás de HTTPS
O processo Node recebe HTTP interno. Em produção, um balanceador ou proxy reverso
deve encerrar TLS e encaminhar as requisições para `HOST` e `PORT`, preservando os
métodos `POST`, `GET`, `DELETE` e `OPTIONS`, além dos cabeçalhos MCP. O endereço
externo precisa ser HTTPS, estável e terminar normalmente em `/mcp`. Não faça
redirecionamento de `/mcp` para outra origem e não armazene respostas MCP em cache.
A infraestrutura deve oferecer:
- Node.js 20 ou uma plataforma compatível com contêiner OCI;
- domínio público estável com certificado HTTPS válido;
- encaminhamento HTTP sem alterar corpo, métodos ou cabeçalhos MCP;
- verificação de saúde por `GET /health`;
- variáveis de ambiente e armazenamento seguro do token de verificação;
- logs operacionais que não registrem corpos de submissões, gabaritos ou tokens.
O `Dockerfile` fornece uma imagem mínima, executada como usuário sem privilégios,
com dependências travadas pelo `pnpm-lock.yaml` e verificação de saúde integrada:
```powershell
docker build -t estudio-aprendizagem .
docker run --rm -p 8787:8787 --env-file .env estudio-aprendizagem
```
Esses comandos servem apenas para validação local da imagem. Nenhuma imagem ou
serviço é publicado automaticamente.
As decisões seguem a documentação oficial atual da OpenAI para
[servidores MCP públicos](https://developers.openai.com/plugins/build/mcp-server),
[UI e CSP do MCP Apps](https://developers.openai.com/plugins/build/chatgpt-ui) e
[verificação de domínio](https://developers.openai.com/plugins/deploy/submission).
## Estado e documentação
O app foi enviado para revisão da OpenAI em 21/09/2026. Isso não significa aprovação. A conexão de teste funcionou no ChatGPT. O projeto está sendo preparado para publicação open source; consulte SECURITY.md antes de hospedar para terceiros.
- [Instalação e deploy](docs/execucao-e-deploy.md)
- [Arquitetura, ferramentas MCP e widget](docs/arquitetura.md)
- [Exemplos](docs/exemplos.md)
- [Contribuição](CONTRIBUTING.md)
- [Segurança](SECURITY.md)
- [Roadmap](docs/roadmap.md)
- [Changelog](CHANGELOG.md)
Licença MIT: veja LICENSE. Não há vínculo oficial com a OpenAI. O software é experimental e não substitui avaliação pedagógica profissional.
## Limites desta etapa
- nenhum banco de dados;
- nenhum login;
- as sessões precisam ser fornecidas por um chamador; não há geração por IA;
- nenhuma chamada à API da OpenAI;
- nenhum ativo, script ou serviço externo no widget;
- nenhum ngrok ou outro túnel;
- publicação do repositório público ainda pendente.
Consulte também as regras permanentes em `AGENTS.md` antes de realizar mudanças.
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues