ClickHouse
oficialConsulte seu servidor de banco de dados ClickHouse.
O que você pode fazer com ClickHouse MCP?
- Executar consultas SQL — Peça ao seu assistente para executar SQL no seu cluster ClickHouse via
run_query, incluindoDESCRIBEeEXPLAIN ESTIMATEpara verificações prévias. - Explorar a estrutura do banco de dados — Use
list_databaseselist_tablespara descobrir bancos de dados, filtrar tabelas com padrõesLIKEe paginar pelos resultados compage_token. - Consultar dados com chDB — Aproveite
run_chdb_select_querypara executar SQL no mecanismo chDB embutido, consultando arquivos, URLs ou bancos de dados sem ETL. - Monitorar a saúde do servidor — Verifique o endpoint
/healthpara sondagens de atividade/prontidão, retornando200 OKquando conectado ou503em caso de falha. - Habilitar operações de escrita — Configure os flags
CLICKHOUSE_ALLOW_WRITE_ACCESSeCLICKHOUSE_ALLOW_DROPpara permitir operações DDL/INSERT ou destrutivas com proteções de segurança.
Documentação
Servidor MCP ClickHouse
Um servidor MCP para ClickHouse.
O servidor implementa MCP 2026-07-28 e suporta handshakes de inicialização legados de
2024-11-05 até 2025-11-25. Clientes modernos usam requisições sem sessão e
server/discover. Clientes existentes podem continuar a negociar o protocolo legado.
[!NOTE] Requisições HTTP sem
MCP-Protocol-Versionsão roteadas pelo tratamento legado para que clientes anteriores a2025-06-18possam continuar a se conectar. MCP2026-07-28permite esse comportamento em servidores que suportam esses clientes. Clientes modernos devem enviar o cabeçalho em toda requisição POST.
Recursos
Ferramentas ClickHouse
As respostas das ferramentas ClickHouse são strings codificadas em JSON. Inteiros fora de
[-9007199254740991, 9007199254740991] são retornados como strings decimais para preservar valores exatos
em clientes JavaScript. Isso se aplica a linhas de consulta e metadados de tabelas inteiros. Inteiros
dentro do intervalo seguro e booleanos mantêm seus tipos JSON.
-
run_query- Executa consultas SQL no seu cluster ClickHouse.
- Entrada:
query(string): A consulta SQL a ser executada. - Consultas são executadas em modo somente leitura por padrão (
CLICKHOUSE_ALLOW_WRITE_ACCESS=false), mas escritas podem ser habilitadas explicitamente se necessário. DESCRIBE (<query>)eEXPLAIN ESTIMATE <query>também são executados aqui e são formas opcionais de inspecionar o esquema de resultado de uma consulta ou suas leituras estimadas. Veja Verificando uma consulta antes de executá-la.
-
list_databases- Lista todos os bancos de dados no seu cluster ClickHouse.
-
list_tables- Lista tabelas em um banco de dados com paginação.
- Entrada obrigatória:
database(string). - Entradas opcionais:
like/not_like(string): Aplica filtrosLIKEouNOT LIKEaos nomes das tabelas.page_token(string): Token de uso único retornado por uma chamada anterior. Ele é retido por até uma hora.page_size(int, padrão50): Número de tabelas retornadas por página; deve ser maior que0.include_detailed_columns(bool, padrãotrue): Quandofalse, omite metadados de colunas para respostas mais leves, mantendo ocreate_table_querycompleto.
- Formato da resposta:
tables: Matriz de objetos de tabela para a página atual.next_page_token: Passe este valor de uso único de volta antes que expire para buscar a próxima página, ounullquando não houver mais tabelas.total_tables: Contagem total de tabelas que correspondem aos filtros fornecidos.
Verificando uma consulta antes de executá-la
run_query também executa DESCRIBE e EXPLAIN ESTIMATE. Ambas são verificações opcionais: use DESCRIBE quando precisar das colunas e tipos de saída de uma consulta, e EXPLAIN ESTIMATE antes de um SELECT que possa ser caro.
DESCRIBE (<query>) inspeciona o esquema de resultado e retorna os mesmos metadados de colunas de saída que DESCRIBE TABLE:
DESCRIBE (SELECT user, sum(amt) FROM events WHERE ts > now() - INTERVAL 30 DAY GROUP BY user)
user String
sum(amt) Decimal(38, 2)
O ClickHouse precisa analisar a consulta para responder, então erros de análise aparecem aqui, com a mensagem do próprio ClickHouse, em vez de no meio da execução:
DESCRIBE (SELECT usr FROM events) -> Code: 47. Unknown expression identifier `usr` ... Maybe you meant: ['user']
DESCRIBE (SELECT * FROM nosuch) -> Code: 60. Unknown table expression identifier 'nosuch'
Uma consulta que descreve corretamente ainda pode falhar ao ser executada, por um limite de memória ou erro de servidor remoto, e não diz nada sobre custo.
EXPLAIN ESTIMATE <query> retorna as partes, linhas e marcas que a consulta leria, uma linha por tabela, que é o que diferencia uma busca por chave primária de uma varredura completa:
EXPLAIN ESTIMATE SELECT count() FROM events WHERE id = 42
database table parts rows marks
default events 1 8192 1
Essas são leituras estimadas de tabelas da família MergeTree, após poda de chave primária e partição. Não são tempo de execução nem tamanho de resultado, e outros mecanismos de tabela não são cobertos.
Nenhuma das declarações executa o corpo da consulta, mas a análise nem sempre é gratuita: DESCRIBE (SELECT (SELECT sleep(1))) executa a subconsulta escalar durante a análise. Ambas são somente leitura e funcionam sob o CLICKHOUSE_ALLOW_WRITE_ACCESS=false padrão. Veja a documentação do ClickHouse para EXPLAIN ESTIMATE e DESCRIBE.
Ferramentas chDB
run_chdb_select_query- Executa consultas SQL usando o mecanismo ClickHouse embutido do chDB.
- Entrada:
query(string): A consulta SQL a ser executada. - Inteiros fora de
[-9007199254740991, 9007199254740991]são retornados como strings decimais. - Consulta dados diretamente de várias fontes (arquivos, URLs, bancos de dados) sem processos de ETL.
- Requer o extra opcional
chdb:pip install 'mcp-clickhouse[chdb]'
Endpoint de Verificação de Saúde
Ao usar transporte HTTP ou SSE, um endpoint de verificação de saúde está disponível em /health. Este endpoint:
- Retorna
200 OK(corpo:OK) se o servidor estiver saudável e puder se conectar ao ClickHouse - Retorna
503 Service Unavailablecom uma mensagem de erro genérica se o servidor não puder se conectar ao ClickHouse - Retorna
503se uma sondagem do ClickHouse não terminar em dois segundos. Requisições concorrentes compartilham uma sondagem em andamento - Reutiliza um resultado de sondagem concluído por um segundo, para que sondagens que chegam em rápida sucessão não se conectem cada uma ao ClickHouse. Uma falha ou recuperação pode, portanto, ser relatada com até um segundo de atraso
Requisições GET e HEAD ao endpoint são intencionalmente não autenticadas e isentas de validação de Host e Origin, para que sondagens de orquestradores (ex.: liveness/readiness do Kubernetes, balanceadores de carga) possam usar IPs de pod ou destino atribuídos em tempo de execução sem configuração extra. /health é reservado e não pode ser usado como caminho de transporte MCP. O corpo da resposta é deliberadamente mínimo para evitar vazamento de strings de versão do backend ou detalhes de erro; depure falhas pelos logs do servidor.
Exemplo:
curl http://localhost:8000/health
# Response: OK
Segurança
Autenticação para Transportes HTTP/SSE
Ao usar transporte HTTP ou SSE, a autenticação é obrigatória por padrão. O transporte stdio (padrão) não exige autenticação, pois se comunica apenas via entrada/saída padrão.
Três modos de autenticação são suportados. Escolha um:
| Modo | Quando usar | Variável de ambiente |
|---|---|---|
| Token estático bearer | Implantações simples, serviços internos | CLICKHOUSE_MCP_AUTH_TOKEN |
| OAuth / OIDC (via FastMCP) | Azure Entra, Google, GitHub, WorkOS, etc. | FASTMCP_SERVER_AUTH=<provider-class-path> (+ variáveis FASTMCP_SERVER_AUTH_* específicas do provedor) |
| Desabilitado | Somente desenvolvimento local | CLICKHOUSE_MCP_AUTH_DISABLED=true |
A inicialização falha se nenhum desses estiver configurado para transportes HTTP/SSE.
Configurando Autenticação
-
Gere um token seguro (pode ser qualquer string aleatória):
# Using uuidgen (macOS/Linux) uuidgen # Using openssl openssl rand -hex 32 -
Configure o servidor com o token:
export CLICKHOUSE_MCP_AUTH_TOKEN="your-generated-token" -
Configure seu cliente MCP para incluir o token nas requisições:
Para Claude Desktop com transporte HTTP/SSE:
{ "mcpServers": { "mcp-clickhouse": { "url": "http://127.0.0.1:8000", "headers": { "Authorization": "Bearer your-generated-token" } } } }Nota: o endpoint
/healthé intencionalmente não autenticado (veja Endpoint de Verificação de Saúde acima). Para verificar se a autenticação por token bearer está realmente rejeitando requisições não autenticadas, acesse o próprio endpoint MCP, ex.: com o MCP Inspector, ou enviando uma requisição JSON-RPC POST para/mcpcom e sem o cabeçalhoAuthorizatione confirmando que a chamada não autenticada retorna401.
OAuth / OIDC via FastMCP
Para implantações de produção com provedores de identidade (Azure Entra, Google, GitHub, WorkOS, etc.), delegue a autenticação aos provedores de autenticação integrados do FastMCP em vez de usar um token estático. Defina FASTMCP_SERVER_AUTH para o caminho completo da classe de um provedor de autenticação FastMCP, junto com as variáveis FASTMCP_SERVER_AUTH_* específicas do provedor, e deixe CLICKHOUSE_MCP_AUTH_TOKEN não definido.
Exemplo (Azure Entra):
export FASTMCP_SERVER_AUTH=fastmcp.server.auth.providers.azure.AzureProvider
export FASTMCP_SERVER_AUTH_AZURE_TENANT_ID="<tenant-id>"
export FASTMCP_SERVER_AUTH_AZURE_CLIENT_ID="<client-id>"
export FASTMCP_SERVER_AUTH_AZURE_CLIENT_SECRET="<client-secret>"
export FASTMCP_SERVER_AUTH_AZURE_BASE_URL="https://mcp.example.com"
export FASTMCP_SERVER_AUTH_AZURE_REQUIRED_SCOPES="read access_as_user"
mcp-clickhouse retém estes prefixos de ambiente FastMCP 2.14.7 para os provedores integrados FastMCP 4.0.0:
| Caminho da classe do provedor | Prefixo da variável do provedor |
|---|---|
fastmcp.server.auth.providers.auth0.Auth0Provider | FASTMCP_SERVER_AUTH_AUTH0_ |
fastmcp.server.auth.providers.aws.AWSCognitoProvider | FASTMCP_SERVER_AUTH_AWS_COGNITO_ |
fastmcp.server.auth.providers.azure.AzureProvider | FASTMCP_SERVER_AUTH_AZURE_ |
fastmcp.server.auth.providers.descope.DescopeProvider | FASTMCP_SERVER_AUTH_DESCOPEPROVIDER_ |
fastmcp.server.auth.providers.discord.DiscordProvider | FASTMCP_SERVER_AUTH_DISCORD_ |
fastmcp.server.auth.providers.github.GitHubProvider | FASTMCP_SERVER_AUTH_GITHUB_ |
fastmcp.server.auth.providers.google.GoogleProvider | FASTMCP_SERVER_AUTH_GOOGLE_ |
fastmcp.server.auth.providers.introspection.IntrospectionTokenVerifier | FASTMCP_SERVER_AUTH_INTROSPECTION_ |
fastmcp.server.auth.providers.jwt.JWTVerifier | FASTMCP_SERVER_AUTH_JWT_ |
fastmcp.server.auth.providers.oci.OCIProvider | FASTMCP_SERVER_AUTH_OCI_ |
fastmcp.server.auth.providers.scalekit.ScalekitProvider | FASTMCP_SERVER_AUTH_SCALEKITPROVIDER_ |
fastmcp.server.auth.providers.supabase.SupabaseProvider | FASTMCP_SERVER_AUTH_SUPABASE_ |
fastmcp.server.auth.providers.workos.WorkOSProvider | FASTMCP_SERVER_AUTH_WORKOS_ |
fastmcp.server.auth.providers.workos.AuthKitProvider | FASTMCP_SERVER_AUTH_AUTHKITPROVIDER_ |
Anexe o nome do campo do provedor em maiúsculas ao prefixo. Veja a documentação do FastMCP para os requisitos de configuração de cada provedor.
Valores de autenticação definidos diretamente no ambiente do processo têm precedência sem diferenciar maiúsculas de minúsculas.
O carregamento padrão de .env começa no diretório do pacote mcp_clickhouse instalado,
resolve symlinks primeiro e sobe até a raiz do sistema de arquivos. Ele carrega o primeiro
.env que encontrar e não carrega nada se não houver nenhum. Ele nunca lê o diretório
de trabalho, independentemente de como o servidor é iniciado. Uma cópia do código-fonte normalmente encontra
o .env da raiz do repositório. Esse arquivo também pode fornecer FASTMCP_SERVER_AUTH e seus
campos de provedor. Seus valores têm precedência sobre o arquivo de autenticação explícito ou de compatibilidade.
Para compatibilidade com FastMCP 2, mcp-clickhouse lê campos de provedor ausentes de .env
no diretório de trabalho, mas esse fallback de compatibilidade não pode selecionar
FASTMCP_SERVER_AUTH. Um FASTMCP_ENV_FILE definido no processo substitui esse fallback
de compatibilidade e pode fornecer tanto o seletor quanto os campos do provedor. Defina-o antes da inicialização.
O carregador de compatibilidade mcp-clickhouse lê apenas FASTMCP_SERVER_AUTH e
FASTMCP_SERVER_AUTH_* desse arquivo, portanto não pode injetar configurações de CLICKHOUSE_*.
O FastMCP 4 pode usar o mesmo arquivo para suas próprias configurações mais amplas. Um provedor personalizado recebe
nenhum argumento de construtor derivado do ambiente e deve suportar construção sem argumentos.
Trate tanto os arquivos .env descobertos quanto os do diretório de trabalho como configuração de autenticação
confiável. Qualquer pessoa que possa criar ou escrever um .env em qualquer diretório do diretório do pacote
até a raiz do sistema de arquivos pode controlar qual arquivo é descoberto, selecionar o
provedor e definir seus campos. Qualquer pessoa que possa escrever o arquivo do diretório de trabalho controla todos os campos do provedor
ausentes do processo e da configuração descoberta, incluindo chaves de assinatura,
emissores e endpoints, e segredos de cliente. Um FASTMCP_ENV_FILE definido no processo que aponte
para um arquivo de propriedade do operador desabilita o fallback do diretório de trabalho.
O FastMCP 4 mudou o armazenamento padrão do proxy de cliente OAuth. Implantações que dependiam do armazenamento padrão do proxy OAuth do FastMCP 2 devem ter clientes registrados e autorizados novamente. Armazenamento personalizado compatível, tokens estáticos bearer e verificação JWT não são afetados.
Modo de Desenvolvimento (Desabilitando Autenticação)
Somente para desenvolvimento e testes locais, você pode desabilitar a autenticação definindo:
export CLICKHOUSE_MCP_AUTH_DISABLED=true
export CLICKHOUSE_MCP_ALLOWED_HOSTS=127.0.0.1:8000,localhost:8000
AVISO: Use apenas para desenvolvimento local. Não desabilite a autenticação quando o servidor estiver exposto a qualquer rede.
Configuração
Este servidor MCP suporta tanto ClickHouse quanto chDB. Você pode habilitar um ou ambos dependendo das suas necessidades. Python 3.10 a 3.14 são suportados. Python 3.12 é recomendado para execuções locais.
-
Abra o arquivo de configuração do Claude Desktop localizado em:
- No macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - No Windows:
%APPDATA%/Claude/claude_desktop_config.json
- No macOS:
-
Adicione o seguinte:
{
"mcpServers": {
"mcp-clickhouse": {
"command": "uv",
"args": [
"run",
"--with",
"mcp-clickhouse",
"--python",
"3.12",
"mcp-clickhouse"
],
"env": {
"CLICKHOUSE_HOST": "<clickhouse-host>",
"CLICKHOUSE_PORT": "<clickhouse-port>",
"CLICKHOUSE_USER": "<clickhouse-user>",
"CLICKHOUSE_PASSWORD": "<clickhouse-password>",
"CLICKHOUSE_ROLE": "<clickhouse-role>",
"CLICKHOUSE_SECURE": "true",
"CLICKHOUSE_VERIFY": "true",
"CLICKHOUSE_CONNECT_TIMEOUT": "30"
}
}
}
}
Atualize as variáveis de ambiente para apontar para o seu próprio serviço ClickHouse.
Ou, se quiser experimentar com o ClickHouse SQL Playground, você pode usar a seguinte configuração:
{
"mcpServers": {
"mcp-clickhouse": {
"command": "uv",
"args": [
"run",
"--with",
"mcp-clickhouse",
"--python",
"3.12",
"mcp-clickhouse"
],
"env": {
"CLICKHOUSE_HOST": "sql-clickhouse.clickhouse.com",
"CLICKHOUSE_PORT": "8443",
"CLICKHOUSE_USER": "demo",
"CLICKHOUSE_PASSWORD": "",
"CLICKHOUSE_SECURE": "true",
"CLICKHOUSE_VERIFY": "true",
"CLICKHOUSE_CONNECT_TIMEOUT": "30"
}
}
}
}
Para chDB (mecanismo ClickHouse embutido), adicione a seguinte configuração:
{
"mcpServers": {
"mcp-clickhouse": {
"command": "uv",
"args": [
"run",
"--with",
"mcp-clickhouse[chdb]",
"--python",
"3.12",
"mcp-clickhouse"
],
"env": {
"CHDB_ENABLED": "true",
"CLICKHOUSE_ENABLED": "false",
"CHDB_DATA_PATH": "/path/to/chdb/data"
}
}
}
}
Você também pode habilitar ClickHouse e chDB simultaneamente:
{
"mcpServers": {
"mcp-clickhouse": {
"command": "uv",
"args": [
"run",
"--with",
"mcp-clickhouse[chdb]",
"--python",
"3.12",
"mcp-clickhouse"
],
"env": {
"CLICKHOUSE_HOST": "<clickhouse-host>",
"CLICKHOUSE_PORT": "<clickhouse-port>",
"CLICKHOUSE_USER": "<clickhouse-user>",
"CLICKHOUSE_PASSWORD": "<clickhouse-password>",
"CLICKHOUSE_SECURE": "true",
"CLICKHOUSE_VERIFY": "true",
"CLICKHOUSE_CONNECT_TIMEOUT": "30",
"CHDB_ENABLED": "true",
"CHDB_DATA_PATH": "/path/to/chdb/data"
}
}
}
}
-
Localize a entrada de comando para
uve substitua-a pelo caminho absoluto para o executáveluv. Isso garante que a versão correta deuvseja usada ao iniciar o servidor. Em um Mac, você pode encontrar esse caminho usandowhich uv. -
Reinicie o Claude Desktop para aplicar as alterações.
Acesso de Escrita Opcional
Por padrão, este MCP impõe consultas somente leitura para que mutações acidentais não possam ocorrer durante a exploração. Para permitir instruções DDL ou INSERT, defina a variável de ambiente CLICKHOUSE_ALLOW_WRITE_ACCESS para true. O servidor continua impondo o modo somente leitura se a própria instância do ClickHouse não permitir escritas.
Proteção contra Operações Destrutivas
Mesmo quando o acesso de escrita está habilitado (CLICKHOUSE_ALLOW_WRITE_ACCESS=true), operações destrutivas exigem um sinalizador adicional de aceitação por segurança. A verificação cobre qualquer instrução DROP (incluindo as cláusulas ALTER TABLE ... DROP PARTITION / DROP PART / DROP COLUMN), qualquer TRUNCATE, DELETE e UPDATE (tanto as instruções leves quanto as mutações ALTER TABLE ... DELETE / ALTER TABLE ... UPDATE), REPLACE TABLE, CREATE OR REPLACE, ALTER TABLE ... REPLACE PARTITION, ALTER TABLE ... CLEAR COLUMN / CLEAR INDEX / CLEAR PROJECTION e DETACH ... PERMANENTLY. Palavras-chave dentro de literais de string, identificadores entre aspas e comentários SQL são ignoradas, portanto não acionam a verificação nem ocultam uma instrução dela.
Esta verificação é executada no servidor MCP e é uma proteção de melhor esforço contra acidentes. Não é um limite de segurança. O limite de segurança são as concessões do usuário do ClickHouse. O modo somente leitura (o padrão) é imposto no lado do servidor via readonly=1. A barreira de operações destrutivas não é imposta pelo servidor.
Para o modo de escrita, forneça ao servidor MCP um usuário dedicado do ClickHouse com apenas os privilégios necessários:
CREATE USER mcp_agent IDENTIFIED BY '...';
GRANT SELECT, INSERT, CREATE TABLE, ALTER ADD COLUMN ON mydb.* TO mcp_agent;
Qualquer instrução fora dessas concessões falha no lado do servidor com ACCESS_DENIED, independentemente dos sinalizadores do MCP. As configurações do servidor max_table_size_to_drop e max_partition_size_to_drop também podem limitar o raio de impacto se fixadas com restrições de configuração.
Para habilitar operações destrutivas, defina ambos os sinalizadores:
"env": {
"CLICKHOUSE_ALLOW_WRITE_ACCESS": "true",
"CLICKHOUSE_ALLOW_DROP": "true"
}
Essa abordagem em duas camadas dificulta a exclusão acidental:
- Operações de escrita (INSERT, CREATE, ALTER ADD COLUMN) exigem
CLICKHOUSE_ALLOW_WRITE_ACCESS=true - Operações destrutivas (DROP, TRUNCATE, DELETE, UPDATE e o restante da lista acima) adicionalmente exigem
CLICKHOUSE_ALLOW_DROP=true
Executando Sem uv (Usando Python do Sistema)
Se você preferir usar a instalação Python do sistema em vez de uv, pode instalar o pacote do PyPI e executá-lo diretamente:
-
Instale o pacote usando pip:
python3 -m pip install mcp-clickhousePara instalar também o suporte a chDB:
python3 -m pip install 'mcp-clickhouse[chdb]'Para atualizar para a versão mais recente:
python3 -m pip install --upgrade mcp-clickhouse -
Atualize sua configuração do Claude Desktop para usar Python diretamente:
{
"mcpServers": {
"mcp-clickhouse": {
"command": "python3",
"args": [
"-m",
"mcp_clickhouse.main"
],
"env": {
"CLICKHOUSE_HOST": "<clickhouse-host>",
"CLICKHOUSE_PORT": "<clickhouse-port>",
"CLICKHOUSE_USER": "<clickhouse-user>",
"CLICKHOUSE_PASSWORD": "<clickhouse-password>",
"CLICKHOUSE_SECURE": "true",
"CLICKHOUSE_VERIFY": "true",
"CLICKHOUSE_CONNECT_TIMEOUT": "30"
}
}
}
}
Alternativamente, você pode usar o script instalado diretamente:
{
"mcpServers": {
"mcp-clickhouse": {
"command": "mcp-clickhouse",
"env": {
"CLICKHOUSE_HOST": "<clickhouse-host>",
"CLICKHOUSE_PORT": "<clickhouse-port>",
"CLICKHOUSE_USER": "<clickhouse-user>",
"CLICKHOUSE_PASSWORD": "<clickhouse-password>",
"CLICKHOUSE_SECURE": "true",
"CLICKHOUSE_VERIFY": "true",
"CLICKHOUSE_CONNECT_TIMEOUT": "30"
}
}
}
}
Nota: Certifique-se de usar o caminho completo para o executável Python ou o script mcp-clickhouse se eles não estiverem no seu PATH do sistema. Você pode encontrar os caminhos usando:
which python3para o executável Pythonwhich mcp-clickhousepara o script instalado
Middleware Personalizado
Você pode adicionar middleware personalizado ao servidor MCP sem modificar o código-fonte. O FastMCP fornece um sistema de middleware que permite interceptar e processar mensagens do protocolo MCP (chamadas de ferramentas, leituras de recursos, prompts, etc.).
Como Usar
- Crie um módulo Python com classes de middleware estendendo
Middlewaree uma funçãosetup_middleware(mcp):
# my_middleware.py
import logging
from fastmcp.server.middleware import Middleware, MiddlewareContext, CallNext
logger = logging.getLogger("my-middleware")
class LoggingMiddleware(Middleware):
"""Log all tool calls."""
async def on_call_tool(self, context: MiddlewareContext, call_next: CallNext):
tool_name = context.message.name if hasattr(context.message, 'name') else 'unknown'
logger.info(f"Calling tool: {tool_name}")
result = await call_next(context)
logger.info(f"Tool {tool_name} completed")
return result
def setup_middleware(mcp):
"""Register middleware with the MCP server."""
mcp.add_middleware(LoggingMiddleware())
- Defina a variável de ambiente
MCP_MIDDLEWARE_MODULEpara o nome do módulo (sem a extensão.py):
{
"mcpServers": {
"mcp-clickhouse": {
"command": "uv",
"args": ["run", "--with", "mcp-clickhouse", "--python", "3.12", "mcp-clickhouse"],
"env": {
"CLICKHOUSE_HOST": "<clickhouse-host>",
"CLICKHOUSE_USER": "<clickhouse-user>",
"CLICKHOUSE_PASSWORD": "<clickhouse-password>",
"MCP_MIDDLEWARE_MODULE": "my_middleware"
}
}
}
}
- Garanta que seu módulo de middleware esteja no caminho de importação do Python (por exemplo, no mesmo diretório onde o servidor MCP é executado, ou instalado como um pacote).
Exemplo de Middleware
Um módulo de middleware de exemplo é fornecido em example_middleware.py mostrando padrões comuns:
- Registro de todas as solicitações MCP
- Registro de chamadas de ferramentas especificamente
- Medição do tempo de processamento de solicitações
Para usar o exemplo:
"env": {
"MCP_MIDDLEWARE_MODULE": "example_middleware"
}
Capacidades do Middleware
A classe base Middleware fornece ganchos para diferentes operações MCP:
on_message(context, call_next)- Chamado para todas as mensagenson_request(context, call_next)- Chamado para todas as solicitaçõeson_notification(context, call_next)- Chamado para todas as notificaçõeson_call_tool(context, call_next)- Chamado quando uma ferramenta é executadaon_read_resource(context, call_next)- Chamado quando um recurso é lidoon_get_prompt(context, call_next)- Chamado quando um prompt é recuperadoon_list_tools(context, call_next)- Chamado ao listar ferramentason_list_resources(context, call_next)- Chamado ao listar recursoson_list_resource_templates(context, call_next)- Chamado ao listar modelos de recursoson_list_prompts(context, call_next)- Chamado ao listar prompts
Cada gancho recebe um objeto MiddlewareContext contendo a mensagem e metadados, e uma função call_next para continuar o pipeline.
Configuração Dinâmica do Cliente via Estado de Contexto
O middleware pode substituir a configuração do cliente ClickHouse por solicitação usando a chave de estado de contexto CLIENT_CONFIG_OVERRIDES_KEY. O servidor mescla essas substituições com a configuração base das variáveis de ambiente.
from fastmcp.server.dependencies import get_context
from fastmcp.server.middleware import CallNext, Middleware, MiddlewareContext
from mcp_clickhouse.mcp_server import CLIENT_CONFIG_OVERRIDES_KEY
class ClientConfigMiddleware(Middleware):
async def on_call_tool(self, context: MiddlewareContext, call_next: CallNext):
ctx = get_context()
await ctx.set_state(
CLIENT_CONFIG_OVERRIDES_KEY,
{
"connect_timeout": 60,
"send_receive_timeout": 120,
},
serializable=False,
)
return await call_next(context)
Isso permite casos de uso avançados como ajustes dinâmicos de tempo limite, roteamento específico de locatário ou configurações de conexão por usuário.
O valor do estado deve ser um dicionário. Valores aninhados settings e generic_args devem ser
mapeamentos e são mesclados com a configuração base. Valores inválidos falham na chamada da ferramenta antes
que um cliente ClickHouse seja criado. CLICKHOUSE_ROLE permanece ativo a menos que a substituição forneça
explicitamente settings.role. Chaves de nível superior role e ch_role, além das mesmas chaves sob
generic_args, são rejeitadas.
Defina verify, ca_cert, client_cert, client_cert_key, tls_mode, server_host_name,
e pool_mgr apenas como substituições de nível superior. Elas não podem ser aninhadas sob generic_args. Um
pool_mgr personalizado não pode ser combinado com configurações gerenciadas de CA ou certificado de cliente. Parâmetros de consulta DSN
não podem definir essas chaves, e um DSN não pode selecionar o backend chdb. Use
substituições explícitas de nível superior host, port, username, password, database e secure para alterar
a conexão. Um DSN encaminhado não substitui campos de conexão base preenchidos nem seleciona
TLS. Ele pode preencher campos vazios e fornecer parâmetros de consulta suportados, como query_limit.
Substituições secure e verify aceitam booleanos ou as strings true e false.
verify também aceita proxy, que se comporta como
tls_mode: proxy quando tls_mode não está definido e, portanto, usa autenticação Basic com a
senha do ambiente. Uma substituição secure seleciona a interface https ou http correspondente e
não altera a porta. Uma substituição explícita interface deve ser http ou https e concordar
com secure. Após mesclar substituições, os modos de certificado de cliente padrão e mutual omitem a
senha. Os modos proxy e strict usam autenticação Basic com a senha do ambiente
a menos que a substituição forneça suas próprias credenciais.
Trate essas substituições como entrada de middleware confiável. O middleware deve autenticar e autorizar
valores derivados de solicitações antes de defini-los. Use serializable=False para que o FastMCP mantenha o
valor no estado local da solicitação. O serializable=True padrão armazena estado de sessão e é
rejeitado pelo servidor. O servidor captura o valor antes de despachar trabalho de banco de dados
bloqueante. Não armazene dados de locatário no estado de Contexto com escopo de sessão. Uma substituição
rejeitada com escopo de sessão permanece anexada a uma sessão MCP legada e causa falhas em chamadas de ferramentas posteriores
nessa sessão até que o cliente se reconecte. Uma função ClickHouse por solicitação é configuração de conexão,
não um limite de autorização de locatário. Imponha isolamento de locatário com usuários, funções
e concessões do ClickHouse.
Desenvolvimento
-
No diretório
test-services, executedocker compose up -dpara iniciar o cluster ClickHouse. -
Adicione as seguintes variáveis a um arquivo
.envna raiz do repositório.
Nota: O uso do usuário default neste contexto é destinado exclusivamente para fins de desenvolvimento local.
CLICKHOUSE_HOST=localhost
CLICKHOUSE_PORT=8123
CLICKHOUSE_USER=default
CLICKHOUSE_PASSWORD=clickhouse
-
Execute
uv syncpara instalar as dependências. Para instalaruv, siga as instruções aqui. Depois, executesource .venv/bin/activate. -
Para testes fáceis com o MCP Inspector, execute
uv run fastmcp dev inspector mcp_clickhouse/mcp_server.py:mcppara iniciar o servidor MCP. -
Para testar com transporte HTTP e o endpoint de verificação de saúde:
# For development, disable authentication CLICKHOUSE_MCP_SERVER_TRANSPORT=http CLICKHOUSE_MCP_AUTH_DISABLED=true CLICKHOUSE_MCP_ALLOWED_HOSTS=127.0.0.1:8000,localhost:8000 python -m mcp_clickhouse.main # Or with authentication (generate a token first) CLICKHOUSE_MCP_SERVER_TRANSPORT=http CLICKHOUSE_MCP_AUTH_TOKEN="your-token" python -m mcp_clickhouse.main # Then in another terminal: curl http://localhost:8000/health
Variáveis de Ambiente
A configuração é dividida em grupos independentes. Misturá-los é uma causa comum de falhas de conexão difíceis de depurar:
| Grupo | Variáveis | Controla |
|---|---|---|
| Conexão do banco de dados ClickHouse | CLICKHOUSE_HOST, CLICKHOUSE_PORT, CLICKHOUSE_SECURE, CLICKHOUSE_VERIFY, variáveis de certificado | Como este servidor MCP se conecta ao seu cluster ClickHouse pela interface HTTP |
| Servidor MCP / transporte | CLICKHOUSE_MCP_*, FASTMCP_SERVER_AUTH, FASTMCP_SERVER_AUTH_*, FASTMCP_ENV_FILE | Transporte MCP, autenticação e limites de execução de ferramentas de consulta |
| Middleware / chDB | MCP_MIDDLEWARE_MODULE, CHDB_* | Extensões opcionais |
[!IMPORTANT]
CLICKHOUSE_SECURE,CLICKHOUSE_VERIFY,CLICKHOUSE_CA_CERT,CLICKHOUSE_CLIENT_CERT,CLICKHOUSE_CLIENT_CERT_KEY,CLICKHOUSE_TLS_MODEeCLICKHOUSE_PORTaplicam-se apenas à conexão de saída do banco de dados ClickHouse. Eles não configuram TLS, certificados de cliente, portas ou autenticação para o endpoint MCP HTTP/SSE de entrada.Exemplo: se o servidor MCP roda em Kubernetes atrás de um ingress que encerra TLS, isso é uma preocupação do transporte MCP. Mantenha
CLICKHOUSE_SECUREalinhado com como o pod alcança o próprio ClickHouse (HTTPS →true, HTTP simples →false). DefinirCLICKHOUSE_SECURE=falseporque o servidor MCP está atrás de um ingress fará o servidor conectar ao ClickHouse via HTTP—frequentemente contra uma porta somente HTTPS—e produzir erros opacos de HTTP/TLS nos logs do servidor.
Conexão do banco de dados ClickHouse
Estas variáveis configuram o cliente HTTP clickhouse-connect e o comportamento das ferramentas baseadas em ClickHouse, como run_query, list_databases e list_tables.
mcp-clickhouse requer clickhouse-connect 1.0.0 ou mais recente.
Variáveis Obrigatórias
CLICKHOUSE_HOST: O hostname do seu servidor ClickHouse (endpoint do banco de dados, não o endereço de bind do servidor MCP)CLICKHOUSE_USER: O nome de usuário para autenticação ClickHouseCLICKHOUSE_PASSWORD: A senha para autenticação ClickHouse- Obrigatória a menos que
CLICKHOUSE_CLIENT_CERTuse o modo TLS padrão ou"mutual" - No modo padrão ou
"mutual", a autenticação por certificado é usada e a senha não é enviada
- Obrigatória a menos que
[!CAUTION] É importante tratar seu usuário de banco de dados MCP como trataria qualquer cliente externo conectando ao seu banco de dados, concedendo apenas os privilégios mínimos necessários para sua operação. O uso de usuários padrão ou administrativos deve ser estritamente evitado em todos os momentos.
Variáveis Opcionais
CLICKHOUSE_PORT: porta da interface HTTP do seu servidor ClickHouse- Padrão:
8443seCLICKHOUSE_SECURE=true,8123seCLICKHOUSE_SECURE=false - Geralmente não precisa ser definido, a menos que você use uma porta não padrão
- Deve ser uma porta de interface HTTP, não a porta do protocolo TCP nativo usada pelo
clickhouse-client - Valores comuns:
- HTTP:
8123(simples) /8443(TLS) — usado por este servidor e pelo ClickHouse Cloud HTTPS - TCP nativo (não suportado aqui):
9000(simples) /9440(TLS) — usado peloclickhouse-client
- HTTP:
- Se o servidor responder com
Port 9000 is for clickhouse-client program, você está apontando para o protocolo nativo; mude para a porta HTTP (8123/8443ou o mapeamento HTTP da sua implantação)
- Padrão:
CLICKHOUSE_ROLE: a função (role) do ClickHouse a ser usada para autenticação- Padrão: None
- Defina isso se o seu usuário exigir uma função específica
CLICKHOUSE_SECURE: Ativar HTTPS para a conexão com o banco de dados ClickHouse (não para clientes MCP)- Padrão:
"true" - Defina como
"false"somente quando o servidor MCP acessar o ClickHouse via HTTP simples (típico para Docker Compose local na porta8123) - Deixe
"true"para o ClickHouse Cloud e qualquer endpoint de banco de dados HTTPS—mesmo que o próprio servidor MCP seja exposto via HTTP, stdio ou um ingress que encerre TLS separadamente - Não corresponder essa flag com a porta do banco de dados (por exemplo,
CLICKHOUSE_SECURE=falsecontra a porta8443) é um erro de configuração frequente e geralmente aparece como erros confusos de cliente HTTP, em vez de uma mensagem clara de "esquema errado"
- Padrão:
CLICKHOUSE_VERIFY: Ativar/desativar a verificação de certificado SSL para a conexão HTTPS do ClickHouse- Padrão:
"true" - Defina como
"false"para desativar a verificação de certificado (não recomendado para produção) - Certificados TLS: o pacote usa o armazenamento de confiança do seu sistema operacional via
truststore.inject_into_ssl()na inicialização. O tratamento SSL padrão do Python é usado se a injeção for desativada comMCP_CLICKHOUSE_TRUSTSTORE_DISABLE=1ou falhar.
- Padrão:
MCP_CLICKHOUSE_TRUSTSTORE_DISABLE: Desativar a integração do armazenamento de confiança do sistema operacional em todo o processo para TLS- Padrão: não definido (a integração do armazenamento de confiança está ativada)
- Defina exatamente como
"1"antes da inicialização para pulartruststore.inject_into_ssl()e usar o tratamento padrão de certificados SSL do Python. Outros valores não desativam a integração. - Isso não desativa a verificação de certificado.
CLICKHOUSE_VERIFYainda controla a verificação para a conexão HTTPS do ClickHouse.
CLICKHOUSE_CA_CERT: Caminho para um pacote de certificados CA em PEM para a conexão HTTPS do ClickHouse- Padrão: None (usa o armazenamento de confiança do sistema operacional, a menos que a injeção do armazenamento de confiança seja desativada ou falhe)
- Use isso sozinho quando um servidor ClickHouse ou proxy privado apresentar um certificado assinado por uma CA privada. Isso altera a verificação do certificado do servidor e não ativa a autenticação de certificado do cliente.
- Requer
CLICKHOUSE_SECURE=trueeCLICKHOUSE_VERIFY=true
CLICKHOUSE_CLIENT_CERT: Caminho para um certificado de cliente PEM para a conexão HTTPS do ClickHouse- Padrão: None
- O arquivo também pode conter a chave privada. Caso contrário, defina
CLICKHOUSE_CLIENT_CERT_KEY. - O usuário do ClickHouse ainda vem de
CLICKHOUSE_USER.
CLICKHOUSE_CLIENT_CERT_KEY: Caminho para a chave privada PEM paraCLICKHOUSE_CLIENT_CERT- Padrão: None
- Opcional quando a chave privada está incluída no arquivo de certificado do cliente
- Não pode ser usado sem
CLICKHOUSE_CLIENT_CERT
CLICKHOUSE_TLS_MODE: Como o clickhouse-connect usaCLICKHOUSE_CLIENT_CERT- Padrão: None, que se comporta como
"mutual"quando um certificado de cliente está definido "mutual": Use o certificado do cliente para autenticação de usuário X.509 do ClickHouse.CLICKHOUSE_PASSWORDé opcional e não é enviado."proxy": Apresente o certificado do cliente a um proxy que encerra TLS e, em seguida, use a autenticação Basic do ClickHouse.CLICKHOUSE_PASSWORDé obrigatório."strict": Apresente o certificado do cliente porque o servidor ClickHouse exige um na camada TLS e, em seguida, use a autenticação Basic do ClickHouse.CLICKHOUSE_PASSWORDé obrigatório. Este modo não reforça a verificação do certificado do servidor.CLICKHOUSE_VERIFYcontrola essa verificação.- O clickhouse-connect trata
"proxy"e"strict"de forma idêntica. Os dois nomes documentam a intenção. - Os valores são removidos de espaços e não diferenciam maiúsculas de minúsculas. Um valor em branco é tratado como não definido. Outros valores são rejeitados antes da criação de um cliente ClickHouse, na primeira chamada de ferramenta do ClickHouse ou na sondagem
/health. - Requer
CLICKHOUSE_CLIENT_CERT. Todas as opções de certificado de cliente exigemCLICKHOUSE_SECURE=true.
- Padrão: None, que se comporta como
CLICKHOUSE_SERVER_HOST_NAME: Nome do host do servidor para substituição de SNI e validação de certificado na conexão ClickHouse- Padrão: None (usa o nome do host da conexão)
- Isso é útil ao conectar por meio de proxies ou balanceadores de carga onde o nome do host do certificado difere do nome do host da conexão. Quando definido, este nome de host será usado tanto para SNI (Indicação de Nome do Servidor) durante o handshake TLS quanto para a validação do nome do host do certificado.
CLICKHOUSE_PROXY_PATH: Prefixo do caminho da URL para o endpoint HTTP do ClickHouse- Padrão: None
- Defina isso quando a interface HTTP do ClickHouse for exposta atrás de um proxy reverso sob um prefixo de caminho (por exemplo,
/clickhouse)
CLICKHOUSE_CONNECT_TIMEOUT: Tempo limite de conexão em segundos para o cliente ClickHouse- Padrão:
"30" - Aumente este valor se você tiver tempos limite de conexão
- Padrão:
CLICKHOUSE_SEND_RECEIVE_TIMEOUT: Tempo limite de envio/recebimento em segundos para o cliente ClickHouse- Padrão: o menor entre
300ouCLICKHOUSE_MCP_QUERY_TIMEOUT + 5, para que as threads de trabalho sejam desbloqueadas logo após um tempo limite de consulta - Se definido explicitamente, o valor é usado como está (por exemplo,
"300"para consultas de longa duração)
- Padrão: o menor entre
CLICKHOUSE_DATABASE: Banco de dados ClickHouse padrão a ser usado- Padrão: None (usa o padrão do servidor)
- Defina isso para conectar automaticamente a um banco de dados específico
CLICKHOUSE_ENABLED: Ativar/desativar as ferramentas de banco de dados do ClickHouse- Padrão:
"true" - Defina como
"false"para desativar as ferramentas do ClickHouse ao usar apenas chDB
- Padrão:
CLICKHOUSE_ALLOW_WRITE_ACCESS: Permitir operações de escrita (DDL e DML) contra o ClickHouse- Padrão:
"false" - Defina como
"true"para permitir DDL e DML não destrutivos (CREATE, INSERT, ALTER ADD COLUMN). Declarações destrutivas adicionalmente precisam deCLICKHOUSE_ALLOW_DROP=true - Quando desativado (padrão), as consultas são executadas com a configuração
readonly=1para evitar modificações de dados
- Padrão:
CLICKHOUSE_ALLOW_DROP: Permitir operações destrutivas (qualquerDROPouTRUNCATE,DELETEeUPDATEincluindo as variantesALTER TABLE,REPLACE TABLE/REPLACE PARTITION/CREATE OR REPLACE,CLEAR COLUMN/CLEAR INDEX/CLEAR PROJECTIONeDETACH ... PERMANENTLY)- Padrão:
"false" - Só tem efeito quando
CLICKHOUSE_ALLOW_WRITE_ACCESS=truetambém está definido - Esta proteção é um guarda de acidente de melhor esforço no servidor MCP, não um limite de segurança. Restrinja as permissões (grants) do usuário do ClickHouse para uma aplicação real (veja Proteção de Operações Destrutivas)
- Padrão:
Arquivos de certificado TLS do ClickHouse
As variáveis de certificado contêm caminhos de arquivo, não conteúdos PEM. O mcp-clickhouse passa esses caminhos para o clickhouse-connect. Para Docker ou Kubernetes, monte o certificado e a chave privada como arquivos somente leitura e use seus caminhos dentro do contêiner. Não incorpore uma chave privada em uma imagem, não a envie para o controle de versão e não coloque seu conteúdo em uma variável de ambiente.
No modo mutual, o certificado de cliente configurado identifica este processo mcp-clickhouse como
CLICKHOUSE_USER. Ele não autentica clientes MCP de entrada nem transmite suas identidades para o
ClickHouse. Configure a autenticação do transporte MCP separadamente.
Reinicie o mcp-clickhouse após substituir um certificado ou chave no mesmo caminho quando for necessária rotação ou revogação imediata. Clientes em cache podem manter conexões TLS existentes, e o cache não rastreia conteúdos de arquivo nem horários de modificação.
O ClickHouse Cloud não suporta autenticação de certificado de cliente X.509 para usuários de banco de dados.
Use CLICKHOUSE_USER e CLICKHOUSE_PASSWORD para o ClickHouse Cloud. Um certificado CA ainda pode
ser útil quando um proxy privado na frente de um endpoint apresenta um certificado assinado por
uma CA privada.
Servidor MCP e transporte
Estas variáveis controlam o próprio processo MCP, incluindo transporte, autenticação e limites de execução de ferramentas de consulta. Elas são independentes das configurações do banco de dados ClickHouse acima. Veja também Autenticação para Transportes HTTP/SSE.
CLICKHOUSE_MCP_SERVER_TRANSPORT: Define o método de transporte para o servidor MCP- Padrão:
"stdio" - Opções válidas:
"stdio","http","sse". Isso é útil para desenvolvimento local com ferramentas como o MCP Inspector. stdioé típico para o Claude Desktop;http/sseexpõem um listener de rede (defina host/porta abaixo)"sse"seleciona o transporte standalone HTTP+SSE descontinuado e registra um aviso. Use"http"para Streamable HTTP em novas implantações.
- Padrão:
CLICKHOUSE_MCP_BIND_HOST: Host ao qual vincular o servidor MCP ao usar transporte HTTP ou SSE- Padrão:
"127.0.0.1" - Defina como
"0.0.0.0"para vincular a todas as interfaces de rede (útil para Docker ou acesso remoto) - Usado apenas quando o transporte é
"http"ou"sse"— não relacionado aCLICKHOUSE_HOST
- Padrão:
CLICKHOUSE_MCP_BIND_PORT: Porta à qual vincular o servidor MCP ao usar transporte HTTP ou SSE- Padrão:
"8000" - Usada apenas quando o transporte é
"http"ou"sse"— não relacionada aCLICKHOUSE_PORT
- Padrão:
CLICKHOUSE_MCP_QUERY_TIMEOUT: Tempo limite em segundos para chamadas de ferramentas de consulta- Padrão:
"30" - Aumente isso se você vir erros de
Query timed out after ...para consultas pesadas - Quando uma consulta expira, o servidor tenta cancelá-la com
KILL QUERY - A menos que
CLICKHOUSE_SEND_RECEIVE_TIMEOUTseja definido explicitamente, o tempo limite de leitura HTTP é limitado a este valor mais cinco segundos
- Padrão:
CLICKHOUSE_MCP_MAX_WORKERS: Número máximo de threads de trabalho de consulta concorrentes- Padrão:
"10" - Aumente se sua carga de trabalho exigir muitas chamadas de ferramentas concorrentes
- Ferramentas de metadados usam um pool separado com
min(4, CLICKHOUSE_MCP_MAX_WORKERS)threads para que a descoberta de esquema não possa atrasar consultas
- Padrão:
CLICKHOUSE_MCP_AUTH_TOKEN: Token bearer estático para transportes HTTP/SSE- Padrão: Nenhum
- Um de
CLICKHOUSE_MCP_AUTH_TOKEN,FASTMCP_SERVER_AUTHouCLICKHOUSE_MCP_AUTH_DISABLED=trueé obrigatório para transportes HTTP/SSE - Gere usando
uuidgenouopenssl rand -hex 32 - Os clientes devem enviar este token no cabeçalho
Authorization: Bearer <token>
FASTMCP_SERVER_AUTH: Delegar autenticação a um provedor de autenticação FastMCP- Padrão: Nenhum
- O valor é o caminho de classe completo de uma subclasse de AuthProvider, por exemplo,
fastmcp.server.auth.providers.azure.AzureProvideroufastmcp.server.auth.providers.google.GoogleProvider - Quando definido, o mcp-clickhouse carrega o provedor das variáveis de ambiente
FASTMCP_SERVER_AUTH_*existentes; deixeCLICKHOUSE_MCP_AUTH_TOKENnão definido neste modo - Provedores personalizados não recebem argumentos de construtor derivados do ambiente e devem suportar construção sem argumentos
- O FastMCP 4 não suporta mais a verificação HS256 do Supabase. Implantações do Supabase devem usar RS256 ou ES256.
FASTMCP_ENV_FILE: Arquivo opcional contendoFASTMCP_SERVER_AUTHe variáveis de ambiente específicas do provedor- Padrão: Nenhum. Quando não definido, o carregador de compatibilidade lê campos de provedor ausentes de
.envno diretório de trabalho. Ele não lêFASTMCP_SERVER_AUTHdesse fallback - Defina-o no ambiente do processo antes da inicialização. Um valor carregado do
.envpadrão não pode redirecionar o carregador de compatibilidade - Se definido pelo processo, este arquivo pode fornecer tanto
FASTMCP_SERVER_AUTHquanto campos de provedor e substitui o fallback do diretório de trabalho - Valores do ambiente do processo têm precedência sem diferenciar maiúsculas de minúsculas
- O carregador de compatibilidade do mcp-clickhouse lê este arquivo apenas ao construir autenticação HTTP/SSE e lê apenas entradas
FASTMCP_SERVER_AUTHeFASTMCP_SERVER_AUTH_*. O FastMCP 4 pode ler o mesmo arquivo para suas configurações mais amplas - O carregamento padrão de
.envé separado. Ele começa no diretório do pacotemcp_clickhouseinstalado, resolve symlinks, sobe até a raiz do sistema de arquivos e carrega o primeiro.envencontrado ou nada. Ele nunca lê o diretório de trabalho, independentemente do método de inicialização. Esse arquivo pode fornecerFASTMCP_SERVER_AUTHe campos de provedor junto com outras configurações do servidor. Uma cópia do código-fonte normalmente encontra o.envda raiz do repositório
- Padrão: Nenhum. Quando não definido, o carregador de compatibilidade lê campos de provedor ausentes de
CLICKHOUSE_MCP_AUTH_DISABLED: Desabilitar autenticação para transportes HTTP/SSE- Padrão:
"false"(autenticação habilitada) - Defina como
"true"para desabilitar a autenticação apenas para desenvolvimento/testes locais - AVISO: Use apenas para desenvolvimento local. Não desabilite quando exposto a redes
- Padrão:
CLICKHOUSE_MCP_ALLOWED_HOSTS: Valores de cabeçalhoHostseparados por vírgula aos quais o servidor HTTP/SSE responde- Padrão para um bind de loopback: formas simples e de qualquer porta de
127.0.0.1,localhoste[::1] - Se definido, o valor deve conter pelo menos uma entrada de Host.
- Um endereço de bind concreto não-loopback usa por padrão esse endereço e a porta configurada. Um bind curinga como
0.0.0.0ou::requer um valor explícito não vazio porque o Host público não pode ser inferido. - A validação de Host é uma defesa em profundidade contra DNS rebinding. A validação de Origin abaixo é exigida separadamente pelo MCP.
- As entradas são exatas (
localhost:8000) ou aceitam qualquer porta (localhost:*). Exemplo:CLICKHOUSE_MCP_ALLOWED_HOSTS=127.0.0.1:8000,localhost:8000 - A forma
host:*corresponde apenas a valores que carregam uma porta. Um Host sem porta (uma implantação de porta padrão onde o cliente omite:80/:443) deve ser listado também como uma entrada exata simples (example.com). - Solicitações com cabeçalho
Hostnão correspondente ou ausente recebem421 Misdirected Request. Solicitações GET e HEAD para/healthestão isentas da validação de Host e Origin para que as sondas do orquestrador continuem funcionando. - Atrás de um proxy reverso, prefira preservar o cabeçalho
Hostoriginal. Você pode, em vez disso, listar o valorHostupstream que o proxy envia. Defina uma lista explícita quando um lançador comofastmcp runsubstituir o endereço de bind para acesso remoto. - O mcp-clickhouse força a proteção separada de Host e Origin do FastMCP a ficar desligada.
FASTMCP_HTTP_HOST_ORIGIN_PROTECTION,FASTMCP_HTTP_ALLOWED_HOSTSeFASTMCP_HTTP_ALLOWED_ORIGINSnão se aplicam.CLICKHOUSE_MCP_ALLOWED_HOSTSeCLICKHOUSE_MCP_ALLOWED_ORIGINSsão autoritativos.
- Padrão para um bind de loopback: formas simples e de qualquer porta de
CLICKHOUSE_MCP_TRUSTED_PROXIES: Endereços IP de proxy ou redes CIDR cujos cabeçalhosX-Forwarded-*são confiáveis- Padrão: Nenhum.
X-Forwarded-Hosté ignorado. O tratamento existente do Uvicorn deX-Forwarded-ForeX-Forwarded-Protopermanece inalterado. - As entradas devem ser endereços IP ou redes CIDR, como
127.0.0.1,10.20.0.0/24,2001:db8::1. CIDRs devem usar seu endereço de rede, então10.20.0.1/24é rejeitado. Nomes de host, endereços IPv6 com escopo,*,0.0.0.0/0e::/0também são rejeitados. - A confiança é baseada no peer imediato do socket bruto. Uma solicitação de qualquer outro peer, ou uma solicitação sem endereço de cliente, ignora
X-Forwarded-Hoste validaHost. - Um peer confiável pode enviar exatamente um cabeçalho
X-Forwarded-Hostcontendo um valor não vazio. Campos duplicados, valores vazios e listas separadas por vírgula recebem421 Misdirected Request. Se o cabeçalho estiver ausente,Hosté validado. - Use o endereço ou rede mais restrito possível. O servidor MCP deve ser alcançável apenas por meio de proxies nas faixas configuradas. Cada proxy confiável deve remover e sobrescrever valores
X-Forwarded-HosteX-Forwarded-Protofornecidos pelo cliente e construirX-Forwarded-Fora partir do peer de conexão verificado. - O servidor integrado e
fastmcp rundesabilitam o tratamento de cabeçalhos de proxy externo do Uvicorn, validam o Host a partir do peer bruto e então aplicamX-Forwarded-ForeX-Forwarded-Proto. Habilitar explicitamenteuvicorn_config["proxy_headers"]falha na inicialização neste modo. - A incorporação direta de ASGI deve desabilitar o tratamento de cabeçalhos de proxy no servidor ASGI externo e chamar
mcp.http_app(raw_client_address_preserved=True). Sem essa asserção explícita, a construção do aplicativo falha quando proxies confiáveis são configurados.
- Padrão: Nenhum.
CLICKHOUSE_MCP_ALLOWED_ORIGINS: Valores de cabeçalhoOriginseparados por vírgula aceitos em HTTP/SSE- Padrão: Nenhum, o que rejeita toda solicitação que carrega um cabeçalho
Origin - O MCP exige validação de Origin para conexões de transporte HTTP/SSE. Solicitações sem Origin são aceitas porque clientes MCP que não são navegadores normalmente o omitem. Um Origin não correspondente recebe
403 Forbidden. O endpoint/healthestá isento conforme descrito acima. - As entradas são exatas (
http://localhost:3000) ou aceitam qualquer porta (http://localhost:*). Assim como com hosts, a forma de qualquer porta corresponde apenas a origins que carregam uma porta; um origin de porta padrão (https://app.example.com) deve ser listado exatamente.
- Padrão: Nenhum, o que rejeita toda solicitação que carrega um cabeçalho
Tratamento de Host em proxy reverso
Preserve Host quando possível. Isso mantém a confiança de Host encaminhado desabilitada:
location / {
proxy_pass http://mcp-clickhouse:8000;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Host "";
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
}
Sanitize X-Forwarded-For e X-Forwarded-Proto independentemente da confiança de X-Forwarded-Host. O Uvicorn pode confiar nesses cabeçalhos com base no peer do proxy mesmo quando CLICKHOUSE_MCP_TRUSTED_PROXIES não está definido.
CLICKHOUSE_MCP_ALLOWED_HOSTS=mcp.example.com
O nginx padrão altera Host para o nome upstream para solicitações via proxy. Ele não cria nem sobrescreve X-Forwarded-Host. Se preservar Host não for possível, sobrescreva o cabeçalho encaminhado na borda confiável:
location / {
proxy_pass http://mcp-clickhouse:8000;
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
}
CLICKHOUSE_MCP_ALLOWED_HOSTS=mcp.example.com
CLICKHOUSE_MCP_TRUSTED_PROXIES=10.20.0.8
A segunda configuração é segura apenas quando 10.20.0.8 é o endereço de origem imediato do proxy, a porta do servidor está isolada de outros clientes e o nginx sobrescreve os cabeçalhos de encaminhamento recebidos conforme mostrado. Para uma cadeia de proxies, cada salto confiável deve descartar valores recebidos não verificados antes de construir os novos cabeçalhos de encaminhamento.
Em um bind IPv6 ou dual-stack, proxies IPv4 podem aparecer como endereços mapeados para IPv4, como ::ffff:10.20.0.8; estes são correspondidos automaticamente contra entradas IPv4. O append_x_forwarded_host do Envoy anexa a um X-Forwarded-Host existente em vez de sobrescrevê-lo, produzindo uma lista separada por vírgula que é rejeitada, então configure o salto confiável para sobrescrever o cabeçalho. No Kubernetes com NAT de origem (por exemplo, externalTrafficPolicy: Cluster), o peer observado pode ser um IP de nó em vez do pod do proxy, então confie no pod ou no CIDR do nó conforme apropriado; o ingress-nginx sobrescreve tanto Host quanto X-Forwarded-Host por conta própria.
Variáveis de Middleware
MCP_MIDDLEWARE_MODULE: Nome do módulo Python contendo middleware personalizado para injetar no servidor MCP- Padrão: Nenhum (nenhum middleware carregado)
- Defina como o nome do módulo (sem a extensão
.py) do seu módulo de middleware - O módulo deve fornecer uma função
setup_middleware(mcp) - Consulte Middleware Personalizado para detalhes e exemplos
Variáveis do chDB
CHDB_ENABLED: Ativar/desativar a funcionalidade do chDB- Padrão:
"false" - Defina como
"true"para ativar as ferramentas do chDB - Requer a instalação do extra opcional:
mcp-clickhouse[chdb]
- Padrão:
CHDB_DATA_PATH: O caminho para o diretório de dados do chDB- Padrão:
":memory:"(banco de dados em memória) - Use
:memory:para banco de dados em memória - Use um caminho de arquivo para armazenamento persistente (por exemplo,
/path/to/chdb/data)
- Padrão:
Armadilhas comuns de configuração
CLICKHOUSE_SECUREvs TLS de MCP/ingress — DesligarCLICKHOUSE_SECUREporque o servidor MCP está atrás de ingress Kubernetes, um proxy reverso ou é alcançado por HTTP simples não desabilita o TLS do banco de dados; isso apenas altera como este processo se conecta ao ClickHouse. Configure o TLS do ingress separadamente das configurações do cliente do banco de dados.- Portas do protocolo nativo —
CLICKHOUSE_PORTdeve ter como alvo a interface HTTP do ClickHouse (8123/8443por padrão). As portas9000/9440são para o protocolo TCP nativo (clickhouse-client) e não funcionarão com este servidor. - Confusão de host —
CLICKHOUSE_HOSTé o hostname do banco de dados.CLICKHOUSE_MCP_BIND_HOSTé apenas o endereço no qual o servidor MCP HTTP/SSE escuta.
Exemplos de Configuração
Para desenvolvimento local com Docker:
# Required variables
CLICKHOUSE_HOST=localhost
CLICKHOUSE_USER=default
CLICKHOUSE_PASSWORD=clickhouse
# Optional: Override defaults for local development
CLICKHOUSE_SECURE=false # Uses port 8123 automatically
CLICKHOUSE_VERIFY=false
Para ClickHouse Cloud:
# Required variables
CLICKHOUSE_HOST=your-instance.clickhouse.cloud
CLICKHOUSE_USER=default
CLICKHOUSE_PASSWORD=your-password
# Optional: These use secure defaults
# CLICKHOUSE_SECURE=true # Uses port 8443 automatically
# CLICKHOUSE_DATABASE=your_database
Para ClickHouse SQL Playground:
CLICKHOUSE_HOST=sql-clickhouse.clickhouse.com
CLICKHOUSE_USER=demo
CLICKHOUSE_PASSWORD=
# Uses secure defaults (HTTPS on port 8443)
Para uma CA de servidor privada sem autenticação de certificado de cliente:
CLICKHOUSE_HOST=your-secure-clickhouse.example.com
CLICKHOUSE_USER=your-user
CLICKHOUSE_PASSWORD=your-password
CLICKHOUSE_SECURE=true
CLICKHOUSE_VERIFY=true
CLICKHOUSE_CA_CERT=/run/secrets/clickhouse-ca.pem
Para autenticação de certificado de cliente X.509 do ClickHouse:
CLICKHOUSE_HOST=your-secure-clickhouse.example.com
CLICKHOUSE_USER=your-certificate-user
CLICKHOUSE_SECURE=true
CLICKHOUSE_CLIENT_CERT=/run/secrets/clickhouse-client.pem
CLICKHOUSE_CLIENT_CERT_KEY=/run/secrets/clickhouse-client-key.pem
# CLICKHOUSE_CA_CERT=/run/secrets/clickhouse-ca.pem # Only for a private server CA
# CLICKHOUSE_TLS_MODE=mutual # Optional. This is the default with a client certificate.
Para um certificado de cliente exigido por um servidor TLS estrito enquanto o ClickHouse usa autenticação Básica:
CLICKHOUSE_HOST=your-secure-clickhouse.example.com
CLICKHOUSE_USER=your-user
CLICKHOUSE_PASSWORD=your-password
CLICKHOUSE_SECURE=true
CLICKHOUSE_CLIENT_CERT=/run/secrets/clickhouse-client.pem
CLICKHOUSE_CLIENT_CERT_KEY=/run/secrets/clickhouse-client-key.pem
CLICKHOUSE_TLS_MODE=strict
Use CLICKHOUSE_TLS_MODE=proxy quando um proxy de terminação TLS exigir o certificado
do cliente e o ClickHouse ainda usar autenticação Basic.
Somente para chDB (em memória):
# chDB configuration
CHDB_ENABLED=true
CLICKHOUSE_ENABLED=false
# CHDB_DATA_PATH defaults to :memory:
Para chDB com armazenamento persistente:
# chDB configuration
CHDB_ENABLED=true
CLICKHOUSE_ENABLED=false
CHDB_DATA_PATH=/path/to/chdb/data
Para MCP Inspector ou acesso remoto com transporte HTTP:
CLICKHOUSE_HOST=localhost
CLICKHOUSE_USER=default
CLICKHOUSE_PASSWORD=clickhouse
CLICKHOUSE_MCP_SERVER_TRANSPORT=http
CLICKHOUSE_MCP_BIND_HOST=0.0.0.0 # Bind to all interfaces
CLICKHOUSE_MCP_BIND_PORT=4200 # Custom port (default: 8000)
CLICKHOUSE_MCP_AUTH_TOKEN=your-generated-token # One auth mode required for HTTP/SSE (or FASTMCP_SERVER_AUTH, or CLICKHOUSE_MCP_AUTH_DISABLED=true)
CLICKHOUSE_MCP_ALLOWED_HOSTS=127.0.0.1:4200,localhost:4200,mcp.example.com:4200 # Include every Host value clients and proxies send
Para desenvolvimento local com transporte HTTP (autenticação desabilitada):
CLICKHOUSE_HOST=localhost
CLICKHOUSE_USER=default
CLICKHOUSE_PASSWORD=clickhouse
CLICKHOUSE_MCP_SERVER_TRANSPORT=http
CLICKHOUSE_MCP_AUTH_DISABLED=true # Only for local development!
CLICKHOUSE_MCP_ALLOWED_HOSTS=127.0.0.1:8000,localhost:8000
Ao usar transporte HTTP, o servidor será executado na porta configurada (padrão 8000). Por exemplo, com a configuração acima:
- Endpoint MCP:
http://localhost:8000/mcp - Verificação de saúde:
http://localhost:8000/health
Você pode definir essas variáveis no seu ambiente, em um arquivo .env, ou na configuração do Claude Desktop:
{
"mcpServers": {
"mcp-clickhouse": {
"command": "uv",
"args": [
"run",
"--with",
"mcp-clickhouse",
"--python",
"3.12",
"mcp-clickhouse"
],
"env": {
"CLICKHOUSE_HOST": "<clickhouse-host>",
"CLICKHOUSE_USER": "<clickhouse-user>",
"CLICKHOUSE_PASSWORD": "<clickhouse-password>",
"CLICKHOUSE_DATABASE": "<optional-database>",
"CLICKHOUSE_MCP_SERVER_TRANSPORT": "stdio",
"CLICKHOUSE_MCP_BIND_HOST": "127.0.0.1",
"CLICKHOUSE_MCP_BIND_PORT": "8000"
}
}
}
}
Nota: As configurações de host e porta de vinculação são usadas apenas quando o transporte está definido como "http" ou "sse".
Executando testes
uv sync --all-extras --dev # install dev dependencies
uv run ruff check . # run linting
docker compose up -d test_services # start ClickHouse
uv run pytest -v tests
uv run pytest -v tests/test_tool.py # ClickHouse only
CHDB_ENABLED=true uv run --extra chdb pytest -v tests/test_chdb_tool.py # chDB only
