Skip to content

Commit 2d1de68

Browse files
committed
Boilerplate: Add software tests and CI configuration
1 parent bb70c07 commit 2d1de68

File tree

12 files changed

+395
-12
lines changed

12 files changed

+395
-12
lines changed

.github/dependabot.yml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# To get started with Dependabot version updates, you'll need to specify which
2+
# package ecosystems to update and where the package manifests are located.
3+
# Please see the documentation for all configuration options:
4+
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
5+
6+
version: 2
7+
updates:
8+
- package-ecosystem: "pip"
9+
directory: "/"
10+
schedule:
11+
interval: "daily"
12+
13+
- package-ecosystem: "github-actions"
14+
directory: "/"
15+
schedule:
16+
interval: "monthly"

.github/workflows/release-pypi.yml

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# Use Trusted Publishing to stage Python packages through GitHub Actions (GHA) to the Python Package Index (PyPI).
2+
name: "Release: Python package"
3+
4+
on:
5+
6+
# Build and publish packages when running a release.
7+
push:
8+
tags:
9+
- '*'
10+
11+
# Build packages on each pull request for validation purposes.
12+
pull_request:
13+
14+
# Build packages each night for validation purposes.
15+
schedule:
16+
- cron: '0 4 * * *'
17+
18+
# Allow the job to be triggered manually.
19+
workflow_dispatch:
20+
21+
jobs:
22+
build-and-publish:
23+
name: "Build and publish to PyPI"
24+
runs-on: ${{ matrix.os }}
25+
strategy:
26+
fail-fast: false
27+
matrix:
28+
os: ["ubuntu-latest"]
29+
python-version: ["3.13"]
30+
env:
31+
OS_TYPE: ${{ matrix.os }}
32+
PYTHON_VERSION: ${{ matrix.python-version }}
33+
34+
# Trusted publishing.
35+
# Specifying a GitHub environment is optional, but strongly encouraged.
36+
environment: pypi
37+
# IMPORTANT: This permission is mandatory for Trusted Publishing.
38+
permissions:
39+
id-token: write
40+
41+
steps:
42+
- name: Acquire sources
43+
uses: actions/checkout@v4
44+
45+
- name: Set up uv
46+
uses: astral-sh/setup-uv@v6
47+
with:
48+
cache-dependency-glob: |
49+
pyproject.toml
50+
cache-suffix: ${{ matrix.python-version }}
51+
enable-cache: true
52+
version: "latest"
53+
54+
- name: Build package
55+
run: |
56+
uv build
57+
58+
- name: Publish package to PyPI
59+
if: startsWith(github.event.ref, 'refs/tags')
60+
run: |
61+
uv publish

.github/workflows/tests.yml

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
name: "Tests"
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
pull_request:
7+
workflow_dispatch:
8+
9+
concurrency:
10+
group: ${{ github.workflow }}-${{ github.ref }}
11+
cancel-in-progress: true
12+
13+
jobs:
14+
15+
test:
16+
name: "
17+
Python ${{ matrix.python-version }}
18+
"
19+
runs-on: ${{ matrix.os }}
20+
strategy:
21+
fail-fast: false
22+
matrix:
23+
os: ['ubuntu-latest']
24+
python-version: [
25+
'3.9',
26+
'3.13',
27+
]
28+
cratedb-version: [
29+
'nightly',
30+
]
31+
32+
env:
33+
OS: ${{ matrix.os }}
34+
PYTHON: ${{ matrix.python-version }}
35+
UV_SYSTEM_PYTHON: true
36+
37+
services:
38+
cratedb:
39+
image: crate/crate:${{ matrix.cratedb-version }}
40+
ports:
41+
- 4200:4200
42+
- 5432:5432
43+
env:
44+
CRATE_HEAP_SIZE: 4g
45+
46+
steps:
47+
48+
- name: Acquire sources
49+
uses: actions/checkout@v4
50+
51+
- name: Set up Python
52+
uses: actions/setup-python@v5
53+
with:
54+
python-version: ${{ matrix.python-version }}
55+
56+
- name: Set up uv
57+
uses: astral-sh/setup-uv@v6
58+
with:
59+
cache-dependency-glob: |
60+
pyproject.toml
61+
cache-suffix: ${{ matrix.python-version }}
62+
enable-cache: true
63+
version: "latest"
64+
65+
- name: Set up project
66+
run: |
67+
uv pip install --editable='.[all,develop,test]'
68+
69+
- name: Run linter and software tests
70+
run: poe check
71+
72+
# https://github.com/codecov/codecov-action
73+
- name: Upload coverage results to Codecov
74+
uses: codecov/codecov-action@v5
75+
env:
76+
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
77+
with:
78+
env_vars: OS,PYTHON
79+
fail_ci_if_error: true

