dot-mcp
MCP auto-hospedado para Linux/Termux: shell, arquivos, memória, tarefas, navegador e um cofre local experimental. Acesso remoto protegido por OAuth; roda na sua própria máquina.
Documentação
dot-mcp
Agente MCP pessoal para ChatGPT, Claude e Gemini: shell, arquivos, memória, metas, tarefas, caixa de entrada, agendador e OAuth auto-hospedado — rodando na sua própria máquina.
⚠️ O servidor dá acesso total ao shell para quem possuir uma credencial. Exponha-o apenas enquanto estiver usando e depois pare-o (
dot-mcp stop).
Instalação
pip install dot-mcp
Requer Python 3.10+ e OpenSSH (ssh, ssh-keygen) para o túnel.
Uso
dot-mcp start # server + public URL (runs in background)
dot-mcp status # check if it is running
dot-mcp stop # stop server + tunnel
dot-mcp start imprime tudo o que o conector precisa:
Public URL https://xxxx.tunnl.gg/mcp/
Owner secret <stored on your machine>
OAuth Client ID dots-xxxxxxxx
OAuth Client secret <stored on your machine>
Adicione a URL pública como um conector MCP personalizado (auth = OAuth). Aprove uma vez com o segredo do proprietário quando solicitado. A URL do túnel permanece a mesma ao reiniciar; o túnel gratuito expira após 24h ou 2h ocioso.
Linux/Termux é o runtime suportado para gerenciamento de processos. Parar afeta apenas processos iniciados com os novos registros de propriedade. Ao atualizar de uma versão mais antiga, pare o servidor/túnel anterior antes de iniciar esta versão; arquivos PID legados simples não são deliberadamente confiáveis.
DOT_MCP_STATE_DIR substitui o diretório completo de credenciais/chaves SSH
(padrão ~/.config/dot-mcp), não seu pai. Isso é separado de --data-dir.
Caminhos de arquivo são relativos a $HOME a menos que sejam absolutos.
Caminhos absolutos mantêm sua localização e devem estar dentro de $HOME,
$TMPDIR ou armazenamento compartilhado disponível; outros caminhos são
rejeitados, não colocados silenciosamente em HOME. No Android, quando
$TMPDIR está fora de /tmp, /tmp e /tmp/...
mapeiam para $TMPDIR. As ferramentas de arquivo retornam o path
efetivo. O texto de comandos shell nunca é remapeado, então use esse caminho
efetivo em comandos shell quando esse mapeamento se aplicar.
As raízes de arquivo são proteções, não uma sandbox de shell. Uma credencial de shell ainda concede acesso total como o usuário do SO do servidor. Use um usuário/contêiner de SO separado para cargas de trabalho não confiáveis.
Opções: --port (padrão 33041), --data-dir (padrão ~/.dot-mcp),
--json (saída amigável para scripts).
Túnel de desenvolvimento (somente teste)
dots start --dev usa um túnel rápido do Cloudflare em vez do fluxo padrão
tunnl.gg com chave estável. Ele precisa de cloudflared no PATH, não OpenSSH.
A ausência de cloudflared é relatada como not installed: cloudflared; nada é instalado.
DEV / INSTÁVEL: os nomes de host do túnel rápido mudam a cada reinicialização e não têm garantia de disponibilidade. Erro 1033/indisponibilidades podem ocorrer. Túneis rápidos do Cloudflare não suportam SSE, então algumas combinações de cliente/transporte MCP podem falhar mesmo se a inicialização passar. Não use este modo para conectores de produção.
A proteção de Host/Origem permanece ativada. O host trycloudflare.com descoberto
é passado ao servidor antes de sua única inicialização, com verificação pública
autenticada de initialize. Uma verificação falha interrompe o servidor e o túnel
de propriedade. dots stop interrompe qualquer provedor; --json
inclui modo, provedor e campos instáveis. Uma configuração Cloudflare vazia
explícita impede reutilizar um túnel nomeado salvo.
Isso é uma troca de provedor, NÃO uma sandbox de segurança: use um
contêiner/usuário de SO separado com credenciais descartáveis. O modo dev não
altera os caminhos padrão de dados ou credenciais e ainda pode usar um vault
local existente opcional. Em uma sandbox isolada, use caminhos DOT_MCP_DATA
e DOT_MCP_STATE_DIR separados e um HOME descartável; não monte arquivos pessoais.
Pacotes opcionais de navegador/vault não são necessários para um teste básico
de MCP/OAuth. --dev --vault usa o mesmo provedor dev, mas requer o desbloqueio
normal do vault local.
Documentação do Cloudflare: https://developers.cloudflare.com/tunnel/get-started/quick-tunnels/
O que ele pode fazer (51 ferramentas nesta revisão de desenvolvimento)
- Shell:
run_command(sessões em segundo plano + timeout) +read_output - Arquivos:
list_dir,read_file(paginado + sha256),write_file(atômico + proteções),append_file,edit_file - Memória:
remember,recall,forget— persiste entre conversas - Metas/Tarefas:
set_goal,add_update,get_state,add_task,complete_task - Caixa de entrada:
notify_user,poll_inbox,ack_inbox— mensagens entre conversas - Agendador:
add_schedule,list_schedules,remove_schedule— trabalhos em segundo plano que rodam entre conversas - Navegador:
browser_open/navigate/snapshot/click/type/scroll/key/screenshot/closebrowser_hover/select/wait/back/reload— snapshots relatam estado desabilitado, marcado e de opção selecionada;waitlida com páginas dinâmicas
- Ao vivo:
/livereconecta automaticamente (capacidade de sessionStorage), mostra o domínio atual, visualização em tela cheia; o controle ainda requer o token do proprietário - UI:
open_workspace— painel embutido (tarefas, memória, sessões)
Trabalho durável (revisão de desenvolvimento)
Nomes/assinaturas de ferramentas existentes permanecem disponíveis. Novas ferramentas de trabalho:
create_work_task,get_work_task,list_work_tasks,update_work_taskstart_command,get_session_status,cancel_commandregister_artifact,bootstrap_context,ack_work_result,purge_session_output
Fluxo sugerido para ChatGPT/Claude:
- Chame
bootstrap_contextno início de uma nova conversa. - Crie uma tarefa de trabalho, depois
start_commandcom seutask_id. - Consulte
read_output/get_session_status. A saída é legível enquanto roda. - Verifique o resultado, registre arquivos de saída e defina a tarefa como
donecom um resultado, oublockedcom uma pergunta. Sair com zero sozinho nunca finaliza uma tarefa. - Em uma nova conversa, carregue o contexto e inspecione
get_work_taskpara retomar.
start_command retorna imediatamente. Um idempotency_key reutilizado retorna a
mesma sessão para uma solicitação idêntica; uma solicitação alterada com essa chave é
rejeitada. Isso evita lançamentos duplicados, não efeitos externos exatamente-uma-vez.
set_goal altera a meta atual sem excluir o histórico de add_update.
O run_command original permanece como a API síncrona legada. Use as novas
ferramentas de início/status para trabalho assíncrono durável; read_output e
get_session_status lidam com ambos. O status legado é apenas em memória e não
sobrevive a reinicializações. purge_session_output limpa a saída legada finalizada
mantendo seus metadados; saída ativa não pode ser purgada. A saída durável ainda
requer ack_work_result antes da purga.
Limites padrão de comandos: 4 sessões ativas, 1 hora de tempo máximo de execução, 4 MiB combinados
de saída por sessão e 64 MiB de saída salva antes que novo trabalho seja recusado. A saída
não é excluída silenciosamente: reconheça um resultado finalizado e purgue explicitamente
sua saída. Os metadados de tarefa/eventos/sessão permanecem em work.sqlite3 (arquivo privado).
No primeiro uso, tarefas legadas são copiadas de state.json uma vez, com um backup
privado. Ferramentas JSON antigas ainda usam seus arquivos antigos, e bootstrap_context mostra
tarefas/caixa de entrada legadas atuais separadamente. Memória/metas/agendamentos/OAuth não são
migrados ou reescritos. Use as novas ferramentas de tarefas de trabalho consistentemente; a lista
de tarefas legadas e a lista de trabalho durável são separadas após a importação inicial.
Um servidor possui a execução por diretório de dados. Após uma falha/reinicialização do servidor,
comandos em execução não verificados são interrompidos se sua identidade de processo salva ainda
corresponder, e marcados como interrupted. Eles nunca são reiniciados automaticamente.
Isso é recuperação de registros verdadeiros, não sobrevivência transparente de processos.
Artefatos são caminhos de arquivo locais mais SHA-256, não links de download hospedados. Esta revisão não tem navegador, notificações push ou worker LLM autônomo, e não precisa de nova chave de API de modelo para o fluxo de trabalho de conversa ativa. Um host pode precisar atualizar suas ferramentas após uma atualização. A integração ao vivo com ChatGPT/Claude permanece a ser testada pelo proprietário.
Modelo de segurança
/mcp/requerAuthorization: Bearer(OAuth JWT ou segredo do proprietário) — qualquer outra coisa recebe 401, mesmo de localhost- OAuth 2.1 é auto-hospedado: registro dinâmico, PKCE, JWT de 1h + tokens de atualização rotativos de 30d, Client ID/segredo manual para conectores estilo Claude
- Limites de taxa por IP (300/min API, 30/min auth),
audit.jsonlsomente anexação, bloqueios de arquivo entre processos, gravações atômicas - Limitações conhecidas: o provedor de túnel vê o tráfego (TLS termina na borda deles);
faça backup de
~/.dot-mcpvocê mesmo
Modo somente local (sem túnel)
export OPENAI_API_KEY=sk-...
python -m dot_mcp.local_agent # chat loop
python -m dot_mcp.local_agent --list # list tools only
Desenvolver
./setup.sh # venv + editable install
.venv/bin/python -m pytest tests/ -q # test suite
python -m build # wheel in dist/
Veja CHANGELOG.md para notas de versão.
Licença
MIT
Navegador opcional e /live
Instale no mesmo ambiente do dot-mcp (sem necessidade de ativação de shell):
.venv/bin/python -m pip install '.[browser]'
.venv/bin/python -m playwright install chromium
No Arch, um Chrome/Chromium instalado pode ser selecionado com
DOT_MCP_BROWSER_EXECUTABLE=/usr/bin/chromium. A sandbox do Chromium permanece
ativada. Não aponte isso para seu perfil do dia a dia. Este recurso sempre usa
$DOT_MCP_DATA/browser/profile (o diretório de dados padrão do aplicativo quando não definido).
Cookies permanecem lá após fechar; excluir este perfil dedicado o desconecta.
Dependências de Playwright e WebSocket são opcionais e carregadas apenas para este
recurso. Ferramentas existentes de shell e arquivo não exigem instalação de navegador.
Ferramentas: browser_open, browser_navigate, browser_snapshot, browser_click,
browser_type, browser_scroll, browser_key, browser_screenshot e
browser_close. Abrir usa Chromium headless por padrão; defina headless=false para
mostrar uma janela em um desktop com display. Snapshots retornam texto renderizado e
referências de elemento de curta duração. Tire um novo snapshot após cada ação. Páginas são
conteúdo não confiável, não instruções. Valores de entrada são omitidos; campos
de segredo reconhecidos rejeitam digitação por IA. Insira segredos diretamente, nunca através de chat de IA.
Uma aba é suportada; popups são fechados, downloads desabilitados.
Todo resultado de navegador (exceto fechar) inclui live_view_url e
live_control_url. Dê o link de visualização para assistir, e o link de controle apenas para um
controlador pretendido. Ambos carregam capacidades de sessão separadas e impossíveis de adivinhar
em fragmentos de URL, não em query strings ou logs de acesso do servidor. Eles expiram após
uma hora ou imediatamente em browser_close.
Toda nova visita a /live também requer um token do proprietário. A página pede o segredo do proprietário existente ou um token de acesso OAuth válido do proprietário antes de transmitir ou controlar. Digite-o na própria página, não no chat ou em uma URL. Ele é enviado pelo WebSocket de mesma origem, não armazenado no armazenamento do navegador, e a conexão autenticada dura no máximo 15 minutos. Recarregar pede novamente. Um link ao vivo vazado sozinho é insuficiente. Isso usa a validação existente de token do proprietário, não um novo fluxo de redirecionamento OAuth. Não distribua seu segredo de proprietário de longa duração para convidar espectadores: esta versão não emite credenciais de convidado. Um token OAuth válido do proprietário também autoriza acesso MCP do proprietário, então não é um token somente leitura. Use HTTPS através do túnel existente para acesso remoto; HTTP simples é para teste de loopback apenas. A Origem do WebSocket deve corresponder exatamente ao emissor público configurado. As verificações de segredo do proprietário/OAuth do MCP não são alteradas.
A página /live tem botões Assumir controle / Liberar, clique e segure, arrastar
de ponteiro, digitação direta, teclado para baixo/cima e rolagem de roda. Apenas um humano
controla por vez. Enquanto o controle está reivindicado, alterações de IA são rejeitadas até
liberação/desconexão; snapshots somente leitura e capturas de tela permanecem disponíveis.
Até cinco espectadores podem entrar. Filas de quadro mais recente descartam quadros antigos em vez de
acumular latência. Vídeo ao vivo não é mascarado e pode mostrar conteúdo privado
de página. PNGs de captura de tela mascaram controles editáveis, mas texto comum de página pode
ainda ser privado. browser_screenshot(task_id=...) registra o PNG local
com artefatos de trabalho existentes; não é um link de download público.
A transmissão visa 60 fps usando screencast JPEGs do CDP do Chromium. A página mostra
taxas recebidas e capturadas. Páginas estáticas naturalmente emitem menos quadros;
rede, CPU, decodificação de imagem e velocidade do túnel podem reduzir a taxa. Falha
na configuração do CDP recorre à amostragem de capturas de tela até 5 fps, relatada em
stream_mode. Sem garantia de 60 fps. Isso é automação de navegador em sua máquina
local, não uma sandbox de rede: sites HTTP/HTTPS podem alcançar serviços localhost ou LAN.
O perfil separado não torna o shell completo existente seguro.
Testes de integração locais (opcionais, precisam de Chromium instalado):
TEST_CHROME=/usr/bin/chromium .venv/bin/python -m pytest tests/test_browser.py -q -s
.venv/bin/python -m pytest tests -q
Os testes de navegador usam apenas um fixture de loopback, incluindo controle /live autenticado, segurar, texto, rolagem, referências obsoletas, expiração de capacidade e fallback.
Cofre local opcional somente para preenchimento (experimental)
Instale o .[browser,vault]. O cofre usa criptografia autenticada AES-256-GCM
com um salt aleatório de 16 bytes e chave derivada de Scrypt (N=32768, r=8, p=1) a partir de uma
senha humana. Ele fica bloqueado por padrão. Nomes, origens e valores estão todos
dentro do arquivo criptografado; o formato/versão da criptografia é público. Os arquivos são
privados (0600), com substituição atômica e um bloqueio de processo cooperativo. Mantenha
um backup offline: não há recuperação de senha. Escolha uma senha longa e
única; 12 caracteres é um mínimo, não uma garantia de segurança.
Configuração local de terminal somente para humanos (sem segredos em argumentos de comando, chat ou env):
.venv/bin/python -m dot_mcp.cli vault init
.venv/bin/python -m dot_mcp.cli vault set --name example-login --origin https://example.com --field username --field password
.venv/bin/python -m dot_mcp.cli vault list
Cada comando solicita getpass e não ecoa valores. Os nomes não são
secretos por design. --origin é normalizado para esquema, host e porta exatos;
caminhos não limitam credenciais dentro de uma origem. Sem curingas de subdomínio ou
correspondência de sufixo. HTTPS é obrigatório. --allow-loopback-http permite explicitamente
apenas fixtures de desenvolvimento HTTP localhost/127.0.0.1/::1, nunca HTTP em LAN.
Para executar com um cofre desbloqueado, pare qualquer servidor existente que mantenha o mesmo diretório de dados, configure a autenticação/túnel do proprietário MCP existente normalmente, e então inicie em primeiro plano:
.venv/bin/python -m dot_mcp.cli vault serve
Isso solicita a senha localmente e inicia o servidor HTTP nesse mesmo
processo. Ele não cria um túnel nem imprime segredos do proprietário/cliente.
Não passe uma senha por variáveis de ambiente ou argumentos. Um dots start normal
inicia bloqueado e não pode desbloquear o cofre via MCP. Não há
API ou página de desbloqueio/edição remota. Após 15 minutos ociosos, o próximo acesso ao cofre
auto-bloqueia; reinicie o comando em primeiro plano para desbloquear novamente. vault_lock
o bloqueia imediatamente. Python não pode prometer apagamento forense de chaves da memória.
Ferramentas MCP adicionadas: vault_list retorna apenas nomes; vault_fill(name,key,ref)
preenche um nome de usuário/senha/token salvo em uma ref de entrada visível nova, com
verificação exata de origem permitida e sem envio; vault_lock remove o estado
desbloqueado. Um preenchimento em outra origem é recusado. Tire um snapshot do navegador antes
de preencher e use essas refs para a sequência de nome de usuário/senha e envio. As
refs de pré-preenchimento permanecem válidas para preenchimentos consecutivos, sujeitas à identidade do DOM e
verificações de URL. Ações subsequentes normais do navegador invalidam refs como antes.
Antes de preencher, o navegador entra em modo de privacidade fixo: ele limpa frames ao vivo enfileirados,
pausa vídeo e bloqueia todos os snapshots/capturas de tela/URL da página/títulos
de saída até browser_close. Isso inclui o fallback de captura de tela.
browser_key('Enter') pode enviar, mas revise a ação primeiro. Uma página pode
refletir uma senha em qualquer lugar, então mascaramento seletivo de entrada não é uma promessa segura.
Este modo conservador significa que a IA não pode verificar visualmente um login após o preenchimento;
o humano verifica na janela dedicada do navegador (headless=false) e a fecha
quando terminar. Nenhuma API restaura vídeo em uma página já preenchida.
Modelo de ameaça e limites
Esta é uma interface de saída de ferramenta somente para preenchimento, não um limite de isolamento de segredos. O JavaScript da página do navegador necessariamente vê valores preenchidos em entradas HTML comuns (mesmo type=password), e o site autorizado os recebe. A vinculação de origem impede o preenchimento em uma origem diferente; ela não protege contra um site autorizado comprometido, XSS, extensões maliciosas ou phishing na origem aprovada. Redirecionamentos HTTP são verificados contra a origem da página atual antes do preenchimento; nenhum conteúdo geral da página pode conceder permissão para usar uma chave.
Não habilite acesso total ao shell para uma IA que você não confia. As ferramentas
sh/comando existentes são executadas como o mesmo usuário do SO. Elas podem inspecionar arquivos/processos,
ler material de chave da memória, automatizar um segundo navegador ou instrumentar código.
O armazenamento criptografado em repouso não pode impedir isso. Guardas de raiz do sistema de arquivos não
isolam o shell. Um limite real precisa de um principal de SO separado para o cofre,
IPC restrito e uma política de navegador/entrada fora do controle da IA, além de
nenhum shell irrestrito do mesmo usuário. Essa arquitetura endurecida não está neste patch.
Da mesma forma, capturas de tela salvas antes do uso do cofre, scrollback do terminal, caches de página,
cookies de perfil e logs de serviços remotos têm suas próprias vidas úteis. Segredos não
devem ser incorporados em nomes de entrada ou enviados ao chat. Nenhum fluxo de cartão de pagamento ou TOTP
é implementado ainda. Use apenas credenciais descartáveis ao avaliar este
recurso experimental.
Credenciais de inicialização e UI de consentimento
A inicialização agora mantém segredos do proprietário/cliente fora da saída normal do terminal e
dots start --json. O resultado JSON inclui credentials_hidden=true
em vez de owner_secret / client_secret. Esta é uma mudança de quebra deliberada
para scripts que leem segredos do JSON de inicialização. O ID do cliente e a URL pública
permanecem disponíveis. Use dots credentials para locais de arquivos ou
dots credentials --show em um terminal interativo privado somente: ele requer
uma confirmação explícita de REVELAR e recusa saída redirecionada. Gravação de terminal/
scrollback ainda captura uma revelação intencional, então não a grave.
Não cole segredos no chat de IA. A página OAuth descreve acesso a shell/arquivos
de nível de proprietário antes da aprovação, não usa ativos remotos e envia cabeçalhos
sem cache, sem referrer e anti-framing. Parâmetros OAuth e regras de verificação
são inalterados.
Largura de banda e backpressure do stream ao vivo
O stream agora usa padrão JPEG qualidade 55 e largura máxima de captura 960 (o
viewport do navegador controlado permanece 1280x720). Configure
DOT_MCP_STREAM_QUALITY=30..85 e DOT_MCP_STREAM_WIDTH=640..1280 antes de
iniciar para texto mais nítido ou menor largura de banda. Coordenadas de controle ainda se referem
ao viewport 1280x720. Isso troca intencionalmente alguma nitidez de imagem por
largura de banda; capturas de tela permanecem PNGs de viewport completo. É configurável, não um
estimador automático de largura de banda.
O cliente /live reconhece frames decodificados. Uma janela limitada de quatro frames mais fila de último frame evita backlog ilimitado enquanto tolera tempo de ida e volta de rede. Um cliente que não reconhece frames é desconectado após cinco segundos. Os contadores agora distinguem frames capturados, recebidos e exibidos; 'exibido' significa imagem decodificada e desenhada no canvas, não refresh de monitor medido. Páginas estáticas emitem poucos frames naturalmente. Sem garantia sustentada de 60 fps.
Diagnósticos e reconexões
dots doctor (ou dots doctor --json) verifica versões de pacotes locais,
escolha de interpretador/fonte, disponibilidade de dependências opcionais e a contagem de ferramentas
/health de loopback ao vivo sem iniciar um navegador ou revelar
credenciais. Ele distingue o Python de diagnóstico do Python do servidor selecionado;
versões de pacotes são para o interpretador de diagnóstico. Disponibilidade instalada
do Chromium é uma pista, não um teste de lançamento bem-sucedido.
Após aplicar patches, reinicie o servidor Python em execução. Editar arquivos não
recarrega o processo antigo. A Rodada 3 sozinha registra 42 ferramentas; a Rodada 4 de cofre adiciona
3 para 45; a rodada de controle do navegador adiciona hover/select/wait/back/reload para 51.
Verifique dots status ou /health ao vivo, então reconecte/atualize a
lista de ferramentas do conector do assistente. Importar código do servidor em um shell separado
apenas verifica arquivos, não o servidor já em execução. Nunca contorne ferramentas browser_*
ausentes com um processo Python separado: seu navegador/tokens não são
de propriedade do manipulador /live do servidor. Não há rota pública de captura de tela
/shot/... nestes patches; artefatos de captura de tela são arquivos locais privados.
vault serve reutiliza o arquivo de segredo do proprietário local privado da CLI quando
MCP_PATH_SECRET não está definido, então não cria uma credencial de proprietário aleatória inalcançável.
Ele ainda não imprime nenhum segredo. Env de proprietário explícito existente tem
precedência. O processo recebe essa credencial de proprietário como dots start normal; isso não é uma variável de env de senha do cofre.
O Chromium usa um diretório temporário privado curto para seus sockets de processo quando
o /tmp do sistema é gravável, mesmo se seu TMPDIR de aplicativo configurado estiver profundamente aninhado.
Ele é limpo no fechamento do navegador. Perfil do navegador e capturas de tela ainda vivem no
diretório de dados dedicado. Isso evita estouro de caminho de socket Unix no Linux;
não enfraquece o sandbox do Chromium.
O CSP de consentimento OAuth permite a origem HTTPS de callback validada, bem como
self para envio de formulário. O Chromium aplica form-action ao redirecionamento
após um POST; restringi-lo apenas a self bloqueou callbacks OAuth
bem-sucedidos. Esta permissão é gerada a partir do redirecionamento já validado,
não um curinga, e não substitui a verificação de segredo do proprietário/redirecionamento/PKCE.
URLs públicas estáveis e um auxiliar somente de túnel
Um servidor Python em execução não aprende um novo hostname público apenas porque um
túnel foi aberto. Defina MCP_PUBLIC_HOST para o hostname HTTPS canônico antes da
inicialização do servidor. URLs de emissor/recurso OAuth, hosts permitidos de rebinding de DNS e verificações
de Origem WebSocket /live usam essa configuração. Reiniciar/reconectar é necessário
quando o hostname muda. Cabeçalhos Host/X-Forwarded-Host controlados pelo chamador não
escolhem o emissor nem autorizam uma nova origem. Nunca desative essas verificações
apenas para fazer um proxy funcionar. Verificações de Origem/Referer de consentimento comparam esquema exato,
host e porta; cookies de aviso de proxy não autenticam o proprietário.
tunnl.gg estável (sem conta)
dots tunnel executa um túnel SSH de chave estável em primeiro plano para um servidor
de loopback saudável já em execução. Ele não inicia/reinicia o servidor nem reescreve sua
configuração OAuth. Stdout contém apenas a URL base não secreta e a URL /mcp/;
banners do provedor são salvos em um log de túnel privado. Ctrl+C para o filho SSH deste
auxiliar, não o servidor. Ele não reconecta infinitamente nem ignora limites do provedor.
OpenSSH é obrigatório. Por padrão, ele cria uma chave privada dedicada em
~/.dot-mcp/tunnel/tunnl-key; mantenha essa mesma chave para reter a URL estável.
Auxiliar amigável ao Fish e comando manual equivalente:
.venv/bin/python -m dot_mcp.cli tunnel --port 33041
# Existing dedicated SSH key:
.venv/bin/python -m dot_mcp.cli tunnel --port 33041 -i ~/.ssh/dot-mcp-tunnel
# Equivalent manual command (keep this terminal open):
ssh -t -i ~/.ssh/dot-mcp-tunnel -o IdentitiesOnly=yes -o ServerAliveInterval=30 -o ExitOnForwardFailure=yes -R 80:localhost:33041 stable@proxy.tunnl.gg
A configuração inicial é em duas fases porque o provedor escolhe o hostname: inicie um servidor local, execute o auxiliar para aprender sua URL estável, pare o servidor usando seu comando de ciclo de vida normal, defina o hostname apenas retornado, então inicie o servidor com essa configuração. O túnel pode permanecer aberto enquanto reinicia apenas o servidor local. Reutilizar a chave SSH mantém a URL do provedor; ela não faz um emissor em execução obsoleto se atualizar sozinho. Um exemplo de inicialização direta do servidor após você provisionar credenciais de proprietário usando configuração CLI normal:
set -gx MCP_PUBLIC_HOST your-returned-host.tunnl.gg
set -gx MCP_PORT 33041
# Human vault serve reuses the provisioned owner credential, starts foreground,
# and prompts locally for vault unlock (no secret in arguments):
.venv/bin/python -m dot_mcp.cli vault serve
Se você não quiser o cofre desbloqueado, use dots start normal para o fluxo de servidor+túnel
empacotado; o auxiliar somente de túnel é para um servidor em execução gerenciado
independentemente, não um gerenciador de ciclo de vida substituto. Não cole segredos de proprietário/cliente
no ChatGPT nem os inclua em argumentos de URL. dots credentials fornece
locais de arquivos de credenciais privados; revelação explícita requer um TTY privado.
A página de aviso gratuita do navegador do provedor aparece uma vez por dia por site. Ela
redireciona GETs do navegador antes do nosso aplicativo; use seu botão normal Continuar para o site,
então continue o OAuth. Clientes não navegador podem ignorá-la de acordo com a política
do provedor. dot-mcp não ignora nem trata esse aviso/cookie como autenticação.
Para /live, passe o aviso primeiro na URL base pública, então reabra o
link ao vivo original contendo seu fragmento #token=. Um servidor não pode receber
fragmentos de URL, então não assuma que um redirecionamento intersticial preserva uma capacidade
ao vivo. /live ainda requer entrada de token do proprietário e Origem configurada exata.
Um proxy deve suportar upgrades WebSocket. Nossos testes de unidade modelam cabeçalhos de proxy,
presença de cookie do provedor e verificações de autenticação; eles não provam a implementação
de aviso futura ou uptime de nenhum provedor.
O provedor atualmente documenta 2 horas de inatividade/24 horas de vida útil máxima, 3 túneis por IP, limites de WebSocket e limites de taxa de solicitação. Reconecte com a mesma chave privada para manter seu nome estável, dentro desses limites. Mudar chaves muda URLs. TLS termina no provedor; ele vê tráfego em trânsito. Veja a documentação atual do tunnl.gg e detalhes de URL estável.
Tailscale Funnel (conta/tailnet obrigatórios)
Com um cliente Tailscale instalado e conectado, e Funnel habilitado para o seu tailnet, exponha a porta de loopback:
tailscale funnel 33041
Use o hostname HTTPS impresso como MCP_PUBLIC_HOST antes de iniciar o dot-mcp,
e sua URL /mcp/ para o conector. O Funnel tem requisitos de HTTPS/MagicDNS/tailnet-policy
e limites de banda; não é uma rota sem conta. Habilitá-lo
pode alterar a política do tailnet, então o proprietário da conta deve fazer a configuração. Não exponha
um diretório de arquivos no lugar do serviço MCP autenticado. Guia oficial:
https://tailscale.com/kb/1223/funnel .
Cloudflare named tunnel (conta e domínio obrigatórios)
Use um named tunnel gerenciado pelo dashboard e uma rota publicada apontando para
http://127.0.0.1:33041, com seu hostname público fixo escolhido. Siga os
passos atuais de instalação/execução do dashboard ou instale-o como um serviço gerenciado. O
token do túnel é uma credencial: não o coloque em chat ou scripts versionados.
Configure MCP_PUBLIC_HOST para o hostname fixo antes de iniciar o servidor. Mantenha
as verificações de owner-secret/OAuth habilitadas mesmo ao adicionar controles de acesso de proxy, e
garanta que qualquer política do Cloudflare Access seja compatível com seu conector.
Execução amigável para um named tunnel gerenciado localmente já configurado cujas credenciais/configuração são mantidas privadas:
cloudflared tunnel run dot-mcp
A configuração named e a gerenciada pelo dashboard diferem; não substitua uma URL de Quick Tunnel pela sua rota named configurada. Configuração oficial: https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/get-started/create-remote-tunnel/ .
Quick/free tunnels são adequados para experimentos curtos, não para endpoints de conector confiáveis. Em testes, o Cloudflare Quick Tunnel intermitentemente retornou Erro 1033 enquanto o processo estava ativo; criar uma nova URL aleatória forçou uma mudança de conector. A saúde funcionando por alguns minutos não garantiu a próxima chamada de ferramenta. A documentação oficial do Quick Tunnel não promete SLA de uptime e observa limitações de SSE: https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/do-more-with-tunnels/trycloudflare/ .
Chrome instalado e inicialização conveniente do vault local
browser_open agora seleciona seu Chrome/Chromium instalado do PATH quando
DOT_MCP_BROWSER_EXECUTABLE não está definido, nesta ordem: google-chrome,
google-chrome-stable, chromium, chromium-browser. Isso inclui um executável em
~/.local/bin se esse diretório estiver no PATH. Um
DOT_MCP_BROWSER_EXECUTABLE explícito ainda tem prioridade. Se nenhum binário instalado for encontrado,
o Playwright usa seu Chromium gerenciado. dots doctor relata a mesma lógica
de seleção, mas a descoberta não é um teste de inicialização bem-sucedido. Os pacotes Playwright e WebSocket
ainda são necessários. O binário é reutilizado, não seu perfil
principal do navegador ou abas já abertas; o dot-mcp mantém seu próprio perfil e sandbox.
As ferramentas de vault estão presentes por padrão; a criptografia ainda precisa de um vault local
inicializado. dots start agora abre o túnel tunnl.gg de chave estável primeiro, descobre seu
hostname, define MCP_PUBLIC_HOST para o servidor e o inicia uma vez. Nenhum
hostname exportado manualmente ou segundo terminal de túnel é necessário. A chave dedicada e o
arquivo known-hosts ficam no diretório de estado local. Mantenha essa chave para reter a
identidade estável do provedor. A disponibilidade do túnel e a página de aviso ainda
dependem do tunnl.gg; "estável" não promete uptime.
Para um prompt manual de passphrase local e tempo de vida em primeiro plano:
.venv/bin/python -m dot_mcp.cli start --vault
Isso inicia seu próprio túnel. Mantenha o terminal aberto; Ctrl+C interrompe ambos. Em modo não interativo ou JSON não há prompt. Uma aceitação prévia de keyring pode ainda desbloquear o servidor destacado. Sem aceitação/keyring, o vault permanece bloqueado.
Aceitação única de desbloqueio automático do vault local (Linux Secret Service)
Após vault init/vault set humano, instale a dependência opcional de desbloqueio automático
somente se você escolher usá-la. No Arch, um provedor de Secret Service desbloqueado
(por exemplo, o keyring usado pelo seu desktop) e sua sessão D-Bus devem estar disponíveis
no ambiente do servidor. Nenhum provedor ou pacote é instalado por este comando.
.venv/bin/python -m pip install -e '.[vault-auto]'
.venv/bin/python -m dot_mcp.cli vault enable-auto
.venv/bin/python -m dot_mcp.cli start
enable-auto requer um terminal local, mostra um aviso, pede que você digite
ENABLE, e então solicita a passphrase com getpass. Ele verifica o vault
existente e armazena a passphrase apenas no OS Secret Service. Um marcador privado
de aceitação não contém segredo. O servidor recupera o segredo diretamente na inicialização,
nunca via argumentos, ambiente, chat ou uma transferência de chave pai-para-filho. Não
há fallback de texto simples ou backend de keyring alternativo. Keyring ausente/bloqueado,
aceitação ausente, segredo errado ou desbloqueio falho deixa o vault bloqueado. O log
do servidor relata apenas o status bloqueado/desbloqueado, não a passphrase.
Aviso: qualquer processo do mesmo usuário com acesso ao keyring do SO desbloqueado pode
recuperar esta passphrase e desbloquear o vault. Isso é conveniência em sua própria
máquina confiável, não uma fronteira contra seu shell ou outro software do mesmo usuário.
Bloqueio automático por inatividade e vault_lock ainda bloqueiam; eles não reabrem automaticamente em
uma chamada de ferramenta posterior. Reiniciar o servidor tenta o desbloqueio automático novamente.
.venv/bin/python -m dot_mcp.cli vault disable-auto
Desabilitar remove a aceitação primeiro e exclui a entrada do keyring. Se o keyring
do SO estiver indisponível/bloqueado, o comando relata que a exclusão da credencial
falhou; desbloqueie-o localmente e execute novamente. O desbloqueio automático permanece desabilitado enquanto isso.
Pare/reinicie qualquer servidor já desbloqueado para descartar sua chave em memória. O modo de privacidade
de preenchimento de origem exata e pós-preenchimento permanece inalterado. dots tunnel permanece disponível
para um servidor já em execução; não execute um segundo túnel para dots start.
Dependências de navegador ausentes
browser_open verifica o Python do servidor em execução para Playwright e websockets,
então seleciona o Chrome/Chromium do PATH instalado ou o Chromium gerenciado pelo Playwright.
Uma substituição explícita de executável é verificada como um arquivo executável. Com nem
um navegador instalado nem um gerenciado, ele relata o navegador como ausente.
Dependências ausentes retornam um resultado de ferramenta como:
{"ok": false, "error": "not_installed", "missing": ["playwright", "websockets"], "message": "not installed: playwright, websockets", "next_action": "Ask the user whether to install or configure the missing dependencies. Do not install without user approval."}
A ferramenta não executa pip, um gerenciador de pacotes ou um instalador de navegador. A IA deve
perguntar antes de instalar. Essas verificações são executadas novamente a cada nova tentativa de browser_open;
após a instalação aprovada, reinicie o servidor se seu ambiente mudou.
dots doctor --json inclui optional.browser_missing para pacotes e um
executável explícito/PATH; ele não inicia o Playwright para verificar seu navegador
gerenciado. Imports instalados mas quebrados, bibliotecas de sistema ausentes, falhas de
exibição ou sandbox são falhas de tempo de execução, não prova de que o Chrome está ausente. Nenhum
rebaixamento de sandbox ou correção automática de dependência é tentado. A inicialização do vault é
inalterada.
Visualização ao vivo sem senha (aceitação explícita de sessão)
browser_open(..., share_view=true) ou browser_share_view(enabled=true)
habilita a visualização sem senha para essa sessão de navegador e retorna um
live_view_url pronto para abrir. Sessões padrão ainda exigem autenticação do proprietário para visualização.
O token aleatório longo está no fragmento da URL, não nas URLs de solicitação do servidor. /live
sozinho nunca expõe vídeo. Os tokens expiram após uma hora e fechar os revoga;
as conexões de visualização duram no máximo 15 minutos antes de reconectar.
Qualquer pessoa com um link de visualização habilitado pode ver vídeo de página sem máscara, incluindo
informações privadas. Trate o link como um segredo. A IA deve obter sua aprovação
antes de habilitá-lo ou compartilhá-lo. browser_share_view(enabled=false) rotaciona o
token de visualização, desconecta visualizadores antigos e restaura a visualização autenticada pelo proprietário.
O controle é separado: um link de controle mais seu segredo de proprietário/token OAuth é sempre
necessário. Um token de visualização não pode se tornar um token de controle, mesmo com uma senha.
As verificações existentes de origem exata, limites e bloqueio de vídeo pós-preenchimento do vault permanecem.
A página ao vivo tenta visualização tokenizada automaticamente. Links privados de visualização/controle mostram um formulário de token do proprietário. Ele nunca armazena esse token do proprietário.
Erros seguros de ferramenta
Falhas de ferramenta retornam isError com texto JSON contendo ok: false e um
objeto error: valores code, message seguro, field opcional e allowed opcional.
Os códigos incluem not_found, bad_argument, invalid_state,
precondition_failed, permission_denied, resource_limit e tool_failed.
Validação e falhas antecipadas se comportam da mesma forma sob MCP 1 e 2. Texto
bruto de exceção, valores de argumento, caminhos de SO e texto de página do navegador não são retornados.
Falhas desconhecidas dão uma causa segura genérica em vez de adivinhar um diagnóstico.