Odysseus Web MCP

Servidor MCP local seguro para busca na web pública e obtenção de URLs com fallback de provedores, extração legível, proteção contra SSRF e resultados orientados a evidências.

Documentação

Odysseus Web MCP — Servidor Seguro de Busca e Busca na Web para Assistentes de IA

Odysseus Web MCP é um servidor autônomo Model Context Protocol (MCP) para busca segura na web pública e busca de URLs. Ele roda localmente via stdio e oferece a assistentes de IA compatíveis com MCP duas ferramentas de recuperação: web_search para descobrir fontes e web_fetch para recuperar e extrair URLs públicas.

Construído para clientes como Claude Code, Cursor e Codex, ele combina fallback de provedores de busca, extração legível de HTML/PDF/texto, renderização opcional de JavaScript e proteções contra SSRF, incluindo validação de DNS e reverificação de redirecionamentos.

Live web search terminal demo

Live web fetch terminal demo

Recursos

  • Busque na web pública com fallback de provedores e fontes ranqueadas e atribuídas.
  • Busque e extraia conteúdo HTML, PDF e texto de URLs públicas.
  • Proteja contra SSRF com verificações de rede pública, validação de DNS e revalidação de redirecionamentos.
  • Retorne saída limitada e orientada a evidências com cursores, sinais de qualidade e links descobertos.
  • Opcionalmente, renderize páginas com muito JavaScript no Playwright isolado.

Instale em minutos

Requisitos: Python 3.11+ e uv.

# after downloading/extracting this folder (or cloning your copy)
cd odysseus-web-mcp
uv venv .venv
uv pip install -e '.[dev]'
./run-web-mcp.sh

O servidor se comunica via stdio, portanto não abre uma porta web e não precisa ser instalado no ambiente Python do seu aplicativo host. Registre o caminho absoluto do launcher no seu cliente MCP:

{
  "name": "odysseus-web-mcp",
  "command": "/absolute/path/to/odysseus-web-mcp/run-web-mcp.sh",
  "args": [],
  "cwd": "/absolute/path/to/odysseus-web-mcp"
}

O launcher usa automaticamente o .venv do pacote. O estado padrão é ~/.local/share/odysseus-web-mcp; defina WEB_MCP_DATA_DIR para colocá-lo em outro lugar. Nenhuma chave de API é necessária para o caminho de fallback padrão, embora chaves Brave, Tavily e Serper possam ser adicionadas quando você quiser esses provedores.

As duas ferramentas

web_search

Use-a para descobrir fontes para uma pergunta focada. Ela aceita de uma a três consultas, além de controles opcionais de modo, vertical e atualização.

{
  "queries": "Model Context Protocol Python SDK",
  "mode": "discovery",
  "vertical": "general"
}

A resposta contém URLs ranqueadas, títulos, trechos, tentativas de provedores, estado de cache, uma projeção de exibição em texto simples e um evidence_id. Um host pode levar qualquer URL retornada diretamente para web_fetch.

web_fetch

Use-a para ler uma URL pública conhecida ou um lote limitado de URLs.

{
  "url": "https://example.com",
  "focus": "the page's purpose",
  "render": "auto"
}

Ela retorna texto extraído, título e tipo de documento, qualidade do conteúdo, descoberta de links, histórico de redirecionamentos, status HTTP, metadados de truncamento/continuação e um evidence_id. Destinos privados e de uso especial são rejeitados antes do transporte por padrão.

Exemplo: como um agente usa o MCP

Um agente normalmente usa as ferramentas como um loop de recuperação em duas etapas: buscar primeiro, depois buscar a fonte que deseja inspecionar. Os payloads abaixo mostram a forma de uma interação MCP real; IDs e texto de resultado são abreviados para legibilidade.

1. O agente busca fontes

{
  "name": "web_search",
  "arguments": {
    "queries": "official Model Context Protocol architecture",
    "mode": "grounding",
    "vertical": "general"
  }
}

O MCP retorna um bloco de conteúdo de texto contendo JSON estruturado:

{
  "status": "ok",
  "query": "official Model Context Protocol architecture",
  "sources": [
    {
      "title": "Architecture - Model Context Protocol",
      "url": "https://modelcontextprotocol.io/docs/concepts/architecture",
      "snippet": "Understand the architecture and communication model...",
      "provider": "duckduckgo",
      "relevance_score": 1.0
    }
  ],
  "provider_attempts": {
    "searxng": "empty",
    "duckduckgo": "ok"
  },
  "evidence_id": "a1b2c3d4...",
  "exit_code": 0
}

