ClickHouse

официальный

Запросы к вашему серверу базы данных ClickHouse.

Что можно делать с ClickHouse MCP?

  • Выполнение SQL-запросов — Попросите выполнить любой SQL-запрос на вашем кластере ClickHouse через run_query, с опциональными именованными параметрами.
  • Список баз данных — Попросите показать все базы данных, доступные на вашем кластере ClickHouse, с помощью list_databases.
  • Просмотр таблиц с фильтрами — Попросите вывести список таблиц в базе данных с шаблонами LIKE/NOT LIKE и пагинацией через list_tables.
  • Проверка схемы запроса — Попросите проверить выходные столбцы и типы запроса перед его выполнением с помощью DESCRIBE.
  • Оценка стоимости запроса — Попросите предварительно просмотреть предполагаемые чтения (части, строки, метки) для SELECT с использованием EXPLAIN ESTIMATE.

Документация

Сервер MCP ClickHouse

PyPI - Version

MCP-сервер для ClickHouse.

mcp-clickhouse MCP server

Сервер реализует MCP 2026-07-28 и поддерживает устаревшие процедуры рукопожатия initialize от 2024-11-05 до 2025-11-25. Современные клиенты используют запросы без сессий и server/discover. Существующие клиенты могут продолжать использовать устаревший протокол.

[!NOTE] HTTP-запросы без MCP-Protocol-Version обрабатываются через устаревший механизм, чтобы клиенты, выпущенные до 2025-06-18, могли продолжать подключаться. MCP 2026-07-28 разрешает такое поведение на серверах, поддерживающих этих клиентов. Современные клиенты должны отправлять заголовок в каждом POST-запросе.

Возможности

Инструменты ClickHouse

Ответы инструментов ClickHouse — это JSON-строки. Целые числа вне диапазона [-9007199254740991, 9007199254740991] возвращаются как десятичные строки для сохранения точных значений в JavaScript-клиентах. Это относится к строкам запросов и целочисленным метаданным таблиц. Целые числа в безопасном диапазоне и логические значения сохраняют свои JSON-типы.

  • run_query

    • Выполнение SQL-запросов к вашему кластеру ClickHouse.
    • Входные данные: query (строка): SQL-запрос для выполнения.
    • Необязательный вход: params (объект): именованные значения для плейсхолдеров ClickHouse {name:Type}. См. Параметры запроса.
    • Запросы по умолчанию выполняются в режиме только для чтения (CLICKHOUSE_ALLOW_WRITE_ACCESS=false), но запись можно явно включить при необходимости.
    • DESCRIBE (<query>) и EXPLAIN ESTIMATE <query> также выполняются здесь и являются необязательными способами проверки схемы результата запроса или его предполагаемого объёма чтения. См. Проверка запроса перед его выполнением.
  • list_databases

    • Список всех баз данных в вашем кластере ClickHouse.
  • list_tables

    • Список таблиц в базе данных с постраничной навигацией.
    • Обязательный вход: database (строка).
    • Необязательные входы:
      • like / not_like (строка): применение фильтров LIKE или NOT LIKE к именам таблиц.
      • page_token (строка): одноразовый токен, возвращённый предыдущим вызовом. Он хранится до одного часа.
      • page_size (целое, по умолчанию 50): количество таблиц на странице; должно быть больше 0.
      • include_detailed_columns (логическое, по умолчанию true): когда false, опускает метаданные столбцов для более лёгких ответов, сохраняя полный create_table_query.
    • Форма ответа:
      • tables: массив объектов таблиц для текущей страницы.
      • next_page_token: передайте это одноразовое значение обратно до его истечения, чтобы получить следующую страницу, или null, когда таблиц больше нет.
      • total_tables: общее количество таблиц, соответствующих заданным фильтрам.

Параметры запроса

Передавайте значения отдельно от SQL через необязательный объект params:

{
  "query": "SELECT {id:UInt32} AS id, {name:String} AS name",
  "params": {"id": 13, "name": "O'Reilly"}
}

Используйте плейсхолдеры ClickHouse {name:Type} без кавычек. Держите открывающую фигурную скобку, имя и двоеточие рядом, как в {id:UInt32}. Пробелы после двоеточия и внутри типа поддерживаются, как в {id: UInt32} и {amount:Decimal(18, 4)}. Для совместимости с поддерживаемыми версиями драйверов начинайте имена с буквы или подчёркивания и используйте только буквы, цифры и подчёркивания. Стиль форматирования Python %s или %(name)s и сырые бинарные параметры драйвера $name$ не поддерживаются. Вызовы только с query по-прежнему работают. Если опустить params, передать null или пустой объект, запрос остаётся несвязанным.

Значения параметров могут быть JSON-строками, числами, логическими значениями, null или массивами, при условии что они соответствуют объявленному типу ClickHouse:

  • Используйте null с типом Nullable(...).
  • Передавайте точные целые числа вне безопасного диапазона JavaScript как десятичные строки, например "18446744073709551615" с {id:UInt64}. Даты, метки времени и точные десятичные числа также можно передавать как строки с соответствующим типом ClickHouse.
  • Привязывайте векторы как один массив, например {vector:Array(Float32)} с "params": {"vector": [0.25, 0.5, 0.75]}.
  • Значения NULL внутри массивов зависят от установленного драйвера. Они работают с clickhouse-connect 1.8.0, но не работают с поддерживаемым минимумом 1.0.0.
  • JSON-списки и объекты не могут быть привязаны к типам ClickHouse Tuple и Map.

Отсутствующие значения и несовместимые типы возвращают ошибки запроса. При непустом params запрос со многими незакрытыми началами плейсхолдеров {name: отклоняется, включая текст, похожий на плейсхолдеры, в комментариях или строковых литералах. Параметризованные запросы используют ту же защиту записи, тайм-ауты, отмену и JSON-кодирование результатов, что и другие запросы.

Значения параметров не попадают в обычные SQL-журналы MCP-сервера, но остаются в аргументах инструментов MCP и могут появляться в ошибках бэкенда. ClickHouse 26.3.20.7 подставляет значения в текст запроса в system.query_log, system.processes и system.text_log. Привязка параметров не является функцией конфиденциальности и не уменьшает количество векторных значений, отправляемых в вызове инструмента.

Проверка запроса перед его выполнением

run_query также выполняет DESCRIBE и EXPLAIN ESTIMATE. Обе проверки необязательны: обращайтесь к DESCRIBE, когда нужны выходные столбцы и типы запроса, и к EXPLAIN ESTIMATE перед SELECT, который может быть дорогостоящим.

DESCRIBE (<query>) проверяет схему результата и возвращает те же метаданные выходных столбцов, что и 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)

ClickHouse должен проанализировать запрос, чтобы ответить, поэтому ошибки анализа появляются здесь, с собственным сообщением ClickHouse, а не в середине выполнения:

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'

Запрос, который успешно описывается, всё равно может завершиться ошибкой при выполнении — из-за лимита памяти или ошибки удалённого сервера, и он ничего не говорит о стоимости.

EXPLAIN ESTIMATE <query> возвращает части, строки и метки, которые запрос прочитал бы, по одной строке на таблицу, что отличает поиск по первичному ключу от полного сканирования:

