Skip to content

feat: add MCP sso mode & docker compose deploy #46

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
### MCP server config
TRANSPORT=sse
PORT=8880

# CLICKHOUSE_HOST: clickhouse host
CLICKHOUSE_HOST=yourip

# CLICKHOUSE_USER: Username for authentication
CLICKHOUSE_USER=testdb

# CLICKHOUSE_PASSWORD: Password for authentication
CLICKHOUSE_PASSWORD=testdb

# Optional environment variables (with defaults)

# CLICKHOUSE_PORT: Port number
# Default: 8443 if HTTPS enabled, 8123 otherwise
# Only need to set when using non-standard port
CLICKHOUSE_PORT=8123


# CLICKHOUSE_DATABASE: Default database
# Default: None (uses server default)
# Set this to auto-connect to specific database
CLICKHOUSE_DATABASE=testdb

# CLICKHOUSE_SECURE: Enable/disable HTTPS connection
# Default: "true"
# Set to "false" for non-secure connections
CLICKHOUSE_SECURE=false

# CLICKHOUSE_VERIFY: Enable/disable SSL certificate verification
# Default: "true"
# Set to "false" to disable verification (not recommended for production)
CLICKHOUSE_VERIFY=false

# CLICKHOUSE_CONNECT_TIMEOUT: Connection timeout (seconds)
# Default: "30"
# Increase if experiencing connection timeouts
#CLICKHOUSE_CONNECT_TIMEOUT=30

# CLICKHOUSE_SEND_RECEIVE_TIMEOUT: Send/receive timeout (seconds)
# Default: "300"
# Increase for long-running queries
#CLICKHOUSE_SEND_RECEIVE_TIMEOUT=300

29 changes: 29 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
FROM python:3.13-slim AS base
WORKDIR /app

ENV CLICKHOUSE_HOST=localhost \
CLICKHOUSE_PORT=8123 \
CLICKHOUSE_USER=default \
CLICKHOUSE_PASSWORD= \
CLICKHOUSE_DATABASE=default \
CLICKHOUSE_SECURE=false \
CLICKHOUSE_VERIFY=true \
TRANSPORT=sse \
PORT=8000

FROM base AS builder
WORKDIR /app
# Install build dependencies
RUN apt-get update && apt-get install -y \
gcc \
libc6-dev \
&& rm -rf /var/lib/apt/lists/*
COPY . /app
RUN pip install -e .


FROM base AS production
COPY --from=builder /app /app
COPY --from=builder /usr/local/lib/python3.13/site-packages /usr/local/lib/python3.13/site-packages
ENTRYPOINT ["python", "-m", "mcp_clickhouse.main"]
CMD ["--transport", "sse", "--port", "8000"]
62 changes: 62 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# 帮助信息
.PHONY: help
help:
@echo "可用的命令:"
@echo "开发命令:"
@echo " install - 安装项目依赖"
@echo " dev - 启动本地开发服务器"
@echo " test - 运行测试"
@echo " lint - 运行代码检查"
@echo "Docker命令:"
@echo " docker-build - 构建Docker镜像"
@echo " docker-up - 启动Docker容器"
@echo " docker-down - 停止Docker容器"
@echo " test-services - 启动测试服务"
@echo "清理命令:"
@echo " clean - 清理临时文件和缓存"

# 开发相关命令
.PHONY: install dev test lint
install:
uv sync --all-extras --dev

# 启动本地开发服务器
dev:
export $(grep -v '^#' .env | xargs)
python -m mcp_clickhouse.main --transport sse --port 8000

# 运行测试
test: test-services
uv run pytest tests

# 代码检查
lint:
uv run ruff check .

# Docker相关命令
.PHONY: docker-build docker-up docker-down test-services
docker-build:
docker-compose build

docker-up:docker-down
docker-compose up

docker-down:
docker-compose down
docker-logs:
docker-compose logs

# 启动测试服务
test-services:
docker-compose -f test-services/docker-compose.yaml up -d

# 清理命令
.PHONY: clean
clean:
find . -type d -name "__pycache__" -exec rm -rf {} +
find . -type f -name "*.pyc" -delete
find . -type f -name "*.pyo" -delete
find . -type f -name "*.pyd" -delete
find . -type f -name ".coverage" -delete
find . -type d -name ".pytest_cache" -exec rm -rf {} +
find . -type d -name ".ruff_cache" -exec rm -rf {} +
23 changes: 22 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ An MCP server for ClickHouse.
* Input: `database` (string): The name of the database.

## Configuration

### stdio mode
1. Open the Claude Desktop configuration file located at:
* On macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
* On Windows: `%APPDATA%/Claude/claude_desktop_config.json`
Expand Down Expand Up @@ -94,6 +94,27 @@ Or, if you'd like to try it out with the [ClickHouse SQL Playground](https://sql

4. Restart Claude Desktop to apply the changes.

### sse mode
```sh
cp .env.example .env
```
you can change .env or set env in docker-compose.yml
build docker image
```sh
make docker-build
```
run docker-compose
```sh
make docker-up
```
```json
"mcpServers": {
"clickhouse-test": {
"url": "http://yourip:8000/sse",
},
}
```

## Development

1. In `test-services` directory run `docker compose up -d` to start the ClickHouse cluster.
Expand Down
15 changes: 15 additions & 0 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
version: '3.8'

services:
mcp-clickhouse:
container_name: mcp-clickhouse
image: mcp-clickhouse:latest
build:
context: .
dockerfile: Dockerfile
ports:
- "${PORT}:${PORT}"
env_file:
- .env
command:
["--transport", "${TRANSPORT}", "--port", "${PORT}"]
32 changes: 23 additions & 9 deletions mcp_clickhouse/main.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,23 @@
from .mcp_server import mcp


def main():
mcp.run()


if __name__ == "__main__":
main()
import click
from .mcp_server import mcp


@click.command()
@click.option(
"--transport",
type=click.Choice(["stdio", "sse"]),
default="stdio",
help="Transport type",
)
@click.option("--port", default=8000, help="Port to listen on for SSE")
def main(port: int, transport: str):
if transport == "sse":
mcp.port = port
mcp.run(transport=transport)
elif transport == "stdio":
mcp.run()


if __name__ == "__main__":
print("Starting MCP ClickHouse server")
main()
Loading