@obiwan90/edgedb-mcp-server
Version:
edgedb mcp server
248 lines (247 loc) • 9.45 kB
JavaScript
/**
* 数据库管理相关MCP工具
* Database management related MCP tools
*/
import { z } from "zod";
import { getClient } from "../services/edgedb.js";
import { handleError } from "../utils/errors.js";
/**
* 注册数据库管理相关工具
* Register database management related tools
* @param server MCP服务器实例 (MCP server instance)
*/
export function registerDatabaseTools(server) {
/**
* 连接到EdgeDB数据库工具
* Connect to EdgeDB database tool
*/
server.tool("connectEdgeDB", {
dsn: z.string().optional().describe("EdgeDB connection string (e.g.: edgedb://user:password@hostname:port/database)"),
instanceName: z.string().optional().describe("EdgeDB instance name"),
}, async ({ dsn, instanceName }, extra) => {
try {
// 导入服务
// Import services
const { initEdgeDBClient } = await import("../services/edgedb.js");
// 初始化连接
// Initialize connection
const result = await initEdgeDBClient(dsn, instanceName);
return {
content: [{
type: "text",
text: result
}]
};
}
catch (error) {
return handleError(error, "连接EdgeDB", "请检查连接参数和网络连接");
}
});
/**
* 列出所有可访问的数据库
* List all accessible databases
*/
server.tool("listDatabases", {}, async ({}, extra) => {
try {
const client = getClient();
const result = await client.query(`
SELECT sys::Database {
name
}
ORDER BY .name;
`);
return {
content: [{
type: "text",
text: JSON.stringify(result, null, 2)
}]
};
}
catch (error) {
return handleError(error, "获取数据库列表", "请检查网络连接和数据库权限");
}
});
/**
* 获取当前数据库名称
* Get current database name
*/
server.tool("currentDatabase", {}, async ({}, extra) => {
try {
const client = getClient();
// 导入getCurrentDatabase函数
// Import getCurrentDatabase function
const { getCurrentDatabase } = await import("../services/edgedb.js");
// 从客户端直接查询当前数据库名称
// Query current database name directly from the client
const actualDb = await client.querySingle('SELECT sys::get_current_database()');
// 获取存储的数据库名称
// Get stored database name
const storedDb = getCurrentDatabase();
// 如果不一致,提供警告
// If inconsistent, provide a warning
if (actualDb !== storedDb) {
return {
content: [{
type: "text",
text: `当前连接的数据库: ${actualDb} (系统记录为: ${storedDb})`
}]
};
}
return {
content: [{
type: "text",
text: `当前连接的数据库: ${actualDb}`
}]
};
}
catch (error) {
const { getCurrentDatabase } = await import("../services/edgedb.js");
const storedDb = getCurrentDatabase();
return {
content: [{
type: "text",
text: `获取数据库名称出错,系统记录的当前数据库: ${storedDb}`
}]
};
}
});
/**
* 创建新数据库
* Create a new database
*/
server.tool("createDatabase", {
name: z.string().describe("New database name"),
switchTo: z.boolean().optional().describe("Whether to switch to the new database after creation")
}, async ({ name, switchTo }, extra) => {
try {
const client = getClient();
const { initEdgeDBClient, getCurrentDatabase } = await import("../services/edgedb.js");
// 创建数据库
// Create database
await client.query(`
CREATE DATABASE ${name};
`);
// 创建数据库成功
// Database created successfully
if (switchTo) {
// 连接到新数据库
// Connect to the new database
await initEdgeDBClient(undefined, undefined, name);
// 验证是否成功切换
// Verify if switch was successful
const currentDb = getCurrentDatabase();
if (currentDb !== name) {
return {
content: [{
type: "text",
text: `数据库 ${name} 创建成功,但切换失败,当前连接的是 ${currentDb}`
}],
isError: true
};
}
return {
content: [{
type: "text",
text: `数据库 ${name} 创建成功并已切换到该数据库。`
}]
};
}
return {
content: [{
type: "text",
text: `数据库 ${name} 创建成功。`
}]
};
}
catch (error) {
return handleError(error, "创建数据库", "请确保有足够的权限创建数据库");
}
});
/**
* 切换到特定数据库
* Switch to a specific database
*/
server.tool("useDatabase", {
database: z.string().describe("Database name")
}, async ({ database }, extra) => {
try {
const client = getClient();
const { getCurrentDatabase, initEdgeDBClient, setCurrentDatabase, getDatabaseClient } = await import("../services/edgedb.js");
// 检查当前数据库
// Check current database
const currentDb = getCurrentDatabase();
if (currentDb === database) {
return {
content: [{
type: "text",
text: `已经连接到数据库 ${database}`
}]
};
}
// 检查数据库是否存在
// Check if database exists
const exists = await client.querySingle(`
SELECT EXISTS (
SELECT sys::Database FILTER .name = <str>$name
)
`, { name: database });
if (!exists) {
return {
content: [{
type: "text",
text: `数据库 ${database} 不存在`
}],
isError: true
};
}
// 检查是否已经有此数据库的连接
// Check if there is already a connection to this database
const existingClient = getDatabaseClient(database);
if (existingClient) {
// 直接切换到已有连接
// Switch directly to existing connection
setCurrentDatabase(database);
// 验证连接
// Verify connection
try {
const dbName = await existingClient.querySingle('SELECT sys::get_current_database()');
console.log(`验证已有连接成功,数据库: ${dbName}`);
if (dbName !== database) {
console.warn(`数据库名称不匹配,期望: ${database}, 实际: ${dbName}`);
}
}
catch (e) {
console.error(`验证已有连接失败:`, e);
// 连接可能已失效,重新创建
await initEdgeDBClient(undefined, undefined, database);
}
}
else {
// 创建新连接
// Create new connection
await initEdgeDBClient(undefined, undefined, database);
}
// 验证当前数据库名称
// Verify current database name
const newCurrentDb = getCurrentDatabase();
if (newCurrentDb !== database) {
return {
content: [{
type: "text",
text: `切换数据库失败,当前仍为: ${newCurrentDb}`
}],
isError: true
};
}
return {
content: [{
type: "text",
text: `已切换到数据库 ${database}`
}]
};
}
catch (error) {
return handleError(error, "切换数据库", "请确保数据库存在并且有足够的权限");
}
});
}