EXPLAIN ESTIMATE SELECT count() FROM events WHERE id = 42
database  table   parts  rows   marks
default   events  1      8192   1

Это предполагаемые чтения из таблиц семейства MergeTree после обрезки по первичному ключу и партициям. Это не время выполнения и не размер результата, и другие движки таблиц не покрываются.

Ни один из операторов не выполняет тело запроса, но анализ не всегда бесплатен: DESCRIBE (SELECT (SELECT sleep(1))) выполняет скалярный подзапрос во время анализа. Оба доступны только для чтения и работают под стандартным CLICKHOUSE_ALLOW_WRITE_ACCESS=false. См. документацию ClickHouse для EXPLAIN ESTIMATE и DESCRIBE.

Инструменты chDB

  • run_chdb_select_query
    • Выполнение SQL-запросов с использованием встроенного движка ClickHouse chDB.
    • Входные данные: query (строка): SQL-запрос для выполнения.
    • Целые числа вне диапазона [-9007199254740991, 9007199254740991] возвращаются как десятичные строки.
    • Запрашивайте данные напрямую из различных источников (файлы, URL-адреса, базы данных) без процессов ETL.
    • Требуется необязательный дополнительный пакет chdb: pip install 'mcp-clickhouse[chdb]'

Конечная точка проверки работоспособности

При использовании HTTP или SSE-транспорта конечная точка проверки работоспособности доступна по адресу /health. Эта конечная точка:

  • Возвращает 200 OK (тело: OK), если сервер работает и может подключиться к ClickHouse
  • Возвращает 503 Service Unavailable с общим сообщением об ошибке, если сервер не может подключиться к ClickHouse
  • Возвращает 503, если проверка ClickHouse не завершается в течение двух секунд. Одновременные запросы используют один общий выполняющийся запрос проверки
  • Повторно использует завершённый результат проверки в течение одной секунды, поэтому проверки, поступающие быстро подряд, не подключаются к ClickHouse каждая отдельно. Сбой или восстановление, таким образом, могут сообщаться с задержкой до одной секунды

GET и HEAD-запросы к конечной точке намеренно не аутентифицированы и освобождены от проверки Host и Origin, чтобы проверки оркестратора (например, liveness/readiness Kubernetes, балансировщики нагрузки) могли использовать назначенные во время выполнения IP-адреса подов или целевые IP-адреса без дополнительной настройки. /health зарезервирован и не может использоваться как путь MCP-транспорта. Тело ответа намеренно минимально, чтобы не раскрывать строки версии бэкенда или детали ошибок; отлаживайте сбои через журналы сервера.

Пример:

curl http://localhost:8000/health
# Response: OK

Безопасность

Аутентификация для HTTP/SSE-транспортов

При использовании HTTP или SSE-транспорта аутентификация обязательна по умолчанию. Транспорт stdio (по умолчанию) не требует аутентификации, так как он общается только через стандартный ввод/вывод.

Поддерживаются три режима аутентификации. Выберите один:

РежимКогда использоватьПеременная окружения
Статический bearer-токенПростые развёртывания, внутренние сервисыCLICKHOUSE_MCP_AUTH_TOKEN
OAuth / OIDC (через FastMCP)Azure Entra, Google, GitHub, WorkOS и др.FASTMCP_SERVER_AUTH=<provider-class-path> (+ специфичные для провайдера переменные FASTMCP_SERVER_AUTH_*)
ОтключеноТолько локальная разработкаCLICKHOUSE_MCP_AUTH_DISABLED=true

Запуск завершается ошибкой, если ни один из этих режимов не настроен для HTTP/SSE-транспортов.

Настройка аутентификации

  1. Сгенерируйте безопасный токен (может быть любой случайной строкой):

    # Using uuidgen (macOS/Linux)
    uuidgen
    
    # Using openssl
    openssl rand -hex 32
    
  2. Настройте сервер с токеном:

    export CLICKHOUSE_MCP_AUTH_TOKEN="your-generated-token"
    
  3. Настройте ваш MCP-клиент на включение токена в запросы:

    Для Claude Desktop с HTTP/SSE-транспортом:

    {
      "mcpServers": {
        "mcp-clickhouse": {
          "url": "http://127.0.0.1:8000",
          "headers": {
            "Authorization": "Bearer your-generated-token"
          }
        }
      }
    }
    

    Примечание: конечная точка /health намеренно не аутентифицирована (см. Конечная точка проверки работоспособности выше). Чтобы убедиться, что аутентификация по bearer-токену действительно отклоняет неаутентифицированные запросы, обратитесь к самой MCP-конечной точке, например, с помощью MCP Inspector, или отправьте JSON-RPC-запрос POST на /mcp с заголовком Authorization и без него, и убедитесь, что неаутентифицированный вызов возвращает 401.

OAuth / OIDC через FastMCP

Для производственных развёртываний с провайдерами удостоверений (Azure Entra, Google, GitHub, WorkOS и др.) делегируйте аутентификацию встроенным провайдерам аутентификации FastMCP вместо использования статического токена. Установите FASTMCP_SERVER_AUTH на полный путь класса провайдера аутентификации FastMCP, вместе со специфичными для провайдера переменными FASTMCP_SERVER_AUTH_*, и оставьте CLICKHOUSE_MCP_AUTH_TOKEN неустановленным.

