Skip to main content
Glama

Quaestio MCP Server

O Quaestio é um servidor Model Context Protocol (MCP) para análise, resolução e verificação de questões. Ele expõe ferramentas MCP para que um host compatível possa enviar perguntas, anexos e materiais de estudo e receber resultados estruturados, rastreáveis e conservadores.

O servidor não é uma interface de usuário nem um modelo de linguagem. Ele é a camada MCP que organiza o contrato de entrada, chama os componentes configurados, valida as respostas e devolve uma decisão estruturada ao cliente.

O que é MCP neste projeto

MCP é um protocolo aberto para conectar aplicações host a servidores que oferecem ferramentas e dados de forma padronizada. No Quaestio:

host MCP / cliente MCP
          │
          │ transporte stdio + JSON-RPC
          ▼
Quaestio MCP Server
          │
          ├── ferramentas de resolução e verificação
          ├── parsing, OCR e PDF
          ├── materiais de estudo e busca semântica
          ├── análise e execução controlada de código
          └── políticas de confiabilidade e auditoria

O MCP Server atualmente expõe a primitiva tools. Ele não publica resources, resource templates ou prompts como primitivas MCP separadas. Materiais, OCR, PDFs e capacidades do servidor são acessados por ferramentas.

Referências de protocolo utilizadas:

Related MCP server: Trust OS MCP Server

Capacidades

  • resolver questões de múltipla escolha e abertas;

  • processar perguntas com imagens inline;

  • executar consenso entre dois backends LLM configuráveis;

  • preparar perguntas não inglesas para os modelos configurados;

  • preservar alternativas, índices, fórmulas, código e anexos;

  • verificar estruturalmente e, quando configurado, semanticamente uma proposta;

  • aplicar verificação matemática determinística e simbólica opcional;

  • adicionar e pesquisar materiais de estudo locais;

  • usar embeddings semânticos com fallback para TF-IDF;

  • extrair texto de imagens com Tesseract;

  • extrair e interpretar texto de PDFs;

  • analisar código sem executá-lo;

  • compilar/verificar sintaxe sem executar o código;

  • executar Python ou JavaScript somente em sandbox Docker;

  • avaliar lotes com gabarito e calcular métricas;

  • retornar um trace das etapas executadas.

Princípios de confiabilidade

O servidor foi projetado para falhar de forma explícita quando não há evidência suficiente.

  • ausência de backend ou proposta válida resulta em needs_review;

  • discordância entre os modelos não é resolvida silenciosamente;

  • verificação semântica não é tratada como prova determinística;

  • verified é reservado para evidência confiável, como verificações matemáticas determinísticas;

  • a confiança declarada por um modelo é limitada pelo servidor;

  • entradas, anexos, contexto e materiais recuperados são tratados como dados não confiáveis, nunca como instruções do sistema;

  • falhas de provedores externos são convertidas em avisos e estados estruturados;

  • o servidor não deve ser usado para considerar uma resposta de LLM como garantia de correção.

Arquitetura interna

tools/call
   │
   ▼
MCP boundary
   │  valida argumentos e serializa resultado
   ▼
QuaestioService
   ├── classificação
   ├── recuperação de materiais
   ├── preparação linguística/OCR
   ├── solver determinístico ou LLM
   ├── consenso
   ├── verificação estrutural/semântica
   └── avaliação e trace

Os principais componentes internos são:

  • models.py: contratos canônicos e estados públicos;

  • mcp_server.py: registro, despacho e transporte MCP;

  • service.py: orquestração do pipeline;

  • backends.py: backends determinísticos, LLM, tradução e consenso;

  • verification.py: validações estruturais e matemáticas;

  • semantic_verifier.py: revisão semântica independente opcional;

  • knowledge.py e embeddings.py: base local e recuperação semântica;

  • ocr.py e pdf.py: extração local de conteúdo;

  • sandbox.py: execução controlada de código em Docker.

