mcp-server-motherduck 0.3.4__py3-none-any.whl → 0.4.1__py3-none-any.whl

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.

@@ -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,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
 
@@ -0,0 +1,8 @@
1
+ mcp_server_motherduck/__init__.py,sha256=_HXXeC7-S1nr4oaNEQKt_TKJrdrS_1iWRt557_pX6kI,1642
2
+ mcp_server_motherduck/prompt.py,sha256=P7BrmhVXwDkPeSHQ3f25WMP6lpBpN2BxDzYPOQ3fxX8,56699
3
+ mcp_server_motherduck/server.py,sha256=gu00iJLnTNNxyC5UHA7Xt_7G_5iv32IVCi5RptjcCyk,9085
4
+ mcp_server_motherduck-0.4.1.dist-info/METADATA,sha256=39Ru2YTcZDBCwr4R5T0bBcbs1hYLYlsMRM4csQGk4hg,8006
5
+ mcp_server_motherduck-0.4.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
6
+ mcp_server_motherduck-0.4.1.dist-info/entry_points.txt,sha256=dRTgcvWJn40bz0PVuKPylK6w92cFN32lwunZOgo5j4s,69
7
+ mcp_server_motherduck-0.4.1.dist-info/licenses/LICENSE,sha256=Tj68w9jCiceFKTvZ3jET-008NjhozcQMXpm-fyL9WUI,1067
8
+ mcp_server_motherduck-0.4.1.dist-info/RECORD,,
@@ -1,8 +0,0 @@
1
- mcp_server_motherduck/__init__.py,sha256=fvkO3-wgyUVAdIzy-As4pl3_LYHFMgO9STVTHAyTyKA,1078
2
- mcp_server_motherduck/prompt.py,sha256=P7BrmhVXwDkPeSHQ3f25WMP6lpBpN2BxDzYPOQ3fxX8,56699
3
- mcp_server_motherduck/server.py,sha256=N7ySKj43BtMRGE_9HGhWr8_3wGSsjxKD9xIJJv7W4Eg,8841
4
- mcp_server_motherduck-0.3.4.dist-info/METADATA,sha256=jhdryCCXMVJdKKi0o7E6v9NiJBakx_d9HRECRn21mks,5623
5
- mcp_server_motherduck-0.3.4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
6
- mcp_server_motherduck-0.3.4.dist-info/entry_points.txt,sha256=dRTgcvWJn40bz0PVuKPylK6w92cFN32lwunZOgo5j4s,69
7
- mcp_server_motherduck-0.3.4.dist-info/licenses/LICENSE,sha256=Tj68w9jCiceFKTvZ3jET-008NjhozcQMXpm-fyL9WUI,1067
8
- mcp_server_motherduck-0.3.4.dist-info/RECORD,,