Пример (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 сохраняет эти префиксы переменных окружения FastMCP 2.14.7 для встроенных провайдеров FastMCP 4.0.0:

Путь класса провайдераПрефикс переменной провайдера
fastmcp.server.auth.providers.auth0.Auth0ProviderFASTMCP_SERVER_AUTH_AUTH0_
fastmcp.server.auth.providers.aws.AWSCognitoProviderFASTMCP_SERVER_AUTH_AWS_COGNITO_
fastmcp.server.auth.providers.azure.AzureProviderFASTMCP_SERVER_AUTH_AZURE_
fastmcp.server.auth.providers.descope.DescopeProviderFASTMCP_SERVER_AUTH_DESCOPEPROVIDER_
fastmcp.server.auth.providers.discord.DiscordProviderFASTMCP_SERVER_AUTH_DISCORD_
fastmcp.server.auth.providers.github.GitHubProviderFASTMCP_SERVER_AUTH_GITHUB_
fastmcp.server.auth.providers.google.GoogleProviderFASTMCP_SERVER_AUTH_GOOGLE_
fastmcp.server.auth.providers.introspection.IntrospectionTokenVerifierFASTMCP_SERVER_AUTH_INTROSPECTION_
fastmcp.server.auth.providers.jwt.JWTVerifierFASTMCP_SERVER_AUTH_JWT_
fastmcp.server.auth.providers.oci.OCIProviderFASTMCP_SERVER_AUTH_OCI_
fastmcp.server.auth.providers.scalekit.ScalekitProviderFASTMCP_SERVER_AUTH_SCALEKITPROVIDER_
fastmcp.server.auth.providers.supabase.SupabaseProviderFASTMCP_SERVER_AUTH_SUPABASE_
fastmcp.server.auth.providers.workos.WorkOSProviderFASTMCP_SERVER_AUTH_WORKOS_
fastmcp.server.auth.providers.workos.AuthKitProviderFASTMCP_SERVER_AUTH_AUTHKITPROVIDER_

Добавьте имя поля провайдера в верхнем регистре к префиксу. См. документацию FastMCP для требований к конфигурации каждого провайдера. Значения аутентификации, заданные непосредственно в переменных окружения процесса, имеют приоритет без учёта регистра. Загрузка по умолчанию .env начинается с установленного каталога пакета mcp_clickhouse, сначала разрешает символические ссылки и поднимается вверх к корню файловой системы. Она загружает первый найденный .env и ничего не загружает, если его нет. Она никогда не читает рабочую директорию, независимо от того, как запущен сервер. При работе из исходников обычно находится .env корня репозитория. Этот файл также может предоставлять FASTMCP_SERVER_AUTH и его поля провайдера. Его значения имеют приоритет над явным или совместимым файлом аутентификации. Для совместимости с FastMCP 2 mcp-clickhouse читает отсутствующие поля провайдера из .env в рабочей директории, но этот резервный механизм совместимости не может выбрать FASTMCP_SERVER_AUTH. Установленный в процессе FASTMCP_ENV_FILE заменяет этот резервный механизм совместимости и может предоставлять как поля селектора, так и поля провайдера. Установите его до запуска. Загрузчик совместимости mcp-clickhouse читает только FASTMCP_SERVER_AUTH и FASTMCP_SERVER_AUTH_* из этого файла, поэтому он не может внедрить настройки CLICKHOUSE_*. FastMCP 4 может использовать тот же файл для своих собственных более широких настроек. Пользовательский провайдер получает без аргументов конструктора, производных от окружения, и должен поддерживать конструкцию без аргументов.

Относитесь как к обнаруженным, так и к файлам .env в рабочей директории как к доверенной конфигурации аутентификации. Любой, кто может создать или записать .env в любом каталоге от каталога пакета до корня файловой системы, может контролировать, какой файл будет обнаружен, выбирать провайдера и устанавливать его поля. Любой, кто может записать файл в рабочей директории, контролирует каждое поле провайдера, отсутствующее в процессе и обнаруженной конфигурации, включая ключи подписи, эмитентов и конечные точки, а также секреты клиентов. Установленный в процессе FASTMCP_ENV_FILE, указывающий на файл, принадлежащий оператору, отключает резервный механизм рабочей директории.

FastMCP 4 изменил хранилище клиентов прокси OAuth по умолчанию. Развёртывания, которые полагались на хранилище прокси OAuth по умолчанию FastMCP 2, должны зарегистрировать клиентов и авторизоваться снова. Совместимое пользовательское хранилище, статические токены Bearer и проверка JWT не затронуты.

Режим разработки (отключение аутентификации)

Только для локальной разработки и тестирования вы можете отключить аутентификацию, установив:

export CLICKHOUSE_MCP_AUTH_DISABLED=true
export CLICKHOUSE_MCP_ALLOWED_HOSTS=127.0.0.1:8000,localhost:8000

ПРЕДУПРЕЖДЕНИЕ: Используйте это только для локальной разработки. Не отключайте аутентификацию, когда сервер доступен из любой сети.

Конфигурация

Этот MCP-сервер поддерживает как ClickHouse, так и chDB. Вы можете включить любой из них или оба в зависимости от ваших потребностей. Поддерживаются Python 3.10–3.14. Для локальных запусков рекомендуется Python 3.12.

  1. Откройте файл конфигурации Claude Desktop, расположенный по адресу:

    • На macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
    • На Windows: %APPDATA%/Claude/claude_desktop_config.json
  2. Добавьте следующее:

{
  "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"
      }
    }
  }
}

Обновите переменные окружения, чтобы они указывали на ваш собственный сервис ClickHouse.

Или, если вы хотите попробовать с ClickHouse SQL Playground, вы можете использовать следующую конфигурацию:

{
  "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"
      }
    }
  }
}

Для chDB (встроенный движок ClickHouse) добавьте следующую конфигурацию:

{
  "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"
      }
    }
  }
}

Вы также можете включить одновременно и ClickHouse, и chDB:

{
  "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"
      }
    }
  }
}
  1. Найдите запись команды для uv и замените её абсолютным путём к исполняемому файлу uv. Это гарантирует, что при запуске сервера будет использоваться правильная версия uv. На Mac вы можете найти этот путь с помощью which uv.

  2. Перезапустите Claude Desktop, чтобы применить изменения.

Необязательный доступ на запись

По умолчанию этот MCP обеспечивает выполнение только запросов на чтение, чтобы случайные изменения не могли произойти во время исследования. Чтобы разрешить операторы DDL или INSERT, установите переменную окружения CLICKHOUSE_ALLOW_WRITE_ACCESS в значение true. Сервер продолжает обеспечивать режим только для чтения, если сам экземпляр ClickHouse запрещает запись.

Защита от разрушительных операций

Даже когда доступ на запись включён (CLICKHOUSE_ALLOW_WRITE_ACCESS=true), разрушительные операции требуют дополнительного флага согласия для безопасности. Проверка охватывает любой оператор DROP (включая предложения ALTER TABLE ... DROP PARTITION / DROP PART / DROP COLUMN), любые TRUNCATE, DELETE и UPDATE (как лёгкие операторы, так и мутации ALTER TABLE ... DELETE / ALTER TABLE ... UPDATE), REPLACE TABLE, CREATE OR REPLACE, ALTER TABLE ... REPLACE PARTITION, ALTER TABLE ... CLEAR COLUMN / CLEAR INDEX / CLEAR PROJECTION и DETACH ... PERMANENTLY. Ключевые слова внутри строковых литералов, идентификаторов в кавычках, SQL-комментариев и имён параметров {name:Type} игнорируются, поэтому они не запускают проверку и не скрывают оператор от неё.

Эта проверка выполняется на MCP-сервере и является добросовестной защитой от случайностей. Она не является границей безопасности. Границей безопасности являются гранты пользователя ClickHouse. Режим только для чтения (по умолчанию) обеспечивается на стороне сервера через readonly=1. Защита от разрушительных операций не обеспечивается на стороне сервера.

Для режима записи предоставьте MCP-серверу выделенного пользователя ClickHouse только с теми привилегиями, которые ему нужны:

CREATE USER mcp_agent IDENTIFIED BY '...';
GRANT SELECT, INSERT, CREATE TABLE, ALTER ADD COLUMN ON mydb.* TO mcp_agent;

Каждый оператор вне этих грантов тогда завершится ошибкой на стороне сервера с ACCESS_DENIED, независимо от флагов MCP. Настройки сервера max_table_size_to_drop и max_partition_size_to_drop также могут ограничить радиус поражения, если они закреплены ограничениями настроек.

Чтобы включить разрушительные операции, установите оба флага:

"env": {
  "CLICKHOUSE_ALLOW_WRITE_ACCESS": "true",
  "CLICKHOUSE_ALLOW_DROP": "true"
}

Этот двухуровневый подход делает случайное удаление маловероятным:

  • Операции записи (INSERT, CREATE, ALTER ADD COLUMN) требуют CLICKHOUSE_ALLOW_WRITE_ACCESS=true
  • Разрушительные операции (DROP, TRUNCATE, DELETE, UPDATE и остальные из списка выше) дополнительно требуют CLICKHOUSE_ALLOW_DROP=true

