mcp-server-motherduck 0.2.0__py3-none-any.whl → 0.2.2__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.
- mcp_server_motherduck/server.py +12 -33
- mcp_server_motherduck-0.2.2.dist-info/METADATA +64 -0
- mcp_server_motherduck-0.2.2.dist-info/RECORD +7 -0
- {mcp_server_motherduck-0.2.0.dist-info → mcp_server_motherduck-0.2.2.dist-info}/WHEEL +1 -1
- mcp_server_motherduck-0.2.2.dist-info/licenses/LICENSE +21 -0
- mcp_server_motherduck-0.2.0.dist-info/METADATA +0 -117
- mcp_server_motherduck-0.2.0.dist-info/RECORD +0 -6
- {mcp_server_motherduck-0.2.0.dist-info → mcp_server_motherduck-0.2.2.dist-info}/entry_points.txt +0 -0
mcp_server_motherduck/server.py
CHANGED
|
@@ -8,8 +8,9 @@ import mcp.server.stdio
|
|
|
8
8
|
import os
|
|
9
9
|
import duckdb
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
SERVER_VERSION = "0.2.2"
|
|
12
|
+
|
|
13
|
+
PROMPT_TEMPLATE = """The assistant's goal is to help users interact with DuckDB/MotherDuck databases effectively.
|
|
13
14
|
Start by establishing the connection type preference and maintain a helpful, conversational tone throughout the interaction.
|
|
14
15
|
<mcp>
|
|
15
16
|
Tools:
|
|
@@ -112,7 +113,7 @@ Here are some DuckDB SQL syntax specifics you should be aware of:
|
|
|
112
113
|
- DuckDB has built-in functions for regex regexp_matches(column, regex), regexp_replace(column, regex), and regexp_extract(column, regex).
|
|
113
114
|
- DuckDB has a way to quickly get a subset of your data with `SELECT * FROM large_table USING SAMPLE 10%;`
|
|
114
115
|
|
|
115
|
-
DuckDB Functions:
|
|
116
|
+
Common DuckDB Functions:
|
|
116
117
|
`count`: Calculates the total number of rows returned by a SQL query result. This function is commonly used to determine the row count of a SELECT operation., Parameters: ['result: The result object']
|
|
117
118
|
`sum`: Calculates the total of all non-null values in a specified column or expression across rows., Parameters: ['arg: Values to be aggregated']
|
|
118
119
|
`max`: Returns the largest value from all values in a specified column or expression., Parameters: ['arg: expression to evaluate maximum', "n: top 'n' value list size(optional)"]
|
|
@@ -143,7 +144,7 @@ DuckDB Functions:
|
|
|
143
144
|
`now`: Obtains the current date and time at the start of the current transaction, using the system's time zone., Parameters: ['None: No parameters required(optional)']
|
|
144
145
|
`group_concat`: Concatenates column string values using a specified separator, respecting the provided order., Parameters: ['arg: The column to concatenate', 'sep: Separator between concatenated values(optional)', 'ORDER BY: Specifies order of concatenation(optional)']
|
|
145
146
|
|
|
146
|
-
DuckDB Statements:
|
|
147
|
+
Common DuckDB Statements:
|
|
147
148
|
`FROM`: The FROM clause specifies the source of the data for the query. It can include a single table, multiple joined tables, or subqueries. The JOIN clause is used to combine rows from two or more tables based on a related column between them. There are several types of joins, including INNER, OUTER, CROSS, NATURAL, SEMI, ANTI, LATERAL, POSITIONAL, ASOF, and self-joins., Examples: ['SELECT * FROM table_name;', 'FROM table_name SELECT *;', 'FROM table_name;', 'SELECT tn.* FROM table_name tn;', 'SELECT * FROM schema_name.table_name;', 'SELECT t.i FROM range(100) AS t(i);', "SELECT * FROM 'test.csv';", 'SELECT * FROM (SELECT * FROM table_name);', 'SELECT t FROM t;', "SELECT t FROM (SELECT unnest(generate_series(41, 43)) AS x, 'hello' AS y) t;", 'SELECT * FROM table_name JOIN other_table ON table_name.key = other_table.key;', 'SELECT * FROM table_name TABLESAMPLE 10%;', 'SELECT * FROM table_name TABLESAMPLE 10 ROWS;', 'FROM range(100) AS t(i) SELECT sum(t.i) WHERE i % 2 = 0;', 'SELECT a.*, b.* FROM a CROSS JOIN b;', 'SELECT a.*, b.* FROM a, b;', 'SELECT n.*, r.* FROM l_nations n JOIN l_regions r ON (n_regionkey = r_regionkey);', 'SELECT * FROM city_airport NATURAL JOIN airport_names;', 'SELECT * FROM city_airport JOIN airport_names USING (iata);', 'SELECT * FROM city_airport SEMI JOIN airport_names USING (iata);', 'SELECT * FROM city_airport WHERE iata IN (SELECT iata FROM airport_names);', 'SELECT * FROM city_airport ANTI JOIN airport_names USING (iata);', 'SELECT * FROM city_airport WHERE iata NOT IN (SELECT iata FROM airport_names WHERE iata IS NOT NULL);', 'SELECT * FROM range(3) t(i), LATERAL (SELECT i + 1) t2(j);', 'SELECT * FROM generate_series(0, 1) t(i), LATERAL (SELECT i + 10 UNION ALL SELECT i + 100) t2(j);', 'SELECT * FROM trades t ASOF JOIN prices p ON t.symbol = p.symbol AND t.when >= p.when;', 'SELECT * FROM trades t ASOF LEFT JOIN prices p ON t.symbol = p.symbol AND t.when >= p.when;', 'SELECT * FROM trades t ASOF JOIN prices p USING (symbol, "when");', 'SELECT t.symbol, t.when AS trade_when, p.when AS price_when, price FROM trades t ASOF LEFT JOIN prices p USING (symbol, "when");', 'SELECT * FROM t AS t t1 JOIN t t2 USING(x);', 'FROM tbl SELECT i, s;', 'FROM tbl;']
|
|
148
149
|
`SELECT`: The SELECT statement retrieves rows from the database. It is used to query the database and retrieve data according to specific requirements. The statement can include several clauses, such as FROM, WHERE, GROUP BY, ORDER BY, and LIMIT, to filter, organize, and limit the query results., Examples: ['SELECT * FROM tbl;', 'SELECT j FROM tbl WHERE i = 3;', 'SELECT i, sum(j) FROM tbl GROUP BY i;', 'SELECT * FROM tbl ORDER BY i DESC LIMIT 3;', 'SELECT * FROM t1 JOIN t2 USING (a, b);', 'SELECT #1, #3 FROM tbl;', 'SELECT DISTINCT city FROM addresses;', 'SELECT d FROM (SELECT 1 AS a, 2 AS b) d;', 'SELECT rowid, id, content FROM t;']
|
|
149
150
|
`WHERE`: The WHERE clause specifies filters to apply to the data being queried, allowing selection of a specific subset of data. It is logically applied immediately after the FROM clause in a SQL query., Examples: ['SELECT * FROM table_name WHERE id = 3;', "SELECT * FROM table_name WHERE name ILIKE '%mark%';", 'SELECT * FROM table_name WHERE id = 3 OR id = 7;']
|
|
@@ -172,7 +173,7 @@ DuckDB Statements:
|
|
|
172
173
|
`PIVOT`: The PIVOT statement in DuckDB allows distinct values within a column to be transformed into their own columns. The values within these new columns are calculated using an aggregate function on the subset of rows matching each distinct value. DuckDB supports both the SQL Standard PIVOT syntax, which requires explicit column names, and a simplified PIVOT syntax that can automatically detect which columns to create. The PIVOT statement is useful for reshaping data for analysis, similar to the way pivot tables work in spreadsheet software., Examples: ['PIVOT Cities ON Year USING sum(Population);', 'PIVOT Cities ON Year USING first(Population);', 'PIVOT Cities ON Year USING sum(Population) GROUP BY Country;', 'PIVOT Cities ON Year IN (2000, 2010) USING sum(Population) GROUP BY Country;', 'PIVOT Cities ON Country, Name USING sum(Population);', "PIVOT Cities ON Country || '_' || Name USING sum(Population);", 'PIVOT Cities ON Year USING sum(Population) AS total, max(Population) AS max GROUP BY Country;', 'PIVOT Cities ON Year USING sum(Population) GROUP BY Country, Name;', 'SELECT * FROM (PIVOT Cities ON Year USING sum(Population) GROUP BY Country) pivot_alias;']
|
|
173
174
|
`FILTER`: The FILTER clause is used in conjunction with aggregate functions within a SELECT statement to filter the input data specifically for the aggregate function. This allows for conditions to be applied similar to a WHERE clause, but localized to the aggregate function. It is useful for scenarios like pivoting data and handling null values cleanly, particularly with functions like 'first', 'last', 'list', and 'array_agg'. FILTER cannot be used in window functions., Examples: ['SELECT count(*) FILTER (i <= 5) AS lte_five FROM generate_series(1, 10) tbl(i);', 'SELECT sum(i) FILTER (i <= 5) AS lte_five_sum FROM generate_series(1, 10) tbl(i);', 'SELECT count(i) FILTER (year = 2022) AS "2022" FROM stacked_data;', 'SELECT first(i) FILTER (year = 2022) AS "2022" FROM stacked_data;']
|
|
174
175
|
|
|
175
|
-
DuckDB Types:
|
|
176
|
+
Common DuckDB Types:
|
|
176
177
|
`VARCHAR`: `VARCHAR` is a versatile data type used to store variable-length character strings, accommodating a wide range of text and string data without enforcing a specific length., Examples: ['CREATE TABLE people (name VARCHAR, age INTEGER);', "INSERT INTO documents (text) VALUES ('This is a VARCHAR example text.');", "SELECT * FROM employees WHERE department = 'Engineering';", 'ALTER TABLE students ADD COLUMN email VARCHAR;', "UPDATE orders SET status = 'Shipped' WHERE order_id = 102;", "COPY products TO 'products.csv' DELIMITER ',' HEADER;"]
|
|
177
178
|
`INTEGER`: The INTEGER data type, with aliases such as int, signed, int4, int32, integer, and integral, represents whole numbers and is commonly used to store numeric data without fractional components., Examples: ['-- Assigning integer values to columns in a CREATE TABLE statement\nCREATE TABLE my_table (id INTEGER, age INTEGER);', '-- Inserting integer values as literals within an INSERT statement\nINSERT INTO my_table VALUES (1, 25);', '-- Using integer operations in a SELECT statement\nSELECT id + 10 AS new_id FROM my_table;', '-- Casting a float to an integer\nSELECT CAST(3.7 AS INTEGER) AS whole_number;', '-- Defining a column to only accept non-negative integers using a CHECK constraint\nCREATE TABLE my_table (id INTEGER CHECK (id >= 0));', '-- Using the INTEGER type in a primary key definition\nCREATE TABLE users (user_id INTEGER PRIMARY KEY, username VARCHAR);', '-- Updating integer columns\nUPDATE my_table SET age = age + 1 WHERE id = 1;', '-- Comparing integer values in a WHERE clause\nSELECT * FROM my_table WHERE age > 20;']
|
|
178
179
|
`NULL`: The `NULL` type in SQL represents a missing or unknown value, allowing for fields within a table to be uninitialized or absent in data., Examples: ['SELECT NULL = NULL;', 'SELECT NULL IS NULL;', "INSERT INTO table_name (column1, column2) VALUES (NULL, 'data');", "SELECT coalesce(NULL, 'default_value');", 'UPDATE table_name SET column1 = NULL WHERE condition;', "SELECT CASE WHEN column IS NULL THEN 'Value is NULL' ELSE column END FROM table_name;"]
|
|
@@ -197,37 +198,13 @@ DuckDB Types:
|
|
|
197
198
|
`SMALLINT`: The SMALLINT type, with aliases such as short, int2, smallint, and int16, represents a signed two-byte integer that can store whole numbers ranging from -32768 to 32767., Examples: ['CREATE TABLE test_table (id SMALLINT);', 'INSERT INTO test_table (id) VALUES (100);', 'SELECT * FROM test_table WHERE id BETWEEN -100 AND 100;', 'ALTER TABLE test_table ADD COLUMN new_column SMALLINT;', 'UPDATE test_table SET id = id + 1 WHERE id < 32767;']
|
|
198
199
|
`BLOB`: The BLOB (Binary Large Object) type represents a variable-length binary data object, used for storing arbitrary binary data in the database, such as images or files, without any interpretation of its contents., Examples: ["-- Create a BLOB with a single byte\\nSELECT '\\xAA'::BLOB;\\n-- Result: \\xAA\\n\\n-- Create a BLOB with multiple bytes\\nSELECT '\\xAA\\xAB\\xAC'::BLOB;\\n-- Result: \\xAA\\xAB\\xAC\\n\\n-- Concatenate two BLOB values\\nSELECT '\\xAA'::BLOB || '\\xBB'::BLOB;\\n-- Result: \\xAABB\\n\\n-- Convert a BLOB to a hexadecimal string\\nSELECT hex('\\xAA\\xBB'::BLOB);\\n-- Result: AABB\\n\\n-- Decode a BLOB to a string, ensuring it is valid UTF-8\\nSELECT decode('\\xC3\\xBC'::BLOB);\\n-- Result: ü\\n\\n-- Read a BLOB from a file\\nSELECT read_blob('myfile.bin');\\n-- Result: Contents of 'myfile.bin' as a BLOB"]
|
|
199
200
|
|
|
200
|
-
DuckDB
|
|
201
|
-
`SELECT`: The `SELECT` statement is used to query and retrieve data from tables, allowing for specification of columns, conditions, and data transformations., Examples: ['SELECT * FROM table_name;', 'SELECT column1, column2 FROM table_name WHERE condition;', 'SELECT DISTINCT column1 FROM table_name;', 'SELECT column1, COUNT(*) FROM table_name GROUP BY column1;', 'SELECT column1, column2 FROM table_name ORDER BY column1 DESC;', 'SELECT column1 AS alias FROM table_name;', 'SELECT t1.column1, t2.column2 FROM table1 t1 JOIN table2 t2 ON t1.id = t2.id;', 'SELECT column1 FROM table_name WHERE column2 IN (SELECT column2 FROM other_table);']
|
|
202
|
-
`FROM`: The FROM clause is used to specify the data source for a SQL query, which can be a single table, a combination of tables joined together, or a subquery, and can optionally use a FROM-first syntax allowing query formation without a SELECT clause., Examples: ['SELECT * FROM table_name;', 'FROM table_name SELECT *;', 'FROM table_name;', 'SELECT tn.* FROM table_name tn;', 'SELECT * FROM schema_name.table_name;', 'SELECT t.i FROM range(100) AS t(i);', "SELECT * FROM 'test.csv';", 'SELECT * FROM (SELECT * FROM table_name);', 'SELECT t FROM t;', "SELECT t FROM (SELECT unnest(generate_series(41, 43)) AS x, 'hello' AS y) t;", 'SELECT * FROM table_name JOIN other_table ON table_name.key = other_table.key;', 'SELECT * FROM table_name TABLESAMPLE 10%;', 'SELECT * FROM table_name TABLESAMPLE 10 ROWS;', 'FROM range(100) AS t(i) SELECT sum(t.i) WHERE i % 2 = 0;']
|
|
201
|
+
Common DuckDB Keywords:
|
|
203
202
|
`AS`: The `AS` keyword in SQL is used to create an alias for columns or tables, helping to simplify query logic and improve readability., Examples: ['SELECT first_name AS name FROM employees;', 'SELECT department AS dept FROM company;', 'CREATE VIEW sales_report AS SELECT * FROM sales WHERE year = 2023;', 'SELECT product_name AS name, SUM(sales) AS total_sales FROM store GROUP BY product_name;', 'SELECT c.customer_id, c.name AS customer_name, o.order_id, o.total_amount AS amount FROM customers c INNER JOIN orders o ON c.customer_id = o.customer_id;']
|
|
204
|
-
`BY`: "by" is used in SQL to specify sorting or grouping columns for organizing query results, such as in "ORDER BY" or "PARTITION BY" clauses., Examples: ['SELECT row_number() OVER (ORDER BY time) FROM sales;', 'SELECT amount - lag(amount) OVER (ORDER BY time) FROM sales;', 'SELECT amount / sum(amount) OVER (PARTITION BY region) FROM sales;', 'SELECT * FROM tbl ORDER BY column_name ASC;', 'SELECT MIN(salary) FROM employees GROUP BY department;']
|
|
205
|
-
`AND`: "AND" is a logical operator used to combine multiple conditions in SQL queries, returning true only if all conditions are true., Examples: ["SELECT * FROM employees WHERE department = 'Sales' AND salary > 50000;", "SELECT * FROM orders WHERE order_date >= '2023-01-01' AND status = 'Pending';", "SELECT * FROM customers WHERE age > 21 AND city = 'New York';", "SELECT * FROM products WHERE category = 'Electronics' AND stock_quantity > 0;", "SELECT * FROM students WHERE grade = 'A' AND attendance_percentage > 90;"]
|
|
206
|
-
`WHERE`: The `WHERE` clause in SQL is used to filter records that satisfy a specified boolean condition, determining which rows are returned in the result set., Examples: ["SELECT * FROM weather WHERE city = 'San Francisco' AND prcp > 0.0;", 'SELECT city, max(temp_lo) FROM weather GROUP BY city HAVING max(temp_lo) < 40;', "UPDATE weather SET temp_hi = temp_hi - 2, temp_lo = temp_lo - 2 WHERE date > '1994-11-28';", "DELETE FROM weather WHERE city = 'Hayward';"]
|
|
207
|
-
`OR`: The `ORDER BY` clause sorts query results based on specified columns or expressions, with optional ascending or descending order and handling of NULL values., Examples: ['SELECT * FROM addresses ORDER BY city;', 'SELECT * FROM addresses ORDER BY city DESC NULLS LAST;', 'SELECT * FROM addresses ORDER BY city, zip;', 'SELECT * FROM addresses ORDER BY city COLLATE DE;', 'SELECT * FROM addresses ORDER BY ALL;', 'SELECT * FROM addresses ORDER BY ALL DESC;']
|
|
208
|
-
`TABLE`: The `CREATE TABLE` statement in SQL is used to define a new table along with its columns and constraints, such as specifying data types, primary keys, unique constraints, and check constraints, among other options., Examples: ['CREATE TABLE t1 (i INTEGER, j INTEGER);', 'CREATE TABLE t1 (id INTEGER PRIMARY KEY, j VARCHAR);', 'CREATE TABLE t1 (id INTEGER, j VARCHAR, PRIMARY KEY (id, j));', 'CREATE TABLE t1 (i INTEGER NOT NULL, decimalnr DOUBLE CHECK (decimalnr < 10), date DATE UNIQUE, time TIMESTAMP);', 'CREATE TABLE t1 AS SELECT 42 AS i, 84 AS j;', "CREATE TABLE t1 AS FROM read_csv('path/file.csv');", 'CREATE TABLE t1 AS FROM t2 LIMIT 0;', "CREATE TEMP TABLE t1 AS SELECT * FROM read_csv('path/file.csv');", 'CREATE OR REPLACE TABLE t1 (i INTEGER, j INTEGER);', 'CREATE TABLE IF NOT EXISTS t1 (i INTEGER, j INTEGER);']
|
|
209
|
-
`JOIN`: Joins are essential operations in SQL for combining tables based on related columns, helping to establish relationships and derive meaningful insights from separate datasets., Examples: ['SELECT * FROM table1 JOIN table2 ON table1.id = table2.id;', 'SELECT a.*, b.* FROM a LEFT JOIN b ON a.id = b.id;', 'SELECT * FROM a NATURAL JOIN b;', 'SELECT * FROM table1 CROSS JOIN table2;', 'SELECT * FROM table1 LEFT OUTER JOIN table2 ON table1.id = table2.id;', 'SELECT * FROM orders INNER JOIN customers ON orders.customer_id = customers.id;', 'SELECT t.*, s.value FROM table t LEFT LATERAL JOIN summary s ON t.id = s.id;', 'SELECT t.* FROM table1 t ANTI JOIN table2 s ON t.id = s.id;']
|
|
210
|
-
`ON`: The `ON` keyword in SQL is used with various clauses and statements such as JOIN, UPDATE, DELETE, and ON CONFLICT to specify conditions for selecting, updating, or deleting rows that match specific criteria in relational databases., Examples: ['SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.id;', "UPDATE employees SET salary = salary * 1.1 ON department.id = employees.department_id WHERE department.name = 'Engineering';", "DELETE FROM orders WHERE orders.date < '2023-01-01' ON CONFLICT DO NOTHING;", "INSERT INTO products (id, name) VALUES (1, 'Widget') ON CONFLICT (id) DO UPDATE SET name = EXCLUDED.name;"]
|
|
211
|
-
`NOT`: The `NOT` keyword in SQL is used to negate a condition, meaning it reverses the truth value of the condition it's used with., Examples: ['SELECT * FROM Students WHERE NOT (grade > 80);', 'SELECT * FROM Employees WHERE NOT EXISTS (SELECT * FROM Promotions WHERE Promotions.employee_id = Employees.id);', "SELECT * FROM Products WHERE NOT (name LIKE 'A%');", 'SELECT * FROM Orders WHERE order_date IS NOT NULL;', 'SELECT * FROM Library WHERE NOT (publication_year BETWEEN 1980 AND 2000);']
|
|
212
|
-
`THEN`: The `FILTER` clause refines the input to an aggregate function in a `SELECT` statement, allowing different conditions for separate aggregates., Examples: ['SELECT count(*) AS total_rows, count(*) FILTER (i <= 5) AS lte_five, count(*) FILTER (i % 2 = 1) AS odds FROM generate_series(1, 10) tbl(i);', 'SELECT sum(i) FILTER (i <= 5) AS lte_five_sum, median(i) FILTER (i % 2 = 1) AS odds_median, median(i) FILTER (i % 2 = 1 AND i <= 5) AS odds_lte_five_median FROM generate_series(1, 10) tbl(i);', 'SELECT count(i) FILTER (year = 2022) AS "2022", count(i) FILTER (year = 2023) AS "2023", count(i) FILTER (year = 2024) AS "2024", count(i) FILTER (year = 2025) AS "2025", count(i) FILTER (year IS NULL) AS "NULLs" FROM stacked_data;', 'SELECT first(i) FILTER (year = 2022) AS "2022", first(i) FILTER (year = 2023) AS "2023", first(i) FILTER (year = 2024) AS "2024", first(i) FILTER (year = 2025) AS "2025", first(i) FILTER (year IS NULL) AS "NULLs" FROM stacked_data;']
|
|
213
|
-
`END`: The FILTER clause is used to apply conditions to aggregate functions, allowing selective aggregation based on specific criteria within a SELECT statement., Examples: ['SELECT count(*) FILTER (i <= 5) AS lte_five FROM generate_series(1, 10) tbl(i);', 'SELECT sum(i) FILTER (i <= 5) AS lte_five_sum FROM generate_series(1, 10) tbl(i);', 'SELECT count(i) FILTER (year = 2022) AS "2022" FROM stacked_data;']
|
|
214
|
-
`WHEN`: The `WHEN` keyword is used in a `CASE` statement to specify a condition that, if true, results in the execution of the corresponding expression., Examples: ["SELECT i, CASE WHEN i > 2 THEN 'Greater than 2' ELSE '2 or less' END FROM integers;", "SELECT i, CASE WHEN i = 1 THEN 'One' WHEN i = 2 THEN 'Two' ELSE 'Other' END FROM integers;", 'SELECT pretty_print_integer(n) AS result FROM numbers WHERE WHEN n > 1000 THEN true ELSE false;']
|
|
215
|
-
`CASE`: The `CASE` statement in SQL is used for conditional logic in queries, allowing you to perform a switch based on a condition, similar to a ternary operator in programming languages., Examples: ['SELECT i, CASE WHEN i > 2 THEN 1 ELSE 0 END AS test FROM integers;', 'SELECT i, CASE WHEN i = 1 THEN 10 WHEN i = 2 THEN 20 ELSE 0 END AS test FROM integers;', 'SELECT i, CASE WHEN i = 1 THEN 10 END AS test FROM integers;', 'SELECT i, CASE i WHEN 1 THEN 10 WHEN 2 THEN 20 WHEN 3 THEN 30 END AS test FROM integers;']
|
|
216
|
-
`NULL`: The NULL keyword in SQL represents a missing or unknown value, often used to indicate the absence of a definite value in a column., Examples: ["CREATE TABLE users (id INTEGER, name VARCHAR, age INTEGER); INSERT INTO users VALUES (1, 'Alice', NULL);", 'SELECT * FROM users WHERE age IS NULL;', 'UPDATE users SET age = 30 WHERE age IS NULL;', 'DELETE FROM users WHERE name IS NULL;', 'SELECT COALESCE(age, 0) AS age_with_default FROM users;', 'SELECT NULL = NULL; -- Returns NULL as NULL is not equal to anything, including itself', "SELECT ifnull(name, 'Unknown') FROM users -- Uses 'Unknown' if name is NULL;"]
|
|
217
203
|
`DISTINCT`: The `DISTINCT` keyword is used in the SQL `SELECT` statement to ensure that only unique values are returned for specified columns, effectively removing duplicate rows from the result set., Examples: ['SELECT DISTINCT city FROM addresses;', 'SELECT DISTINCT ON(country) city, population FROM cities ORDER BY population DESC;']
|
|
218
|
-
`DESC`: The keyword `desc` is used in SQL to describe the DESCENDING order in which query results should be sorted, often associated with the `ORDER BY` clause., Examples: ['SELECT name FROM employees ORDER BY salary DESC;', 'CREATE TABLE example (id INTEGER, name VARCHAR);', 'DESCRIBE example;', 'DESCRIBE SELECT * FROM example WHERE id < 10 ORDER BY name DESC;']
|
|
219
|
-
`CREATE`: The `CREATE` keyword is used to define new database structures, such as tables or macros, in the SQL catalog., Examples: ['CREATE TABLE t1 (i INTEGER, j INTEGER);', "CREATE TEMP TABLE t1 AS SELECT * FROM read_csv('path/file.csv');", 'CREATE OR REPLACE TABLE t1 (i INTEGER, j INTEGER);', 'CREATE TABLE IF NOT EXISTS t1 (i INTEGER, j INTEGER);', 'CREATE TABLE nums AS SELECT i FROM range(0, 3) t(i);', 'CREATE TABLE t1 (x FLOAT, two_x AS (2 * x));', 'CREATE MACRO add(a, b) AS a + b;']
|
|
220
|
-
`ORDER`: The `ORDER BY` clause is used to sort the rows returned by a SQL query based on specified columns, allowing for ascending or descending order and optional null order modifiers., Examples: ['SELECT * FROM addresses ORDER BY city;', 'SELECT * FROM addresses ORDER BY city DESC NULLS LAST;', 'SELECT * FROM addresses ORDER BY city, zip;', 'SELECT * FROM addresses ORDER BY city COLLATE DE;', 'SELECT * FROM addresses ORDER BY ALL;', 'SELECT * FROM addresses ORDER BY ALL DESC;']
|
|
221
|
-
`ELSE`: The "ELSE" keyword in a CASE statement provides a default result when none of the "WHEN" conditions are met., Examples: ['SELECT i, CASE WHEN i > 2 THEN 1 ELSE 0 END AS test FROM integers;', 'SELECT i, CASE WHEN i = 1 THEN 10 WHEN i = 2 THEN 20 ELSE 0 END AS test FROM integers;', 'SELECT i, CASE WHEN i = 1 THEN 10 END AS test FROM integers;']
|
|
222
|
-
`GROUP`: Grouping in SQL using clauses like GROUPING SETS, ROLLUP, and CUBE allows for performing aggregations across multiple dimensions within a single query., Examples: ['SELECT city, street_name, avg(income) FROM addresses GROUP BY GROUPING SETS ((city, street_name), (city), (street_name), ());', 'SELECT city, street_name, avg(income) FROM addresses GROUP BY CUBE (city, street_name);', 'SELECT city, street_name, avg(income) FROM addresses GROUP BY ROLLUP (city, street_name);', 'SELECT course, type, count(*) FROM students GROUP BY GROUPING SETS ((course, type), course, type, ());', 'SELECT y, q, m, GROUPING_ID(y, q, m) AS "grouping_id()" FROM days GROUP BY GROUPING SETS ((y, q, m), (y, q), (y), ()) ORDER BY y, q, m;']
|
|
223
|
-
`IS`: The "IS" keyword is used in SQL to perform tests on values to check for NULL values or to use as part of statements like IS DISTINCT FROM which can handle NULLs in equality comparisons., Examples: ['SELECT 4 IS DISTINCT FROM NULL;', 'SELECT 4 IS NOT DISTINCT FROM 4;', 'SELECT NULL IS NULL;', 'SELECT NULL IS NOT NULL;']
|
|
224
|
-
`REPLACE`: The `REPLACE` clause is used in a `SELECT` statement to replace specific columns with different expressions, effectively transforming the output of the `REPLACE` columns with the new specified expressions while retaining the rest of the columns unchanged., Examples: ['SELECT * REPLACE (lower(city) AS city) FROM addresses;', 'SELECT * REPLACE (col / 1000 AS col) FROM tbl;']
|
|
225
|
-
`WITH`: The `WITH` clause allows defining common table expressions (CTEs) for simplifying complex queries by creating temporary result sets that can be referenced within the main SQL query., Examples: ['WITH cte AS (SELECT 42 AS x) SELECT * FROM cte;', 'WITH cte1 AS (SELECT 42 AS i), cte2 AS (SELECT i * 100 AS x FROM cte1) SELECT * FROM cte2;', 'WITH t(x) AS MATERIALIZED (SELECT * FROM t), SELECT * FROM t AS t1, t AS t2, t AS t3;', 'WITH RECURSIVE FibonacciNumbers AS (... recursive logic ...) SELECT ... FROM FibonacciNumbers;']
|
|
226
204
|
`IN`: The `IN` keyword is used in SQL to specify a list of discrete values for a column to match against, typically in a `WHERE` clause, allowing for multiple specific conditions to be evaluated at once., Examples: ["SELECT * FROM employees WHERE department IN ('HR', 'Engineering', 'Marketing');", 'SELECT id, name FROM students WHERE grade IN (10, 11, 12);', "DELETE FROM orders WHERE order_status IN ('Cancelled', 'Returned');", "UPDATE items SET status = 'Unavailable' WHERE item_id IN (1001, 1002, 1003);", "SELECT * FROM logs WHERE severity IN ('ERROR', 'CRITICAL') ORDER BY timestamp DESC;"]
|
|
227
205
|
`OVER`: The `OVER` clause in SQL specifies a window for evaluating window functions, allowing computations over a defined group of rows in a result set., Examples: ['SELECT row_number() OVER () FROM sales;', 'SELECT row_number() OVER (ORDER BY time) FROM sales;', 'SELECT row_number() OVER (PARTITION BY region ORDER BY time) FROM sales;', 'SELECT amount - lag(amount) OVER (ORDER BY time) FROM sales;', 'SELECT amount / sum(amount) OVER (PARTITION BY region) FROM sales;']
|
|
228
206
|
`ALL`: The `ALL` keyword in SQL specifies that operations should retain all duplicate rows, as seen in commands like `UNION ALL`, `INTERSECT ALL`, and `EXCEPT ALL`, which follow bag semantics instead of eliminating duplicates., Examples: ['UNION ALL\n\n```sql\nSELECT * FROM range(2) t1(x)\nUNION ALL\nSELECT * FROM range(3) t2(x);\n```\nThis example demonstrates using `UNION ALL` to combine rows from two queries without eliminating duplicates.', 'INTERSECT ALL\n\n```sql\nSELECT unnest([5, 5, 6, 6, 6, 6, 7, 8]) AS x\nINTERSECT ALL\nSELECT unnest([5, 6, 6, 7, 7, 9]);\n```\nThis example shows using `INTERSECT ALL` to select rows that are present in both result sets, keeping duplicate values.', 'EXCEPT ALL\n\n```sql\nSELECT unnest([5, 5, 6, 6, 6, 6, 7, 8]) AS x\nEXCEPT ALL\nSELECT unnest([5, 6, 6, 7, 7, 9]);\n```\nThis example illustrates `EXCEPT ALL`, which selects all rows present in the first query but not in the second, without removing duplicates.', 'ORDER BY ALL\n\n```sql\nSELECT *\nFROM addresses\nORDER BY ALL;\n```\nThis SQL command uses `ORDER BY ALL` to sort the result set by all columns sequentially from left to right.']
|
|
229
207
|
`LIKE`: The `LIKE` expression is used to determine if a string matches a specified pattern, allowing wildcard characters such as `_` to represent any single character and `%` to match any sequence of characters., Examples: ["SELECT 'abc' LIKE 'abc'; -- true", "SELECT 'abc' LIKE 'a%'; -- true", "SELECT 'abc' LIKE '_b_'; -- true", "SELECT 'abc' LIKE 'c'; -- false", "SELECT 'abc' LIKE 'c%'; -- false", "SELECT 'abc' LIKE '%c'; -- true", "SELECT 'abc' NOT LIKE '%c'; -- false", "SELECT 'abc' ILIKE '%C'; -- true"]
|
|
230
|
-
`LEFT`: The `LEFT JOIN` keyword in SQL is used to combine rows from two or more tables based on a related column between them, but it will return all records from the left table and the matched records from the right table, with null values in columns of the right table where there is no match., Examples: ['SELECT customers.customer_id, orders.order_id FROM customers LEFT JOIN orders ON customers.customer_id = orders.customer_id;', 'SELECT city.name, weather.temp_lo FROM city LEFT JOIN weather ON city.name = weather.city;', 'SELECT a.id, b.value FROM table_a a LEFT JOIN table_b b ON a.id = b.a_id;', 'SELECT * FROM employees LEFT JOIN departments ON employees.department_id = departments.id;', 'SELECT students.name, grades.score FROM students LEFT JOIN grades ON students.id = grades.student_id WHERE grades.score IS NULL;']
|
|
231
208
|
"""
|
|
232
209
|
|
|
233
210
|
server = Server("mcp-server-motherduck")
|
|
@@ -275,7 +252,7 @@ async def handle_get_prompt(
|
|
|
275
252
|
raise ValueError(f"Unknown prompt: {name}")
|
|
276
253
|
|
|
277
254
|
return types.GetPromptResult(
|
|
278
|
-
description=f"Initial prompt
|
|
255
|
+
description=f"Initial prompt for interacting with DuckDB/MotherDuck",
|
|
279
256
|
messages=[
|
|
280
257
|
types.PromptMessage(
|
|
281
258
|
role="user",
|
|
@@ -342,7 +319,9 @@ async def handle_call_tool(
|
|
|
342
319
|
if type == 'MOTHERDUCK' and not os.getenv('motherduck_token'):
|
|
343
320
|
raise ValueError("Please set the `motherduck_token` environment variable.")
|
|
344
321
|
if type == 'MOTHERDUCK':
|
|
345
|
-
conn = duckdb.connect('md:'
|
|
322
|
+
conn = duckdb.connect('md:', config={
|
|
323
|
+
"custom_user_agent": f"mcp-server-motherduck/{SERVER_VERSION}"
|
|
324
|
+
})
|
|
346
325
|
elif type == 'DUCKDB':
|
|
347
326
|
conn = duckdb.connect()
|
|
348
327
|
databases = conn.execute("""select string_agg(database_name, ',\n')
|
|
@@ -381,7 +360,7 @@ async def main():
|
|
|
381
360
|
write_stream,
|
|
382
361
|
InitializationOptions(
|
|
383
362
|
server_name="motherduck",
|
|
384
|
-
server_version=
|
|
363
|
+
server_version=SERVER_VERSION,
|
|
385
364
|
capabilities=server.get_capabilities(
|
|
386
365
|
notification_options=NotificationOptions(),
|
|
387
366
|
experimental_capabilities={},
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: mcp-server-motherduck
|
|
3
|
+
Version: 0.2.2
|
|
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: duckdb>=1.1.3
|
|
9
|
+
Requires-Dist: mcp>=1.0.0
|
|
10
|
+
Description-Content-Type: text/markdown
|
|
11
|
+
|
|
12
|
+
# mcp-server-motherduck MCP server
|
|
13
|
+
|
|
14
|
+
A MCP server for MotherDuck and local DuckDB
|
|
15
|
+
|
|
16
|
+
## Components
|
|
17
|
+
|
|
18
|
+
### Resources
|
|
19
|
+
|
|
20
|
+
### Prompts
|
|
21
|
+
|
|
22
|
+
The server provides one prompt:
|
|
23
|
+
- duckdb-motherduck-initial-prompt: A prompt to initialize a connection to duckdb or motherduck and start working with it
|
|
24
|
+
|
|
25
|
+
### Tools
|
|
26
|
+
|
|
27
|
+
The server offers three tools:
|
|
28
|
+
- initialize-connection: Create a connection to either a local DuckDB or MotherDuck and retrieve available databases
|
|
29
|
+
- Takes "type" (DuckDB or MotherDuck) as input
|
|
30
|
+
- read-schemas: Get table schemas from a specific DuckDB/MotherDuck database
|
|
31
|
+
- Takes "database_name" as required string arguments
|
|
32
|
+
- execute-query: Execute a query on the MotherDuck (DuckDB) database
|
|
33
|
+
- Takes "query" as required string arguments
|
|
34
|
+
|
|
35
|
+
## Usage with Claude Desktop
|
|
36
|
+
|
|
37
|
+
Add the snippet below to your Claude Desktop config and make sure to set the HOME var to your home folder (needed by DuckDB).
|
|
38
|
+
|
|
39
|
+
When using MotherDuck, you also need to set a [MotherDuck token](https://motherduck.com/docs/key-tasks/authenticating-and-connecting-to-motherduck/authenticating-to-motherduck/#storing-the-access-token-as-an-environment-variable) env var.
|
|
40
|
+
|
|
41
|
+
On MacOS: `~/Library/Application\ Support/Claude/claude_desktop_config.json`
|
|
42
|
+
|
|
43
|
+
On Windows: `%APPDATA%/Claude/claude_desktop_config.json`
|
|
44
|
+
|
|
45
|
+
### Servers Configuration
|
|
46
|
+
```
|
|
47
|
+
"mcpServers": {
|
|
48
|
+
"mcp-server-motherduck": {
|
|
49
|
+
"command": "uvx",
|
|
50
|
+
"args": [
|
|
51
|
+
"mcp-server-motherduck"
|
|
52
|
+
],
|
|
53
|
+
"env": {
|
|
54
|
+
"motherduck_token": "",
|
|
55
|
+
"HOME": ""
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## License
|
|
62
|
+
|
|
63
|
+
This MCP server is licensed under the MIT License. This means you are free to use, modify, and distribute the software, subject to the terms and conditions of the MIT License. For more details, please see the LICENSE file in the project repository.
|
|
64
|
+
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
mcp_server_motherduck/__init__.py,sha256=KNZ1bD9ZGfyZwlv91Ueeega_1lsRDLs2fYQDgNbBdtc,212
|
|
2
|
+
mcp_server_motherduck/server.py,sha256=1PHePShKoDM51fMxyqPEkia5sEjZlABDPxYOv-p9Dus,63630
|
|
3
|
+
mcp_server_motherduck-0.2.2.dist-info/METADATA,sha256=ErMEO2zKtdDjIB-wJWd0FRBgHYqLPFo9SS4g_YgCaao,2066
|
|
4
|
+
mcp_server_motherduck-0.2.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
5
|
+
mcp_server_motherduck-0.2.2.dist-info/entry_points.txt,sha256=dRTgcvWJn40bz0PVuKPylK6w92cFN32lwunZOgo5j4s,69
|
|
6
|
+
mcp_server_motherduck-0.2.2.dist-info/licenses/LICENSE,sha256=Tj68w9jCiceFKTvZ3jET-008NjhozcQMXpm-fyL9WUI,1067
|
|
7
|
+
mcp_server_motherduck-0.2.2.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 MotherDuck
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.3
|
|
2
|
-
Name: mcp-server-motherduck
|
|
3
|
-
Version: 0.2.0
|
|
4
|
-
Summary: A MCP server for MotherDuck
|
|
5
|
-
Author-email: tdoehmen <till@motherduck.com>
|
|
6
|
-
Requires-Python: >=3.10
|
|
7
|
-
Requires-Dist: duckdb>=1.1.3
|
|
8
|
-
Requires-Dist: mcp>=1.0.0
|
|
9
|
-
Description-Content-Type: text/markdown
|
|
10
|
-
|
|
11
|
-
# mcp-server-motherduck MCP server
|
|
12
|
-
|
|
13
|
-
A MCP server for MotherDuck and local DuckDB
|
|
14
|
-
|
|
15
|
-
## Components
|
|
16
|
-
|
|
17
|
-
### Resources
|
|
18
|
-
|
|
19
|
-
### Prompts
|
|
20
|
-
|
|
21
|
-
The server implements one prompt:
|
|
22
|
-
- duckdb-motherduck-initial-prompt: A prompt to initialize a connection to duckdb or motherduck and start working with it
|
|
23
|
-
|
|
24
|
-
### Tools
|
|
25
|
-
|
|
26
|
-
The server implements three tools:
|
|
27
|
-
- initialize-connection: Create a connection to either a local DuckDB or MotherDuck and retrieve available databases
|
|
28
|
-
- Takes "type" (DuckDB or MotherDuck) as input
|
|
29
|
-
- read-schemas: Get table schemas from a specific DuckDB/MotherDuck database
|
|
30
|
-
- Takes "database_name" as required string arguments
|
|
31
|
-
- execute-query: Execute a query on the MotherDuck (DuckDB) database
|
|
32
|
-
- Takes "query" as required string arguments
|
|
33
|
-
|
|
34
|
-
## Configuration Claude Desktop
|
|
35
|
-
|
|
36
|
-
Add the snippet below to your Claude Desktop config and make sure to set the HOME var to your home folder (needed by DuckDB).
|
|
37
|
-
|
|
38
|
-
When using MotherDuck, you also need to set a [MotherDuck token](https://motherduck.com/docs/key-tasks/authenticating-and-connecting-to-motherduck/authenticating-to-motherduck/#storing-the-access-token-as-an-environment-variable) env var.
|
|
39
|
-
|
|
40
|
-
On MacOS: `~/Library/Application\ Support/Claude/claude_desktop_config.json`
|
|
41
|
-
On Windows: `%APPDATA%/Claude/claude_desktop_config.json`
|
|
42
|
-
|
|
43
|
-
<details>
|
|
44
|
-
<summary>Published Servers Configuration</summary>
|
|
45
|
-
```
|
|
46
|
-
"mcpServers": {
|
|
47
|
-
"mcp-server-motherduck": {
|
|
48
|
-
"command": "uvx",
|
|
49
|
-
"args": [
|
|
50
|
-
"mcp-server-motherduck"
|
|
51
|
-
],
|
|
52
|
-
"env": {
|
|
53
|
-
"motherduck_token": "",
|
|
54
|
-
"HOME": ""
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
```
|
|
59
|
-
</details>
|
|
60
|
-
|
|
61
|
-
## Development
|
|
62
|
-
|
|
63
|
-
### Building and Publishing
|
|
64
|
-
|
|
65
|
-
To prepare the package for distribution:
|
|
66
|
-
|
|
67
|
-
1. Sync dependencies and update lockfile:
|
|
68
|
-
```bash
|
|
69
|
-
uv sync
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
2. Build package distributions:
|
|
73
|
-
```bash
|
|
74
|
-
uv build
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
This will create source and wheel distributions in the `dist/` directory.
|
|
78
|
-
|
|
79
|
-
3. Publish to PyPI:
|
|
80
|
-
```bash
|
|
81
|
-
uv publish
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
Note: You'll need to set PyPI credentials via environment variables or command flags:
|
|
85
|
-
- Token: `--token` or `UV_PUBLISH_TOKEN`
|
|
86
|
-
- Or username/password: `--username`/`UV_PUBLISH_USERNAME` and `--password`/`UV_PUBLISH_PASSWORD`
|
|
87
|
-
|
|
88
|
-
### Debugging
|
|
89
|
-
|
|
90
|
-
<details>
|
|
91
|
-
<summary>Development/Unpublished Servers Configuration</summary>
|
|
92
|
-
```
|
|
93
|
-
"mcpServers": {
|
|
94
|
-
"mcp-server-motherduck": {
|
|
95
|
-
"command": "uv",
|
|
96
|
-
"args": [
|
|
97
|
-
"--directory",
|
|
98
|
-
"/Users/<username>/mcp-server/mcp-server-motherduck",
|
|
99
|
-
"run",
|
|
100
|
-
"mcp-server-motherduck"
|
|
101
|
-
]
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
```
|
|
105
|
-
</details>
|
|
106
|
-
|
|
107
|
-
Since MCP servers run over stdio, debugging can be challenging. For the best debugging
|
|
108
|
-
experience, we strongly recommend using the [MCP Inspector](https://github.com/modelcontextprotocol/inspector).
|
|
109
|
-
|
|
110
|
-
You can launch the MCP Inspector via [`npm`](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) with this command:
|
|
111
|
-
|
|
112
|
-
```bash
|
|
113
|
-
npx @modelcontextprotocol/inspector uv --directory /Users/<username>/mcp-server/mcp-server-motherduck run mcp-server-motherduck
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
Upon launching, the Inspector will display a URL that you can access in your browser to begin debugging.
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
mcp_server_motherduck/__init__.py,sha256=KNZ1bD9ZGfyZwlv91Ueeega_1lsRDLs2fYQDgNbBdtc,212
|
|
2
|
-
mcp_server_motherduck/server.py,sha256=Ahg2Y4dbEYXVlYeb-HOMkjj8JaRJUVRs8g_-Fh8ezbQ,77014
|
|
3
|
-
mcp_server_motherduck-0.2.0.dist-info/METADATA,sha256=YsfTGiygwp5FcHoLWTB2k7RN6KwLt6KHXLE9OsliNrI,3332
|
|
4
|
-
mcp_server_motherduck-0.2.0.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
|
|
5
|
-
mcp_server_motherduck-0.2.0.dist-info/entry_points.txt,sha256=dRTgcvWJn40bz0PVuKPylK6w92cFN32lwunZOgo5j4s,69
|
|
6
|
-
mcp_server_motherduck-0.2.0.dist-info/RECORD,,
|
{mcp_server_motherduck-0.2.0.dist-info → mcp_server_motherduck-0.2.2.dist-info}/entry_points.txt
RENAMED
|
File without changes
|