Um agente que consegue ler o seu banco de dados responde perguntas para as quais você, de outro modo, abriria um editor de SQL. “Por que os cadastros caíram na terça?” “Quais pedidos estão travados em pending há mais de uma hora?” “O que há de fato na tabela events?” Com uma capacidade de consulta, o modelo responde em segundos; sem ela, ele adivinha. A parte útil não é o SQL — tanto o Claude Code quanto o Cursor escrevem SQL bem — é dar ao agente uma forma de executar uma leitura sem lhe entregar as suas credenciais. Essa passagem de bastão é toda a fricção, e é o que este post percorre para as duas ferramentas.
Já escrevemos à parte sobre por que colar uma string de conexão de banco de dados em um agente é a jogada que não dá para desfazer (em inglês) — a credencial é acesso ao portador, ela pode escrever e dropar além de ler, e, uma vez que passou pelo contexto de um modelo, você não consegue “descompartilhá-la”. Leia aquilo para o modelo de segurança; aqui tomamos isso como resolvido e deixamos a parte técnica pronta. A versão curta: o cliente guarda a credencial, o agente recebe um pedido escopado e, por padrão, somente leitura.
O que você precisa
- Termalin — o app de desktop, o plano Free já basta. É um cliente SSH e de banco de dados com um servidor MCP integrado; é com esse servidor local que o seu agente vai falar.
- Pelo menos uma conexão de banco de dados salva no cliente de dados do Termalin — Postgres, MySQL, SQLite, SQL Server, ClickHouse, MongoDB, Redis e mais. Escolha algo de baixo risco para a primeira vez: uma réplica de analytics, um banco de staging, uma cópia.
- Claude Code ou Cursor na mesma máquina que o app. As ferramentas de banco de dados conduzem o app de desktop ao vivo, então o agente e o app dividem a mesma máquina.
Uma expectativa a alinhar: para o Claude Code e o Cursor, o acesso ao banco de dados passa pelo servidor MCP stdio local, então o agente precisa estar na mesma máquina que o seu app de desktop desbloqueado. (Há um caminho hospedado também — o servidor MCP hospedado, termal.in/mcp com login para claude.ai, ChatGPT, Claude Code e Cursor, ou termal.in/api/v1/mcp com uma chave de API, consegue consultar os bancos de dados de um servidor cadastrado sem senha, usando a confiança local do próprio servidor no banco, sem nenhum app de desktop em execução. Para as conexões salvas no cliente de dados do app de desktop, o servidor local é o que você quer.)
Passo 1 — ative o acesso do agente aos dados
Isso vem desativado por padrão, e de propósito. Abra Configurações → Acesso do agente (MCP) e ative “Let agents query your databases” (permitir que agentes consultem seus bancos de dados). O subtítulo deixa a postura explícita: desativado por padrão, e permanece somente leitura, a menos que uma conexão conceda acesso total. Até você acioná-lo, toda ferramenta de banco de dados retorna database access for agents is off — enable it in Settings → Agent, ponto final.
Vale internalizar dois padrões antes de ir adiante:
- É um segundo opt-in, por cima do app em execução. Ativar o acesso do agente aos servidores não ativa o acesso ao banco de dados — esta é uma opção própria. Nada fica exposto até você tomar a decisão.
- Toda conexão é somente leitura para o agente. Mesmo com a opção principal ligada, cada consulta é verificada antes de rodar. Uma escrita só passa se você tiver elevado a política do agente daquela conexão específica para acesso total — uma escolha por conexão, não global. Deixe em somente leitura por enquanto.
A credencial em si nunca se move: o host, a porta e a senha da conexão ficam no cofre do app, e o agente só pode pedir ao app em execução que rode uma consulta e devolva as linhas. Não há string de conexão em um arquivo de configuração para o agente — ou uma injeção de prompt — ler.
Passo 2 — registre o servidor MCP local
Claude Code — um comando:
claude mcp add termalin -- <path>/termalin-mcp
Substitua <path> por onde quer que o binário termalin-mcp esteja (o app pode te indicar). Reinicie o Claude Code e ele pega as ferramentas.
Cursor — o Cursor lê os servidores MCP de um arquivo JSON: .cursor/mcp.json na raiz de um projeto, só para aquele projeto, ou ~/.cursor/mcp.json para deixar o servidor disponível em todo lugar. Para um servidor stdio local, a entrada é um comando e seus argumentos:
{
"mcpServers": {
"termalin": {
"command": "<path>/termalin-mcp",
"args": []
}
}
}
O arquivo global é a escolha sensata — acesso ao banco de dados não é uma questão por repositório. Reinicie o Cursor (ou recarregue a lista de MCP nas configurações dele) e confirme que o servidor aparece como em execução. É o mesmo registro que o passo a passo de Cursor SSH e o de Claude Code (em inglês) usam — um servidor, e ele agora carrega as ferramentas de banco de dados ao lado das de SSH.
Passo 3 — as ferramentas, e uma primeira tarefa de verdade
Com o servidor registrado e a opção ligada, o agente vê quatro ferramentas de banco de dados:
data_list # your saved connections: id, name, engine, and whether the agent may write
data_tables # tables / collections / measurements for a connection, with row counts
data_schema # one table's columns: name, type, nullable, primary key
data_query # run a query in the connection's own language; default cap 200 rows
Elas espelham como você exploraria um banco de dados à mão: listar o que está conectado, ver as tabelas, descrever uma tabela, rodar a consulta. O data_query fala o que quer que a conexão fale — SQL para os motores relacionais e o ClickHouse, Cypher para o Neo4j, um comando Redis, um collection {filter} para o MongoDB — e retorna linhas até um limite que você pode elevar por chamada (maxRows), com padrão de 200, para que um agente não puxe, sem querer, um milhão de linhas para o contexto dele.
Agora dê a ele uma pergunta que você de fato faria, não uma consulta de demonstração:
Os cadastros caíram na terça, segundo o painel. Usando o banco de dados de analytics, descubra o que aconteceu.
Observe o agente usar as ferramentas em ordem:
data_list— ele encontra a sua conexãoanalytics, vê que o motor é Postgres e anota que ela é somente leitura para o agente.data_tables— ele lista as tabelas, notasignupsesignup_eventse lê as contagens de linhas para saber o que vale consultar.data_schemaemsignups— ele descobre as colunas (created_at,source,status, …) e agora sabe como fatiar por dia e por origem.data_query— ele roda algo comoSELECT date_trunc('day', created_at) AS day, source, count(*) FROM signups WHERE created_at >= now() - interval '10 days' GROUP BY 1, 2 ORDER BY 1e lê as linhas de volta.
As linhas contam a história — talvez um source tenha ido a zero na terça (um link de indicação quebrado), talvez o total tenha se mantido mas status = 'failed' tenha disparado (uma queda de um provedor). De qualquer forma, o agente montou a consulta a partir do schema real, não de um chute, e nunca teve mais do que a capacidade de perguntar. Se um resultado é truncado no limite de 200 linhas, ele avisa e estreita a consulta, em vez de insistir por mais.
Onde ficam os limites
Breve, porque o post sobre segurança (em inglês) cobre isso por completo — mas os padrões nos quais você está se apoiando:
- Somente leitura por padrão. Nos motores da família SQL, só passam verbos de leitura —
SELECT,SHOW,DESCRIBE,EXPLAIN,WITH,PRAGMA. No Redis, só comandos de leitura; no MongoDB, uma agregação com$out/$mergeé bloqueada; no Neo4j,CREATE/MERGE/DELETE/SET/DROPsão bloqueados. Um modelo confuso ou sequestrado recebe uma leitura, não umDROP. - Por conexão, não global. A sua réplica de analytics é uma decisão separada do seu primário de produção; elevar uma para acesso de escrita total não toca a outra.
- Desligado com uma opção, e o app guarda a credencial — nada foi compartilhado, então desligar não deixa cópias nem senha para rotacionar.
Para qualquer coisa sensível, faça as duas: aponte a conexão de dados para uma réplica de leitura ou para um papel de banco de dados de menor privilégio e deixe o agente em somente leitura. A barreira do lado do cliente pega os enganos; a concessão no banco de dados define o teto.
Observações específicas de cada ferramenta
- Cursor pergunta antes de cada chamada de ferramenta por padrão. Deixe isso ligado nas primeiras sessões — você vai ver cada
data_queryantes de ele rodar e pode ler o SQL que o agente propõe. A aprovação automática é uma conveniência para estender uma ferramenta por vez:data_listedata_schemasão seguras de liberar primeiro;data_queryé a que vale manter no manual por mais tempo. - Claude Code mostra cada chamada de ferramenta em linha, com os argumentos, então o texto da consulta está na transcrição antes de executar. Você está lendo o SQL do agente, não confiando em um resumo dele — e cada chamada é atribuída ao agente, então, às 2 da manhã, você consegue distinguir “foi ele que leu isso” de “fui eu que li isso”.
Onde o Termalin entra
A maioria dos guias de “conecte o seu agente a um banco de dados” termina em colar uma string de conexão em um arquivo de configuração, o que concede silenciosamente a um agente o mesmo poder de escrever e dropar que o seu app tem. O cliente de dados do Termalin inverte isso: o app é o custodiante, o agente recebe quatro ferramentas escopadas conduzidas pela janela em execução, e toda a capacidade é somente leitura até você decidir o contrário, e desligável com uma única opção. É a mesma ideia de custódia que aplicamos ao acesso SSH para agentes (em inglês) e ao o que é de fato um servidor MCP (em inglês) — um banco de dados é só a versão em que uma escrita ruim é medida em linhas. Comece com uma conexão, mantenha-a em somente leitura e pergunte algo real antes de pensar em ampliar qualquer coisa.
O Termalin é um cliente SSH e de banco de dados gratuito e multiplataforma, com um servidor MCP integrado e uma política de agente por conexão — baixe o Termalin, ou leia como ele cuida das credenciais com segurança.