Запуск без uv (с использованием системного Python)

Если вы предпочитаете использовать системную установку Python вместо uv, вы можете установить пакет из PyPI и запустить его напрямую:

  1. Установите пакет с помощью pip:

    python3 -m pip install mcp-clickhouse
    

    Чтобы также установить поддержку chDB:

    python3 -m pip install 'mcp-clickhouse[chdb]'
    

    Чтобы обновиться до последней версии:

    python3 -m pip install --upgrade mcp-clickhouse
    
  2. Обновите конфигурацию Claude Desktop, чтобы использовать Python напрямую:

{
  "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"
      }
    }
  }
}

В качестве альтернативы вы можете использовать установленный скрипт напрямую:

{
  "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"
      }
    }
  }
}

Примечание: Убедитесь, что вы используете полный путь к исполняемому файлу Python или скрипту mcp-clickhouse, если они не находятся в вашем системном PATH. Вы можете найти пути с помощью:

  • which python3 для исполняемого файла Python
  • which mcp-clickhouse для установленного скрипта

Пользовательское промежуточное ПО

Вы можете добавить пользовательское промежуточное ПО на MCP-сервер без изменения исходного кода. FastMCP предоставляет систему промежуточного ПО, которая позволяет перехватывать и обрабатывать сообщения протокола MCP (вызовы инструментов, чтение ресурсов, подсказки и т. д.).

Как использовать

  1. Создайте модуль Python с классами промежуточного ПО, расширяющими Middleware, и функцию setup_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())
  1. Установите переменную окружения MCP_MIDDLEWARE_MODULE в имя модуля (без расширения .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"
      }
    }
  }
}
  1. Убедитесь, что ваш модуль промежуточного ПО находится в пути импорта Python (например, в том же каталоге, где запускается MCP-сервер, или установлен как пакет).

Пример промежуточного ПО

Пример модуля промежуточного ПО предоставлен в example_middleware.py и показывает распространённые шаблоны:

  • Журналирование всех запросов MCP
  • Журналирование вызовов инструментов отдельно
  • Измерение времени обработки запросов

Чтобы использовать пример:

"env": {
  "MCP_MIDDLEWARE_MODULE": "example_middleware"
}

Возможности промежуточного ПО

Базовый класс Middleware предоставляет хуки для различных операций MCP:

  • on_message(context, call_next) — вызывается для всех сообщений
  • on_request(context, call_next) — вызывается для всех запросов
  • on_notification(context, call_next) — вызывается для всех уведомлений
  • on_call_tool(context, call_next) — вызывается при выполнении инструмента
  • on_read_resource(context, call_next) — вызывается при чтении ресурса
  • on_get_prompt(context, call_next) — вызывается при получении подсказки
  • on_list_tools(context, call_next) — вызывается при перечислении инструментов
  • on_list_resources(context, call_next) — вызывается при перечислении ресурсов
  • on_list_resource_templates(context, call_next) — вызывается при перечислении шаблонов ресурсов
  • on_list_prompts(context, call_next) — вызывается при перечислении подсказок

Каждый хук получает объект MiddlewareContext, содержащий сообщение и метаданные, и функцию call_next для продолжения конвейера.

Динамическая конфигурация клиента через состояние контекста

Промежуточное ПО может переопределять конфигурацию клиента ClickHouse для каждого запроса, используя ключ состояния контекста CLIENT_CONFIG_OVERRIDES_KEY. Сервер объединяет эти переопределения с базовой конфигурацией из переменных окружения.

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)

Это позволяет реализовать продвинутые сценарии использования, такие как динамическая настройка тайм-аутов, маршрутизация по арендаторам или настройки подключения для конкретного пользователя.

Значение состояния должно быть словарём. Вложенные значения settings и generic_args должны быть сопоставлениями и объединяются с базовой конфигурацией. Недопустимые значения приводят к сбою вызова инструмента до создания клиента ClickHouse. CLICKHOUSE_ROLE остаётся активным, если переопределение явно не предоставляет settings.role. Ключи верхнего уровня role и ch_role, а также те же ключи в generic_args, отклоняются.

Устанавливайте verify, ca_cert, client_cert, client_cert_key, tls_mode, server_host_name и pool_mgr только как переопределения верхнего уровня. Они не могут быть вложены в generic_args. Пользовательский pool_mgr не может быть объединён с управляемыми настройками CA или сертификатов клиента. Параметры запроса DSN не могут устанавливать эти ключи, и DSN не может выбрать бэкенд chdb. Используйте явные переопределения верхнего уровня host, port, username, password, database и secure для изменения подключения. Пересылаемый DSN не заменяет заполненные базовые поля подключения и не выбирает TLS. Он может заполнить пустые поля и предоставить поддерживаемые параметры запроса, такие как query_limit. Переопределения secure и verify принимают логические значения или строки true и false. verify также принимает proxy, который ведёт себя как tls_mode: proxy, когда tls_mode не установлен, и поэтому использует базовую аутентификацию с паролем из окружения. Переопределение secure выбирает соответствующий интерфейс https или http и не изменяет порт. Явное переопределение interface должно быть http или https и согласовываться с secure. После объединения переопределений режимы сертификатов клиента по умолчанию и mutual опускают пароль. Режимы proxy и strict используют базовую аутентификацию с паролем из окружения, если переопределение не предоставляет свои собственные учётные данные.

Относитесь к этим переопределениям как к доверенному вводу промежуточного ПО. Промежуточное ПО должно аутентифицировать и авторизовать значения, производные от запроса, перед их установкой. Используйте serializable=False, чтобы FastMCP сохранял значение в состоянии, локальном для запроса. По умолчанию serializable=True хранит состояние сеанса и отклоняется сервером. Сервер делает снимок значения перед отправкой блокирующей работы с базой данных. Не храните данные арендатора в состоянии Context, ограниченном сеансом. Отклонённое переопределение, ограниченное сеансом, остаётся прикреплённым к устаревшему сеансу MCP и вызывает сбои последующих вызовов инструментов в этом сеансе до тех пор, пока клиент не переподключится. Роль ClickHouse для конкретного запроса — это конфигурация подключения, а не граница авторизации арендатора. Обеспечивайте изоляцию арендаторов с помощью пользователей, ролей и грантов ClickHouse.

Разработка

  1. В каталоге test-services выполните docker compose up -d, чтобы запустить кластер ClickHouse.

  2. Добавьте следующие переменные в файл .env в корне репозитория.

Примечание: Использование пользователя default в этом контексте предназначено исключительно для целей локальной разработки.

CLICKHOUSE_HOST=localhost
CLICKHOUSE_PORT=8123
CLICKHOUSE_USER=default
CLICKHOUSE_PASSWORD=clickhouse
  1. Выполните uv sync, чтобы установить зависимости. Чтобы установить uv, следуйте инструкциям здесь. Затем выполните source .venv/bin/activate.

  2. Для удобного тестирования с MCP Inspector выполните uv run fastmcp dev inspector mcp_clickhouse/mcp_server.py:mcp, чтобы запустить MCP-сервер.

  3. Чтобы протестировать с HTTP-транспортом и конечной точкой проверки работоспособности:

    # 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
    

Переменные окружения

