@aliyun-rds/supabase-mcp-server 1.0.2 → 1.0.3
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/README.md +67 -5
- package/dist/index.js +209 -4
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -56,7 +56,7 @@ For example, when you ask an AI assistant "List all tables in my database", it w
|
|
|
56
56
|
The easiest way to use this server is via npx, which requires no installation:
|
|
57
57
|
|
|
58
58
|
```bash
|
|
59
|
-
npx @
|
|
59
|
+
npx @aliyun-rds/supabase-mcp-server --url http://localhost:8000 --anon-key YOUR_ANON_KEY
|
|
60
60
|
```
|
|
61
61
|
|
|
62
62
|
### Method 2: Installing via Smithery
|
|
@@ -72,7 +72,7 @@ npx -y @smithery/cli install @HenkDz/selfhosted-supabase-mcp --client claude
|
|
|
72
72
|
Install the package globally:
|
|
73
73
|
|
|
74
74
|
```bash
|
|
75
|
-
npm install -g @
|
|
75
|
+
npm install -g @aliyun-rds/supabase-mcp-server
|
|
76
76
|
supabase-mcp --url http://localhost:8000 --anon-key YOUR_ANON_KEY
|
|
77
77
|
```
|
|
78
78
|
|
|
@@ -118,11 +118,39 @@ The server requires configuration details for your Supabase instance. These can
|
|
|
118
118
|
* `--db-url <url>` or `DATABASE_URL=<url>`: The direct PostgreSQL connection string for your Supabase database (e.g., `postgresql://postgres:password@localhost:5432/postgres`). Required for tools needing direct database access or transactions (`apply_migration`, Auth tools, Storage tools, querying `pg_catalog`, etc.).
|
|
119
119
|
* `--jwt-secret <secret>` or `SUPABASE_AUTH_JWT_SECRET=<secret>`: Your Supabase project's JWT secret. Needed for tools like `verify_jwt_secret`.
|
|
120
120
|
* `--tools-config <path>`: Path to a JSON file specifying which tools to enable (whitelist). If omitted, all tools defined in the server are enabled. The file should have the format `{"enabledTools": ["tool_name_1", "tool_name_2"]}`.
|
|
121
|
+
* `--enable-rag-agent` or `ENABLE_RAG_AGENT=true`: Enable RAG Agent MCP integration. When enabled, this server will connect to a rag-agent MCP server and expose its tools alongside the Supabase tools. The host and port are extracted from `--url`, and `--anon-key` is used as the API key for rag-agent.
|
|
122
|
+
|
|
123
|
+
### RAG Agent Integration
|
|
124
|
+
|
|
125
|
+
This server can integrate with [rag-agent-mcp](https://pypi.org/project/rag-agent-mcp/) to provide RAG (Retrieval-Augmented Generation) capabilities alongside your Supabase database tools.
|
|
126
|
+
|
|
127
|
+
**How it works:**
|
|
128
|
+
- When `--enable-rag-agent` is set, the server automatically connects to a rag-agent MCP server
|
|
129
|
+
- The host and port are extracted from your `--url` parameter (e.g., `http://8.161.141.95:80` → host: `8.161.141.95`, port: `80`)
|
|
130
|
+
- The `--anon-key` value is used as the API key for authenticating with rag-agent
|
|
131
|
+
- All rag-agent tools are prefixed with `rag_` to avoid naming conflicts (e.g., `rag_search`, `rag_index`)
|
|
132
|
+
|
|
133
|
+
**Example configuration:**
|
|
134
|
+
```bash
|
|
135
|
+
npx @aliyun-rds/supabase-mcp-server \
|
|
136
|
+
--url http://8.161.141.95:80 \
|
|
137
|
+
--anon-key "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..." \
|
|
138
|
+
--enable-rag-agent
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
**Requirements:**
|
|
142
|
+
- `uvx` must be installed on your system
|
|
143
|
+
- `rag-agent-mcp` package must be available via `uvx`
|
|
144
|
+
- The rag-agent service must be running at the specified host and port
|
|
121
145
|
|
|
122
146
|
### Important Notes:
|
|
123
147
|
|
|
124
148
|
* **`execute_sql` Helper Function:** Many tools rely on a `public.execute_sql` function within your Supabase database for secure and efficient SQL execution via RPC. The server attempts to check for this function on startup. If it's missing *and* a `service-key` (or `SUPABASE_SERVICE_ROLE_KEY`) *and* `db-url` (or `DATABASE_URL`) are provided, it will attempt to create the function and grant necessary permissions. If creation fails or keys aren't provided, tools relying solely on RPC may fail.
|
|
125
149
|
* **Direct Database Access:** Tools interacting directly with privileged schemas (`auth`, `storage`) or system catalogs (`pg_catalog`) generally require the `DATABASE_URL` to be configured for a direct `pg` connection.
|
|
150
|
+
* **Database URL Special Characters:** If your database password or username contains special characters (such as `#`, `$`, etc.), they need to be properly URL encoded to prevent connection issues. The server automatically handles common special characters in the database URL:
|
|
151
|
+
* `#` is automatically encoded as `%23`
|
|
152
|
+
* `$` is automatically encoded as `%24`
|
|
153
|
+
* Note: The `@` symbol is not encoded as it serves as a delimiter in the URL between credentials and hostname
|
|
126
154
|
|
|
127
155
|
## Using with AI Assistant Tools
|
|
128
156
|
|
|
@@ -134,10 +162,10 @@ The server requires configuration details for your Supabase instance. These can
|
|
|
134
162
|
```json
|
|
135
163
|
{
|
|
136
164
|
"mcpServers": {
|
|
137
|
-
"selfhosted-supabase": {
|
|
165
|
+
"selfhosted-supabase": {
|
|
138
166
|
"command": "npx",
|
|
139
167
|
"args": [
|
|
140
|
-
"@
|
|
168
|
+
"@aliyun-rds/supabase-mcp-server",
|
|
141
169
|
"--url",
|
|
142
170
|
"<your-supabase-url>", // e.g., "http://localhost:8000"
|
|
143
171
|
"--anon-key",
|
|
@@ -151,13 +179,47 @@ The server requires configuration details for your Supabase instance. These can
|
|
|
151
179
|
"<your-jwt-secret>",
|
|
152
180
|
// Optional - Whitelist specific tools
|
|
153
181
|
"--tools-config",
|
|
154
|
-
"<path-to-tools-config.json>"
|
|
182
|
+
"<path-to-tools-config.json>",
|
|
183
|
+
// Optional - Enable RAG Agent integration
|
|
184
|
+
"--enable-rag-agent"
|
|
155
185
|
]
|
|
156
186
|
}
|
|
157
187
|
}
|
|
158
188
|
}
|
|
159
189
|
```
|
|
160
190
|
|
|
191
|
+
**Example with RAG Agent integration:**
|
|
192
|
+
|
|
193
|
+
If you want to use this server with both Supabase and RAG Agent tools, configure it like this:
|
|
194
|
+
|
|
195
|
+
```json
|
|
196
|
+
{
|
|
197
|
+
"mcpServers": {
|
|
198
|
+
"remote-selfhosted-supabase": {
|
|
199
|
+
"command": "ssh",
|
|
200
|
+
"args": [
|
|
201
|
+
"root@8.161.141.95",
|
|
202
|
+
"cd /root/selfhosted-supabase-mcp && node dist/index.js",
|
|
203
|
+
"--url",
|
|
204
|
+
"http://8.161.141.95:80",
|
|
205
|
+
"--anon-key",
|
|
206
|
+
"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJvbGUiOiJhbm9uIiwiaWF0IjoxNzYwNDIwNjM5LCJleHAiOjEzMjcxMDYwNjM5fQ.ZV2geUEdh096snzWaCnKXFTyQbyJxLbur8zZooZkY88",
|
|
207
|
+
"--service-key",
|
|
208
|
+
"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJvbGUiOiJzZXJ2aWNlX3JvbGUiLCJpYXQiOjE3NjA0MjA2MzksImV4cCI6MTMyNzEwNjA2Mzl9.4wqKCLqJqQqQqQqQqQqQqQqQqQqQqQqQqQqQqQqQqQQ",
|
|
209
|
+
"--enable-rag-agent"
|
|
210
|
+
]
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
In this configuration:
|
|
217
|
+
- The server runs on a remote machine via SSH
|
|
218
|
+
- It connects to Supabase at `http://8.161.141.95:80`
|
|
219
|
+
- RAG Agent integration is enabled and will connect to the same host:port
|
|
220
|
+
- Both Supabase and RAG Agent tools will be available to your AI assistant
|
|
221
|
+
```
|
|
222
|
+
|
|
161
223
|
### Claude for Desktop
|
|
162
224
|
|
|
163
225
|
For Claude Desktop, you can add the following to your configuration:
|
package/dist/index.js
CHANGED
|
@@ -167,6 +167,25 @@ var SelfhostedSupabaseClient = class _SelfhostedSupabaseClient {
|
|
|
167
167
|
client?.release();
|
|
168
168
|
}
|
|
169
169
|
}
|
|
170
|
+
/**
|
|
171
|
+
* Encodes special characters in database URL to prevent parsing errors
|
|
172
|
+
* Handles characters like #, $ that may cause issues with pg library
|
|
173
|
+
*/
|
|
174
|
+
encodeDatabaseUrl(url) {
|
|
175
|
+
try {
|
|
176
|
+
const parsedUrl = new URL(url);
|
|
177
|
+
if (parsedUrl.username) {
|
|
178
|
+
parsedUrl.username = encodeURIComponent(parsedUrl.username);
|
|
179
|
+
}
|
|
180
|
+
if (parsedUrl.password) {
|
|
181
|
+
parsedUrl.password = encodeURIComponent(parsedUrl.password);
|
|
182
|
+
}
|
|
183
|
+
return parsedUrl.toString();
|
|
184
|
+
} catch (error) {
|
|
185
|
+
console.error("Database URL contains special characters. Applying basic encoding (excluding @).");
|
|
186
|
+
return url.replace(/#/g, "%23").replace(/\$/g, "%24");
|
|
187
|
+
}
|
|
188
|
+
}
|
|
170
189
|
/**
|
|
171
190
|
* Ensures the pg connection pool is initialized.
|
|
172
191
|
* Should be called before accessing this.pgPool.
|
|
@@ -177,7 +196,8 @@ var SelfhostedSupabaseClient = class _SelfhostedSupabaseClient {
|
|
|
177
196
|
throw new Error("DATABASE_URL is not configured. Cannot initialize pg pool.");
|
|
178
197
|
}
|
|
179
198
|
console.error("Initializing pg pool...");
|
|
180
|
-
|
|
199
|
+
const encodedDbUrl = this.encodeDatabaseUrl(this.options.databaseUrl);
|
|
200
|
+
this.pgPool = new Pool({ connectionString: encodedDbUrl });
|
|
181
201
|
this.pgPool.on("error", (err, client) => {
|
|
182
202
|
console.error("PG Pool Error: Unexpected error on idle client", err);
|
|
183
203
|
});
|
|
@@ -1485,7 +1505,7 @@ var updateAuthUserTool = {
|
|
|
1485
1505
|
};
|
|
1486
1506
|
|
|
1487
1507
|
// src/index.ts
|
|
1488
|
-
import { z as
|
|
1508
|
+
import { z as z24 } from "zod";
|
|
1489
1509
|
|
|
1490
1510
|
// src/tools/list_storage_buckets.ts
|
|
1491
1511
|
import { z as z20 } from "zod";
|
|
@@ -1695,9 +1715,157 @@ var list_realtime_publications_default = listRealtimePublicationsTool;
|
|
|
1695
1715
|
// src/index.ts
|
|
1696
1716
|
import * as fs from "node:fs";
|
|
1697
1717
|
import * as path from "node:path";
|
|
1718
|
+
|
|
1719
|
+
// src/integrations/rag-agent-client.ts
|
|
1720
|
+
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
1721
|
+
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
|
|
1722
|
+
var RagAgentClient = class {
|
|
1723
|
+
config;
|
|
1724
|
+
client = null;
|
|
1725
|
+
tools = [];
|
|
1726
|
+
constructor(config) {
|
|
1727
|
+
this.config = config;
|
|
1728
|
+
}
|
|
1729
|
+
/**
|
|
1730
|
+
* Initialize connection to rag-agent MCP server and fetch tools
|
|
1731
|
+
*/
|
|
1732
|
+
async initialize() {
|
|
1733
|
+
console.error("Initializing RAG Agent MCP client...");
|
|
1734
|
+
try {
|
|
1735
|
+
this.client = new Client(
|
|
1736
|
+
{
|
|
1737
|
+
name: "supabase-mcp-rag-agent-client",
|
|
1738
|
+
version: "1.0.0"
|
|
1739
|
+
},
|
|
1740
|
+
{
|
|
1741
|
+
capabilities: {}
|
|
1742
|
+
}
|
|
1743
|
+
);
|
|
1744
|
+
const env = {};
|
|
1745
|
+
for (const [key, value] of Object.entries(process.env)) {
|
|
1746
|
+
if (value !== void 0 && !["http_proxy", "https_proxy", "HTTP_PROXY", "HTTPS_PROXY", "all_proxy", "ALL_PROXY", "no_proxy", "NO_PROXY"].includes(key)) {
|
|
1747
|
+
env[key] = value;
|
|
1748
|
+
}
|
|
1749
|
+
}
|
|
1750
|
+
env.NO_PROXY = "*";
|
|
1751
|
+
env.no_proxy = "*";
|
|
1752
|
+
const transport = new StdioClientTransport({
|
|
1753
|
+
command: "uvx",
|
|
1754
|
+
args: [
|
|
1755
|
+
"--from",
|
|
1756
|
+
"rag-agent-mcp",
|
|
1757
|
+
"rag-agent",
|
|
1758
|
+
"--host",
|
|
1759
|
+
this.config.host,
|
|
1760
|
+
"--port",
|
|
1761
|
+
this.config.port.toString(),
|
|
1762
|
+
"--api-key",
|
|
1763
|
+
this.config.apiKey
|
|
1764
|
+
],
|
|
1765
|
+
env
|
|
1766
|
+
});
|
|
1767
|
+
await this.client.connect(transport);
|
|
1768
|
+
console.error("Connected to RAG Agent MCP server");
|
|
1769
|
+
const response = await this.client.listTools();
|
|
1770
|
+
this.tools = response.tools.map((tool) => ({
|
|
1771
|
+
name: tool.name,
|
|
1772
|
+
description: tool.description,
|
|
1773
|
+
inputSchema: tool.inputSchema
|
|
1774
|
+
}));
|
|
1775
|
+
console.error(`Loaded ${this.tools.length} tools from RAG Agent MCP server`);
|
|
1776
|
+
console.error(`RAG Agent tools: ${this.tools.map((t) => t.name).join(", ")}`);
|
|
1777
|
+
} catch (error) {
|
|
1778
|
+
console.error("Failed to initialize RAG Agent MCP client:", error);
|
|
1779
|
+
throw error;
|
|
1780
|
+
}
|
|
1781
|
+
}
|
|
1782
|
+
/**
|
|
1783
|
+
* Get the list of available tools from rag-agent
|
|
1784
|
+
*/
|
|
1785
|
+
getTools() {
|
|
1786
|
+
return this.tools;
|
|
1787
|
+
}
|
|
1788
|
+
/**
|
|
1789
|
+
* Call a tool on the rag-agent MCP server
|
|
1790
|
+
*/
|
|
1791
|
+
async callTool(name, args) {
|
|
1792
|
+
if (!this.client) {
|
|
1793
|
+
throw new Error("RAG Agent client not initialized");
|
|
1794
|
+
}
|
|
1795
|
+
try {
|
|
1796
|
+
const response = await this.client.callTool({
|
|
1797
|
+
name,
|
|
1798
|
+
arguments: args
|
|
1799
|
+
});
|
|
1800
|
+
if (response.content && Array.isArray(response.content)) {
|
|
1801
|
+
const textContent = response.content.filter((item) => item.type === "text").map((item) => "text" in item ? item.text : "").join("\n");
|
|
1802
|
+
try {
|
|
1803
|
+
return JSON.parse(textContent);
|
|
1804
|
+
} catch {
|
|
1805
|
+
return textContent;
|
|
1806
|
+
}
|
|
1807
|
+
}
|
|
1808
|
+
return response;
|
|
1809
|
+
} catch (error) {
|
|
1810
|
+
console.error(`Error calling RAG Agent tool ${name}:`, error);
|
|
1811
|
+
throw error;
|
|
1812
|
+
}
|
|
1813
|
+
}
|
|
1814
|
+
/**
|
|
1815
|
+
* Close the connection to rag-agent MCP server
|
|
1816
|
+
*/
|
|
1817
|
+
async close() {
|
|
1818
|
+
if (this.client) {
|
|
1819
|
+
await this.client.close();
|
|
1820
|
+
this.client = null;
|
|
1821
|
+
console.error("RAG Agent MCP client closed");
|
|
1822
|
+
}
|
|
1823
|
+
}
|
|
1824
|
+
};
|
|
1825
|
+
async function createRagAgentClient(config) {
|
|
1826
|
+
const client = new RagAgentClient(config);
|
|
1827
|
+
await client.initialize();
|
|
1828
|
+
return client;
|
|
1829
|
+
}
|
|
1830
|
+
|
|
1831
|
+
// src/integrations/rag-agent-tools.ts
|
|
1832
|
+
import { z as z23 } from "zod";
|
|
1833
|
+
function wrapRagAgentTool(ragTool, ragClient) {
|
|
1834
|
+
const inputSchema2 = z23.any();
|
|
1835
|
+
return {
|
|
1836
|
+
name: `rag_${ragTool.name}`,
|
|
1837
|
+
// Prefix with 'rag_' to avoid naming conflicts
|
|
1838
|
+
description: ragTool.description || `RAG Agent tool: ${ragTool.name}`,
|
|
1839
|
+
inputSchema: inputSchema2,
|
|
1840
|
+
mcpInputSchema: ragTool.inputSchema,
|
|
1841
|
+
outputSchema: z23.any(),
|
|
1842
|
+
execute: async (input, context) => {
|
|
1843
|
+
context.log(`Calling RAG Agent tool: ${ragTool.name}`, "info");
|
|
1844
|
+
try {
|
|
1845
|
+
const result = await ragClient.callTool(ragTool.name, input);
|
|
1846
|
+
return result;
|
|
1847
|
+
} catch (error) {
|
|
1848
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
1849
|
+
context.log(`Error calling RAG Agent tool ${ragTool.name}: ${errorMessage}`, "error");
|
|
1850
|
+
throw new Error(`RAG Agent tool error: ${errorMessage}`);
|
|
1851
|
+
}
|
|
1852
|
+
}
|
|
1853
|
+
};
|
|
1854
|
+
}
|
|
1855
|
+
function wrapAllRagAgentTools(ragClient) {
|
|
1856
|
+
const tools = ragClient.getTools();
|
|
1857
|
+
const wrappedTools = {};
|
|
1858
|
+
for (const tool of tools) {
|
|
1859
|
+
const wrapped = wrapRagAgentTool(tool, ragClient);
|
|
1860
|
+
wrappedTools[wrapped.name] = wrapped;
|
|
1861
|
+
}
|
|
1862
|
+
return wrappedTools;
|
|
1863
|
+
}
|
|
1864
|
+
|
|
1865
|
+
// src/index.ts
|
|
1698
1866
|
async function main() {
|
|
1699
1867
|
const program = new Command();
|
|
1700
|
-
program.name("self-hosted-supabase-mcp").description("MCP Server for self-hosted Supabase instances").option("--url <url>", "Supabase project URL", process.env.SUPABASE_URL).option("--anon-key <key>", "Supabase anonymous key", process.env.SUPABASE_ANON_KEY).option("--service-key <key>", "Supabase service role key (optional)", process.env.SUPABASE_SERVICE_ROLE_KEY).option("--db-url <url>", "Direct database connection string (optional, for pg fallback)", process.env.DATABASE_URL).option("--jwt-secret <secret>", "Supabase JWT secret (optional, needed for some tools)", process.env.SUPABASE_AUTH_JWT_SECRET).option("--workspace-path <path>", "Workspace root path (for file operations)", process.cwd()).option("--tools-config <path>", 'Path to a JSON file specifying which tools to enable (e.g., { "enabledTools": ["tool1", "tool2"] }). If omitted, all tools are enabled.').parse(process.argv);
|
|
1868
|
+
program.name("self-hosted-supabase-mcp").description("MCP Server for self-hosted Supabase instances").option("--url <url>", "Supabase project URL", process.env.SUPABASE_URL).option("--anon-key <key>", "Supabase anonymous key", process.env.SUPABASE_ANON_KEY).option("--service-key <key>", "Supabase service role key (optional)", process.env.SUPABASE_SERVICE_ROLE_KEY).option("--db-url <url>", "Direct database connection string (optional, for pg fallback)", process.env.DATABASE_URL).option("--jwt-secret <secret>", "Supabase JWT secret (optional, needed for some tools)", process.env.SUPABASE_AUTH_JWT_SECRET).option("--workspace-path <path>", "Workspace root path (for file operations)", process.cwd()).option("--tools-config <path>", 'Path to a JSON file specifying which tools to enable (e.g., { "enabledTools": ["tool1", "tool2"] }). If omitted, all tools are enabled.').option("--enable-rag-agent", "Enable RAG Agent MCP integration (uses --url host:port and --anon-key as API key)", process.env.ENABLE_RAG_AGENT === "true").parse(process.argv);
|
|
1701
1869
|
const options = program.opts();
|
|
1702
1870
|
if (!options.url) {
|
|
1703
1871
|
console.error("Error: Supabase URL is required. Use --url or SUPABASE_URL.");
|
|
@@ -1717,6 +1885,24 @@ async function main() {
|
|
|
1717
1885
|
jwtSecret: options.jwtSecret
|
|
1718
1886
|
});
|
|
1719
1887
|
console.error("Supabase client initialized successfully.");
|
|
1888
|
+
let ragAgentClient = null;
|
|
1889
|
+
if (options.enableRagAgent) {
|
|
1890
|
+
try {
|
|
1891
|
+
console.error("RAG Agent integration enabled, initializing...");
|
|
1892
|
+
const urlObj = new URL(options.url);
|
|
1893
|
+
const host = urlObj.hostname;
|
|
1894
|
+
const port = urlObj.port ? parseInt(urlObj.port, 10) : urlObj.protocol === "https:" ? 443 : 80;
|
|
1895
|
+
ragAgentClient = await createRagAgentClient({
|
|
1896
|
+
host,
|
|
1897
|
+
port,
|
|
1898
|
+
apiKey: options.anonKey
|
|
1899
|
+
});
|
|
1900
|
+
console.error("RAG Agent client initialized successfully.");
|
|
1901
|
+
} catch (error) {
|
|
1902
|
+
console.error("Failed to initialize RAG Agent client:", error);
|
|
1903
|
+
console.error("Continuing without RAG Agent integration...");
|
|
1904
|
+
}
|
|
1905
|
+
}
|
|
1720
1906
|
const availableTools = {
|
|
1721
1907
|
// Cast here assumes tools will implement AppTool structure
|
|
1722
1908
|
[listTablesTool.name]: listTablesTool,
|
|
@@ -1741,6 +1927,11 @@ async function main() {
|
|
|
1741
1927
|
[list_storage_objects_default.name]: list_storage_objects_default,
|
|
1742
1928
|
[list_realtime_publications_default.name]: list_realtime_publications_default
|
|
1743
1929
|
};
|
|
1930
|
+
if (ragAgentClient) {
|
|
1931
|
+
const ragTools = wrapAllRagAgentTools(ragAgentClient);
|
|
1932
|
+
Object.assign(availableTools, ragTools);
|
|
1933
|
+
console.error(`Added ${Object.keys(ragTools).length} RAG Agent tools to available tools.`);
|
|
1934
|
+
}
|
|
1744
1935
|
let registeredTools = { ...availableTools };
|
|
1745
1936
|
const toolsConfigPath = options.toolsConfig;
|
|
1746
1937
|
let enabledToolNames = null;
|
|
@@ -1847,7 +2038,7 @@ async function main() {
|
|
|
1847
2038
|
} catch (error) {
|
|
1848
2039
|
console.error(`Error executing tool ${toolName}:`, error);
|
|
1849
2040
|
let errorMessage = `Error executing tool ${toolName}: `;
|
|
1850
|
-
if (error instanceof
|
|
2041
|
+
if (error instanceof z24.ZodError) {
|
|
1851
2042
|
errorMessage += `Input validation failed: ${error.errors.map((e) => `${e.path.join(".")}: ${e.message}`).join(", ")}`;
|
|
1852
2043
|
} else if (error instanceof Error) {
|
|
1853
2044
|
errorMessage += error.message;
|
|
@@ -1864,6 +2055,20 @@ async function main() {
|
|
|
1864
2055
|
const transport = new StdioServerTransport();
|
|
1865
2056
|
await server.connect(transport);
|
|
1866
2057
|
console.error("MCP Server connected to stdio.");
|
|
2058
|
+
const cleanup = async () => {
|
|
2059
|
+
console.error("Shutting down...");
|
|
2060
|
+
if (ragAgentClient) {
|
|
2061
|
+
await ragAgentClient.close();
|
|
2062
|
+
}
|
|
2063
|
+
};
|
|
2064
|
+
process.on("SIGINT", async () => {
|
|
2065
|
+
await cleanup();
|
|
2066
|
+
process.exit(0);
|
|
2067
|
+
});
|
|
2068
|
+
process.on("SIGTERM", async () => {
|
|
2069
|
+
await cleanup();
|
|
2070
|
+
process.exit(0);
|
|
2071
|
+
});
|
|
1867
2072
|
} catch (error) {
|
|
1868
2073
|
console.error("Failed to initialize or start the MCP server:", error);
|
|
1869
2074
|
throw error;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aliyun-rds/supabase-mcp-server",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "MCP (Model Context Protocol) server for self-hosted Supabase instances. Allows AI assistants to interact with your self-hosted Supabase database.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -47,4 +47,4 @@
|
|
|
47
47
|
"engines": {
|
|
48
48
|
"node": ">=18"
|
|
49
49
|
}
|
|
50
|
-
}
|
|
50
|
+
}
|