Transporte e ciclo MCP

O transporte principal é stdio, adequado para servidores locais. O host inicia o processo e conversa com ele por stdin e stdout; cada mensagem é JSON-RPC. Logs de inicialização são enviados para stderr para não corromper o canal MCP.

O servidor implementa os fluxos modernos:

  1. server/discover — descoberta da versão, identidade, capacidades e instruções;

  2. tools/list — descoberta determinística das ferramentas, schemas e cache;

  3. tools/call — execução de uma ferramenta com resultado estruturado.

Quando o pacote oficial mcp está instalado, o servidor utiliza o SDK moderno com transporte stdio. Sem o pacote, utiliza a implementação stdio mínima incluída no projeto. Os dois caminhos registram o mesmo conjunto de ferramentas e seguem o contrato moderno. Cada ferramenta declara inputSchema e outputSchema; o caminho stdio mínimo também valida argumentos antes de executar o handler.

O servidor não inicia uma porta HTTP. Streamable HTTP permanece fora do escopo desta versão.

Instalação

Requisitos:

  • Python 3.11 ou superior;

  • pip;

  • credenciais de um endpoint LLM compatível com a API de chat da OpenAI para resolução assistida;

  • Tesseract, somente para OCR local;

  • Docker e imagens locais, somente para run_code;

  • pypdf, somente para extração de PDFs.

Instalação básica:

python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -e ".[dev]"

Extras opcionais:

pip install -e ".[sdk]"   # Python SDK oficial do MCP
pip install -e ".[math]"  # SymPy
pip install -e ".[pdf]"   # pypdf

Configuração

Copie .env.example para .env e preencha somente os provedores que deseja utilizar. O .env não deve ser versionado nem compartilhado.

Resolução LLM

QUAESTIO_LLM_BASE_URL=https://integrate.api.nvidia.com/v1
QUAESTIO_LLM_API_KEY=...
QUAESTIO_LLM_MODEL=...
QUAESTIO_LLM_TIMEOUT_SECONDS=45

Esse é o backend principal. Se o segundo backend estiver totalmente configurado, o Quaestio executa consenso:

QUAESTIO_SECONDARY_LLM_BASE_URL=https://integrate.api.nvidia.com/v1
QUAESTIO_SECONDARY_LLM_API_KEY=...
QUAESTIO_SECONDARY_LLM_MODEL=...

Sem backend, o servidor continua disponível, mas questões que não puderem ser resolvidas deterministicamente retornam needs_review.

Preparação linguística

QUAESTIO_TRANSLATION_MODE=auto
QUAESTIO_TRANSLATION_TARGET_LANGUAGE=en
QUAESTIO_TRANSLATOR_BASE_URL=https://integrate.api.nvidia.com/v1
QUAESTIO_TRANSLATOR_API_KEY=...
QUAESTIO_TRANSLATOR_MODEL=...
QUAESTIO_TRANSLATOR_TIMEOUT_SECONDS=30
QUAESTIO_TRANSLATION_OCR=auto
QUAESTIO_TRANSLATION_OCR_LANGUAGE=por+eng

Modos disponíveis:

  • never: nunca traduz;

  • auto: traduz quando a pergunta não estiver em inglês;

  • required: exige o tradutor quando a tradução for necessária.

A imagem original não é alterada. Quando há OCR, o texto reconhecido pode ser usado como contexto auxiliar, mas a imagem continua sendo enviada como evidência visual.

Busca semântica

QUAESTIO_KNOWLEDGE_BASE_PATH=./data/knowledge.json
QUAESTIO_EMBEDDING_BASE_URL=https://integrate.api.nvidia.com/v1
QUAESTIO_EMBEDDING_API_KEY=...
QUAESTIO_EMBEDDING_MODEL=...
QUAESTIO_EMBEDDING_TIMEOUT_SECONDS=30

Embeddings são opcionais. Quando indisponíveis, a base local usa TF-IDF. A base armazena materiais e vetores localmente; não adicione conteúdo que não possa ser persistido nesse arquivo.