Конфигурация разделена на независимые группы. Их смешивание — частая причина трудно диагностируемых ошибок подключения:

ГруппаПеременныеЧто управляет
Подключение к базе данных ClickHouseCLICKHOUSE_HOST, CLICKHOUSE_PORT, CLICKHOUSE_SECURE, CLICKHOUSE_VERIFY, переменные сертификатовКак этот MCP-сервер подключается к вашему кластеру ClickHouse через HTTP-интерфейс
MCP-сервер / транспортCLICKHOUSE_MCP_*, FASTMCP_SERVER_AUTH, FASTMCP_SERVER_AUTH_*, FASTMCP_ENV_FILEMCP-транспорт, аутентификация и ограничения выполнения инструментов запросов
Промежуточное ПО / chDBMCP_MIDDLEWARE_MODULE, CHDB_*Необязательные расширения

[!IMPORTANT] CLICKHOUSE_SECURE, CLICKHOUSE_VERIFY, CLICKHOUSE_CA_CERT, CLICKHOUSE_CLIENT_CERT, CLICKHOUSE_CLIENT_CERT_KEY, CLICKHOUSE_TLS_MODE и CLICKHOUSE_PORT применяются только к исходящему подключению к базе данных ClickHouse. Они не настраивают TLS, клиентские сертификаты, порты или аутентификацию для входящей MCP HTTP/SSE конечной точки.

Пример: если MCP-сервер работает в Kubernetes за ingress, который завершает TLS, это вопрос MCP-транспорта. Держите CLICKHOUSE_SECURE согласованным с тем, как под достигает самого ClickHouse (HTTPS → true, обычный HTTP → false). Установка CLICKHOUSE_SECURE=false из-за того, что MCP-сервер находится за ingress, заставит сервер подключаться к ClickHouse по HTTP — часто к порту, поддерживающему только HTTPS — и приведет к непонятным ошибкам HTTP/TLS в журналах сервера.

Подключение к базе данных ClickHouse

Эти переменные настраивают HTTP-клиент clickhouse-connect и поведение инструментов на базе ClickHouse, таких как run_query, list_databases и list_tables. mcp-clickhouse требует clickhouse-connect 1.x, начиная с версии 1.0.0.

Обязательные переменные
  • CLICKHOUSE_HOST: Имя хоста вашего сервера ClickHouse (конечная точка базы данных, а не адрес привязки MCP-сервера)
  • CLICKHOUSE_USER: Имя пользователя для аутентификации ClickHouse
  • CLICKHOUSE_PASSWORD: Пароль для аутентификации ClickHouse
    • Обязателен, если только CLICKHOUSE_CLIENT_CERT не использует значение по умолчанию или режим TLS "mutual"
    • В режиме по умолчанию или "mutual" используется аутентификация по сертификату, и пароль не отправляется

[!CAUTION] Важно относиться к пользователю MCP-базы данных так же, как к любому внешнему клиенту, подключающемуся к вашей базе данных, предоставляя только минимально необходимые привилегии для его работы. Использование пользователей по умолчанию или административных пользователей должно строго избегаться в любое время.

