Skip to content

Commit 77ae9c9

Browse files
committed
feat: mysql mcp
1 parent 3c34b7b commit 77ae9c9

File tree

3 files changed

+169
-1
lines changed

3 files changed

+169
-1
lines changed

mcp/src/server.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2-
import { registerDatabaseTools } from "./tools/database.js";
2+
import { registerDatabaseTools } from "./tools/databaseNoSQL.js";
3+
import { registerSQLDatabaseTools } from "./tools/databaseSQL.js";
34
import { registerDownloadTools } from "./tools/download.js";
45
import { registerEnvTools } from "./tools/env.js";
56
import { registerFunctionTools } from "./tools/functions.js";
@@ -30,6 +31,7 @@ const DEFAULT_PLUGINS = ['env', 'database', 'functions', 'hosting', 'storage', '
3031

3132
function registerDatabase(server: ExtendedMcpServer) {
3233
registerDatabaseTools(server);
34+
registerSQLDatabaseTools(server);
3335
registerDataModelTools(server);
3436
}
3537

@@ -176,3 +178,4 @@ export type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
176178
export { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
177179
export { error, info, warn } from "./utils/logger.js";
178180
export { reportToolCall, reportToolkitLifecycle, telemetryReporter } from "./utils/telemetry.js";
181+
File renamed without changes.

mcp/src/tools/databaseSQL.ts

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
import { z } from "zod";
2+
import { getCloudBaseManager, getEnvId } from "../cloudbase-manager.js";
3+
import { ExtendedMcpServer } from "../server.js";
4+
5+
const CATEGORY = "SQL database";
6+
7+
export function registerSQLDatabaseTools(server: ExtendedMcpServer) {
8+
// Get cloudBaseOptions, if not available then undefined
9+
const cloudBaseOptions = server.cloudBaseOptions;
10+
11+
// Create closure function to get CloudBase Manager
12+
const getManager = () => getCloudBaseManager({ cloudBaseOptions });
13+
14+
// executeReadOnlySQL
15+
server.registerTool?.(
16+
"executeReadOnlySQL",
17+
{
18+
title: "Execute read-only SQL query",
19+
description: "Execute a read-only SQL query on the SQL database",
20+
inputSchema: {
21+
sql: z.string().describe("SQL query statement (SELECT queries only)"),
22+
instanceId: z
23+
.string()
24+
.optional()
25+
.describe("Database instance ID (defaults to 'default')"),
26+
},
27+
annotations: {
28+
readOnlyHint: true,
29+
openWorldHint: true,
30+
category: CATEGORY,
31+
},
32+
},
33+
async ({ sql, instanceId = "default" }) => {
34+
try {
35+
const cloudbase = await getManager();
36+
const envId = await getEnvId(cloudBaseOptions);
37+
38+
const result = await cloudbase.commonService("tcb").call({
39+
Action: "RunSql",
40+
Param: {
41+
EnvId: envId,
42+
Sql: sql,
43+
DbInstance: {
44+
EnvId: envId,
45+
InstanceId: instanceId,
46+
},
47+
},
48+
});
49+
return {
50+
content: [
51+
{
52+
type: "text",
53+
text: JSON.stringify(
54+
{
55+
success: true,
56+
message: "SQL query executed successfully",
57+
result,
58+
},
59+
null,
60+
2
61+
),
62+
},
63+
],
64+
};
65+
} catch (error: any) {
66+
return {
67+
content: [
68+
{
69+
type: "text",
70+
text: JSON.stringify(
71+
{
72+
success: false,
73+
error: error.message,
74+
message: "SQL query execution failed",
75+
},
76+
null,
77+
2
78+
),
79+
},
80+
],
81+
};
82+
}
83+
}
84+
);
85+
86+
// executeWriteSQL
87+
server.registerTool?.(
88+
"executeWriteSQL",
89+
{
90+
title: "Execute write SQL statement",
91+
description:
92+
"Execute a write SQL statement on the SQL database (INSERT, UPDATE, DELETE, etc.)",
93+
inputSchema: {
94+
sql: z
95+
.string()
96+
.describe(
97+
"SQL statement (INSERT, UPDATE, DELETE, CREATE, ALTER, etc.)"
98+
),
99+
instanceId: z
100+
.string()
101+
.optional()
102+
.describe("Database instance ID (defaults to 'default')"),
103+
},
104+
annotations: {
105+
readOnlyHint: false,
106+
destructiveHint: true,
107+
idempotentHint: false,
108+
openWorldHint: true,
109+
category: CATEGORY,
110+
},
111+
},
112+
async ({ sql, instanceId = "default" }) => {
113+
try {
114+
const cloudbase = await getManager();
115+
const envId = await getEnvId(cloudBaseOptions);
116+
117+
const result = await cloudbase.commonService("tcb").call({
118+
Action: "RunSql",
119+
Param: {
120+
EnvId: envId,
121+
Sql: sql,
122+
DbInstance: {
123+
EnvId: envId,
124+
InstanceId: instanceId,
125+
},
126+
},
127+
});
128+
129+
return {
130+
content: [
131+
{
132+
type: "text",
133+
text: JSON.stringify(
134+
{
135+
success: true,
136+
message: "SQL statement executed successfully",
137+
result,
138+
},
139+
null,
140+
2
141+
),
142+
},
143+
],
144+
};
145+
} catch (error: any) {
146+
return {
147+
content: [
148+
{
149+
type: "text",
150+
text: JSON.stringify(
151+
{
152+
success: false,
153+
error: error.message,
154+
message: "SQL statement execution failed",
155+
},
156+
null,
157+
2
158+
),
159+
},
160+
],
161+
};
162+
}
163+
}
164+
);
165+
}

0 commit comments

Comments
 (0)