Skip to main content
Glama
clickhouse-mcp-server

clickhouse-mcp-server

by reiple

clickhouse-mcp-server

ClickHouse에 읽기 전용으로 접근하는 MCP(Model Context Protocol) 서버입니다. Python MCP SDK(mcp[cli])와 clickhouse-connect로 구현했습니다.

프로젝트 구조

.
├── pyproject.toml
├── README.md
└── src/clickhouse_mcp_server/
    ├── __init__.py
    └── server.py        # FastMCP 서버 본체, 도구 4개 정의

Related MCP server: clickhouse-mcp-server

제공 도구

도구

설명

list_databases()

서버의 모든 데이터베이스 목록 조회

list_tables(database?)

데이터베이스 내 테이블 목록, 엔진, row 수 조회 (미지정 시 기본 DB)

describe_table(table, database?)

테이블 컬럼 스키마(이름/타입/기본값/코멘트 등) 조회

run_select_query(query, max_rows?)

SELECT/SHOW/DESCRIBE 등 읽기 전용 쿼리 실행

run_select_query는 {"columns": [...], "rows": [...], "row_count": N, "truncated": bool} 형태로 반환합니다. max_rows(기본 1000, 최대 10000)를 넘는 결과는 잘리고 truncated: true로 표시됩니다.

읽기 전용 보장 (2단계)

  1. 정규식 사전 차단: 쿼리 문자열 시작 부분이 INSERT/UPDATE/DELETE/ALTER/CREATE/DROP/TRUNCATE/RENAME/GRANT/REVOKE/OPTIMIZE/ATTACH/DETACH/KILL/SYSTEM 등으로 시작하면 ClickHouse에 보내기 전에 ValueError로 즉시 거부합니다.

  2. 서버 측 readonly 모드: ClickHouse 커넥션 자체를 readonly=2 설정으로 엽니다. readonly=1이 아니라 2를 쓰는 이유는, 1은 세션 설정 변경 자체를 막아버려서 max_result_rows(행 수 캡)도 함께 무시되는 문제가 있었기 때문입니다(아래 "테스트 중 발견한 버그" 참고). readonly=2는 쓰기는 그대로 막으면서 설정 변경만 허용합니다.

행 수 캡은 서버 설정(max_result_rows/result_overflow_mode=break)만으로는 정확하지 않을 수 있어(ClickHouse가 블록 단위로만 자르기 때문에, 결과가 작아서 한 블록에 다 들어가면 캡이 적용되지 않음), 반환 직전에 클라이언트 코드에서도 max_rows만큼 다시 슬라이싱해서 정확한 상한을 보장합니다.

설치

uv venv .venv
uv pip install -e .

환경 변수

변수

기본값

설명

CLICKHOUSE_HOST

localhost

ClickHouse 호스트

CLICKHOUSE_PORT

8123

HTTP 포트

CLICKHOUSE_USER

default

사용자명

CLICKHOUSE_PASSWORD

(빈 값)

비밀번호

CLICKHOUSE_DATABASE

default

기본 데이터베이스

CLICKHOUSE_SECURE

false

true면 HTTPS 사용 (보통 포트 8443)

사용 방법

1. Claude Code에 등록

claude mcp add clickhouse \
  --env CLICKHOUSE_HOST=your-host \
  --env CLICKHOUSE_PORT=8123 \
  --env CLICKHOUSE_USER=default \
  --env CLICKHOUSE_PASSWORD=your-password \
  --env CLICKHOUSE_DATABASE=default \
  -- /home/trsprs/workspace/claude/test1/.venv/bin/python -m clickhouse_mcp_server.server

또는 ~/.claude.json / 프로젝트 .mcp.json에 직접 추가:

{
  "mcpServers": {
    "clickhouse": {
      "command": "/home/trsprs/workspace/claude/test1/.venv/bin/python",
      "args": ["-m", "clickhouse_mcp_server.server"],
      "env": {
        "CLICKHOUSE_HOST": "your-host",
        "CLICKHOUSE_PORT": "8123",
        "CLICKHOUSE_USER": "default",
        "CLICKHOUSE_PASSWORD": "your-password",
        "CLICKHOUSE_DATABASE": "default"
      }
    }
  }
}

등록 후 Claude Code에서 "clickhouse의 테이블 목록 보여줘" 같은 요청을 하면 위 도구들이 자동으로 호출됩니다.

2. MCP Inspector로 직접 확인

Node.js가 있으면 브라우저 UI로 도구 목록/호출을 직접 테스트할 수 있습니다.

CLICKHOUSE_HOST=your-host CLICKHOUSE_USER=default CLICKHOUSE_PASSWORD=your-password \
  .venv/bin/mcp dev src/clickhouse_mcp_server/server.py

3. 로컬 Docker ClickHouse로 임시 테스트

실제 ClickHouse가 없어도 아래처럼 임시 컨테이너를 띄워 전체 흐름을 검증할 수 있습니다 (이 저장소를 개발할 때 실제로 이렇게 검증했습니다).