Необязательные переменные
  • CLICKHOUSE_PORT: Порт HTTP-интерфейса вашего сервера ClickHouse
    • По умолчанию: 8443, если CLICKHOUSE_SECURE=true, 8123, если CLICKHOUSE_SECURE=false
    • Обычно не требует установки, если не используется нестандартный порт
    • Должен быть портом HTTP-интерфейса, а не портом нативного TCP-протокола, используемого clickhouse-client
    • Часто используемые значения:
      • HTTP: 8123 (обычный) / 8443 (TLS) — используется этим сервером и ClickHouse Cloud HTTPS
      • Нативный TCP (не поддерживается здесь): 9000 (обычный) / 9440 (TLS) — используется clickhouse-client
    • Если сервер отвечает Port 9000 is for clickhouse-client program, вы указали на нативный протокол; переключитесь на HTTP-порт (8123/8443 или HTTP-сопоставление вашего развертывания)
  • CLICKHOUSE_ROLE: Роль ClickHouse для аутентификации
    • По умолчанию: нет
    • Установите, если вашему пользователю требуется конкретная роль
  • CLICKHOUSE_SECURE: Включение HTTPS для подключения к базе данных ClickHouse (не для MCP-клиентов)
    • По умолчанию: "true"
    • Установите "false" только когда MCP-сервер достигает ClickHouse по обычному HTTP (типично для локального Docker Compose на порту 8123)
    • Оставьте "true" для ClickHouse Cloud и любой HTTPS-конечной точки базы данных — даже если сам MCP-сервер доступен через HTTP, stdio или ingress, завершающий TLS отдельно
    • Несоответствие этого флага порту базы данных (например, CLICKHOUSE_SECURE=false против порта 8443) — частая ошибка настройки, которая обычно проявляется как запутанные ошибки HTTP-клиента, а не четкое сообщение «неверная схема»
  • CLICKHOUSE_VERIFY: Включение/отключение проверки SSL-сертификатов для HTTPS-подключения ClickHouse
    • По умолчанию: "true"
    • Установите "false" для отключения проверки сертификатов (не рекомендуется для продакшена)
    • TLS-сертификаты: пакет использует хранилище доверия операционной системы через truststore.inject_into_ssl() при запуске. Обработка SSL по умолчанию Python используется, если внедрение отключено с помощью MCP_CLICKHOUSE_TRUSTSTORE_DISABLE=1 или не удается.
  • MCP_CLICKHOUSE_TRUSTSTORE_DISABLE: Отключение интеграции общесистемного хранилища доверия операционной системы для TLS
    • По умолчанию: не задано (интеграция хранилища доверия включена)
    • Установите точно "1" перед запуском, чтобы пропустить truststore.inject_into_ssl() и использовать стандартную обработку SSL-сертификатов Python. Другие значения не отключают интеграцию.
    • Это не отключает проверку сертификатов. CLICKHOUSE_VERIFY по-прежнему управляет проверкой для HTTPS-подключения ClickHouse.
  • CLICKHOUSE_CA_CERT: Путь к пакету PEM CA-сертификатов для HTTPS-подключения ClickHouse
    • По умолчанию: нет (используется хранилище доверия операционной системы, если внедрение хранилища доверия не отключено или не удается)
    • Используйте это отдельно, когда сервер ClickHouse или частный прокси представляет сертификат, подписанный частным CA. Это изменяет проверку сертификата сервера и не включает аутентификацию по клиентскому сертификату.
    • Требует CLICKHOUSE_SECURE=true и CLICKHOUSE_VERIFY=true
  • CLICKHOUSE_CLIENT_CERT: Путь к PEM-клиентскому сертификату для HTTPS-подключения ClickHouse
    • По умолчанию: нет
    • Файл также может содержать закрытый ключ. В противном случае установите CLICKHOUSE_CLIENT_CERT_KEY.
    • Пользователь ClickHouse по-прежнему берется из CLICKHOUSE_USER.
  • CLICKHOUSE_CLIENT_CERT_KEY: Путь к PEM-закрытому ключу для CLICKHOUSE_CLIENT_CERT
    • По умолчанию: нет
    • Необязателен, когда закрытый ключ включен в файл клиентского сертификата
    • Не может использоваться без CLICKHOUSE_CLIENT_CERT
  • CLICKHOUSE_TLS_MODE: Как clickhouse-connect использует CLICKHOUSE_CLIENT_CERT
    • По умолчанию: нет, что ведет себя как "mutual", когда установлен клиентский сертификат
    • "mutual": Использовать клиентский сертификат для аутентификации пользователя ClickHouse X.509. CLICKHOUSE_PASSWORD необязателен и не отправляется.
    • "proxy": Представить клиентский сертификат TLS-завершающему прокси, затем использовать базовую аутентификацию ClickHouse. CLICKHOUSE_PASSWORD обязателен.
    • "strict": Представить клиентский сертификат, потому что сервер ClickHouse требует его на уровне TLS, затем использовать базовую аутентификацию ClickHouse. CLICKHOUSE_PASSWORD обязателен. Этот режим не усиливает проверку сертификата сервера. CLICKHOUSE_VERIFY управляет этой проверкой.
    • clickhouse-connect обрабатывает "proxy" и "strict" одинаково. Два имени документируют намерение.
    • Значения обрезаются и нечувствительны к регистру. Пустое значение рассматривается как не заданное. Другие значения отклоняются до создания клиента ClickHouse, при первом вызове инструмента ClickHouse или проверке /health.
    • Требует CLICKHOUSE_CLIENT_CERT. Все опции клиентского сертификата требуют CLICKHOUSE_SECURE=true.
  • CLICKHOUSE_SERVER_HOST_NAME: Имя хоста сервера для переопределения SNI и проверки сертификата на подключении ClickHouse
    • По умолчанию: нет (используется имя хоста подключения)
    • Полезно при подключении через прокси или балансировщики нагрузки, где имя хоста сертификата отличается от имени хоста подключения. При установке это имя хоста будет использоваться как для SNI (Server Name Indication) во время TLS-рукопожатия, так и для проверки имени хоста сертификата.
  • CLICKHOUSE_PROXY_PATH: Префикс пути URL для HTTP-конечной точки ClickHouse
    • По умолчанию: нет
    • Установите, когда HTTP-интерфейс ClickHouse доступен за обратным прокси с префиксом пути (например, /clickhouse)
  • CLICKHOUSE_CONNECT_TIMEOUT: Таймаут подключения в секундах для клиента ClickHouse
    • По умолчанию: "30"
    • Увеличьте это значение, если возникают таймауты подключения
  • CLICKHOUSE_SEND_RECEIVE_TIMEOUT: Таймаут отправки/получения в секундах для клиента ClickHouse
    • По умолчанию: меньшее из 300 или CLICKHOUSE_MCP_QUERY_TIMEOUT + 5, чтобы рабочие потоки разблокировались вскоре после таймаута запроса
    • Если задано явно, значение используется как есть (например, "300" для длительных запросов)
  • CLICKHOUSE_DATABASE: База данных ClickHouse по умолчанию
    • По умолчанию: нет (используется серверная база данных по умолчанию)
    • Установите для автоматического подключения к конкретной базе данных
  • CLICKHOUSE_ENABLED: Включение/отключение инструментов базы данных ClickHouse
    • По умолчанию: "true"
    • Установите "false" для отключения инструментов ClickHouse при использовании только chDB
  • CLICKHOUSE_ALLOW_WRITE_ACCESS: Разрешение операций записи (DDL и DML) против ClickHouse
    • По умолчанию: "false"
    • Установите "true" для разрешения неразрушающих DDL и DML (CREATE, INSERT, ALTER ADD COLUMN). Разрушающие операторы дополнительно требуют CLICKHOUSE_ALLOW_DROP=true
    • При отключении (по умолчанию) запросы выполняются с настройкой readonly=1 для предотвращения изменений данных
  • CLICKHOUSE_ALLOW_DROP: Разрешение разрушающих операций (любой DROP или TRUNCATE, DELETE и UPDATE включая варианты ALTER TABLE, REPLACE TABLE / REPLACE PARTITION / CREATE OR REPLACE, CLEAR COLUMN / CLEAR INDEX / CLEAR PROJECTION и DETACH ... PERMANENTLY)
    • По умолчанию: "false"
    • Действует только когда также установлен CLICKHOUSE_ALLOW_WRITE_ACCESS=true
    • Этот барьер — защита от случайностей на уровне MCP-сервера, а не граница безопасности. Ограничьте гранты пользователя ClickHouse для реального контроля (см. Защита от разрушающих операций)
Файлы TLS-сертификатов ClickHouse

Переменные сертификатов содержат пути к файлам, а не содержимое PEM. mcp-clickhouse передает эти пути в clickhouse-connect. Для Docker или Kubernetes смонтируйте сертификат и закрытый ключ как файлы только для чтения и используйте их пути внутри контейнера. Не встраивайте закрытый ключ в образ, не коммитьте его в систему контроля версий и не помещайте его содержимое в переменную окружения.

В режиме mutual настроенный клиентский сертификат идентифицирует этот процесс mcp-clickhouse как CLICKHOUSE_USER. Он не аутентифицирует входящих MCP-клиентов и не передает их личности в ClickHouse. Настройте аутентификацию MCP-транспорта отдельно.

Перезапустите mcp-clickhouse после замены сертификата или ключа по тому же пути, если требуется немедленная ротация или отзыв. Кэшированные клиенты могут сохранять существующие TLS-подключения, а кэш не отслеживает содержимое файлов или время их изменения.

ClickHouse Cloud не поддерживает аутентификацию по клиентскому сертификату X.509 для пользователей базы данных. Используйте CLICKHOUSE_USER и CLICKHOUSE_PASSWORD для ClickHouse Cloud. CA-сертификат может по-прежнему быть полезен, когда частный прокси перед конечной точкой представляет сертификат, подписанный частным CA.

MCP-сервер и транспорт

