mcp-server-motherduck 0.3.4__tar.gz → 0.4.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.

Potentially problematic release.


This version of mcp-server-motherduck might be problematic. Click here for more details.

@@ -0,0 +1,8 @@
1
+ # Default ignored files
2
+ /shelf/
3
+ /workspace.xml
4
+ # Editor-based HTTP Client requests
5
+ /httpRequests/
6
+ # Datasource local storage ignored files
7
+ /dataSources/
8
+ /dataSources.local.xml
@@ -0,0 +1,9 @@
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>
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="ProjectRootManager" version="2" languageLevel="JDK_20" project-jdk-name="Python 3.11" project-jdk-type="Python SDK">
4
+ <output url="file://$PROJECT_DIR$/out" />
5
+ </component>
6
+ </project>
@@ -0,0 +1,8 @@
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>
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="VcsDirectoryMappings">
4
+ <mapping directory="" vcs="Git" />
5
+ </component>
6
+ </project>
@@ -0,0 +1,65 @@
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="ChangeListManager">
7
+ <list default="true" id="5f5ca33d-24b5-4ccd-b2b3-3ff0b492aff6" name="Changes" comment="">
8
+ <change beforePath="$PROJECT_DIR$/pyproject.toml" beforeDir="false" afterPath="$PROJECT_DIR$/pyproject.toml" afterDir="false" />
9
+ <change beforePath="$PROJECT_DIR$/src/mcp_server_motherduck/server.py" beforeDir="false" afterPath="$PROJECT_DIR$/src/mcp_server_motherduck/server.py" afterDir="false" />
10
+ </list>
11
+ <option name="SHOW_DIALOG" value="false" />
12
+ <option name="HIGHLIGHT_CONFLICTS" value="true" />
13
+ <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
14
+ <option name="LAST_RESOLUTION" value="IGNORE" />
15
+ </component>
16
+ <component name="Git.Settings">
17
+ <option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
18
+ </component>
19
+ <component name="MarkdownSettingsMigration">
20
+ <option name="stateVersion" value="1" />
21
+ </component>
22
+ <component name="ProjectColorInfo">{
23
+ &quot;associatedIndex&quot;: 1
24
+ }</component>
25
+ <component name="ProjectId" id="2u5xTlafNwhlw0HAUWKYPjo4ax8" />
26
+ <component name="ProjectViewState">
27
+ <option name="hideEmptyMiddlePackages" value="true" />
28
+ <option name="showLibraryContents" value="true" />
29
+ </component>
30
+ <component name="PropertiesComponent">{
31
+ &quot;keyToString&quot;: {
32
+ &quot;RunOnceActivity.OpenProjectViewOnStart&quot;: &quot;true&quot;,
33
+ &quot;RunOnceActivity.ShowReadmeOnStart&quot;: &quot;true&quot;,
34
+ &quot;WebServerToolWindowFactoryState&quot;: &quot;false&quot;,
35
+ &quot;git-widget-placeholder&quot;: &quot;main&quot;,
36
+ &quot;last_opened_file_path&quot;: &quot;/Users/doehmen/Documents/Research/docs/ai-playground/mcp-server/github_md/mcp-server-motherduck&quot;,
37
+ &quot;node.js.detected.package.eslint&quot;: &quot;true&quot;,
38
+ &quot;node.js.detected.package.tslint&quot;: &quot;true&quot;,
39
+ &quot;node.js.selected.package.eslint&quot;: &quot;(autodetect)&quot;,
40
+ &quot;node.js.selected.package.tslint&quot;: &quot;(autodetect)&quot;,
41
+ &quot;nodejs_package_manager_path&quot;: &quot;npm&quot;,
42
+ &quot;project.structure.last.edited&quot;: &quot;Project&quot;,
43
+ &quot;project.structure.proportion&quot;: &quot;0.0&quot;,
44
+ &quot;project.structure.side.proportion&quot;: &quot;0.0&quot;,
45
+ &quot;vue.rearranger.settings.migration&quot;: &quot;true&quot;
46
+ }
47
+ }</component>
48
+ <component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
49
+ <component name="TaskManager">
50
+ <task active="true" id="Default" summary="Default task">
51
+ <changelist id="5f5ca33d-24b5-4ccd-b2b3-3ff0b492aff6" name="Changes" comment="" />
52
+ <created>1741552248367</created>
53
+ <option name="number" value="Default" />
54
+ <option name="presentableId" value="Default" />
55
+ <updated>1741552248367</updated>
56
+ <workItem from="1741552249680" duration="3949000" />
57
+ <workItem from="1741799556448" duration="2256000" />
58
+ <workItem from="1742223629669" duration="5595000" />
59
+ </task>
60
+ <servers />
61
+ </component>
62
+ <component name="TypeScriptGeneratedFilesManager">
63
+ <option name="version" value="3" />
64
+ </component>
65
+ </project>
@@ -1,14 +1,13 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mcp-server-motherduck
3
- Version: 0.3.4
3
+ Version: 0.4.1
4
4
  Summary: A MCP server for MotherDuck and local DuckDB