CHANGES.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# CrateDB MCP changelog
2+
3+
## Unreleased
4+
5+
## v0.0.1 - 2025-05-xx
6+
- Project: Established project layout
7+
- Features: First working version
8+
- Packaging: Adjusted package dependencies for interoperability
9+
- Packaging: Added basic CLI entry point and server launcher `cratedb-mcp`
10+
- Documentation: Show a simple Claude Desktop configuration
11+
- MCP documentation: Add reference to medium-sized llms.txt context file
12+
- Boilerplate: Added software tests and CI configuration

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
[![Bluesky][badge-bluesky]][target-bluesky]
44
[![Status][badge-status]][target-project]
55
[![License][badge-license]][target-license]
6+
[![CI][badge-ci]][project-ci]
7+
[![Coverage][badge-coverage]][project-coverage]
68

79
» [Documentation]
810
| [Releases]
@@ -99,11 +101,15 @@ omit the `uv run` prefix displayed above.
99101
[Source code]: https://github.com/crate/cratedb-mcp
100102
[Releases]: https://github.com/surister/cratedb-mcp/releases
101103

104+
[badge-ci]: https://github.com/crate/cratedb-mcp/actions/workflows/tests.yml/badge.svg
105+
[badge-coverage]: https://codecov.io/gh/crate/cratedb-mcp/branch/main/graph/badge.svg
102106
[badge-bluesky]: https://img.shields.io/badge/Bluesky-0285FF?logo=bluesky&logoColor=fff&label=Follow%20%40CrateDB
103107
[badge-issues]: https://img.shields.io/github/issues/crate/cratedb-mcp
104108
[badge-license]: https://img.shields.io/github/license/crate/cratedb-mcp
105109
[badge-release-notes]: https://img.shields.io/badge/Release%20Notes-v0.0.0-blue
106110
[badge-status]: https://img.shields.io/badge/status--alpha-orange
111+
[project-ci]: https://github.com/crate/cratedb-mcp/actions/workflows/tests.yml
112+
[project-coverage]: https://app.codecov.io/gh/crate/cratedb-mcp
107113
[target-bluesky]: https://bsky.app/search?q=cratedb
108114
[target-license]: https://github.com/crate/cratedb-mcp/blob/main/LICENSE
109115
[target-project]: https://github.com/crate/cratedb-mcp

cratedb_mcp/__main__.py

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,20 @@
1-
import os
2-
31
import httpx
4-
52
from mcp.server.fastmcp import FastMCP
63

7-
from .constants import Queries, DOCUMENTATION_INDEX
4+
from .constants import DOCUMENTATION_INDEX, Queries
5+
from .settings import HTTP_URL
86

97
mcp = FastMCP("cratedb-mcp")
108

119

1210
def query_cratedb(query: str) -> list[dict]:
13-
return httpx.post(f'{os.getenv("CRATEDB_MCP_HTTP_URL")}/_sql', json={'stmt': query}).json()
11+
return httpx.post(f'{HTTP_URL}/_sql', json={'stmt': query}).json()
1412

1513

1614
@mcp.tool(description="Send a SQL query to CrateDB, only 'SELECT' queries are allows, queries that"
1715
" modify data, columns or are otherwise deemed un-safe are rejected.")
1816
def query_sql(query: str):
19-
if not 'select' in query.lower():
17+
if 'select' not in query.lower():
2018
raise ValueError('Only queries that have a SELECT statement are allowed.')
2119
return query_cratedb(query)
2220

@@ -29,7 +27,7 @@ def get_cratedb_documentation_index():
2927
' Only used to download CrateDB docs.')
3028
def fetch_cratedb_docs(link: str):
3129
"""Fetches a CrateDB documentation link from GitHub raw content."""
32-
if not 'https://raw.githubusercontent.com/crate/crate/' in link:
30+
if 'https://raw.githubusercontent.com/crate/crate/' not in link:
3331
raise ValueError('Only github cratedb links can be fetched.')
3432
return httpx.get(link).text
3533

cratedb_mcp/cli.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,4 @@ def main():
1111
if transport not in ("stdio", "sse"):
1212
raise ValueError(f"Unsupported transport: '{transport}'. Please use one of 'stdio', 'sse'.")
1313
logger.info(f"Starting CrateDB MCP server using transport '{transport}'")
14-
mcp.run(transport=transport)
14+
mcp.run(transport=transport) # type: ignore[arg-type]

cratedb_mcp/constants.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
# ruff: noqa: E501
2+
13
class Queries:
24
TABLES_METADATA = """
35
WITH partitions_health AS (SELECT table_name,

cratedb_mcp/settings.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import os
2+
3+
HTTP_URL = os.getenv("CRATEDB_MCP_HTTP_URL", "http://localhost:4200")

0 commit comments

Comments
 (0)