Verificação semântica independente

QUAESTIO_VERIFIER_LLM_BASE_URL=https://integrate.api.nvidia.com/v1
QUAESTIO_VERIFIER_LLM_API_KEY=...
QUAESTIO_VERIFIER_LLM_MODEL=...
QUAESTIO_VERIFIER_LLM_TIMEOUT_SECONDS=45

Esse backend deve ser separado do solver quando a independência da revisão for importante. Ele retorna supports, contradicts ou uncertain; não transforma uma resposta de LLM em verified.

Recursos locais opcionais

QUAESTIO_TESSERACT_PATH=
QUAESTIO_DOCKER_PATH=
QUAESTIO_SANDBOX_PYTHON_IMAGE=python:3.12-slim

O Docker sandbox não baixa imagens automaticamente. As imagens precisam existir localmente.

Como iniciar o servidor

Após a instalação editável:

quaestio

Sem instalação editável:

$env:PYTHONPATH = "src"
python -m quaestio.mcp_server

O processo parece ficar aguardando entrada porque o transporte stdio é dirigido pelo cliente MCP. Isso é o comportamento esperado.

Configuração em um cliente MCP

Um host MCP precisa iniciar o comando do servidor como subprocesso. Exemplo genérico para Windows:

{
  "mcpServers": {
    "quaestio": {
      "command": "C:\\caminho\\para\\Quaestio\\.venv\\Scripts\\quaestio.exe"
    }
  }
}

Alternativamente, usando Python:

{
  "mcpServers": {
    "quaestio": {
      "command": "C:\\caminho\\para\\Quaestio\\.venv\\Scripts\\python.exe",
      "args": ["-m", "quaestio.mcp_server"],
      "env": {
        "PYTHONPATH": "C:\\caminho\\para\\Quaestio\\src"
      }
    }
  }
}

As variáveis de ambiente podem ser fornecidas pelo .env local ou pela configuração do host. Prefira o mecanismo de segredos do host quando disponível e nunca inclua chaves reais no repositório.

Ferramentas MCP

Resolução e verificação

Ferramenta

Uso

solve_question

Resolve uma questão e retorna resposta, status, confiança, fontes, verificações e trace.

solve_questions_batch

Resolve até 500 questões preservando seus IDs.

verify_answer

Verifica consistência estrutural de uma proposta com a pergunta e suas opções.

verify_answer_semantically

Solicita revisão a um verificador LLM independente, quando configurado.

classify_question

Classifica tipo, disciplina e tópico.

evaluate_questions

Resolve questões com gabarito e retorna métricas de avaliação.

Materiais e recuperação

Ferramenta

Uso

add_study_material

Adiciona texto autorizado à base local.

search_study_material

Busca materiais relevantes por TF-IDF ou embeddings.

Parsing, OCR e documentos

Ferramenta

Uso

parse_questions

Converte texto numerado em questões canônicas.

solve_text

Faz parsing e resolução de um bloco de texto.

extract_questions_from_image

Extrai questões de imagens por backend visual configurado.

ocr_image

Executa OCR local com Tesseract, sem persistir a imagem.

ocr_parse_image

Executa OCR e transforma o resultado em questões.

extract_pdf_text

Extrai texto de um PDF inline usando pypdf.

extract_questions_from_pdf

Extrai texto do PDF e cria questões canônicas.

Para processamento visual e OCR, a entrada precisa conter uma imagem inline em base64. Referências URI são aceitas no contrato canônico, mas o fluxo atual de OCR e envio multimodal utiliza os bytes inline.

Código

Ferramenta

Uso

analyze_code

Analisa código estaticamente sem executar.

compile_code

Verifica sintaxe/compilação sem executar.

run_code

Executa somente Python ou JavaScript em Docker sem rede e com limites de recursos.

