Skip to content

Commit e6ce859

Browse files
committed
Adjust MCP server to be run in SSE mode
1 parent 19b4e7d commit e6ce859

File tree

6 files changed

+127
-3
lines changed

6 files changed

+127
-3
lines changed

Dockerfile

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# Use a Python image with uv pre-installed
2+
FROM ghcr.io/astral-sh/uv:python3.13-bookworm-slim AS uv
3+
4+
# Install the project into `/app`
5+
WORKDIR /app
6+
7+
# Enable bytecode compilation
8+
ENV UV_COMPILE_BYTECODE=1
9+
10+
# Copy from the cache instead of linking since it's a mounted volume
11+
ENV UV_LINK_MODE=copy
12+
13+
RUN apt-get update && apt-get install -y --no-install-recommends \
14+
build-essential liblz4-dev libzstd-dev
15+
# Install the project's dependencies using the lockfile and settings
16+
RUN --mount=type=cache,target=/root/.cache/uv \
17+
--mount=type=bind,source=uv.lock,target=uv.lock \
18+
--mount=type=bind,source=pyproject.toml,target=pyproject.toml \
19+
uv sync --frozen --no-install-project --no-dev --no-editable
20+
21+
# Then, add the rest of the project source code and install it
22+
# Installing separately from its dependencies allows optimal layer caching
23+
ADD . /app
24+
RUN --mount=type=cache,target=/root/.cache/uv \
25+
uv sync --frozen --no-dev --no-editable
26+
27+
FROM python:3.13-slim-bookworm
28+
29+
WORKDIR /app
30+
# Copy the virtual environment
31+
COPY --from=uv --chown=app:app /app/.venv /app/.venv
32+
# Copy the uv executable
33+
COPY --from=uv /usr/local/bin/uv /usr/local/bin/
34+
# Copy the project files
35+
COPY --from=uv /app /app
36+
37+
# Place executables in the environment at the front of the path
38+
ENV PATH="/app/.venv/bin:/usr/local/bin:$PATH"
39+
40+
# Add ClickHouse environment variables
41+
ENV CLICKHOUSE_HOST=""
42+
ENV CLICKHOUSE_PORT="8443"
43+
ENV CLICKHOUSE_USER=""
44+
ENV CLICKHOUSE_PASSWORD=""
45+
ENV CLICKHOUSE_SECURE="true"
46+
ENV CLICKHOUSE_VERIFY="true"
47+
ENV CLICKHOUSE_CONNECT_TIMEOUT="30"
48+
ENV CLICKHOUSE_SEND_RECEIVE_TIMEOUT="300"
49+
ENV CLICKHOUSE_DATABASE=""
50+
51+
EXPOSE 28123
52+
# when running the container, add --db-path and a bind mount to the host's db file
53+
ENTRYPOINT ["uv", "run", "mcp-clickhouse-sse", "--directory", "/app"]

README.md

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,50 @@ You can set these variables in your environment, in a `.env` file, or in the Cla
210210
}
211211
```
212212

213+
## Running with Docker Compose
214+
215+
You can run the MCP server using Docker Compose with SSE mode. Create a `docker-compose.yml` file with the following configuration:
216+
217+
```yaml
218+
version: '3.8'
219+
services:
220+
mcp-clickhouse:
221+
build: .
222+
environment:
223+
- CLICKHOUSE_HOST=your-clickhouse-host
224+
- CLICKHOUSE_PORT=8443
225+
- CLICKHOUSE_USER=your-user
226+
- CLICKHOUSE_PASSWORD=your-password
227+
- CLICKHOUSE_DATABASE=your-database
228+
- CLICKHOUSE_SECURE=true
229+
- CLICKHOUSE_VERIFY=true
230+
ports:
231+
- "28123:28123"
232+
```
233+
234+
Then run:
235+
```bash
236+
docker compose up -d
237+
```
238+
239+
### MCP Configuration for Docker
240+
241+
When running the MCP server in Docker in SSE, you'll need to configure your MCP client to use `host.docker.internal` when running on the same machine. Update your MCP configuration to use the following URI:
242+
243+
```json
244+
{
245+
"mcpServers": {
246+
"mcp-clickhouse": {
247+
"type": "sse",
248+
"uri": "http://host.docker.internal:28123/sse",
249+
"timeout": 60000
250+
}
251+
}
252+
}
253+
```
254+
255+
If you're using Claude Desktop, add this configuration to your `claude_desktop_config.json` file along with the existing configuration.
256+
213257
### Running tests
214258

215259
```bash

docker-compose.yml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
version: '3.8'
2+
3+
services:
4+
mcp-clickhouse:
5+
build:
6+
context: .
7+
dockerfile: Dockerfile
8+
ports:
9+
- "28123:28123"
10+
environment:
11+
- CLICKHOUSE_HOST=sql-clickhouse.clickhouse.com
12+
- CLICKHOUSE_PORT=8443
13+
- CLICKHOUSE_USER=demo
14+
- CLICKHOUSE_PASSWORD=
15+
- CLICKHOUSE_SECURE=true
16+
- CLICKHOUSE_VERIFY=true
17+
- CLICKHOUSE_CONNECT_TIMEOUT=30
18+
- CLICKHOUSE_SEND_RECEIVE_TIMEOUT=30

mcp_clickhouse/main.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
1+
import asyncio
2+
import argparse
3+
14
from .mcp_server import mcp
25

36

47
def main():
58
mcp.run()
69

710

11+
def main_sse():
12+
mcp.run(transport="sse")
13+
14+
815
if __name__ == "__main__":
916
main()

mcp_clickhouse/mcp_server.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ class Table:
4646

4747

4848
MCP_SERVER_NAME = "mcp-clickhouse"
49+
SERVER_PORT = 28123
4950

5051
# Configure logging
5152
logging.basicConfig(
@@ -66,7 +67,7 @@ class Table:
6667
"pip-system-certs",
6768
]
6869

69-
mcp = FastMCP(MCP_SERVER_NAME, dependencies=deps)
70+
mcp = FastMCP(MCP_SERVER_NAME, dependencies=deps, port=SERVER_PORT)
7071

7172

7273
def result_to_table(query_columns, result) -> List[Table]:

pyproject.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "mcp-clickhouse"
3-
version = "0.1.7"
3+
version = "0.1.8"
44
description = "An MCP server for ClickHouse."
55
readme = "README.md"
66
license = "Apache-2.0"
@@ -10,13 +10,14 @@ dependencies = [
1010
"mcp[cli]>=1.3.0",
1111
"python-dotenv>=1.0.1",
1212
"uvicorn>=0.34.0",
13+
"uvicorn[standard]>=0.34.0",
1314
"clickhouse-connect>=0.8.16",
1415
"pip-system-certs>=4.0",
1516
]
1617

1718
[project.scripts]
1819
mcp-clickhouse = "mcp_clickhouse.main:main"
19-
20+
mcp-clickhouse-sse = "mcp_clickhouse.main:main_sse"
2021
[project.urls]
2122
Home = "https://github.com/ClickHouse/mcp-clickhouse"
2223

0 commit comments

Comments
 (0)