Эти переменные управляют самим процессом MCP, включая транспорт, аутентификацию и ограничения выполнения инструментов запросов. Они независимы от настроек базы данных ClickHouse выше. См. также Аутентификация для HTTP/SSE транспортов.

  • CLICKHOUSE_MCP_SERVER_TRANSPORT: Задает метод транспорта для MCP-сервера
    • По умолчанию: "stdio"
    • Допустимые варианты: "stdio", "http", "sse". Это полезно для локальной разработки с такими инструментами, как MCP Inspector.
    • stdio типичен для Claude Desktop; http/sse открывают сетевой прослушиватель (адрес и порт привязки указаны ниже)
    • "sse" выбирает устаревший автономный транспорт HTTP+SSE и выводит предупреждение. Используйте "http" для Streamable HTTP в новых развертываниях.
  • CLICKHOUSE_MCP_BIND_HOST: Хост для привязки MCP-сервера при использовании транспорта HTTP или SSE
    • По умолчанию: "127.0.0.1"
    • Установите "0.0.0.0", чтобы привязаться ко всем сетевым интерфейсам (полезно для Docker или удаленного доступа)
    • Используется только когда транспорт — "http" или "sse" — не связано с CLICKHOUSE_HOST
  • CLICKHOUSE_MCP_BIND_PORT: Порт для привязки MCP-сервера при использовании транспорта HTTP или SSE
    • По умолчанию: "8000"
    • Используется только когда транспорт — "http" или "sse" — не связано с CLICKHOUSE_PORT
  • CLICKHOUSE_MCP_QUERY_TIMEOUT: Тайм-аут в секундах для вызовов инструментов запросов
    • По умолчанию: "30"
    • Увеличьте это значение, если вы видите ошибки Query timed out after ... для тяжелых запросов
    • Когда запрос превышает тайм-аут, сервер пытается отменить его с помощью KILL QUERY
    • Если CLICKHOUSE_SEND_RECEIVE_TIMEOUT явно не задан, тайм-аут чтения HTTP ограничен этим значением плюс пять секунд
  • CLICKHOUSE_MCP_MAX_WORKERS: Максимальное количество одновременных рабочих потоков запросов
    • По умолчанию: "10"
    • Увеличьте, если ваша рабочая нагрузка требует множества одновременных вызовов инструментов
    • Инструменты метаданных используют отдельный пул с min(4, CLICKHOUSE_MCP_MAX_WORKERS) потоками, поэтому обнаружение схемы не может задерживать запросы
  • CLICKHOUSE_MCP_AUTH_TOKEN: Статический bearer-токен для транспортов HTTP/SSE
    • По умолчанию: нет
    • Один из CLICKHOUSE_MCP_AUTH_TOKEN, FASTMCP_SERVER_AUTH или CLICKHOUSE_MCP_AUTH_DISABLED=true обязателен для транспортов HTTP/SSE
    • Сгенерируйте с помощью uuidgen или openssl rand -hex 32
    • Клиенты должны отправлять этот токен в заголовке Authorization: Bearer <token>
  • FASTMCP_SERVER_AUTH: Делегирование аутентификации провайдеру аутентификации FastMCP
    • По умолчанию: нет
    • Значение — это полный путь к классу подкласса AuthProvider, например fastmcp.server.auth.providers.azure.AzureProvider или fastmcp.server.auth.providers.google.GoogleProvider
    • При установке mcp-clickhouse загружает провайдера из существующих переменных окружения FASTMCP_SERVER_AUTH_*; оставьте CLICKHOUSE_MCP_AUTH_TOKEN неустановленным в этом режиме
    • Пользовательские провайдеры не получают аргументов конструктора из окружения и должны поддерживать конструкцию без аргументов
    • FastMCP 4 больше не поддерживает проверку Supabase HS256. Развертывания Supabase должны использовать RS256 или ES256.
  • FASTMCP_ENV_FILE: Необязательный файл, содержащий FASTMCP_SERVER_AUTH и переменные окружения, специфичные для провайдера
    • По умолчанию: нет. Если не задан, загрузчик совместимости читает отсутствующие поля провайдера из .env в рабочем каталоге. Он не читает FASTMCP_SERVER_AUTH из этого резервного варианта
    • Установите его в окружении процесса перед запуском. Значение, загруженное из стандартного .env, не может перенаправить загрузчик совместимости
    • Если задан в процессе, этот файл может предоставлять как FASTMCP_SERVER_AUTH, так и поля провайдера и заменяет резервный вариант рабочего каталога
    • Значения окружения процесса имеют приоритет без учета регистра
    • Загрузчик совместимости mcp-clickhouse читает этот файл только при построении аутентификации HTTP/SSE и читает только записи FASTMCP_SERVER_AUTH и FASTMCP_SERVER_AUTH_*. FastMCP 4 может читать тот же файл для своих более широких настроек
    • Загрузка стандартного .env выполняется отдельно. Она начинается в установленном каталоге пакета mcp_clickhouse, разрешает символические ссылки, поднимается вверх к корню файловой системы и загружает первый найденный .env или ничего. Она никогда не читает рабочий каталог, независимо от способа запуска. Этот файл может предоставлять FASTMCP_SERVER_AUTH и поля провайдера вместе с другими настройками сервера. Проверка исходного кода обычно находит .env в корне репозитория
  • CLICKHOUSE_MCP_AUTH_DISABLED: Отключение аутентификации для транспортов HTTP/SSE
    • По умолчанию: "false" (аутентификация включена)
    • Установите "true", чтобы отключить аутентификацию только для локальной разработки/тестирования
    • ПРЕДУПРЕЖДЕНИЕ: Используйте только для локальной разработки. Не отключайте при доступе из сети
  • CLICKHOUSE_MCP_ALLOWED_HOSTS: Разделенные запятыми значения заголовка Host, на которые отвечает сервер HTTP/SSE
    • По умолчанию для привязки к loopback: голые и любые портовые формы 127.0.0.1, localhost и [::1]
    • Если задано, значение должно содержать как минимум одну запись Host.
    • Конкретный не-loopback адрес привязки по умолчанию соответствует этому адресу и настроенному порту. Привязка с подстановочным знаком, такая как 0.0.0.0 или ::, требует явного непустого значения, поскольку публичный Host не может быть выведен.
    • Проверка Host — это защита в глубину от DNS-ребinding. Проверка Origin ниже требуется отдельно MCP.
    • Записи точные (localhost:8000) или принимают любой порт (localhost:*). Пример: CLICKHOUSE_MCP_ALLOWED_HOSTS=127.0.0.1:8000,localhost:8000
    • Форма host:* соответствует только значениям с портом. Host без порта (развертывание со стандартным портом, где клиент опускает :80/:443) должен быть указан как отдельная точная запись (example.com).
    • Запросы с несовпадающим или отсутствующим заголовком Host получают 421 Misdirected Request. GET и HEAD запросы к /health освобождаются от проверки Host и Origin, чтобы проверки оркестратора продолжали работать.
    • За обратным прокси предпочтительно сохранять исходный заголовок Host. Вместо этого можно указать значение Host, которое отправляет прокси. Установите явный список, когда такой лаунчер, как fastmcp run, переопределяет адрес привязки для удаленного доступа.
    • mcp-clickhouse принудительно отключает отдельную защиту Host и Origin FastMCP. FASTMCP_HTTP_HOST_ORIGIN_PROTECTION, FASTMCP_HTTP_ALLOWED_HOSTS и FASTMCP_HTTP_ALLOWED_ORIGINS не применяются. CLICKHOUSE_MCP_ALLOWED_HOSTS и CLICKHOUSE_MCP_ALLOWED_ORIGINS являются авторитетными.
  • CLICKHOUSE_MCP_TRUSTED_PROXIES: IP-адреса прокси или CIDR-сети, чьи заголовки X-Forwarded-* доверены
    • По умолчанию: нет. X-Forwarded-Host игнорируется. Существующая обработка Uvicorn для X-Forwarded-For и X-Forwarded-Proto не изменяется.
    • Записи должны быть IP-адресами или CIDR-сетями, например 127.0.0.1,10.20.0.0/24,2001:db8::1. CIDR должны использовать сетевой адрес, поэтому 10.20.0.1/24 отклоняется. Имена хостов, IPv6-адреса с областью, *, 0.0.0.0/0 и ::/0 также отклоняются.
    • Доверие основано на непосредственном сыром peer сокета. Запрос от любого другого peer или запрос без адреса клиента игнорирует X-Forwarded-Host и проверяет Host.
    • Доверенный peer может отправить ровно один заголовок X-Forwarded-Host, содержащий одно непустое значение. Дублирующиеся поля, пустые значения и списки, разделенные запятыми, получают 421 Misdirected Request. Если заголовок отсутствует, проверяется Host.
    • Используйте максимально узкий адрес или сеть. MCP-сервер должен быть доступен только через прокси в настроенных диапазонах. Каждый доверенный прокси должен удалять и перезаписывать значения X-Forwarded-Host и X-Forwarded-Proto, предоставленные клиентом, и строить X-Forwarded-For из проверенного peer соединения.
    • Встроенный сервер и fastmcp run отключают внешнюю обработку прокси-заголовков Uvicorn, проверяют Host от сырого peer, затем применяют X-Forwarded-For и X-Forwarded-Proto. Явное включение uvicorn_config["proxy_headers"] приводит к сбою запуска в этом режиме.
    • Прямое встраивание ASGI должно отключать обработку прокси-заголовков во внешнем ASGI-сервере и вызывать mcp.http_app(raw_client_address_preserved=True). Без этого явного утверждения построение приложения завершается ошибкой при настройке доверенных прокси.
  • CLICKHOUSE_MCP_ALLOWED_ORIGINS: Разделенные запятыми значения заголовка Origin, принимаемые на HTTP/SSE
    • По умолчанию: нет, что отклоняет каждый запрос с заголовком Origin
    • MCP требует проверки Origin для соединений транспорта HTTP/SSE. Запросы без Origin принимаются, поскольку не-браузерные MCP-клиенты обычно его опускают. Несовпадающий Origin получает 403 Forbidden. Конечная точка /health освобождена, как описано выше.
    • Записи точные (http://localhost:3000) или принимают любой порт (http://localhost:*). Как и с хостами, форма с любым портом соответствует только origin с портом; origin со стандартным портом (https://app.example.com) должен быть указан точно.
Обработка Host за обратным прокси

Сохраняйте Host, когда это возможно. Это сохраняет доверие к forwarded Host отключенным:

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;
}