2. O agente busca a fonte selecionada

O agente pega a URL retornada e chama a segunda ferramenta:

{
  "name": "web_fetch",
  "arguments": {
    "url": "https://modelcontextprotocol.io/docs/concepts/architecture",
    "focus": "How do clients and servers communicate?",
    "render": "auto"
  }
}

O MCP retorna evidências extraídas e limitadas:

{
  "success": true,
  "url": "https://modelcontextprotocol.io/docs/concepts/architecture",
  "final_url": "https://modelcontextprotocol.io/docs/concepts/architecture",
  "http_status": 200,
  "document_kind": "html",
  "content_quality": "good",
  "content": "The Model Context Protocol defines how clients and servers...",
  "links": [
    {
      "url": "https://modelcontextprotocol.io/docs/concepts/transports",
      "text": "Transports"
    }
  ],
  "evidence_id": "e5f6g7h8...",
  "exit_code": 0
}

O agente agora pode responder ao usuário a partir do conteúdo extraído, preservar o evidence_id para rastreabilidade e continuar com outro web_fetch usando um cursor retornado se a página for maior que o orçamento de saída.

Como funciona localmente

MCP host ──stdio──▶ mcp_server.py
                       ├─ web_search → provider chain → ranked evidence
                       └─ web_fetch  → security → HTTP/extract/render → evidence

Todo o estado persistente está enraizado sob WEB_MCP_DATA_DIR. O pacote não tem importações em tempo de execução do Odysseus e nenhum acesso às suas credenciais, banco de dados, memória, perfis de navegador, agendador ou loop de agente.

Leia o design completo do sistema local em docs/TECHNICAL_DESIGN.md e veja como os GIFs foram gravados em docs/INTERACTIVE_DEMO.md.

Provedores de busca e configuração

A cadeia de provedores padrão é:

SearXNG → Brave → Tavily → Serper → DuckDuckGo → Wikipedia → Bing

Configure-a com WEB_MCP_SEARCH_PROVIDER_CHAIN. Credenciais opcionais são DATA_BRAVE_API_KEY, TAVILY_API_KEY e SERPER_API_KEY. Copie .env.example como referência, mas mantenha segredos no ambiente host em vez de commitá-los.

O caminho opcional do navegador está desabilitado por padrão:

uv pip install -e '.[render]'
./.venv/bin/python -m playwright install chromium
export WEB_MCP_RENDER_ENABLED=true

Distribuição e descoberta

O servidor é publicado no Registro MCP oficial sob io.github.AceAtDev/odysseus-web-mcp.

Para Claude Desktop e outros clientes compatíveis com MCPB, baixe o pacote de lançamento MCPB validado do Lançamento v0.1.0 no GitHub. O pacote usa o runtime uv para resolver as dependências Python declaradas sem enviar um ambiente virtual específico da máquina.

Verifique você mesmo

O projeto tem uma suíte de testes focada e um executor de qualificação ao vivo:

./.venv/bin/python -m pytest -q
./.venv/bin/python tests/live_20_cases.py --output reports/live-20-cases.json

A qualificação ao vivo executa 10 buscas e 10 buscas de URL através do launcher MCP real com estado descartável. O registro de verificação mais recente está em VERIFICATION.md.

Para regravar as prévias de terminal a partir de chamadas ao vivo recentes (requer o comando convert do ImageMagick):

./.venv/bin/python demos/record_terminal_demos.py

Cada GIF tem intencionalmente menos de dez segundos e mostra um handshake MCP real e a forma do resultado, não um mockup estático de produto.

Limites do projeto

Este pacote é um primitivo de recuperação, não um loop de agente, rastreador de uso geral, agendador, armazenamento de memória, gerenciador de perfis de navegador ou cofre de credenciais. Ele é projetado para ser baixado e conectado como um servidor MCP independente.

Licença e status

Este é o espaço de trabalho de extração autônomo para a capacidade de busca/busca de URL web do Odysseus. Veja MIGRATION_MAP.md para o mapeamento fonte-para-módulo e VERIFICATION.md para o status atual baseado em evidências.