# 1) ClickHouse 컨테이너 실행
docker run -d --name clickhouse-mcp-test \
  -p 8123:8123 -p 9000:9000 \
  -e CLICKHOUSE_USER=default \
  -e CLICKHOUSE_PASSWORD=testpass \
  -e CLICKHOUSE_DB=default \
  clickhouse/clickhouse-server:latest

# 2) 준비될 때까지 대기
until curl -s http://localhost:8123/ping | grep -q Ok; do sleep 1; done

# 3) 샘플 테이블/데이터 생성
curl -s -u default:testpass "http://localhost:8123/" --data-binary "
CREATE TABLE default.events (
    id UInt64, event_name String, user_id UInt32, created_at DateTime
) ENGINE = MergeTree ORDER BY id;
INSERT INTO default.events VALUES
(1,'signup',101,'2026-07-01 10:00:00'),
(2,'login',101,'2026-07-01 10:05:00'),
(3,'purchase',102,'2026-07-02 14:30:00');
"

# 4) MCP 서버를 실제 stdio 프로토콜로 띄워 도구 호출 (파이썬 클라이언트 예시는 아래)
CLICKHOUSE_HOST=localhost CLICKHOUSE_PORT=8123 CLICKHOUSE_USER=default \
CLICKHOUSE_PASSWORD=testpass CLICKHOUSE_DATABASE=default \
  .venv/bin/python -m clickhouse_mcp_server.server

# 5) 테스트 끝나면 컨테이너 정리
docker rm -f clickhouse-mcp-test

4)번 대신 아래처럼 파이썬에서 MCP 클라이언트로 직접 붙여 전 도구를 검증할 수도 있습니다:

import asyncio, os
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client

async def main():
    params = StdioServerParameters(
        command=".venv/bin/python",
        args=["-m", "clickhouse_mcp_server.server"],
        env={**os.environ, "CLICKHOUSE_HOST": "localhost",
             "CLICKHOUSE_USER": "default", "CLICKHOUSE_PASSWORD": "testpass"},
    )
    async with stdio_client(params) as (read, write):
        async with ClientSession(read, write) as session:
            await session.initialize()
            print(await session.list_tools())
            print(await session.call_tool("list_tables", {}))

asyncio.run(main())

검증 이력

  • venv 설치 후 모듈 import, 도구 4개 등록 확인

  • 로컬 Docker ClickHouse(샘플 테이블 events, 5행)에 대해 4개 도구 전부를 실제 MCP stdio 프로토콜(클라이언트 세션)로 호출해 정상 응답 확인

  • DROP TABLE 등 쓰기 쿼리가 정규식 단계에서 즉시 차단됨을 확인

  • 버그 수정: run_select_query의 max_rows 캡이 작은 결과셋에서 적용되지 않던 문제를 발견 → readonly=2 + 클라이언트 측 슬라이싱으로 수정, 10만 행 쿼리에서도 정확히 캡되는 것을 재확인

Available Tools

4 tools
describe_tableB

Describe the columns of a table: name, type, default expression, comment.

Inputs: table (required), database. Returns: result

list_databasesA

List all databases available on the ClickHouse server.

Inputs: no named parameters. Returns: result

list_tablesA

List tables in a database (defaults to the connection's default database).

Returns table name, engine, and total row count for each table.

Inputs: database. Returns: result

run_select_queryA

Run a read-only SQL query (SELECT/SHOW/DESCRIBE/EXISTS/...) against ClickHouse.

Results are capped at max_rows (default 1000, hard cap 10000) and the response's "truncated" field reports whether rows were cut off. Data-modifying statements are rejected before reaching the server, and the connection is additionally opened in ClickHouse's server-side readonly mode as a second layer of enforcement.

Inputs: query (required), max_rows. Returns: object

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A4.1/5.0

    Scored across 4 tools

    Disambiguation5/5

    Each tool has a unique and clearly defined purpose. There is no overlap; an agent can easily distinguish between describing a table, listing databases, listing tables, and running arbitrary queries.

    Naming Consistency5/5

    All tool names follow a consistent verb_noun pattern (describe, list, list, run). The naming is predictable and intuitive.

    Tool Count5/5

    With four tools, the server is well-scoped for its read-only metadata and querying purpose. Each tool is essential and provides a distinct function without unnecessary bloat.

    Completeness4/5

    The tool set covers the core operations for inspecting a ClickHouse server's schema and executing queries. While some advanced metadata operations (e.g., listing table engines) are missing, the generic run_select_query tool can compensate for many gaps, making the surface reasonably complete.

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      B
      quality
      D
      maintenance
      An MCP server implementation that enables Claude AI to interact with Clickhouse databases. Features include secure database connections, query execution, read-only mode support, and multi-query capabilities.
      2
      23 PyPI
      2
      MIT
    • F
      license
      Not graded
      quality
      D
      maintenance
      MCP server for executing SQL queries on PostgreSQL and ClickHouse with per-connection allow/deny policies by statement group.
      -
    • F
      license
      Not graded
      quality
      C
      maintenance
      Minimal MCP server for read-only access to ClickHouse, enabling AI agents to explore schemas and execute SELECT queries safely.
      -