Очищайте X-Forwarded-For и X-Forwarded-Proto независимо от доверия X-Forwarded-Host. Uvicorn может доверять этим заголовкам на основе peer прокси, даже когда CLICKHOUSE_MCP_TRUSTED_PROXIES не задан.

CLICKHOUSE_MCP_ALLOWED_HOSTS=mcp.example.com

Стандартный nginx изменяет Host на имя upstream для проксируемых запросов. Он не создает и не перезаписывает X-Forwarded-Host. Если сохранение Host невозможно, перезапишите forwarded-заголовок на доверенном краю:

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

Вторая конфигурация безопасна только когда 10.20.0.8 — непосредственный исходный адрес прокси, порт сервера изолирован от других клиентов, и nginx перезаписывает входящие forwarding-заголовки, как показано. Для цепочки прокси каждый доверенный хоп должен отбрасывать непроверенные входящие значения перед построением новых forwarding-заголовков.

При привязке IPv6 или dual-stack IPv4-прокси могут появляться как IPv4-mapped адреса, например ::ffff:10.20.0.8; они автоматически сопоставляются с IPv4-записями. append_x_forwarded_host Envoy добавляет к существующему X-Forwarded-Host, а не перезаписывает его, создавая список, разделенный запятыми, который отклоняется, поэтому настройте доверенный хоп на перезапись заголовка. В Kubernetes с source NAT (например, externalTrafficPolicy: Cluster) наблюдаемый peer может быть IP-адресом узла, а не pod прокси, поэтому доверяйте pod или CIDR узла по мере необходимости; ingress-nginx перезаписывает и Host, и X-Forwarded-Host сам.

Переменные Middleware

  • MCP_MIDDLEWARE_MODULE: Имя Python-модуля, содержащего пользовательский middleware для внедрения в MCP-сервер
    • По умолчанию: нет (middleware не загружается)
    • Установите имя модуля (без расширения .py) вашего модуля middleware
    • Модуль должен предоставлять функцию setup_middleware(mcp)
    • См. Пользовательский Middleware для деталей и примеров

Переменные chDB

  • CHDB_ENABLED: Включение/отключение функциональности chDB
    • По умолчанию: "false"
    • Установите "true", чтобы включить инструменты chDB
    • Требует установки дополнительного пакета: mcp-clickhouse[chdb]
  • CHDB_DATA_PATH: Путь к каталогу данных chDB
    • По умолчанию: ":memory:" (база данных в памяти)
    • Используйте :memory: для базы данных в памяти
    • Используйте путь к файлу для постоянного хранения (например, /path/to/chdb/data)

Частые ошибки конфигурации

  • CLICKHOUSE_SECURE против MCP / ingress TLS — Отключение CLICKHOUSE_SECURE потому, что MCP-сервер находится за Kubernetes ingress, обратным прокси или доступен по обычному HTTP, не отключает TLS базы данных; это только меняет способ подключения этого процесса к ClickHouse. Настройте ingress TLS отдельно от настроек клиента базы данных.
  • Порты нативного протоколаCLICKHOUSE_PORT должен указывать на HTTP-интерфейс ClickHouse (8123/8443 по умолчанию). Порты 9000/9440 предназначены для нативного TCP-протокола (clickhouse-client) и не будут работать с этим сервером.
  • Путаница с хостамиCLICKHOUSE_HOST — это имя хоста базы данных. CLICKHOUSE_MCP_BIND_HOST — это только адрес, на котором прослушивает MCP HTTP/SSE-сервер.

Примеры конфигураций

Для локальной разработки с 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

Для 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

Для ClickHouse SQL Playground:

CLICKHOUSE_HOST=sql-clickhouse.clickhouse.com
CLICKHOUSE_USER=demo
CLICKHOUSE_PASSWORD=
# Uses secure defaults (HTTPS on port 8443)

Для частного CA сервера без аутентификации клиентского сертификата:

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

Для аутентификации клиентского сертификата X.509 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.

Для клиентского сертификата, требуемого строгим TLS-сервером, пока ClickHouse использует базовую аутентификацию:

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

Используйте CLICKHOUSE_TLS_MODE=proxy вместо этого, когда прокси с завершением TLS требует клиентский сертификат, а ClickHouse всё ещё использует базовую аутентификацию.

Только для chDB (в памяти):

# chDB configuration
CHDB_ENABLED=true
CLICKHOUSE_ENABLED=false
# CHDB_DATA_PATH defaults to :memory:

Для chDB с постоянным хранилищем:

# chDB configuration
CHDB_ENABLED=true
CLICKHOUSE_ENABLED=false
CHDB_DATA_PATH=/path/to/chdb/data

Для MCP Inspector или удалённого доступа с 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

Для локальной разработки с HTTP-транспортом (аутентификация отключена):

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

При использовании HTTP-транспорта сервер будет работать на настроенном порту (по умолчанию 8000). Например, с приведённой выше конфигурацией:

  • MCP-эндпоинт: http://localhost:8000/mcp
  • Проверка состояния: http://localhost:8000/health

Вы можете задать эти переменные в своём окружении, в файле .env или в конфигурации 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"
      }
    }
  }
}

Примечание: Настройки адреса и порта привязки используются только когда для транспорта задано значение "http" или "sse".

Запуск тестов

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

Обзор YouTube

YouTube