run_code não executa código no host. Se Docker, imagem ou linguagem não estiverem disponíveis, retorna um estado estruturado de indisponibilidade.

Diagnóstico

Ferramenta

Uso

server_capabilities

Expõe capacidades e a política de confiabilidade do servidor.

Contrato de entrada

Uma questão canônica pode ser enviada assim:

{
  "question": "Qual é a capital do Brasil?",
  "options": ["Rio de Janeiro", "Brasília", "São Paulo"],
  "question_id": "q-001",
  "context": "Questão de geografia.",
  "attachments": []
}

Campos principais:

  • question: texto obrigatório;

  • options: lista opcional com pelo menos duas alternativas únicas;

  • question_id: identificador preservado em lotes;

  • context: contexto adicional ou material recuperado;

  • attachments: imagens ou documentos, normalmente com mime_type e data_base64;

  • expected_answer e expected_option_index: somente para avaliação com gabarito, não para orientar o solver.

Contrato de saída

Uma resposta contém, entre outros campos:

{
  "question_type": "multiple_choice",
  "answer": "Brasília",
  "option_index": 1,
  "confidence": 0.75,
  "status": "answered",
  "method": "consensus",
  "verification": {
    "status": "answered",
    "verified": false,
    "semantic": {
      "status": "supports",
      "confidence": 0.91
    }
  },
  "sources": [],
  "warnings": [],
  "trace": []
}

Status da resposta

  • verified: evidência determinística suficiente;

  • answered: uma proposta foi produzida, mas não há prova determinística;

  • needs_review: faltou consenso, evidência ou validação;

  • error: falha no pipeline.

O campo correct só é preenchido quando o cliente fornece um gabarito por expected_answer ou expected_option_index.

Exemplo de chamada MCP

Depois de server/discover, o cliente pode chamar:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "_meta": {
      "io.modelcontextprotocol/protocolVersion": "2026-07-28",
      "io.modelcontextprotocol/clientInfo": {"name": "example-client", "version": "1.0.0"},
      "io.modelcontextprotocol/clientCapabilities": {}
    },
    "name": "solve_question",
    "arguments": {
      "question": "Qual é a capital do Brasil?",
      "options": ["Rio de Janeiro", "Brasília", "São Paulo"]
    }
  }
}

O resultado MCP inclui conteúdo textual serializado e structuredContent para clientes que suportam resultados estruturados.

Desenvolvimento e validação

Execute a suíte automatizada com:

pytest -q

Os testes unitários devem ser executados sem depender de chamadas reais aos provedores. Smoke tests contra APIs externas devem ser explícitos, usando credenciais locais e questões autorizadas.

Para validar os endpoints configurados, execute o smoke test opt-in:

quaestio-smoke --require-all --json

quaestio-smoke aplica internamente, no próprio processo, um teto fixo de 40 requisições por minuto. Essa proteção não é lida pelo servidor MCP e não limita o uso normal dos backends.

O dataset sintético de 30 questões pode ser avaliado com:

quaestio-evaluate data/evaluation/benchmark-v1.jsonl --output benchmark-report.json

Ele inclui matemática, engenharia de software e categorias de controle; o gabarito é usado somente para medir o resultado e não é enviado ao solver.

No relatório, needs_review representa uma abstenção por evidência insuficiente ou divergência entre modelos. Essas ocorrências ficam fora de incorrect e reduzem apenas a coverage.

Documentação técnica relacionada:

Limites atuais

  • transporte público HTTP ainda não está implementado;

  • o servidor não expõe resources ou prompts MCP;

  • o verificador semântico aceita imagens inline; URIs externas, PDFs e vídeo ainda não são enviados nessa etapa;

  • o índice de embeddings exige reindexação quando o modelo configurado é trocado;

  • OCR e extração de PDF dependem de instalações locais opcionais;

  • consenso e revisão semântica reduzem risco, mas não substituem gabarito, prova formal ou revisão humana.

Related MCP Connectors

Related MCP Servers