5
5
  Author-email: tdoehmen <till@motherduck.com>
6
6
  License-File: LICENSE
7
7
  Requires-Python: >=3.10
8
- Requires-Dist: duckdb>=1.2.1
8
+ Requires-Dist: duckdb==1.2.1
9
9
  Requires-Dist: mcp>=1.3.0
10
10
  Requires-Dist: pandas>=2.0.0
11
- Requires-Dist: pydantic-settings>=2.8.1
12
11
  Requires-Dist: tabulate>=0.9.0
13
12
  Description-Content-Type: text/markdown
14
13
 
@@ -48,7 +47,7 @@ All interactions with both DuckDB and MotherDuck are done through writing SQL qu
48
47
 
49
48
  - A MotherDuck account (sign up at [motherduck.com](https://motherduck.com))
50
49
  - A MotherDuck access token
51
- - `uvx` installed, you can install it using `pip install uvx` or `brew install uvx`
50
+ - `uv` installed, you can install it using `pip install uv` or `brew install uv`
52
51
 
53
52
  If you plan to use MotherDuck MCP with Claude Desktop, you will also need Claude Desktop installed.
54
53
 
@@ -58,6 +57,69 @@ If you plan to use MotherDuck MCP with Claude Desktop, you will also need Claude
58
57
  2. Generate an access token via the [MotherDuck UI](https://app.motherduck.com/settings/tokens?auth_flow=signup)
59
58
  3. Store the token securely for use in the configuration
60
59
 
60
+ ### Usage with VS Code
61
+
62
+ [![Install with UV in VS Code](https://img.shields.io/badge/VS_Code-UV-0098FF?style=flat-square&logo=visualstudiocode&logoColor=white)](https://insiders.vscode.dev/redirect/mcp/install?name=mcp-server-motherduck&config=%7B%22command%22%3A%22uvx%22%2C%22args%22%3A%5B%22mcp-server-motherduck%22%2C%22--db-path%22%2C%22md%3A%22%2C%22--motherduck-token%22%2C%22%24%7Binput%3Amotherduck_token%7D%22%5D%7D&inputs=%5B%7B%22type%22%3A%22promptString%22%2C%22id%22%3A%22motherduck_token%22%2C%22description%22%3A%22MotherDuck+Token%22%2C%22password%22%3Atrue%7D%5D) [![Install with UV in VS Code Insiders](https://img.shields.io/badge/VS_Code_Insiders-UV-24bfa5?style=flat-square&logo=visualstudiocode&logoColor=white)](https://insiders.vscode.dev/redirect/mcp/install?name=mcp-server-motherduck&config=%7B%22command%22%3A%22uvx%22%2C%22args%22%3A%5B%22mcp-server-motherduck%22%2C%22--db-path%22%2C%22md%3A%22%2C%22--motherduck-token%22%2C%22%24%7Binput%3Amotherduck_token%7D%22%5D%7D&inputs=%5B%7B%22type%22%3A%22promptString%22%2C%22id%22%3A%22motherduck_token%22%2C%22description%22%3A%22MotherDuck+Token%22%2C%22password%22%3Atrue%7D%5D&quality=insiders)
63
+ 1. For the quickest installation, click one of the "Install with UV" buttons at the top of this README.
64
+
65
+ ### Manual Installation
66
+
67
+ Add the following JSON block to your User Settings (JSON) file in VS Code. You can do this by pressing `Ctrl + Shift + P` and typing `Preferences: Open User Settings (JSON)`.
68
+
69
+ ```json
70
+ {
71
+ "mcp": {
72
+ "inputs": [
73
+ {
74
+ "type": "promptString",
75
+ "id": "motherduck_token",
76
+ "description": "MotherDuck Token",
77
+ "password": true
78
+ }
79
+ ],
80
+ "servers": {
81
+ "motherduck": {
82
+ "command": "uvx",
83
+ "args": [
84
+ "mcp-server-motherduck",
85
+ "--db-path",
86
+ "md:",
87
+ "--motherduck-token",
88
+ "${input:motherduck_token}"
89
+ ]
90
+ }
91
+ }
92
+ }
93
+ }
94
+ ```
95
+
96
+ Optionally, you can add it to a file called `.vscode/mcp.json` in your workspace. This will allow you to share the configuration with others.
97
+
98
+ ```json
99
+ {
100
+ "inputs": [
101
+ {
102
+ "type": "promptString",
103
+ "id": "motherduck_token",
104
+ "description": "MotherDuck Token",
105
+ "password": true
106
+ }
107
+ ],
108
+ "servers": {
109
+ "motherduck": {
110
+ "command": "uvx",
111
+ "args": [
112
+ "mcp-server-motherduck",
113
+ "--db-path",
114
+ "md:",
115
+ "--motherduck-token",
116
+ "${input:motherduck_token}"
117
+ ]
118
+ }
119
+ }
120
+ }
121
+ ```
122
+
61
123
  ### Usage with Claude Desktop
62
124
 
63
125
  1. Install Claude Desktop from [claude.ai/download](https://claude.ai/download) if you haven't already
@@ -68,15 +130,17 @@ If you plan to use MotherDuck MCP with Claude Desktop, you will also need Claude
68
130
  - Add the following configuration to your `claude_desktop_config.json`:
69
131
 
70
132
  ```json
71
- "mcpServers": {
72
- "mcp-server-motherduck": {
73
- "command": "uvx",
74
- "args": [
75
- "mcp-server-motherduck"
76
- ],
77
- "env": {
78
- "motherduck_token": "YOUR_MOTHERDUCK_TOKEN_HERE",
79
- "HOME": "YOUR_HOME_FOLDER_PATH"
133
+ {
134
+ "mcpServers": {
135
+ "mcp-server-motherduck": {
136
+ "command": "uvx",
137
+ "args": [
138
+ "mcp-server-motherduck",
139
+ "--db-path",
140
+ "md:",
141
+ "--motherduck-token",
142
+ "<YOUR_MOTHERDUCK_TOKEN_HERE>"
143
+ ],
80
144
  }
81
145
  }
82
146
  }
@@ -99,27 +163,20 @@ Once configured, you can ask Claude to run queries like:
99
163
 
100
164
  ## Testing
101
165
 
102
- The server is designed to be run by tools like Claude Desktop, but you can start it manually for testing purposes. When testing the server manually, you can specify which database to connect to using the `--db-path` parameter:
166
+ The server is designed to be run by tools like Claude Desktop and Cursor, but you can start it manually for testing purposes. When testing the server manually, you can specify which database to connect to using the `--db-path` parameter:
103
167
 
104
168
  1. **Default MotherDuck database**:
105
169
 
106
- - To connect to the default MotherDuck database, you will need to export the `motherduck_token` environment variable.
170
+ - To connect to the default MotherDuck database, you will need to pass the auth token using the `--motherduck-token` parameter.
107
171
 
108
172
  ```bash
109
- export motherduck_token=<your_motherduck_token>
110
- uvx mcp-server-motherduck --db-path md:
111
- ```
112
-
113
- - Alternatively, you can pass the token directly:
114
-
115
- ```bash
116
- motherduck_token=<your_motherduck_token> uvx mcp-server-motherduck --db-path md:
173
+ uvx mcp-server-motherduck --db-path md: --motherduck-token <your_motherduck_token>
117
174
  ```
118
175
 
119
176
  2. **Specific MotherDuck database**:
120
177
 
121
178
  ```bash
122
- uvx mcp-server-motherduck --db-path md:your_database_name
179
+ uvx mcp-server-motherduck --db-path md:your_database_name --motherduck-token <your_motherduck_token>
123
180
  ```
124
181
 
125
182
  3. **Local DuckDB database**:
@@ -128,10 +185,10 @@ The server is designed to be run by tools like Claude Desktop, but you can start
128
185
  uvx mcp-server-motherduck --db-path /path/to/your/local.db
129
186
  ```
130
187
 
131
- 4. **In-memory database** (default if no path and no token):
188
+ 4. **In-memory database**:
132
189
 
133
190
  ```bash
134
- uvx mcp-server-motherduck
191
+ uvx mcp-server-motherduck --db-path :memory:
135
192
  ```
136
193
 
137
194
  If you don't specify a database path but have set the `motherduck_token` environment variable, the server will automatically connect to the default MotherDuck database (`md:`).
@@ -141,23 +198,18 @@ If you don't specify a database path but have set the `motherduck_token` environ
141
198
  The server could also be run ing SSE mode using `supergateway` by running the following command:
142
199
 
143
200
  ```bash
144
- motherduck_token=<your_motherduck_token> HOME=<your_home_folder_path> npx -y supergateway --stdio "uvx mcp-server-motherduck"
201
+ npx -y supergateway --stdio "uvx mcp-server-motherduck --db-path md: --motherduck-token <your_motherduck_token>"
145
202
  ```
146
203
 
147
204
  And you can point your clients such as Claude Desktop, Cursor to this endpoint.
148
205
 
149
- ### Environment Variables
150
-
151
- The server uses the following environment variables:
152
-
153
- - `motherduck_token`: Your MotherDuck authentication token
154
- - `HOME`: Directory used by DuckDB for file operations
155
-
156
206
  ## Troubleshooting
157
207
 
158
208
  - If you encounter connection issues, verify your MotherDuck token is correct
159
- - For local file access problems, ensure the `HOME` environment variable is set correctly
209
+ - For local file access problems, ensure the `--home-dir` parameter is set correctly
160
210
  - Check that the `uvx` command is available in your PATH
211
+ - If you encounter [`spawn uvx ENOENT`](https://github.com/motherduckdb/mcp-server-motherduck/issues/6) errors, try specifying the full path to `uvx` (output of `which uvx`)
212
+ - In version previous for v0.4.0 we used environment variables, now we use parameters
161
213
 
162
214
  ## License
163
215
 
@@ -34,7 +34,7 @@ All interactions with both DuckDB and MotherDuck are done through writing SQL qu
34
34
 
35
35
  - A MotherDuck account (sign up at [motherduck.com](https://motherduck.com))
36
36
  - A MotherDuck access token
37
- - `uvx` installed, you can install it using `pip install uvx` or `brew install uvx`
37
+ - `uv` installed, you can install it using `pip install uv` or `brew install uv`
38
38
 
39
39
  If you plan to use MotherDuck MCP with Claude Desktop, you will also need Claude Desktop installed.
40
40
 
@@ -44,6 +44,69 @@ If you plan to use MotherDuck MCP with Claude Desktop, you will also need Claude
44
44
  2. Generate an access token via the [MotherDuck UI](https://app.motherduck.com/settings/tokens?auth_flow=signup)
45
45
  3. Store the token securely for use in the configuration
46
46
 
47
+ ### Usage with VS Code
48
+
49
+ [![Install with UV in VS Code](https://img.shields.io/badge/VS_Code-UV-0098FF?style=flat-square&logo=visualstudiocode&logoColor=white)](https://insiders.vscode.dev/redirect/mcp/install?name=mcp-server-motherduck&config=%7B%22command%22%3A%22uvx%22%2C%22args%22%3A%5B%22mcp-server-motherduck%22%2C%22--db-path%22%2C%22md%3A%22%2C%22--motherduck-token%22%2C%22%24%7Binput%3Amotherduck_token%7D%22%5D%7D&inputs=%5B%7B%22type%22%3A%22promptString%22%2C%22id%22%3A%22motherduck_token%22%2C%22description%22%3A%22MotherDuck+Token%22%2C%22password%22%3Atrue%7D%5D) [![Install with UV in VS Code Insiders](https://img.shields.io/badge/VS_Code_Insiders-UV-24bfa5?style=flat-square&logo=visualstudiocode&logoColor=white)](https://insiders.vscode.dev/redirect/mcp/install?name=mcp-server-motherduck&config=%7B%22command%22%3A%22uvx%22%2C%22args%22%3A%5B%22mcp-server-motherduck%22%2C%22--db-path%22%2C%22md%3A%22%2C%22--motherduck-token%22%2C%22%24%7Binput%3Amotherduck_token%7D%22%5D%7D&inputs=%5B%7B%22type%22%3A%22promptString%22%2C%22id%22%3A%22motherduck_token%22%2C%22description%22%3A%22MotherDuck+Token%22%2C%22password%22%3Atrue%7D%5D&quality=insiders)
50
+ 1. For the quickest installation, click one of the "Install with UV" buttons at the top of this README.
51
+
52
+ ### Manual Installation
53
+
54
+ Add the following JSON block to your User Settings (JSON) file in VS Code. You can do this by pressing `Ctrl + Shift + P` and typing `Preferences: Open User Settings (JSON)`.
55
+
56
+ ```json
57
+ {
58
+ "mcp": {
59
+ "inputs": [
60
+ {
61
+ "type": "promptString",
62
+ "id": "motherduck_token",
63
+ "description": "MotherDuck Token",
64
+ "password": true
65
+ }
66
+ ],
67
+ "servers": {
68
+ "motherduck": {
69
+ "command": "uvx",
70
+ "args": [
71
+ "mcp-server-motherduck",
72
+ "--db-path",
73
+ "md:",
74
+ "--motherduck-token",
75
+ "${input:motherduck_token}"
76
+ ]
77
+ }
78
+ }
79
+ }
80
+ }
81
+ ```
82
+
83
+ Optionally, you can add it to a file called `.vscode/mcp.json` in your workspace. This will allow you to share the configuration with others.
84
+
85
+ ```json
86
+ {
87
+ "inputs": [
88
+ {
89
+ "type": "promptString",
90
+ "id": "motherduck_token",
91
+ "description": "MotherDuck Token",
92
+ "password": true
93
+ }
94
+ ],
95
+ "servers": {
96
+ "motherduck": {
97
+ "command": "uvx",
98
+ "args": [
99
+ "mcp-server-motherduck",
100
+ "--db-path",
101
+ "md:",
102
+ "--motherduck-token",
103
+ "${input:motherduck_token}"
104
+ ]
105
+ }
106
+ }
107
+ }
108
+ ```
109
+
47
110
  ### Usage with Claude Desktop
48
111
 
49
112
  1. Install Claude Desktop from [claude.ai/download](https://claude.ai/download) if you haven't already
@@ -54,15 +117,17 @@ If you plan to use MotherDuck MCP with Claude Desktop, you will also need Claude
54
117
  - Add the following configuration to your `claude_desktop_config.json`:
55
118
 
56
119
  ```json
57
- "mcpServers": {
58
- "mcp-server-motherduck": {
59
- "command": "uvx",
60
- "args": [
61
- "mcp-server-motherduck"
62
- ],
63
- "env": {
64
- "motherduck_token": "YOUR_MOTHERDUCK_TOKEN_HERE",
65
- "HOME": "YOUR_HOME_FOLDER_PATH"
120
+ {
121
+ "mcpServers": {
122
+ "mcp-server-motherduck": {
123
+ "command": "uvx",
124
+ "args": [
125
+ "mcp-server-motherduck",
126
+ "--db-path",
127
+ "md:",
128
+ "--motherduck-token",
129
+ "<YOUR_MOTHERDUCK_TOKEN_HERE>"
130
+ ],
66
131
  }
67
132
  }
68
133
  }
@@ -85,27 +150,20 @@ Once configured, you can ask Claude to run queries like:
85
150
 
86
151
  ## Testing
87
152
 
88
- The server is designed to be run by tools like Claude Desktop, but you can start it manually for testing purposes. When testing the server manually, you can specify which database to connect to using the `--db-path` parameter:
153
+ The server is designed to be run by tools like Claude Desktop and Cursor, but you can start it manually for testing purposes. When testing the server manually, you can specify which database to connect to using the `--db-path` parameter:
89
154
 
90
155
  1. **Default MotherDuck database**:
91
156
 
92
- - To connect to the default MotherDuck database, you will need to export the `motherduck_token` environment variable.
157
+ - To connect to the default MotherDuck database, you will need to pass the auth token using the `--motherduck-token` parameter.
93
158
 
94
159
  ```bash
95
- export motherduck_token=<your_motherduck_token>
96
- uvx mcp-server-motherduck --db-path md:
97
- ```
98
-
99
- - Alternatively, you can pass the token directly:
100
-
101
- ```bash
102
- motherduck_token=<your_motherduck_token> uvx mcp-server-motherduck --db-path md:
160
+ uvx mcp-server-motherduck --db-path md: --motherduck-token <your_motherduck_token>
103
161
  ```
104
162
 
105
163
  2. **Specific MotherDuck database**:
106
164
 
107
165
  ```bash
108
- uvx mcp-server-motherduck --db-path md:your_database_name
166
+ uvx mcp-server-motherduck --db-path md:your_database_name --motherduck-token <your_motherduck_token>
109
167
  ```
110
168
 
111
169
  3. **Local DuckDB database**:
@@ -114,10 +172,10 @@ The server is designed to be run by tools like Claude Desktop, but you can start
114
172
  uvx mcp-server-motherduck --db-path /path/to/your/local.db
115
173
  ```
116
174
 
117
- 4. **In-memory database** (default if no path and no token):
175
+ 4. **In-memory database**:
118
176
 
119
177
  ```bash
120
- uvx mcp-server-motherduck
178
+ uvx mcp-server-motherduck --db-path :memory:
121
179
  ```
122
180
 
123
181
  If you don't specify a database path but have set the `motherduck_token` environment variable, the server will automatically connect to the default MotherDuck database (`md:`).
@@ -127,23 +185,18 @@ If you don't specify a database path but have set the `motherduck_token` environ
127
185
  The server could also be run ing SSE mode using `supergateway` by running the following command:
128
186
 
129
187
  ```bash
130
- motherduck_token=<your_motherduck_token> HOME=<your_home_folder_path> npx -y supergateway --stdio "uvx mcp-server-motherduck"
188
+ npx -y supergateway --stdio "uvx mcp-server-motherduck --db-path md: --motherduck-token <your_motherduck_token>"
131
189
  ```
132
190
 
133
191
  And you can point your clients such as Claude Desktop, Cursor to this endpoint.
134
192
 
135
- ### Environment Variables
136
-
137
- The server uses the following environment variables:
138
-
139
- - `motherduck_token`: Your MotherDuck authentication token
140
- - `HOME`: Directory used by DuckDB for file operations
141
-
142
193
  ## Troubleshooting
143
194
 
144
195
  - If you encounter connection issues, verify your MotherDuck token is correct
145
- - For local file access problems, ensure the `HOME` environment variable is set correctly
196
+ - For local file access problems, ensure the `--home-dir` parameter is set correctly
146
197
  - Check that the `uvx` command is available in your PATH
198
+ - If you encounter [`spawn uvx ENOENT`](https://github.com/motherduckdb/mcp-server-motherduck/issues/6) errors, try specifying the full path to `uvx` (output of `which uvx`)
199
+ - In version previous for v0.4.0 we used environment variables, now we use parameters
147
200
 
148
201
  ## License
149
202
 
@@ -1,15 +1,14 @@
1
1
  [project]
2
2
  name = "mcp-server-motherduck"
3
- version = "0.3.4"
3
+ version = "0.4.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
8
  "mcp>=1.3.0",
9
- "duckdb>=1.2.1",
9
+ "duckdb==1.2.1",
10
10
  "pandas>=2.0.0",
11
11
  "tabulate>=0.9.0",
12
- "pydantic-settings>=2.8.1",
13
12
  ]
14
13
 
15
14
  [[project.authors]]
@@ -13,12 +13,23 @@ def main():
13
13
  parser = argparse.ArgumentParser(description="MotherDuck MCP Server")
14
14
  parser.add_argument(
15
15
  "--db-path",
16
- help="Path to local DuckDB database file",
16
+ default="md:",
17
+ help="(Default: `md:`) Path to local DuckDB database file or MotherDuck database",
18
+ )
19
+ parser.add_argument(
20
+ "--motherduck-token",
21
+ default=None,
22
+ help="(Default: env var `motherduck_token`) Access token to use for MotherDuck database connections",
23
+ )
24
+ parser.add_argument(
25
+ "--home-dir",
26
+ default=None,
27
+ help="(Default: env var `HOME`) Home directory for DuckDB",
17
28
  )
18
29
  # This is experimental and will change in the future
19
30
  parser.add_argument(
20
31
  "--result-format",
21
- help="Format of the output",
32
+ help="(Default: `markdown`) Format of the query result",
22
33
  default="markdown",
23
34
  choices=["markdown", "duckbox", "text"],
24
35
  )
@@ -28,7 +39,14 @@ def main():
28
39
  logger.info("Ready to execute SQL queries via DuckDB/MotherDuck")
29
40
  logger.info("Waiting for client connection...\n")
30
41
 
31
- asyncio.run(server.main(db_path=args.db_path, result_format=args.result_format))
42
+ asyncio.run(
43
+ server.main(
44
+ db_path=args.db_path,
45
+ motherduck_token=args.motherduck_token,
46
+ result_format=args.result_format,
47
+ home_dir=args.home_dir,
48
+ )
49
+ )
32
50
 
33
51
 
34
52
  # Optionally expose other important items at package level
@@ -12,7 +12,7 @@ from mcp.server.models import InitializationOptions
12
12
  from .prompt import PROMPT_TEMPLATE
13
13
 
14
14
 
15
- SERVER_VERSION = "0.3.4"
15
+ SERVER_VERSION = "0.4.1"
16
16
 
17
17
  logger = logging.getLogger("mcp_server_motherduck")
18
18
 
@@ -21,18 +21,26 @@ class DatabaseClient:
21
21
  def __init__(
22
22
  self,
23
23
  db_path: str | None = None,
24
+ motherduck_token: str | None = None,
24
25
  result_format: Literal["markdown", "duckbox", "text"] = "markdown",
26
+ home_dir: str | None = None,
25
27
  ):
26
- self.db_path, self.db_type = self._resolve_db_path_type(db_path)
28
+ self.db_path, self.db_type = self._resolve_db_path_type(
29
+ db_path, motherduck_token
30
+ )
27
31
  logger.info(f"Database client initialized in `{self.db_type}` mode")
28
32
 
33
+ # Set the home directory for DuckDB
34
+ if home_dir:
35
+ os.environ["HOME"] = home_dir
36
+
29
37
  self.conn = self._initialize_connection()
30
38
  self.result_format = result_format
31
39
 
32
40
  def _initialize_connection(self) -> duckdb.DuckDBPyConnection:
33
41
  """Initialize connection to the MotherDuck or DuckDB database"""
34
42
 
35
- logger.info(f"🔌 Connecting to {self.db_type} database: {self.db_path}")
43
+ logger.info(f"🔌 Connecting to {self.db_type} database")
36
44
 
37
45
  conn = duckdb.connect(
38
46
  self.db_path,
@@ -44,32 +52,36 @@ class DatabaseClient:
44
52
  return conn
45
53
 
46
54
  def _resolve_db_path_type(
47
- self, db_path: str | None = None
55
+ self, db_path: str, motherduck_token: str | None = None
48
56
  ) -> tuple[str, Literal["duckdb", "motherduck"]]:
49
57
  """Resolve and validate the database path"""
50
- # Use MotherDuck if token is available and no path specified
51
- if db_path is None and os.getenv("motherduck_token"):
52
- logger.info("Using MotherDuck token to connect to database `md:`")
53
- return "md:", "motherduck"
54
-
55
58
  # Handle MotherDuck paths
56
- if db_path and (db_path == "md:" or db_path.startswith("md:")):
57
- if not os.getenv("motherduck_token"):
59
+ if db_path.startswith("md:"):
60
+ if motherduck_token:
61
+ logger.info("Using MotherDuck token to connect to database `md:`")
62
+ return f"{db_path}?motherduck_token={motherduck_token}", "motherduck"
63
+ elif os.getenv("motherduck_token"):
64
+ logger.info(
65
+ "Using MotherDuck token from env to connect to database `md:`"
66
+ )
67
+ return (
68
+ f"{db_path}?motherduck_token={os.getenv('motherduck_token')}",
69
+ "motherduck",
70
+ )
71
+ else:
58
72
  raise ValueError(
59
- "Please set the `motherduck_token` environment variable when using `md:` as db_path."
73
+ "Please set the `motherduck_token` as an environment variable or pass it as an argument with `--motherduck-token` when using `md:` as db_path."
60
74
  )
61
- return db_path, "motherduck"
62
75
 
63
- # Handle local database paths
64
- if db_path:
65
- if not os.path.exists(db_path):
66
- raise FileNotFoundError(
67
- f"The database path `{db_path}` does not exist."
68
- )
76
+ if db_path == ":memory:":
69
77
  return db_path, "duckdb"
70
78
 
71
- # Default to in-memory database
72
- return ":memory:", "duckdb"
79
+ # Handle local database paths as the last check
80
+ if not os.path.exists(db_path):
81
+ raise FileNotFoundError(
82
+ f"The local database path `{db_path}` does not exist."
83
+ )
84
+ return db_path, "duckdb"
73
85
 
74
86
  def query(self, query: str) -> str:
75
87
  try:
@@ -94,21 +106,21 @@ class DatabaseClient:
94
106
  except Exception as e:
95
107
  raise ValueError(f"❌ Error executing query: {e}")
96
108
 
97
- def mcp_config(self) -> dict[str, str]:
98
- """Used for debugging purposes to show the current MCP config"""
99
- return {
100
- "current_working_directory": os.getcwd(),
101
- "database_type": self.db_type,
102
- "database_path": self.db_path,
103
- }
104
-
105
109
 
106
110
  async def main(
107
- db_path: str, result_format: Literal["markdown", "duckbox", "text"] = "markdown"
111
+ db_path: str,
112
+ motherduck_token: str | None = None,
113
+ result_format: Literal["markdown", "duckbox", "text"] = "markdown",
114
+ home_dir: str | None = None,
108
115
  ):
109
- logger.info(f"Starting MotherDuck MCP Server with DB path: {db_path}")
116
+ logger.info("Starting MotherDuck MCP Server")
110
117
  server = Server("mcp-server-motherduck")
111
- db_client = DatabaseClient(db_path=db_path, result_format=result_format)
118
+ db_client = DatabaseClient(
119
+ db_path=db_path,
120
+ result_format=result_format,
121
+ motherduck_token=motherduck_token,
122
+ home_dir=home_dir,
123
+ )
112
124
 
113
125
  logger.info("Registering handlers")
114
126
 
@@ -235,4 +247,3 @@ async def main(
235
247
 
236
248
  # This will only be reached when the server is shutting down
237
249
  logger.info("\n🦆 MotherDuck MCP Server shutting down...")
238
- logger.info(f"Database connection to {db_client.db_path} closed.")
@@ -1,5 +1,4 @@
1
1
  version = 1
2
- revision = 1
3
2
  requires-python = ">=3.10"
4
3
  resolution-markers = [
5
4
  "python_full_version >= '3.12'",
@@ -45,7 +44,7 @@ name = "click"
45
44
  version = "8.1.8"
46
45
  source = { registry = "https://pypi.org/simple" }
47
46
  dependencies = [
48
- { name = "colorama", marker = "sys_platform == 'win32'" },
47
+ { name = "colorama", marker = "platform_system == 'Windows'" },
49
48
  ]
50
49
  sdist = { url = "https://files.pythonhosted.org/packages/b9/2e/0090cbf739cee7d23781ad4b89a9894a41538e4fcf4c31dcdd705b78eb8b/click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a", size = 226593 }
51
50
  wheels = [
@@ -186,22 +185,20 @@ wheels = [
186
185
 
187
186
  [[package]]
188
187
  name = "mcp-server-motherduck"
189
- version = "0.3.4"
188
+ version = "0.4.1"
190
189
  source = { editable = "." }
191
190
  dependencies = [
192
191
  { name = "duckdb" },
193
192
  { name = "mcp" },
194
193
  { name = "pandas" },
195
- { name = "pydantic-settings" },
196
194
  { name = "tabulate" },
197
195
  ]
198
196
 
199
197
  [package.metadata]
200
198
  requires-dist = [
201
- { name = "duckdb", specifier = ">=1.2.1" },
199
+ { name = "duckdb", specifier = "==1.2.1" },
202
200
  { name = "mcp", specifier = ">=1.3.0" },
203
201
  { name = "pandas", specifier = ">=2.0.0" },
204
- { name = "pydantic-settings", specifier = ">=2.8.1" },
205
202
  { name = "tabulate", specifier = ">=0.9.0" },
206
203
  ]
207
204