mcp-server-motherduck 0.6.4__tar.gz → 0.7.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mcp_server_motherduck-0.7.1/.bumpver.toml +19 -0
- mcp_server_motherduck-0.7.1/.github/workflows/bump-version.yml +65 -0
- mcp_server_motherduck-0.7.1/.github/workflows/publish-mcp.yml +78 -0
- {mcp_server_motherduck-0.6.4 → mcp_server_motherduck-0.7.1}/.gitignore +2 -1
- mcp_server_motherduck-0.6.4/README.md → mcp_server_motherduck-0.7.1/PKG-INFO +50 -2
- mcp_server_motherduck-0.6.4/PKG-INFO → mcp_server_motherduck-0.7.1/README.md +33 -19
- {mcp_server_motherduck-0.6.4 → mcp_server_motherduck-0.7.1}/pyproject.toml +2 -2
- mcp_server_motherduck-0.7.1/server.json +90 -0
- {mcp_server_motherduck-0.6.4 → mcp_server_motherduck-0.7.1}/src/mcp_server_motherduck/configs.py +1 -1
- {mcp_server_motherduck-0.6.4 → mcp_server_motherduck-0.7.1}/src/mcp_server_motherduck/database.py +70 -2
- {mcp_server_motherduck-0.6.4 → mcp_server_motherduck-0.7.1}/uv.lock +28 -32
- mcp_server_motherduck-0.6.4/.github/workflows/python-publish.yml +0 -33
- mcp_server_motherduck-0.6.4/.idea/.gitignore +0 -8
- mcp_server_motherduck-0.6.4/.idea/mcp-server-motherduck.iml +0 -9
- mcp_server_motherduck-0.6.4/.idea/misc.xml +0 -5
- mcp_server_motherduck-0.6.4/.idea/modules.xml +0 -8
- mcp_server_motherduck-0.6.4/.idea/vcs.xml +0 -6
- mcp_server_motherduck-0.6.4/.idea/workspace.xml +0 -106
- mcp_server_motherduck-0.6.4/server.json +0 -31
- {mcp_server_motherduck-0.6.4 → mcp_server_motherduck-0.7.1}/LICENSE +0 -0
- {mcp_server_motherduck-0.6.4 → mcp_server_motherduck-0.7.1}/makefile +0 -0
- {mcp_server_motherduck-0.6.4 → mcp_server_motherduck-0.7.1}/src/mcp_server_motherduck/__init__.py +0 -0
- {mcp_server_motherduck-0.6.4 → mcp_server_motherduck-0.7.1}/src/mcp_server_motherduck/prompt.py +0 -0
- {mcp_server_motherduck-0.6.4 → mcp_server_motherduck-0.7.1}/src/mcp_server_motherduck/server.py +0 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
[bumpver]
|
|
2
|
+
current_version = "0.7.0"
|
|
3
|
+
version_pattern = "MAJOR.MINOR.PATCH"
|
|
4
|
+
commit_message = "Bump version {old_version} -> {new_version}"
|
|
5
|
+
commit = true
|
|
6
|
+
tag = true
|
|
7
|
+
push = false
|
|
8
|
+
|
|
9
|
+
[bumpver.file_patterns]
|
|
10
|
+
"pyproject.toml" = [
|
|
11
|
+
'version = "{version}"',
|
|
12
|
+
]
|
|
13
|
+
"src/mcp_server_motherduck/configs.py" = [
|
|
14
|
+
'SERVER_VERSION = "{version}"',
|
|
15
|
+
]
|
|
16
|
+
"server.json" = [
|
|
17
|
+
'"version": "{version}"',
|
|
18
|
+
]
|
|
19
|
+
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
name: Release New Version
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
inputs:
|
|
6
|
+
version:
|
|
7
|
+
description: 'Version number (e.g., 0.8.0)'
|
|
8
|
+
required: true
|
|
9
|
+
type: string
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
bump-version:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
permissions:
|
|
15
|
+
contents: write
|
|
16
|
+
|
|
17
|
+
steps:
|
|
18
|
+
- name: Checkout code
|
|
19
|
+
uses: actions/checkout@v4
|
|
20
|
+
with:
|
|
21
|
+
fetch-depth: 0
|
|
22
|
+
token: ${{ secrets.GITHUB_TOKEN }}
|
|
23
|
+
|
|
24
|
+
- name: Setup Python
|
|
25
|
+
uses: actions/setup-python@v5
|
|
26
|
+
with:
|
|
27
|
+
python-version: '3.11'
|
|
28
|
+
|
|
29
|
+
- name: Install uv
|
|
30
|
+
uses: astral-sh/setup-uv@v5
|
|
31
|
+
with:
|
|
32
|
+
enable-cache: true
|
|
33
|
+
|
|
34
|
+
- name: Install bumpver
|
|
35
|
+
run: uv tool install bumpver
|
|
36
|
+
|
|
37
|
+
- name: Configure git
|
|
38
|
+
run: |
|
|
39
|
+
git config --global user.name "github-actions[bot]"
|
|
40
|
+
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
|
41
|
+
|
|
42
|
+
- name: Update version to ${{ inputs.version }}
|
|
43
|
+
run: |
|
|
44
|
+
uv tool run bumpver update --set-version ${{ inputs.version }}
|
|
45
|
+
echo "NEW_VERSION=${{ inputs.version }}" >> $GITHUB_ENV
|
|
46
|
+
|
|
47
|
+
- name: Push changes
|
|
48
|
+
run: |
|
|
49
|
+
git push origin main
|
|
50
|
+
git push origin --tags
|
|
51
|
+
|
|
52
|
+
- name: Create GitHub Release
|
|
53
|
+
env:
|
|
54
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
55
|
+
run: |
|
|
56
|
+
gh release create "v${{ env.NEW_VERSION }}" \
|
|
57
|
+
--title "v${{ env.NEW_VERSION }}" \
|
|
58
|
+
--generate-notes
|
|
59
|
+
|
|
60
|
+
# Publish job will be triggered automatically by the tag push
|
|
61
|
+
call-publish:
|
|
62
|
+
needs: bump-version
|
|
63
|
+
uses: ./.github/workflows/publish-mcp.yml
|
|
64
|
+
secrets: inherit
|
|
65
|
+
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
name: Publish to PyPI and MCP Registry
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch: # Allows manual triggering from GitHub Actions UI
|
|
5
|
+
workflow_call: # Allows triggering from other workflows
|
|
6
|
+
push:
|
|
7
|
+
tags:
|
|
8
|
+
- 'v*' # Trigger on version tags like v0.7.0
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
publish:
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
permissions:
|
|
14
|
+
id-token: write # Required for OIDC authentication
|
|
15
|
+
contents: read
|
|
16
|
+
|
|
17
|
+
steps:
|
|
18
|
+
- name: Checkout code
|
|
19
|
+
uses: actions/checkout@v4
|
|
20
|
+
|
|
21
|
+
- name: Setup Python
|
|
22
|
+
uses: actions/setup-python@v5
|
|
23
|
+
with:
|
|
24
|
+
python-version: '3.11'
|
|
25
|
+
|
|
26
|
+
- name: Install uv
|
|
27
|
+
uses: astral-sh/setup-uv@v5
|
|
28
|
+
with:
|
|
29
|
+
enable-cache: true
|
|
30
|
+
cache-dependency-glob: "uv.lock"
|
|
31
|
+
|
|
32
|
+
- name: Install dependencies
|
|
33
|
+
run: uv sync --all-extras --dev
|
|
34
|
+
|
|
35
|
+
- name: Build package
|
|
36
|
+
run: uv build
|
|
37
|
+
|
|
38
|
+
- name: Publish to PyPI
|
|
39
|
+
id: pypi-publish
|
|
40
|
+
continue-on-error: true
|
|
41
|
+
run: |
|
|
42
|
+
uv publish --token ${{ secrets.PYPI_TOKEN }} 2>&1 | tee publish_output.txt
|
|
43
|
+
exit_code=${PIPESTATUS[0]}
|
|
44
|
+
if [ $exit_code -eq 0 ]; then
|
|
45
|
+
echo "✅ Successfully published to PyPI"
|
|
46
|
+
echo "pypi_status=success" >> $GITHUB_OUTPUT
|
|
47
|
+
elif grep -q "already exists" publish_output.txt || grep -q "File already exists" publish_output.txt; then
|
|
48
|
+
echo "⚠️ Package version already exists on PyPI, skipping..."
|
|
49
|
+
echo "pypi_status=already_exists" >> $GITHUB_OUTPUT
|
|
50
|
+
exit 0
|
|
51
|
+
else
|
|
52
|
+
echo "❌ Failed to publish to PyPI"
|
|
53
|
+
echo "pypi_status=failed" >> $GITHUB_OUTPUT
|
|
54
|
+
exit 1
|
|
55
|
+
fi
|
|
56
|
+
env:
|
|
57
|
+
UV_PUBLISH_TOKEN: ${{ secrets.PYPI_TOKEN }}
|
|
58
|
+
|
|
59
|
+
- name: Setup Node.js (for schema validation)
|
|
60
|
+
uses: actions/setup-node@v4
|
|
61
|
+
with:
|
|
62
|
+
node-version: '20'
|
|
63
|
+
|
|
64
|
+
- name: Install MCP Publisher
|
|
65
|
+
run: |
|
|
66
|
+
# Clone and build the MCP publisher
|
|
67
|
+
git clone https://github.com/modelcontextprotocol/registry publisher-repo
|
|
68
|
+
cd publisher-repo
|
|
69
|
+
make publisher
|
|
70
|
+
cp bin/mcp-publisher ../mcp-publisher
|
|
71
|
+
cd ..
|
|
72
|
+
chmod +x mcp-publisher
|
|
73
|
+
|
|
74
|
+
- name: Login to MCP Registry
|
|
75
|
+
run: ./mcp-publisher login github-oidc
|
|
76
|
+
|
|
77
|
+
- name: Publish to MCP Registry
|
|
78
|
+
run: ./mcp-publisher publish
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
# Custom
|
|
4
4
|
.python-version
|
|
5
|
+
.mcpregistry_*
|
|
5
6
|
|
|
6
7
|
# Byte-compiled / optimized / DLL files
|
|
7
8
|
__pycache__/
|
|
@@ -170,7 +171,7 @@ cython_debug/
|
|
|
170
171
|
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
|
171
172
|
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
|
172
173
|
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
|
173
|
-
|
|
174
|
+
.idea/
|
|
174
175
|
|
|
175
176
|
# Ruff stuff:
|
|
176
177
|
.ruff_cache/
|
|
@@ -1,8 +1,25 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: mcp-server-motherduck
|
|
3
|
+
Version: 0.7.1
|
|
4
|
+
Summary: A MCP server for MotherDuck and local DuckDB
|
|
5
|
+
Author-email: tdoehmen <till@motherduck.com>
|
|
6
|
+
License-File: LICENSE
|
|
7
|
+
Requires-Python: >=3.10
|
|
8
|
+
Requires-Dist: anyio>=4.8.0
|
|
9
|
+
Requires-Dist: click>=8.1.8
|
|
10
|
+
Requires-Dist: duckdb==1.4.1
|
|
11
|
+
Requires-Dist: mcp>=1.9.4
|
|
12
|
+
Requires-Dist: pytz>=2025.2
|
|
13
|
+
Requires-Dist: starlette>=0.46.1
|
|
14
|
+
Requires-Dist: tabulate>=0.9.0
|
|
15
|
+
Requires-Dist: uvicorn>=0.34.0
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
|
|
1
18
|
# MotherDuck's DuckDB MCP Server
|
|
2
19
|
|
|
3
20
|
An MCP server implementation that interacts with DuckDB and MotherDuck databases, providing SQL analytics capabilities to AI Assistants and IDEs.
|
|
4
21
|
|
|
5
|
-
[
|
|
22
|
+
[<img src="https://cursor.com/deeplink/mcp-install-dark.svg" alt="Install in Cursor">](https://cursor.com/en/install-mcp?name=DuckDB&config=eyJjb21tYW5kIjoidXZ4IG1jcC1zZXJ2ZXItbW90aGVyZHVjayAtLWRiLXBhdGggOm1lbW9yeToiLCJlbnYiOnsibW90aGVyZHVja190b2tlbiI6IiJ9fQ%3D%3D)
|
|
6
23
|
|
|
7
24
|
## Resources
|
|
8
25
|
- [Close the Loop: Faster Data Pipelines with MCP, DuckDB & AI (Blogpost)](https://motherduck.com/blog/faster-data-pipelines-with-mcp-duckdb-ai/)
|
|
@@ -42,7 +59,7 @@ The MCP server supports the following parameters:
|
|
|
42
59
|
|-----------|------|---------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|
43
60
|
| `--transport` | Choice | `stdio` | Transport type. Options: `stdio`, `sse`, `stream` |
|
|
44
61
|
| `--port` | Integer | `8000` | Port to listen on for sse and stream transport mode |
|
|
45
|
-
| `--db-path` | String | `md:` | Path to local DuckDB database file or
|
|
62
|
+
| `--db-path` | String | `md:` | Path to local DuckDB database file, MotherDuck database, or S3 URL (e.g., `s3://bucket/path/to/db.duckdb`) |
|
|
46
63
|
| `--motherduck-token` | String | `None` | Access token to use for MotherDuck database connections (uses `motherduck_token` env var by default) |
|
|
47
64
|
| `--read-only` | Flag | `False` | Flag for connecting to DuckDB or MotherDuck in read-only mode. For DuckDB it uses short-lived connections to enable concurrent access |
|
|
48
65
|
| `--home-dir` | String | `None` | Home directory for DuckDB (uses `HOME` env var by default) |
|
|
@@ -337,6 +354,37 @@ modeling data within duckdb and then an MCP client (Windsurf/Cline/Claude/Cursor
|
|
|
337
354
|
was used for exploring the database. The short lived connections allow each tool
|
|
338
355
|
to run and then release their connection, allowing the next tool to connect.
|
|
339
356
|
|
|
357
|
+
## Connect to DuckDB on S3
|
|
358
|
+
|
|
359
|
+
You can connect to DuckDB databases stored on Amazon S3 by providing an S3 URL as the database path. The server will automatically configure the necessary S3 credentials from your environment variables.
|
|
360
|
+
|
|
361
|
+
```json
|
|
362
|
+
{
|
|
363
|
+
"mcpServers": {
|
|
364
|
+
"mcp-server-motherduck": {
|
|
365
|
+
"command": "uvx",
|
|
366
|
+
"args": [
|
|
367
|
+
"mcp-server-motherduck",
|
|
368
|
+
"--db-path",
|
|
369
|
+
"s3://your-bucket/path/to/database.duckdb"
|
|
370
|
+
],
|
|
371
|
+
"env": {
|
|
372
|
+
"AWS_ACCESS_KEY_ID": "<your_key>",
|
|
373
|
+
"AWS_SECRET_ACCESS_KEY": "<your_secret>",
|
|
374
|
+
"AWS_DEFAULT_REGION": "<your_region>"
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
|
|
382
|
+
**Note**: For S3 connections:
|
|
383
|
+
- AWS credentials must be provided via environment variables (`AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, and optionally `AWS_DEFAULT_REGION`)
|
|
384
|
+
- The S3 database is attached to an in-memory DuckDB instance
|
|
385
|
+
- The httpfs extension is automatically installed and configured for S3 access
|
|
386
|
+
- Both read and write operations are supported
|
|
387
|
+
|
|
340
388
|
## Example Queries
|
|
341
389
|
|
|
342
390
|
Once configured, you can e.g. ask Claude to run queries like:
|
|
@@ -1,25 +1,8 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: mcp-server-motherduck
|
|
3
|
-
Version: 0.6.4
|
|
4
|
-
Summary: A MCP server for MotherDuck and local DuckDB
|
|
5
|
-
Author-email: tdoehmen <till@motherduck.com>
|
|
6
|
-
License-File: LICENSE
|
|
7
|
-
Requires-Python: >=3.10
|
|
8
|
-
Requires-Dist: anyio>=4.8.0
|
|
9
|
-
Requires-Dist: click>=8.1.8
|
|
10
|
-
Requires-Dist: duckdb==1.3.1
|
|
11
|
-
Requires-Dist: mcp>=1.9.4
|
|
12
|
-
Requires-Dist: pytz>=2025.2
|
|
13
|
-
Requires-Dist: starlette>=0.46.1
|
|
14
|
-
Requires-Dist: tabulate>=0.9.0
|
|
15
|
-
Requires-Dist: uvicorn>=0.34.0
|
|
16
|
-
Description-Content-Type: text/markdown
|
|
17
|
-
|
|
18
1
|
# MotherDuck's DuckDB MCP Server
|
|
19
2
|
|
|
20
3
|
An MCP server implementation that interacts with DuckDB and MotherDuck databases, providing SQL analytics capabilities to AI Assistants and IDEs.
|
|
21
4
|
|
|
22
|
-
[
|
|
5
|
+
[<img src="https://cursor.com/deeplink/mcp-install-dark.svg" alt="Install in Cursor">](https://cursor.com/en/install-mcp?name=DuckDB&config=eyJjb21tYW5kIjoidXZ4IG1jcC1zZXJ2ZXItbW90aGVyZHVjayAtLWRiLXBhdGggOm1lbW9yeToiLCJlbnYiOnsibW90aGVyZHVja190b2tlbiI6IiJ9fQ%3D%3D)
|
|
23
6
|
|
|
24
7
|
## Resources
|
|
25
8
|
- [Close the Loop: Faster Data Pipelines with MCP, DuckDB & AI (Blogpost)](https://motherduck.com/blog/faster-data-pipelines-with-mcp-duckdb-ai/)
|
|
@@ -59,7 +42,7 @@ The MCP server supports the following parameters:
|
|
|
59
42
|
|-----------|------|---------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|
60
43
|
| `--transport` | Choice | `stdio` | Transport type. Options: `stdio`, `sse`, `stream` |
|
|
61
44
|
| `--port` | Integer | `8000` | Port to listen on for sse and stream transport mode |
|
|
62
|
-
| `--db-path` | String | `md:` | Path to local DuckDB database file or
|
|
45
|
+
| `--db-path` | String | `md:` | Path to local DuckDB database file, MotherDuck database, or S3 URL (e.g., `s3://bucket/path/to/db.duckdb`) |
|
|
63
46
|
| `--motherduck-token` | String | `None` | Access token to use for MotherDuck database connections (uses `motherduck_token` env var by default) |
|
|
64
47
|
| `--read-only` | Flag | `False` | Flag for connecting to DuckDB or MotherDuck in read-only mode. For DuckDB it uses short-lived connections to enable concurrent access |
|
|
65
48
|
| `--home-dir` | String | `None` | Home directory for DuckDB (uses `HOME` env var by default) |
|
|
@@ -354,6 +337,37 @@ modeling data within duckdb and then an MCP client (Windsurf/Cline/Claude/Cursor
|
|
|
354
337
|
was used for exploring the database. The short lived connections allow each tool
|
|
355
338
|
to run and then release their connection, allowing the next tool to connect.
|
|
356
339
|
|
|
340
|
+
## Connect to DuckDB on S3
|
|
341
|
+
|
|
342
|
+
You can connect to DuckDB databases stored on Amazon S3 by providing an S3 URL as the database path. The server will automatically configure the necessary S3 credentials from your environment variables.
|
|
343
|
+
|
|
344
|
+
```json
|
|
345
|
+
{
|
|
346
|
+
"mcpServers": {
|
|
347
|
+
"mcp-server-motherduck": {
|
|
348
|
+
"command": "uvx",
|
|
349
|
+
"args": [
|
|
350
|
+
"mcp-server-motherduck",
|
|
351
|
+
"--db-path",
|
|
352
|
+
"s3://your-bucket/path/to/database.duckdb"
|
|
353
|
+
],
|
|
354
|
+
"env": {
|
|
355
|
+
"AWS_ACCESS_KEY_ID": "<your_key>",
|
|
356
|
+
"AWS_SECRET_ACCESS_KEY": "<your_secret>",
|
|
357
|
+
"AWS_DEFAULT_REGION": "<your_region>"
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
|
|
365
|
+
**Note**: For S3 connections:
|
|
366
|
+
- AWS credentials must be provided via environment variables (`AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, and optionally `AWS_DEFAULT_REGION`)
|
|
367
|
+
- The S3 database is attached to an in-memory DuckDB instance
|
|
368
|
+
- The httpfs extension is automatically installed and configured for S3 access
|
|
369
|
+
- Both read and write operations are supported
|
|
370
|
+
|
|
357
371
|
## Example Queries
|
|
358
372
|
|
|
359
373
|
Once configured, you can e.g. ask Claude to run queries like:
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "mcp-server-motherduck"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.7.1"
|
|
4
4
|
description = "A MCP server for MotherDuck and local DuckDB"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.10"
|
|
7
7
|
dependencies = [
|
|
8
|
-
"duckdb==1.
|
|
8
|
+
"duckdb==1.4.1",
|
|
9
9
|
"tabulate>=0.9.0",
|
|
10
10
|
"click>=8.1.8",
|
|
11
11
|
"starlette>=0.46.1",
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-09-29/server.schema.json",
|
|
3
|
+
"name": "io.github.motherduckdb/mcp-server-motherduck",
|
|
4
|
+
"description": "Fast analytics and data processing with DuckDB and MotherDuck",
|
|
5
|
+
"repository": {
|
|
6
|
+
"url": "https://github.com/motherduckdb/mcp-server-motherduck",
|
|
7
|
+
"source": "github"
|
|
8
|
+
},
|
|
9
|
+
"version": "0.7.1",
|
|
10
|
+
"packages": [
|
|
11
|
+
{
|
|
12
|
+
"registryType": "pypi",
|
|
13
|
+
"registryBaseUrl": "https://pypi.org",
|
|
14
|
+
"identifier": "mcp-server-motherduck",
|
|
15
|
+
"version": "0.7.1",
|
|
16
|
+
"transport": {
|
|
17
|
+
"type": "stdio"
|
|
18
|
+
},
|
|
19
|
+
"packageArguments": [
|
|
20
|
+
{
|
|
21
|
+
"type": "named",
|
|
22
|
+
"name": "--transport",
|
|
23
|
+
"description": "Transport type for MCP server",
|
|
24
|
+
"default": "stdio",
|
|
25
|
+
"choices": ["stdio", "sse", "stream"],
|
|
26
|
+
"isRequired": false
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"type": "named",
|
|
30
|
+
"name": "--port",
|
|
31
|
+
"description": "Port to listen on for sse and stream transport mode",
|
|
32
|
+
"default": "8000",
|
|
33
|
+
"format": "number",
|
|
34
|
+
"isRequired": false
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"type": "named",
|
|
38
|
+
"name": "--db-path",
|
|
39
|
+
"description": "Path to local DuckDB database file or MotherDuck database",
|
|
40
|
+
"default": "md:",
|
|
41
|
+
"isRequired": false
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"type": "named",
|
|
45
|
+
"name": "--motherduck-token",
|
|
46
|
+
"description": "Access token to use for MotherDuck database connections",
|
|
47
|
+
"isRequired": false,
|
|
48
|
+
"isSecret": true
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"type": "named",
|
|
52
|
+
"name": "--read-only",
|
|
53
|
+
"description": "Flag for connecting to DuckDB or MotherDuck in read-only mode",
|
|
54
|
+
"isRequired": false
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
"type": "named",
|
|
58
|
+
"name": "--home-dir",
|
|
59
|
+
"description": "Home directory for DuckDB",
|
|
60
|
+
"isRequired": false
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"type": "named",
|
|
64
|
+
"name": "--saas-mode",
|
|
65
|
+
"description": "Flag for connecting to MotherDuck in SaaS mode (disables filesystem and write permissions for local DuckDB)",
|
|
66
|
+
"isRequired": false
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
"type": "named",
|
|
70
|
+
"name": "--json-response",
|
|
71
|
+
"description": "Enable JSON responses for HTTP stream (only supported for stream transport)",
|
|
72
|
+
"isRequired": false
|
|
73
|
+
}
|
|
74
|
+
],
|
|
75
|
+
"environmentVariables": [
|
|
76
|
+
{
|
|
77
|
+
"name": "motherduck_token",
|
|
78
|
+
"description": "Access token to use for MotherDuck database connections",
|
|
79
|
+
"isRequired": false,
|
|
80
|
+
"isSecret": true
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
"name": "HOME",
|
|
84
|
+
"description": "Home directory for DuckDB (used as default if --home-dir not specified)",
|
|
85
|
+
"isRequired": false
|
|
86
|
+
}
|
|
87
|
+
]
|
|
88
|
+
}
|
|
89
|
+
]
|
|
90
|
+
}
|
{mcp_server_motherduck-0.6.4 → mcp_server_motherduck-0.7.1}/src/mcp_server_motherduck/database.py
RENAMED
|
@@ -36,6 +36,10 @@ class DatabaseClient:
|
|
|
36
36
|
|
|
37
37
|
logger.info(f"🔌 Connecting to {self.db_type} database")
|
|
38
38
|
|
|
39
|
+
# S3 databases don't support read-only mode
|
|
40
|
+
if self.db_type == "s3" and self._read_only:
|
|
41
|
+
raise ValueError("Read-only mode is not supported for S3 databases")
|
|
42
|
+
|
|
39
43
|
if self.db_type == "duckdb" and self._read_only:
|
|
40
44
|
# check that we can connect, issue a `select 1` and then close + return None
|
|
41
45
|
try:
|
|
@@ -53,6 +57,66 @@ class DatabaseClient:
|
|
|
53
57
|
logger.error(f"❌ Read-only check failed: {e}")
|
|
54
58
|
raise
|
|
55
59
|
|
|
60
|
+
# Check if this is an S3 path
|
|
61
|
+
if self.db_type == "s3":
|
|
62
|
+
# For S3, we need to create an in-memory connection and attach the S3 database
|
|
63
|
+
conn = duckdb.connect(':memory:')
|
|
64
|
+
|
|
65
|
+
# Install and load the httpfs extension for S3 support
|
|
66
|
+
import io
|
|
67
|
+
from contextlib import redirect_stdout, redirect_stderr
|
|
68
|
+
|
|
69
|
+
null_file = io.StringIO()
|
|
70
|
+
with redirect_stdout(null_file), redirect_stderr(null_file):
|
|
71
|
+
try:
|
|
72
|
+
conn.execute("INSTALL httpfs;")
|
|
73
|
+
except:
|
|
74
|
+
pass # Extension might already be installed
|
|
75
|
+
conn.execute("LOAD httpfs;")
|
|
76
|
+
|
|
77
|
+
# Configure S3 credentials from environment variables using CREATE SECRET
|
|
78
|
+
aws_access_key = os.environ.get('AWS_ACCESS_KEY_ID')
|
|
79
|
+
aws_secret_key = os.environ.get('AWS_SECRET_ACCESS_KEY')
|
|
80
|
+
aws_region = os.environ.get('AWS_DEFAULT_REGION', 'us-east-1')
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
if aws_access_key and aws_secret_key:
|
|
84
|
+
# Use CREATE SECRET for better credential management
|
|
85
|
+
conn.execute(f"""
|
|
86
|
+
CREATE SECRET IF NOT EXISTS s3_secret (
|
|
87
|
+
TYPE S3,
|
|
88
|
+
KEY_ID '{aws_access_key}',
|
|
89
|
+
SECRET '{aws_secret_key}',
|
|
90
|
+
REGION '{aws_region}'
|
|
91
|
+
);
|
|
92
|
+
""")
|
|
93
|
+
|
|
94
|
+
# Attach the S3 database
|
|
95
|
+
try:
|
|
96
|
+
# For S3, we always attach as READ_ONLY since S3 storage is typically read-only
|
|
97
|
+
# Even when not in read_only mode, we attach as READ_ONLY for S3
|
|
98
|
+
conn.execute(f"ATTACH '{self.db_path}' AS s3db (READ_ONLY);")
|
|
99
|
+
# Use the attached database
|
|
100
|
+
conn.execute("USE s3db;")
|
|
101
|
+
logger.info(f"✅ Successfully connected to {self.db_type} database (attached as read-only)")
|
|
102
|
+
except Exception as e:
|
|
103
|
+
logger.error(f"Failed to attach S3 database: {e}")
|
|
104
|
+
# If the database doesn't exist and we're not in read-only mode, try to create it
|
|
105
|
+
if "database does not exist" in str(e) and not self._read_only:
|
|
106
|
+
logger.info("S3 database doesn't exist, attempting to create it...")
|
|
107
|
+
try:
|
|
108
|
+
# Create a new database at the S3 location
|
|
109
|
+
conn.execute(f"ATTACH '{self.db_path}' AS s3db;")
|
|
110
|
+
conn.execute("USE s3db;")
|
|
111
|
+
logger.info(f"✅ Created new S3 database at {self.db_path}")
|
|
112
|
+
except Exception as create_error:
|
|
113
|
+
logger.error(f"Failed to create S3 database: {create_error}")
|
|
114
|
+
raise
|
|
115
|
+
else:
|
|
116
|
+
raise
|
|
117
|
+
|
|
118
|
+
return conn
|
|
119
|
+
|
|
56
120
|
conn = duckdb.connect(
|
|
57
121
|
self.db_path,
|
|
58
122
|
config={"custom_user_agent": f"mcp-server-motherduck/{SERVER_VERSION}"},
|
|
@@ -65,8 +129,12 @@ class DatabaseClient:
|
|
|
65
129
|
|
|
66
130
|
def _resolve_db_path_type(
|
|
67
131
|
self, db_path: str, motherduck_token: str | None = None, saas_mode: bool = False
|
|
68
|
-
) -> tuple[str, Literal["duckdb", "motherduck"]]:
|
|
132
|
+
) -> tuple[str, Literal["duckdb", "motherduck", "s3"]]:
|
|
69
133
|
"""Resolve and validate the database path"""
|
|
134
|
+
# Handle S3 paths
|
|
135
|
+
if db_path.startswith("s3://"):
|
|
136
|
+
return db_path, "s3"
|
|
137
|
+
|
|
70
138
|
# Handle MotherDuck paths
|
|
71
139
|
if db_path.startswith("md:"):
|
|
72
140
|
if motherduck_token:
|
|
@@ -102,7 +170,7 @@ class DatabaseClient:
|
|
|
102
170
|
|
|
103
171
|
def _execute(self, query: str) -> str:
|
|
104
172
|
if self.conn is None:
|
|
105
|
-
# open short lived readonly connection, run query, close connection, return result
|
|
173
|
+
# open short lived readonly connection for local DuckDB, run query, close connection, return result
|
|
106
174
|
conn = duckdb.connect(
|
|
107
175
|
self.db_path,
|
|
108
176
|
config={"custom_user_agent": f"mcp-server-motherduck/{SERVER_VERSION}"},
|
|
@@ -62,38 +62,34 @@ wheels = [
|
|
|
62
62
|
|
|
63
63
|
[[package]]
|
|
64
64
|
name = "duckdb"
|
|
65
|
-
version = "1.
|
|
65
|
+
version = "1.4.1"
|
|
66
66
|
source = { registry = "https://pypi.org/simple" }
|
|
67
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
67
|
+
sdist = { url = "https://files.pythonhosted.org/packages/ea/e7/21cf50a3d52ffceee1f0bcc3997fa96a5062e6bab705baee4f6c4e33cce5/duckdb-1.4.1.tar.gz", hash = "sha256:f903882f045d057ebccad12ac69975952832edfe133697694854bb784b8d6c76", size = 18461687 }
|
|
68
68
|
wheels = [
|
|
69
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
70
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
71
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
72
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
73
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
74
|
-
{ url = "https://files.pythonhosted.org/packages/5b/
|
|
75
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
76
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
77
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
78
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
79
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
80
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
81
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
82
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
83
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
84
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
85
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
86
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
87
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
88
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
89
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
90
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
91
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
92
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
93
|
-
{ url = "https://files.pythonhosted.org/packages/9a/06/5755f93be743ec27986f275847a85d44bb1bd6d8631492d337729fbe9145/duckdb-1.3.1-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:663610b591ea6964f140441c81b718e745704cf098c540e905b200b9079e2a5c", size = 19173540 },
|
|
94
|
-
{ url = "https://files.pythonhosted.org/packages/90/a6/c8577b741974f106e24f8eb3efedc399be1a23cbbdcf49dd4bea5bb8aa4e/duckdb-1.3.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8793b5abb365bbbf64ba3065f3a37951fe04f2d4506b0e24f3f8ecd08b3af4ba", size = 21122193 },
|
|
95
|
-
{ url = "https://files.pythonhosted.org/packages/43/10/b4576bbfa895a0ab125697fd58c0fbe54338672a9df25e7311bdf21f9e04/duckdb-1.3.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:27d775a5af405d1c228561830c8ccbe4e2832dafb4012f16c05fde1cde206dee", size = 22773434 },
|
|
96
|
-
{ url = "https://files.pythonhosted.org/packages/94/b9/f5ae51f7331f79c184fd96456c0896de875149fdeb092084fd20433ec97c/duckdb-1.3.1-cp313-cp313-win_amd64.whl", hash = "sha256:3eb045a9bf92da890d890cde2f676b3bda61b9de3b7dc46cbaaf75875b41e4b0", size = 11302770 },
|
|
69
|
+
{ url = "https://files.pythonhosted.org/packages/68/cc/00a07de0e33d16763edd4132d7c8a2f9efd57a2f296a25a948f239a1fadf/duckdb-1.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:296b4fff3908fb4c47b0aa1d77bd1933375e75401009d2dc81af8e7a0b8a05b4", size = 29062814 },
|
|
70
|
+
{ url = "https://files.pythonhosted.org/packages/17/ea/fb0fda8886d1928f1b2a53a1163ef94f6f4b41f6d8b29eee457acfc2fa67/duckdb-1.4.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0b4182800092115feee5d71a8691efb283d3c9f5eb0b36362b308ef007a12222", size = 16161652 },
|
|
71
|
+
{ url = "https://files.pythonhosted.org/packages/b4/5f/052e6436a71f461e61cd3a982954c029145a84b58cefa1dfb3eb2d96e4fc/duckdb-1.4.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:67cc3b6c7f7ba07a69e9331b8ccea7a60cbcd4204bb473e5da9b71588bd2eca9", size = 13753030 },
|
|
72
|
+
{ url = "https://files.pythonhosted.org/packages/c2/fd/3ae3c89d0f6ad54c0be4430e572306fbfc9f173c97b23c5025a540449325/duckdb-1.4.1-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0cef0cee7030b561640cb9af718f8841b19cdd2aa020d53561057b5743bea90b", size = 18487683 },
|
|
73
|
+
{ url = "https://files.pythonhosted.org/packages/d4/3c/eef454cd7c3880c2d55b50e18a9c7a213bf91ded79efcfb573d8d6dd8a47/duckdb-1.4.1-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2bf93347f37a46bacce6ac859d651dbf5731e2c94a64ab358300425b09e3de23", size = 20487080 },
|
|
74
|
+
{ url = "https://files.pythonhosted.org/packages/bb/5b/b619f4c986a1cb0b06315239da9ce5fd94a20c07a344d03e2635d56a6967/duckdb-1.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:2e60d2361f978908a3d96eebaf1f4b346f283afcc467351aae50ea45ca293a2b", size = 12324436 },
|
|
75
|
+
{ url = "https://files.pythonhosted.org/packages/d9/52/606f13fa9669a24166d2fe523e28982d8ef9039874b4de774255c7806d1f/duckdb-1.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:605d563c1d5203ca992497cd33fb386ac3d533deca970f9dcf539f62a34e22a9", size = 29065894 },
|
|
76
|
+
{ url = "https://files.pythonhosted.org/packages/84/57/138241952ece868b9577e607858466315bed1739e1fbb47205df4dfdfd88/duckdb-1.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d3305c7c4b70336171de7adfdb50431f23671c000f11839b580c4201d9ce6ef5", size = 16163720 },
|
|
77
|
+
{ url = "https://files.pythonhosted.org/packages/a3/81/afa3a0a78498a6f4acfea75c48a70c5082032d9ac87822713d7c2d164af1/duckdb-1.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a063d6febbe34b32f1ad2e68822db4d0e4b1102036f49aaeeb22b844427a75df", size = 13756223 },
|
|
78
|
+
{ url = "https://files.pythonhosted.org/packages/47/dd/5f6064fbd9248e37a3e806a244f81e0390ab8f989d231b584fb954f257fc/duckdb-1.4.1-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d1ffcaaf74f7d1df3684b54685cbf8d3ce732781c541def8e1ced304859733ae", size = 18487022 },
|
|
79
|
+
{ url = "https://files.pythonhosted.org/packages/a1/10/b54969a1c42fd9344ad39228d671faceb8aa9f144b67cd9531a63551757f/duckdb-1.4.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:685d3d1599dc08160e0fa0cf09e93ac4ff8b8ed399cb69f8b5391cd46b5b207c", size = 20491004 },
|
|
80
|
+
{ url = "https://files.pythonhosted.org/packages/ed/d5/7332ae8f804869a4e895937821b776199a283f8d9fc775fd3ae5a0558099/duckdb-1.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:78f1d28a15ae73bd449c43f80233732adffa49be1840a32de8f1a6bb5b286764", size = 12327619 },
|
|
81
|
+
{ url = "https://files.pythonhosted.org/packages/0e/6c/906a3fe41cd247b5638866fc1245226b528de196588802d4df4df1e6e819/duckdb-1.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:cd1765a7d180b7482874586859fc23bc9969d7d6c96ced83b245e6c6f49cde7f", size = 29076820 },
|
|
82
|
+
{ url = "https://files.pythonhosted.org/packages/66/c7/01dd33083f01f618c2a29f6dd068baf16945b8cbdb132929d3766610bbbb/duckdb-1.4.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:8ed7a86725185470953410823762956606693c0813bb64e09c7d44dbd9253a64", size = 16167558 },
|
|
83
|
+
{ url = "https://files.pythonhosted.org/packages/81/e2/f983b4b7ae1dfbdd2792dd31dee9a0d35f88554452cbfc6c9d65e22fdfa9/duckdb-1.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8a189bdfc64cfb9cc1adfbe4f2dcfde0a4992ec08505ad8ce33c886e4813f0bf", size = 13762226 },
|
|
84
|
+
{ url = "https://files.pythonhosted.org/packages/ed/34/fb69a7be19b90f573b3cc890961be7b11870b77514769655657514f10a98/duckdb-1.4.1-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a9090089b6486f7319c92acdeed8acda022d4374032d78a465956f50fc52fabf", size = 18500901 },
|
|
85
|
+
{ url = "https://files.pythonhosted.org/packages/e4/a5/1395d7b49d5589e85da9a9d7ffd8b50364c9d159c2807bef72d547f0ad1e/duckdb-1.4.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:142552ea3e768048e0e8c832077a545ca07792631c59edaee925e3e67401c2a0", size = 20514177 },
|
|
86
|
+
{ url = "https://files.pythonhosted.org/packages/c0/21/08f10706d30252753349ec545833fc0cea67c11abd0b5223acf2827f1056/duckdb-1.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:567f3b3a785a9e8650612461893c49ca799661d2345a6024dda48324ece89ded", size = 12336422 },
|
|
87
|
+
{ url = "https://files.pythonhosted.org/packages/d7/08/705988c33e38665c969f7876b3ca4328be578554aa7e3dc0f34158da3e64/duckdb-1.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:46496a2518752ae0c6c5d75d4cdecf56ea23dd098746391176dd8e42cf157791", size = 29077070 },
|
|
88
|
+
{ url = "https://files.pythonhosted.org/packages/99/c5/7c9165f1e6b9069441bcda4da1e19382d4a2357783d37ff9ae238c5c41ac/duckdb-1.4.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1c65ae7e9b541cea07d8075343bcfebdecc29a3c0481aa6078ee63d51951cfcd", size = 16167506 },
|
|
89
|
+
{ url = "https://files.pythonhosted.org/packages/38/46/267f4a570a0ee3ae6871ddc03435f9942884284e22a7ba9b7cb252ee69b6/duckdb-1.4.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:598d1a314e34b65d9399ddd066ccce1eeab6a60a2ef5885a84ce5ed62dbaf729", size = 13762330 },
|
|
90
|
+
{ url = "https://files.pythonhosted.org/packages/15/7b/c4f272a40c36d82df20937d93a1780eb39ab0107fe42b62cba889151eab9/duckdb-1.4.1-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e2f16b8def782d484a9f035fc422bb6f06941ed0054b4511ddcdc514a7fb6a75", size = 18504687 },
|
|
91
|
+
{ url = "https://files.pythonhosted.org/packages/17/fc/9b958751f0116d7b0406406b07fa6f5a10c22d699be27826d0b896f9bf51/duckdb-1.4.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a5a7d0aed068a5c33622a8848857947cab5cfb3f2a315b1251849bac2c74c492", size = 20513823 },
|
|
92
|
+
{ url = "https://files.pythonhosted.org/packages/30/79/4f544d73fcc0513b71296cb3ebb28a227d22e80dec27204977039b9fa875/duckdb-1.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:280fd663dacdd12bb3c3bf41f3e5b2e5b95e00b88120afabb8b8befa5f335c6f", size = 12336460 },
|
|
97
93
|
]
|
|
98
94
|
|
|
99
95
|
[[package]]
|
|
@@ -182,7 +178,7 @@ wheels = [
|
|
|
182
178
|
|
|
183
179
|
[[package]]
|
|
184
180
|
name = "mcp-server-motherduck"
|
|
185
|
-
version = "0.
|
|
181
|
+
version = "0.7.1"
|
|
186
182
|
source = { editable = "." }
|
|
187
183
|
dependencies = [
|
|
188
184
|
{ name = "anyio" },
|
|
@@ -199,7 +195,7 @@ dependencies = [
|
|
|
199
195
|
requires-dist = [
|
|
200
196
|
{ name = "anyio", specifier = ">=4.8.0" },
|
|
201
197
|
{ name = "click", specifier = ">=8.1.8" },
|
|
202
|
-
{ name = "duckdb", specifier = "==1.
|
|
198
|
+
{ name = "duckdb", specifier = "==1.4.1" },
|
|
203
199
|
{ name = "mcp", specifier = ">=1.9.4" },
|
|
204
200
|
{ name = "pytz", specifier = ">=2025.2" },
|
|
205
201
|
{ name = "starlette", specifier = ">=0.46.1" },
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
name: Upload Python Package
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
release:
|
|
5
|
-
types: [published]
|
|
6
|
-
|
|
7
|
-
permissions:
|
|
8
|
-
contents: read
|
|
9
|
-
|
|
10
|
-
jobs:
|
|
11
|
-
pypi-publish:
|
|
12
|
-
name: python
|
|
13
|
-
runs-on: ubuntu-latest
|
|
14
|
-
|
|
15
|
-
steps:
|
|
16
|
-
- uses: actions/checkout@v4
|
|
17
|
-
|
|
18
|
-
- name: Install uv
|
|
19
|
-
uses: astral-sh/setup-uv@v5
|
|
20
|
-
|
|
21
|
-
- name: "Set up Python"
|
|
22
|
-
uses: actions/setup-python@v5
|
|
23
|
-
with:
|
|
24
|
-
python-version-file: "pyproject.toml"
|
|
25
|
-
|
|
26
|
-
- name: Install the project
|
|
27
|
-
run: uv sync
|
|
28
|
-
|
|
29
|
-
- name: Build package
|
|
30
|
-
run: uv build
|
|
31
|
-
|
|
32
|
-
- name: Publish package
|
|
33
|
-
run: uv publish
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<module type="JAVA_MODULE" version="4">
|
|
3
|
-
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
|
4
|
-
<exclude-output />
|
|
5
|
-
<content url="file://$MODULE_DIR$" />
|
|
6
|
-
<orderEntry type="inheritedJdk" />
|
|
7
|
-
<orderEntry type="sourceFolder" forTests="false" />
|
|
8
|
-
</component>
|
|
9
|
-
</module>
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<project version="4">
|
|
3
|
-
<component name="ProjectModuleManager">
|
|
4
|
-
<modules>
|
|
5
|
-
<module fileurl="file://$PROJECT_DIR$/.idea/mcp-server-motherduck.iml" filepath="$PROJECT_DIR$/.idea/mcp-server-motherduck.iml" />
|
|
6
|
-
</modules>
|
|
7
|
-
</component>
|
|
8
|
-
</project>
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<project version="4">
|
|
3
|
-
<component name="AutoImportSettings">
|
|
4
|
-
<option name="autoReloadType" value="SELECTIVE" />
|
|
5
|
-
</component>
|
|
6
|
-
<component name="CMakeProjectFlavorService">
|
|
7
|
-
<option name="flavorId" value="CMakePlainProjectFlavor" />
|
|
8
|
-
</component>
|
|
9
|
-
<component name="CMakeSettings">
|
|
10
|
-
<configurations>
|
|
11
|
-
<configuration PROFILE_NAME="Debug" ENABLED="true" CONFIG_NAME="Debug" />
|
|
12
|
-
</configurations>
|
|
13
|
-
</component>
|
|
14
|
-
<component name="ChangeListManager">
|
|
15
|
-
<list default="true" id="8bdee1d4-886c-4093-b4cf-95b120034c9e" name="Changes" comment="" />
|
|
16
|
-
<option name="SHOW_DIALOG" value="false" />
|
|
17
|
-
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
|
18
|
-
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
|
19
|
-
<option name="LAST_RESOLUTION" value="IGNORE" />
|
|
20
|
-
</component>
|
|
21
|
-
<component name="ClangdSettings">
|
|
22
|
-
<option name="formatViaClangd" value="false" />
|
|
23
|
-
</component>
|
|
24
|
-
<component name="FlaskConsoleOptions" custom-start-script="import sys sys.path.extend([WORKING_DIR_AND_PYTHON_PATHS]) from flask.cli import ScriptInfo locals().update(ScriptInfo(create_app=None).load_app().make_shell_context()) print("Python %s on %s\nApp: %s [%s]\nInstance: %s" % (sys.version, sys.platform, app.import_name, app.env, app.instance_path))">
|
|
25
|
-
<envs>
|
|
26
|
-
<env key="FLASK_APP" value="app" />
|
|
27
|
-
</envs>
|
|
28
|
-
<option name="myCustomStartScript" value="import sys sys.path.extend([WORKING_DIR_AND_PYTHON_PATHS]) from flask.cli import ScriptInfo locals().update(ScriptInfo(create_app=None).load_app().make_shell_context()) print("Python %s on %s\nApp: %s [%s]\nInstance: %s" % (sys.version, sys.platform, app.import_name, app.env, app.instance_path))" />
|
|
29
|
-
<option name="myEnvs">
|
|
30
|
-
<map>
|
|
31
|
-
<entry key="FLASK_APP" value="app" />
|
|
32
|
-
</map>
|
|
33
|
-
</option>
|
|
34
|
-
</component>
|
|
35
|
-
<component name="Git.Settings">
|
|
36
|
-
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
|
|
37
|
-
</component>
|
|
38
|
-
<component name="MarkdownSettingsMigration">
|
|
39
|
-
<option name="stateVersion" value="1" />
|
|
40
|
-
</component>
|
|
41
|
-
<component name="ProjectColorInfo">{
|
|
42
|
-
"associatedIndex": 3
|
|
43
|
-
}</component>
|
|
44
|
-
<component name="ProjectId" id="2vcb2orYlzlw5ZHOvoXgpTtCdVi" />
|
|
45
|
-
<component name="ProjectViewState">
|
|
46
|
-
<option name="hideEmptyMiddlePackages" value="true" />
|
|
47
|
-
<option name="showLibraryContents" value="true" />
|
|
48
|
-
</component>
|
|
49
|
-
<component name="PropertiesComponent">{
|
|
50
|
-
"keyToString": {
|
|
51
|
-
"RunOnceActivity.OpenProjectViewOnStart": "true",
|
|
52
|
-
"RunOnceActivity.ShowReadmeOnStart": "true",
|
|
53
|
-
"RunOnceActivity.cidr.known.project.marker": "true",
|
|
54
|
-
"RunOnceActivity.git.unshallow": "true",
|
|
55
|
-
"RunOnceActivity.readMode.enableVisualFormatting": "true",
|
|
56
|
-
"WebServerToolWindowFactoryState": "false",
|
|
57
|
-
"cf.first.check.clang-format": "false",
|
|
58
|
-
"cidr.known.project.marker": "true",
|
|
59
|
-
"git-widget-placeholder": "main",
|
|
60
|
-
"last_opened_file_path": "/Users/doehmen/Documents/motherduck/mcp-server-motherduck",
|
|
61
|
-
"node.js.detected.package.eslint": "true",
|
|
62
|
-
"node.js.detected.package.tslint": "true",
|
|
63
|
-
"node.js.selected.package.eslint": "(autodetect)",
|
|
64
|
-
"node.js.selected.package.tslint": "(autodetect)",
|
|
65
|
-
"nodejs_package_manager_path": "npm",
|
|
66
|
-
"project.structure.last.edited": "Project",
|
|
67
|
-
"project.structure.proportion": "0.0",
|
|
68
|
-
"project.structure.side.proportion": "0.0",
|
|
69
|
-
"settings.editor.selected.configurable": "preferences.updates",
|
|
70
|
-
"vue.rearranger.settings.migration": "true"
|
|
71
|
-
}
|
|
72
|
-
}</component>
|
|
73
|
-
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
|
|
74
|
-
<component name="TaskManager">
|
|
75
|
-
<task active="true" id="Default" summary="Default task">
|
|
76
|
-
<changelist id="8bdee1d4-886c-4093-b4cf-95b120034c9e" name="Changes" comment="" />
|
|
77
|
-
<created>1744447105618</created>
|
|
78
|
-
<option name="number" value="Default" />
|
|
79
|
-
<option name="presentableId" value="Default" />
|
|
80
|
-
<updated>1744447105618</updated>
|
|
81
|
-
<workItem from="1744447107447" duration="7470000" />
|
|
82
|
-
<workItem from="1744787944049" duration="599000" />
|
|
83
|
-
<workItem from="1744896732489" duration="6070000" />
|
|
84
|
-
<workItem from="1747725447463" duration="5949000" />
|
|
85
|
-
<workItem from="1747924921526" duration="17579000" />
|
|
86
|
-
<workItem from="1749541956173" duration="67000" />
|
|
87
|
-
<workItem from="1749546948380" duration="272000" />
|
|
88
|
-
<workItem from="1749547445107" duration="2288000" />
|
|
89
|
-
<workItem from="1750068892931" duration="1202000" />
|
|
90
|
-
<workItem from="1750076934923" duration="598000" />
|
|
91
|
-
<workItem from="1750084124415" duration="194000" />
|
|
92
|
-
<workItem from="1750084439422" duration="575000" />
|
|
93
|
-
<workItem from="1750086684829" duration="92000" />
|
|
94
|
-
<workItem from="1750099676834" duration="5651000" />
|
|
95
|
-
<workItem from="1750235697329" duration="4120000" />
|
|
96
|
-
</task>
|
|
97
|
-
<servers />
|
|
98
|
-
</component>
|
|
99
|
-
<component name="TypeScriptGeneratedFilesManager">
|
|
100
|
-
<option name="version" value="3" />
|
|
101
|
-
</component>
|
|
102
|
-
<component name="XSLT-Support.FileAssociations.UIState">
|
|
103
|
-
<expand />
|
|
104
|
-
<select />
|
|
105
|
-
</component>
|
|
106
|
-
</project>
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-07-09/server.schema.json",
|
|
3
|
-
"name": "io.github.motherduckdb/mcp-server-motherduck",
|
|
4
|
-
"description": "Fast analytics and data processing with DuckDB and MotherDuck",
|
|
5
|
-
"status": "active",
|
|
6
|
-
"repository": {
|
|
7
|
-
"url": "https://github.com/motherduckdb/mcp-server-motherduck",
|
|
8
|
-
"source": "github"
|
|
9
|
-
},
|
|
10
|
-
"version": "0.6.4",
|
|
11
|
-
"packages": [
|
|
12
|
-
{
|
|
13
|
-
"registry_type": "pypi",
|
|
14
|
-
"registry_base_url": "https://pypi.org",
|
|
15
|
-
"identifier": "mcp-server-motherduck",
|
|
16
|
-
"version": "0.6.4",
|
|
17
|
-
"transport": {
|
|
18
|
-
"type": "stdio"
|
|
19
|
-
},
|
|
20
|
-
"environment_variables": [
|
|
21
|
-
{
|
|
22
|
-
"description": "Access token to use for MotherDuck database connections",
|
|
23
|
-
"is_required": false,
|
|
24
|
-
"format": "string",
|
|
25
|
-
"is_secret": true,
|
|
26
|
-
"name": "motherduck_token"
|
|
27
|
-
}
|
|
28
|
-
]
|
|
29
|
-
}
|
|
30
|
-
]
|
|
31
|
-
}
|
|
File without changes
|
|
File without changes
|
{mcp_server_motherduck-0.6.4 → mcp_server_motherduck-0.7.1}/src/mcp_server_motherduck/__init__.py
RENAMED
|
File without changes
|
{mcp_server_motherduck-0.6.4 → mcp_server_motherduck-0.7.1}/src/mcp_server_motherduck/prompt.py
RENAMED
|
File without changes
|
{mcp_server_motherduck-0.6.4 → mcp_server_motherduck-0.7.1}/src/mcp_server_motherduck/server.py
RENAMED
|
File without changes
|