Skip to main content
Glama
mrsnurk32

cfm-dwh-mcp

by mrsnurk32
README.md
# cfm-dwh-mcp

Python MCP server for Coffeemania DWH: lets an LLM client query ClickHouse `analytics` tables (read-only).

Linear: **NIK-15** (scaffold), **NIK-16** (auth/guards), **NIK-17** (query tools), **NIK-26** (Docker).

Stack: Python 3.11+ / [FastMCP](https://gofastmcp.com/) / clickhouse-connect.

## Setup

```bash
python3.11 -m venv .venv
source .venv/bin/activate
pip install -e .
cp .env.example .env
# fill host, port, database, user, password
```

## Start / stop

MCP over stdio (Cursor / Claude Desktop / etc.):

```bash
cfm-dwh-mcp
# or: python -m cfm_dwh_mcp.server
# stop: Ctrl+C
```

Optional HTTP healthcheck:

```bash
cfm-dwh-mcp-health
curl -s http://127.0.0.1:8787/health
```

## Docker

Runs `cfm-dwh-mcp-health` (HTTP on 8787) against **existing** ClickHouse. This compose file does **not** start ClickHouse or Qwen.

```bash
cp .env.example .env
# fill host, port, database, user, password
# if ClickHouse is on the Docker host, use host=host.docker.internal (not localhost)

docker compose up --build
# logs should show: health listening on http://0.0.0.0:8787/health
curl -s http://127.0.0.1:8787/health

docker compose down
```

Credentials come from `.env` (`env_file` + read-only mount). They are not baked into the image.

Stdio MCP (`cfm-dwh-mcp`) is for a local MCP client, not the Compose service.

## Config

Loaded from `.env` (exact lowercase keys; `CLICKHOUSE_*` aliases also work). Never commit `.env`.

| Key | Meaning |
| --- | --- |
| `host` | ClickHouse host |
| `port` | HTTP port (usually `8123`) |
| `database` | default `analytics` |
| `user` | CH user |
| `password` | CH password |

## Allowlist (NIK-17)

- `analytics.f_kafka_mobile_events`
- `analytics.f_logistics`

## Verify

1. Fill `.env`
2. `cfm-dwh-mcp-health` then `curl -s http://127.0.0.1:8787/health`
3. Point your MCP client at `cfm-dwh-mcp`; tools should include `ping` and `list_allowed_tables`. `query_clickhouse` is a stub until NIK-17.

TDQS

A3.8/5.0

Scored across 3 tools

Disambiguation5/5

ping, list_allowed_tables, and query_clickhouse have clearly distinct purposes: health check, table discovery, and query execution. There is no overlap that would cause an agent to misselect.

Naming Consistency4/5

All names are lowercase snake_case and verb-led, giving a consistent style. ping is a standalone verb rather than a verb_noun pair, but this is a minor and conventional deviation for a health check.

Tool Count5/5

Three tools is small but well-scoped for a read-only ClickHouse gateway: connectivity check, allowlist discovery, and query execution. Each tool has a necessary and distinct role.

Completeness4/5

The core read-only workflow is covered: verify connectivity, list allowed tables, and run parameterized queries. The main gap is schema or column introspection, since list_allowed_tables exposes table names but not their structure.

Maintenance

ActivityMaintained
ResponsivenessResponsive