@cmd233/mcp-database-server 1.1.1
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.
- package/LICENSE +21 -0
- package/dist/src/db/adapter.js +29 -0
- package/dist/src/db/index.js +95 -0
- package/dist/src/db/mysql-adapter.js +205 -0
- package/dist/src/db/postgresql-adapter.js +169 -0
- package/dist/src/db/sqlite-adapter.js +134 -0
- package/dist/src/db/sqlserver-adapter.js +186 -0
- package/dist/src/handlers/resourceHandlers.js +71 -0
- package/dist/src/handlers/toolHandlers.js +158 -0
- package/dist/src/index.js +259 -0
- package/dist/src/tools/insightTools.js +54 -0
- package/dist/src/tools/queryTools.js +73 -0
- package/dist/src/tools/schemaTools.js +118 -0
- package/dist/src/utils/formatUtils.js +56 -0
- package/package.json +41 -0
- package/readme.md +328 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { dbAll, dbExec, dbRun } from '../db/index.js';
|
|
2
|
+
import { formatSuccessResponse } from '../utils/formatUtils.js';
|
|
3
|
+
/**
|
|
4
|
+
* Add a business insight to the memo
|
|
5
|
+
* @param insight Business insight text
|
|
6
|
+
* @returns Result of the operation
|
|
7
|
+
*/
|
|
8
|
+
export async function appendInsight(insight) {
|
|
9
|
+
try {
|
|
10
|
+
if (!insight) {
|
|
11
|
+
throw new Error("Insight text is required");
|
|
12
|
+
}
|
|
13
|
+
// Create insights table if it doesn't exist
|
|
14
|
+
await dbExec(`
|
|
15
|
+
CREATE TABLE IF NOT EXISTS mcp_insights (
|
|
16
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
17
|
+
insight TEXT NOT NULL,
|
|
18
|
+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
19
|
+
)
|
|
20
|
+
`);
|
|
21
|
+
// Insert the insight
|
|
22
|
+
await dbRun("INSERT INTO mcp_insights (insight) VALUES (?)", [insight]);
|
|
23
|
+
return formatSuccessResponse({ success: true, message: "Insight added" });
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
throw new Error(`Error adding insight: ${error.message}`);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* List all insights in the memo
|
|
31
|
+
* @returns Array of insights
|
|
32
|
+
*/
|
|
33
|
+
export async function listInsights() {
|
|
34
|
+
try {
|
|
35
|
+
// Check if insights table exists
|
|
36
|
+
const tableExists = await dbAll("SELECT name FROM sqlite_master WHERE type='table' AND name = 'mcp_insights'");
|
|
37
|
+
if (tableExists.length === 0) {
|
|
38
|
+
// Create table if it doesn't exist
|
|
39
|
+
await dbExec(`
|
|
40
|
+
CREATE TABLE IF NOT EXISTS mcp_insights (
|
|
41
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
42
|
+
insight TEXT NOT NULL,
|
|
43
|
+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
44
|
+
)
|
|
45
|
+
`);
|
|
46
|
+
return formatSuccessResponse([]);
|
|
47
|
+
}
|
|
48
|
+
const insights = await dbAll("SELECT * FROM mcp_insights ORDER BY created_at DESC");
|
|
49
|
+
return formatSuccessResponse(insights);
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
throw new Error(`Error listing insights: ${error.message}`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { dbAll, dbRun } from '../db/index.js';
|
|
2
|
+
import { formatSuccessResponse, convertToCSV } from '../utils/formatUtils.js';
|
|
3
|
+
/**
|
|
4
|
+
* Execute a read-only SQL query
|
|
5
|
+
* @param query SQL query to execute
|
|
6
|
+
* @returns Query results
|
|
7
|
+
*/
|
|
8
|
+
export async function readQuery(query) {
|
|
9
|
+
try {
|
|
10
|
+
if (!query.trim().toLowerCase().startsWith("select")) {
|
|
11
|
+
throw new Error("Only SELECT queries are allowed with read_query");
|
|
12
|
+
}
|
|
13
|
+
const result = await dbAll(query);
|
|
14
|
+
return formatSuccessResponse(result);
|
|
15
|
+
}
|
|
16
|
+
catch (error) {
|
|
17
|
+
throw new Error(`SQL Error: ${error.message}`);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Execute a data modification SQL query
|
|
22
|
+
* @param query SQL query to execute
|
|
23
|
+
* @returns Information about affected rows
|
|
24
|
+
*/
|
|
25
|
+
export async function writeQuery(query) {
|
|
26
|
+
try {
|
|
27
|
+
const lowerQuery = query.trim().toLowerCase();
|
|
28
|
+
if (lowerQuery.startsWith("select")) {
|
|
29
|
+
throw new Error("Use read_query for SELECT operations");
|
|
30
|
+
}
|
|
31
|
+
if (!(lowerQuery.startsWith("insert") || lowerQuery.startsWith("update") || lowerQuery.startsWith("delete"))) {
|
|
32
|
+
throw new Error("Only INSERT, UPDATE, or DELETE operations are allowed with write_query");
|
|
33
|
+
}
|
|
34
|
+
const result = await dbRun(query);
|
|
35
|
+
return formatSuccessResponse({ affected_rows: result.changes });
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
throw new Error(`SQL Error: ${error.message}`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Export query results to CSV or JSON format
|
|
43
|
+
* @param query SQL query to execute
|
|
44
|
+
* @param format Output format (csv or json)
|
|
45
|
+
* @returns Formatted query results
|
|
46
|
+
*/
|
|
47
|
+
export async function exportQuery(query, format) {
|
|
48
|
+
try {
|
|
49
|
+
if (!query.trim().toLowerCase().startsWith("select")) {
|
|
50
|
+
throw new Error("Only SELECT queries are allowed with export_query");
|
|
51
|
+
}
|
|
52
|
+
const result = await dbAll(query);
|
|
53
|
+
if (format === "csv") {
|
|
54
|
+
const csvData = convertToCSV(result);
|
|
55
|
+
return {
|
|
56
|
+
content: [{
|
|
57
|
+
type: "text",
|
|
58
|
+
text: csvData
|
|
59
|
+
}],
|
|
60
|
+
isError: false,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
else if (format === "json") {
|
|
64
|
+
return formatSuccessResponse(result);
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
throw new Error("Unsupported export format. Use 'csv' or 'json'");
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
throw new Error(`Export Error: ${error.message}`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { dbAll, dbExec, getListTablesQuery, getDescribeTableQuery } from '../db/index.js';
|
|
2
|
+
import { formatSuccessResponse } from '../utils/formatUtils.js';
|
|
3
|
+
/**
|
|
4
|
+
* Create a new table in the database
|
|
5
|
+
* @param query CREATE TABLE SQL statement
|
|
6
|
+
* @returns Result of the operation
|
|
7
|
+
*/
|
|
8
|
+
export async function createTable(query) {
|
|
9
|
+
try {
|
|
10
|
+
if (!query.trim().toLowerCase().startsWith("create table")) {
|
|
11
|
+
throw new Error("Only CREATE TABLE statements are allowed");
|
|
12
|
+
}
|
|
13
|
+
await dbExec(query);
|
|
14
|
+
return formatSuccessResponse({ success: true, message: "Table created successfully" });
|
|
15
|
+
}
|
|
16
|
+
catch (error) {
|
|
17
|
+
throw new Error(`SQL Error: ${error.message}`);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Alter an existing table schema
|
|
22
|
+
* @param query ALTER TABLE SQL statement
|
|
23
|
+
* @returns Result of the operation
|
|
24
|
+
*/
|
|
25
|
+
export async function alterTable(query) {
|
|
26
|
+
try {
|
|
27
|
+
if (!query.trim().toLowerCase().startsWith("alter table")) {
|
|
28
|
+
throw new Error("Only ALTER TABLE statements are allowed");
|
|
29
|
+
}
|
|
30
|
+
await dbExec(query);
|
|
31
|
+
return formatSuccessResponse({ success: true, message: "Table altered successfully" });
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
throw new Error(`SQL Error: ${error.message}`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Drop a table from the database
|
|
39
|
+
* @param tableName Name of the table to drop
|
|
40
|
+
* @param confirm Safety confirmation flag
|
|
41
|
+
* @returns Result of the operation
|
|
42
|
+
*/
|
|
43
|
+
export async function dropTable(tableName, confirm) {
|
|
44
|
+
try {
|
|
45
|
+
if (!tableName) {
|
|
46
|
+
throw new Error("Table name is required");
|
|
47
|
+
}
|
|
48
|
+
if (!confirm) {
|
|
49
|
+
return formatSuccessResponse({
|
|
50
|
+
success: false,
|
|
51
|
+
message: "Safety confirmation required. Set confirm=true to proceed with dropping the table."
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
// First check if table exists by directly querying for tables
|
|
55
|
+
const query = getListTablesQuery();
|
|
56
|
+
const tables = await dbAll(query);
|
|
57
|
+
const tableNames = tables.map(t => t.name);
|
|
58
|
+
if (!tableNames.includes(tableName)) {
|
|
59
|
+
throw new Error(`Table '${tableName}' does not exist`);
|
|
60
|
+
}
|
|
61
|
+
// Drop the table
|
|
62
|
+
await dbExec(`DROP TABLE "${tableName}"`);
|
|
63
|
+
return formatSuccessResponse({
|
|
64
|
+
success: true,
|
|
65
|
+
message: `Table '${tableName}' dropped successfully`
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
throw new Error(`Error dropping table: ${error.message}`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* List all tables in the database
|
|
74
|
+
* @returns Array of table names
|
|
75
|
+
*/
|
|
76
|
+
export async function listTables() {
|
|
77
|
+
try {
|
|
78
|
+
// Use adapter-specific query for listing tables
|
|
79
|
+
const query = getListTablesQuery();
|
|
80
|
+
const tables = await dbAll(query);
|
|
81
|
+
return formatSuccessResponse(tables.map((t) => t.name));
|
|
82
|
+
}
|
|
83
|
+
catch (error) {
|
|
84
|
+
throw new Error(`Error listing tables: ${error.message}`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Get schema information for a specific table
|
|
89
|
+
* @param tableName Name of the table to describe
|
|
90
|
+
* @returns Column definitions for the table
|
|
91
|
+
*/
|
|
92
|
+
export async function describeTable(tableName) {
|
|
93
|
+
try {
|
|
94
|
+
if (!tableName) {
|
|
95
|
+
throw new Error("Table name is required");
|
|
96
|
+
}
|
|
97
|
+
// First check if table exists by directly querying for tables
|
|
98
|
+
const query = getListTablesQuery();
|
|
99
|
+
const tables = await dbAll(query);
|
|
100
|
+
const tableNames = tables.map(t => t.name);
|
|
101
|
+
if (!tableNames.includes(tableName)) {
|
|
102
|
+
throw new Error(`Table '${tableName}' does not exist`);
|
|
103
|
+
}
|
|
104
|
+
// Use adapter-specific query for describing tables
|
|
105
|
+
const descQuery = getDescribeTableQuery(tableName);
|
|
106
|
+
const columns = await dbAll(descQuery);
|
|
107
|
+
return formatSuccessResponse(columns.map((col) => ({
|
|
108
|
+
name: col.name,
|
|
109
|
+
type: col.type,
|
|
110
|
+
notnull: !!col.notnull,
|
|
111
|
+
default_value: col.dflt_value,
|
|
112
|
+
primary_key: !!col.pk
|
|
113
|
+
})));
|
|
114
|
+
}
|
|
115
|
+
catch (error) {
|
|
116
|
+
throw new Error(`Error describing table: ${error.message}`);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Convert data to CSV format
|
|
3
|
+
* @param data Array of objects to convert to CSV
|
|
4
|
+
* @returns CSV formatted string
|
|
5
|
+
*/
|
|
6
|
+
export function convertToCSV(data) {
|
|
7
|
+
if (data.length === 0)
|
|
8
|
+
return '';
|
|
9
|
+
// Get headers
|
|
10
|
+
const headers = Object.keys(data[0]);
|
|
11
|
+
// Create CSV header row
|
|
12
|
+
let csv = headers.join(',') + '\n';
|
|
13
|
+
// Add data rows
|
|
14
|
+
data.forEach(row => {
|
|
15
|
+
const values = headers.map(header => {
|
|
16
|
+
const val = row[header];
|
|
17
|
+
// Handle strings with commas, quotes, etc.
|
|
18
|
+
if (typeof val === 'string') {
|
|
19
|
+
return `"${val.replace(/"/g, '""')}"`;
|
|
20
|
+
}
|
|
21
|
+
// Use empty string for null/undefined
|
|
22
|
+
return val === null || val === undefined ? '' : val;
|
|
23
|
+
});
|
|
24
|
+
csv += values.join(',') + '\n';
|
|
25
|
+
});
|
|
26
|
+
return csv;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Format error response
|
|
30
|
+
* @param error Error object or message
|
|
31
|
+
* @returns Formatted error response object
|
|
32
|
+
*/
|
|
33
|
+
export function formatErrorResponse(error) {
|
|
34
|
+
const message = error instanceof Error ? error.message : error;
|
|
35
|
+
return {
|
|
36
|
+
content: [{
|
|
37
|
+
type: "text",
|
|
38
|
+
text: JSON.stringify({ error: message }, null, 2)
|
|
39
|
+
}],
|
|
40
|
+
isError: true
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Format success response
|
|
45
|
+
* @param data Data to format
|
|
46
|
+
* @returns Formatted success response object
|
|
47
|
+
*/
|
|
48
|
+
export function formatSuccessResponse(data) {
|
|
49
|
+
return {
|
|
50
|
+
content: [{
|
|
51
|
+
type: "text",
|
|
52
|
+
text: JSON.stringify(data, null, 2)
|
|
53
|
+
}],
|
|
54
|
+
isError: false
|
|
55
|
+
};
|
|
56
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@cmd233/mcp-database-server",
|
|
3
|
+
"version": "1.1.1",
|
|
4
|
+
"description": "MCP server for interacting with SQLite, SQL Server, PostgreSQL and MySQL databases (Fixed nullable field detection)",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "cmd233",
|
|
7
|
+
"homepage": "https://github.com/cmd233/mcp-database-server",
|
|
8
|
+
"bugs": "https://github.com/cmd233/mcp-database-server/issues",
|
|
9
|
+
"type": "module",
|
|
10
|
+
"bin": {
|
|
11
|
+
"ea-database-server": "dist/src/index.js"
|
|
12
|
+
},
|
|
13
|
+
"files": [
|
|
14
|
+
"dist"
|
|
15
|
+
],
|
|
16
|
+
"scripts": {
|
|
17
|
+
"build": "tsc && shx chmod +x dist/src/index.js",
|
|
18
|
+
"prepare": "npm run build",
|
|
19
|
+
"watch": "tsc --watch",
|
|
20
|
+
"start": "node dist/src/index.js",
|
|
21
|
+
"dev": "tsc && node dist/src/index.js",
|
|
22
|
+
"example": "node examples/example.js",
|
|
23
|
+
"clean": "rimraf dist"
|
|
24
|
+
},
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"@aws-sdk/rds-signer": "^3.0.0",
|
|
27
|
+
"@modelcontextprotocol/sdk": "1.9.0",
|
|
28
|
+
"mssql": "11.0.1",
|
|
29
|
+
"mysql2": "^3.14.1",
|
|
30
|
+
"pg": "^8.11.3",
|
|
31
|
+
"sqlite3": "5.1.7"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@types/mssql": "^9.1.5",
|
|
35
|
+
"@types/pg": "^8.11.13",
|
|
36
|
+
"@types/sqlite3": "5.1.0",
|
|
37
|
+
"rimraf": "^5.0.5",
|
|
38
|
+
"shx": "0.4.0",
|
|
39
|
+
"typescript": "5.8.3"
|
|
40
|
+
}
|
|
41
|
+
}
|
package/readme.md
ADDED
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
[](https://mseep.ai/app/executeautomation-mcp-database-server)
|
|
2
|
+
|
|
3
|
+
# MCP Database Server
|
|
4
|
+
|
|
5
|
+
This MCP (Model Context Protocol) server provides database access capabilities to Claude, supporting SQLite, SQL Server, PostgreSQL, and MySQL databases.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
1. Clone the repository:
|
|
10
|
+
```
|
|
11
|
+
git clone https://github.com/executeautomation/mcp-database-server.git
|
|
12
|
+
cd mcp-database-server
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
2. Install dependencies:
|
|
16
|
+
```
|
|
17
|
+
npm install
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
3. Build the project:
|
|
21
|
+
```
|
|
22
|
+
npm run build
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Usage Options
|
|
26
|
+
|
|
27
|
+
There are two ways to use this MCP server with Claude:
|
|
28
|
+
|
|
29
|
+
1. **Direct usage**: Install the package globally and use it directly
|
|
30
|
+
2. **Local development**: Run from your local development environment
|
|
31
|
+
|
|
32
|
+
### Direct Usage with NPM Package
|
|
33
|
+
|
|
34
|
+
The easiest way to use this MCP server is by installing it globally:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
npm install -g @executeautomation/database-server
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
This allows you to use the server directly without building it locally.
|
|
41
|
+
|
|
42
|
+
### Local Development Setup
|
|
43
|
+
|
|
44
|
+
If you want to modify the code or run from your local environment:
|
|
45
|
+
|
|
46
|
+
1. Clone and build the repository as shown in the Installation section
|
|
47
|
+
2. Run the server using the commands in the Usage section below
|
|
48
|
+
|
|
49
|
+
## Usage
|
|
50
|
+
|
|
51
|
+
### SQLite Database
|
|
52
|
+
|
|
53
|
+
To use with an SQLite database:
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
node dist/src/index.js /path/to/your/database.db
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### SQL Server Database
|
|
60
|
+
|
|
61
|
+
To use with a SQL Server database:
|
|
62
|
+
|
|
63
|
+
```
|
|
64
|
+
node dist/src/index.js --sqlserver --server <server-name> --database <database-name> [--user <username> --password <password>]
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Required parameters:
|
|
68
|
+
- `--server`: SQL Server host name or IP address
|
|
69
|
+
- `--database`: Name of the database
|
|
70
|
+
|
|
71
|
+
Optional parameters:
|
|
72
|
+
- `--user`: Username for SQL Server authentication (if not provided, Windows Authentication will be used)
|
|
73
|
+
- `--password`: Password for SQL Server authentication
|
|
74
|
+
- `--port`: Port number (default: 1433)
|
|
75
|
+
|
|
76
|
+
### PostgreSQL Database
|
|
77
|
+
|
|
78
|
+
To use with a PostgreSQL database:
|
|
79
|
+
|
|
80
|
+
```
|
|
81
|
+
node dist/src/index.js --postgresql --host <host-name> --database <database-name> [--user <username> --password <password>]
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Required parameters:
|
|
85
|
+
- `--host`: PostgreSQL host name or IP address
|
|
86
|
+
- `--database`: Name of the database
|
|
87
|
+
|
|
88
|
+
Optional parameters:
|
|
89
|
+
- `--user`: Username for PostgreSQL authentication
|
|
90
|
+
- `--password`: Password for PostgreSQL authentication
|
|
91
|
+
- `--port`: Port number (default: 5432)
|
|
92
|
+
- `--ssl`: Enable SSL connection (true/false)
|
|
93
|
+
- `--connection-timeout`: Connection timeout in milliseconds (default: 30000)
|
|
94
|
+
|
|
95
|
+
### MySQL Database
|
|
96
|
+
|
|
97
|
+
#### Standard Authentication
|
|
98
|
+
|
|
99
|
+
To use with a MySQL database:
|
|
100
|
+
|
|
101
|
+
```
|
|
102
|
+
node dist/src/index.js --mysql --host <host-name> --database <database-name> --port <port> [--user <username> --password <password>]
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Required parameters:
|
|
106
|
+
- `--host`: MySQL host name or IP address
|
|
107
|
+
- `--database`: Name of the database
|
|
108
|
+
- `--port`: Port number (default: 3306)
|
|
109
|
+
|
|
110
|
+
Optional parameters:
|
|
111
|
+
- `--user`: Username for MySQL authentication
|
|
112
|
+
- `--password`: Password for MySQL authentication
|
|
113
|
+
- `--ssl`: Enable SSL connection (true/false or object)
|
|
114
|
+
- `--connection-timeout`: Connection timeout in milliseconds (default: 30000)
|
|
115
|
+
|
|
116
|
+
#### AWS IAM Authentication
|
|
117
|
+
|
|
118
|
+
For Amazon RDS MySQL instances with IAM database authentication:
|
|
119
|
+
|
|
120
|
+
**Prerequisites:**
|
|
121
|
+
- AWS credentials must be configured (the RDS Signer uses the default credential provider chain)
|
|
122
|
+
- Configure using one of these methods:
|
|
123
|
+
- `aws configure` (uses default profile)
|
|
124
|
+
- `AWS_PROFILE=myprofile` environment variable
|
|
125
|
+
- `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` environment variables
|
|
126
|
+
- IAM roles (if running on EC2)
|
|
127
|
+
|
|
128
|
+
```
|
|
129
|
+
node dist/src/index.js --mysql --aws-iam-auth --host <rds-endpoint> --database <database-name> --user <aws-username> --aws-region <region>
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Required parameters:
|
|
133
|
+
- `--host`: RDS endpoint hostname
|
|
134
|
+
- `--database`: Name of the database
|
|
135
|
+
- `--aws-iam-auth`: Enable AWS IAM authentication
|
|
136
|
+
- `--user`: AWS IAM username (also the database user)
|
|
137
|
+
- `--aws-region`: AWS region where RDS instance is located
|
|
138
|
+
|
|
139
|
+
Note: SSL is automatically enabled for AWS IAM authentication
|
|
140
|
+
|
|
141
|
+
## Configuring Claude Desktop
|
|
142
|
+
|
|
143
|
+
### Direct Usage Configuration
|
|
144
|
+
|
|
145
|
+
If you installed the package globally, configure Claude Desktop with:
|
|
146
|
+
|
|
147
|
+
```json
|
|
148
|
+
{
|
|
149
|
+
"mcpServers": {
|
|
150
|
+
"sqlite": {
|
|
151
|
+
"command": "npx",
|
|
152
|
+
"args": [
|
|
153
|
+
"-y",
|
|
154
|
+
"@executeautomation/database-server",
|
|
155
|
+
"/path/to/your/database.db"
|
|
156
|
+
]
|
|
157
|
+
},
|
|
158
|
+
"sqlserver": {
|
|
159
|
+
"command": "npx",
|
|
160
|
+
"args": [
|
|
161
|
+
"-y",
|
|
162
|
+
"@executeautomation/database-server",
|
|
163
|
+
"--sqlserver",
|
|
164
|
+
"--server", "your-server-name",
|
|
165
|
+
"--database", "your-database-name",
|
|
166
|
+
"--user", "your-username",
|
|
167
|
+
"--password", "your-password"
|
|
168
|
+
]
|
|
169
|
+
},
|
|
170
|
+
"postgresql": {
|
|
171
|
+
"command": "npx",
|
|
172
|
+
"args": [
|
|
173
|
+
"-y",
|
|
174
|
+
"@executeautomation/database-server",
|
|
175
|
+
"--postgresql",
|
|
176
|
+
"--host", "your-host-name",
|
|
177
|
+
"--database", "your-database-name",
|
|
178
|
+
"--user", "your-username",
|
|
179
|
+
"--password", "your-password"
|
|
180
|
+
]
|
|
181
|
+
},
|
|
182
|
+
"mysql": {
|
|
183
|
+
"command": "npx",
|
|
184
|
+
"args": [
|
|
185
|
+
"-y",
|
|
186
|
+
"@executeautomation/database-server",
|
|
187
|
+
"--mysql",
|
|
188
|
+
"--host", "your-host-name",
|
|
189
|
+
"--database", "your-database-name",
|
|
190
|
+
"--port", "3306",
|
|
191
|
+
"--user", "your-username",
|
|
192
|
+
"--password", "your-password"
|
|
193
|
+
]
|
|
194
|
+
},
|
|
195
|
+
"mysql-aws": {
|
|
196
|
+
"command": "npx",
|
|
197
|
+
"args": [
|
|
198
|
+
"-y",
|
|
199
|
+
"@executeautomation/database-server",
|
|
200
|
+
"--mysql",
|
|
201
|
+
"--aws-iam-auth",
|
|
202
|
+
"--host", "your-rds-endpoint.region.rds.amazonaws.com",
|
|
203
|
+
"--database", "your-database-name",
|
|
204
|
+
"--user", "your-aws-username",
|
|
205
|
+
"--aws-region", "us-east-1"
|
|
206
|
+
]
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### Local Development Configuration
|
|
213
|
+
|
|
214
|
+
For local development, configure Claude Desktop to use your locally built version:
|
|
215
|
+
|
|
216
|
+
```json
|
|
217
|
+
{
|
|
218
|
+
"mcpServers": {
|
|
219
|
+
"sqlite": {
|
|
220
|
+
"command": "node",
|
|
221
|
+
"args": [
|
|
222
|
+
"/absolute/path/to/mcp-database-server/dist/src/index.js",
|
|
223
|
+
"/path/to/your/database.db"
|
|
224
|
+
]
|
|
225
|
+
},
|
|
226
|
+
"sqlserver": {
|
|
227
|
+
"command": "node",
|
|
228
|
+
"args": [
|
|
229
|
+
"/absolute/path/to/mcp-database-server/dist/src/index.js",
|
|
230
|
+
"--sqlserver",
|
|
231
|
+
"--server", "your-server-name",
|
|
232
|
+
"--database", "your-database-name",
|
|
233
|
+
"--user", "your-username",
|
|
234
|
+
"--password", "your-password"
|
|
235
|
+
]
|
|
236
|
+
},
|
|
237
|
+
"postgresql": {
|
|
238
|
+
"command": "node",
|
|
239
|
+
"args": [
|
|
240
|
+
"/absolute/path/to/mcp-database-server/dist/src/index.js",
|
|
241
|
+
"--postgresql",
|
|
242
|
+
"--host", "your-host-name",
|
|
243
|
+
"--database", "your-database-name",
|
|
244
|
+
"--user", "your-username",
|
|
245
|
+
"--password", "your-password"
|
|
246
|
+
]
|
|
247
|
+
},
|
|
248
|
+
"mysql": {
|
|
249
|
+
"command": "node",
|
|
250
|
+
"args": [
|
|
251
|
+
"/absolute/path/to/mcp-database-server/dist/src/index.js",
|
|
252
|
+
"--mysql",
|
|
253
|
+
"--host", "your-host-name",
|
|
254
|
+
"--database", "your-database-name",
|
|
255
|
+
"--port", "3306",
|
|
256
|
+
"--user", "your-username",
|
|
257
|
+
"--password", "your-password"
|
|
258
|
+
]
|
|
259
|
+
},
|
|
260
|
+
"mysql-aws": {
|
|
261
|
+
"command": "node",
|
|
262
|
+
"args": [
|
|
263
|
+
"/absolute/path/to/mcp-database-server/dist/src/index.js",
|
|
264
|
+
"--mysql",
|
|
265
|
+
"--aws-iam-auth",
|
|
266
|
+
"--host", "your-rds-endpoint.region.rds.amazonaws.com",
|
|
267
|
+
"--database", "your-database-name",
|
|
268
|
+
"--user", "your-aws-username",
|
|
269
|
+
"--aws-region", "us-east-1"
|
|
270
|
+
]
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
The Claude Desktop configuration file is typically located at:
|
|
277
|
+
- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
278
|
+
- Windows: `%APPDATA%\Claude\claude_desktop_config.json`
|
|
279
|
+
- Linux: `~/.config/Claude/claude_desktop_config.json`
|
|
280
|
+
|
|
281
|
+
## Available Database Tools
|
|
282
|
+
|
|
283
|
+
The MCP Database Server provides the following tools that Claude can use:
|
|
284
|
+
|
|
285
|
+
| Tool | Description | Required Parameters |
|
|
286
|
+
|------|-------------|---------------------|
|
|
287
|
+
| `read_query` | Execute SELECT queries to read data | `query`: SQL SELECT statement |
|
|
288
|
+
| `write_query` | Execute INSERT, UPDATE, or DELETE queries | `query`: SQL modification statement |
|
|
289
|
+
| `create_table` | Create new tables in the database | `query`: CREATE TABLE statement |
|
|
290
|
+
| `alter_table` | Modify existing table schema | `query`: ALTER TABLE statement |
|
|
291
|
+
| `drop_table` | Remove a table from the database | `table_name`: Name of table<br>`confirm`: Safety flag (must be true) |
|
|
292
|
+
| `list_tables` | Get a list of all tables | None |
|
|
293
|
+
| `describe_table` | View schema information for a table | `table_name`: Name of table |
|
|
294
|
+
| `export_query` | Export query results as CSV/JSON | `query`: SQL SELECT statement<br>`format`: "csv" or "json" |
|
|
295
|
+
| `append_insight` | Add a business insight to memo | `insight`: Text of insight |
|
|
296
|
+
| `list_insights` | List all business insights | None |
|
|
297
|
+
|
|
298
|
+
For practical examples of how to use these tools with Claude, see [Usage Examples](docs/usage-examples.md).
|
|
299
|
+
|
|
300
|
+
## Additional Documentation
|
|
301
|
+
|
|
302
|
+
- [SQL Server Setup Guide](docs/sql-server-setup.md): Details on connecting to SQL Server databases
|
|
303
|
+
- [PostgreSQL Setup Guide](docs/postgresql-setup.md): Details on connecting to PostgreSQL databases
|
|
304
|
+
- [Usage Examples](docs/usage-examples.md): Example queries and commands to use with Claude
|
|
305
|
+
|
|
306
|
+
## Development
|
|
307
|
+
|
|
308
|
+
To run the server in development mode:
|
|
309
|
+
|
|
310
|
+
```
|
|
311
|
+
npm run dev
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
To watch for changes during development:
|
|
315
|
+
|
|
316
|
+
```
|
|
317
|
+
npm run watch
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
## Requirements
|
|
321
|
+
|
|
322
|
+
- Node.js 18+
|
|
323
|
+
- For SQL Server connectivity: SQL Server 2012 or later
|
|
324
|
+
- For PostgreSQL connectivity: PostgreSQL 9.5 or later
|
|
325
|
+
|
|
326
|
+
## License
|
|
327
|
+
|
|
328
|
+
MIT
|