@hechtcarmel/vertica-mcp
Version:
MCP server for Vertica database operations with configurable readonly mode
157 lines (154 loc) • 4.73 kB
JavaScript
import { parseArgs } from "node:util";
import { resolve } from "node:path";
import { existsSync, readFileSync } from "node:fs";
import { fileURLToPath } from "node:url";
import { dirname, join } from "node:path";
import dotenv from "dotenv";
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const packageJson = JSON.parse(readFileSync(join(__dirname, "..", "package.json"), "utf-8"));
const VERSION = packageJson.version;
const { values } = parseArgs({
args: process.argv.slice(2),
options: {
"env-file": {
type: "string",
short: "e",
},
help: {
type: "boolean",
short: "h",
},
version: {
type: "boolean",
short: "v",
},
},
allowPositionals: false,
});
if (values.help) {
console.log(`
Vertica MCP Server
Usage: npx @hechtcarmel/vertica-mcp [options]
Options:
-e, --env-file <path> Path to environment file (default: .env in current directory)
-h, --help Show this help message
-v, --version Show version number
Examples:
npx @hechtcarmel/vertica-mcp
npx @hechtcarmel/vertica-mcp --env-file /path/to/custom.env
npx @hechtcarmel/vertica-mcp -e ~/.config/vertica/production.env
`);
process.exit(0);
}
if (values.version) {
console.log(VERSION);
process.exit(0);
}
const envFile = values["env-file"];
if (envFile) {
const envPath = resolve(envFile);
if (!existsSync(envPath)) {
console.error(`Error: Environment file not found: ${envPath}`);
process.exit(1);
}
console.error(`Loading environment from: ${envPath}`);
dotenv.config({ path: envPath });
}
else {
dotenv.config();
}
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
import ExecuteQueryTool from "./tools/execute-query.js";
import StreamQueryTool from "./tools/stream-query.js";
import ListTablesTool from "./tools/list-tables.js";
import ListViewsTool from "./tools/list-views.js";
import ListIndexesTool from "./tools/list-indexes.js";
import GetTableStructureTool from "./tools/get-table-structure.js";
const server = new Server({
name: "@hechtcarmel/vertica-mcp",
version: VERSION,
}, {
capabilities: {
tools: {},
},
});
const tools = [
new ExecuteQueryTool(),
new StreamQueryTool(),
new ListTablesTool(),
new ListViewsTool(),
new ListIndexesTool(),
new GetTableStructureTool(),
];
server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
tools: tools.map((tool) => ({
name: tool.name,
description: tool.description,
inputSchema: tool.inputSchema,
})),
};
});
server.setRequestHandler(CallToolRequestSchema, async (request) => {
const { name, arguments: args } = request.params;
const tool = tools.find((t) => t.name === name);
if (!tool) {
throw new Error(`Unknown tool: ${name}`);
}
try {
const result = await tool.execute(args || {});
return {
content: [
{
type: "text",
text: result,
},
],
};
}
catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error);
return {
content: [
{
type: "text",
text: JSON.stringify({
success: false,
error: errorMessage,
executedAt: new Date().toISOString(),
}, null, 2),
},
],
isError: true,
};
}
});
async function main() {
const transport = new StdioServerTransport();
await server.connect(transport);
console.error("Vertica MCP Server running on stdio");
}
process.on("unhandledRejection", (reason, promise) => {
console.error("Unhandled Rejection at:", promise, "reason:", reason);
});
process.on("uncaughtException", (error) => {
console.error("Uncaught Exception:", error);
process.exit(1);
});
process.on("SIGTERM", () => {
console.error("Received SIGTERM, shutting down gracefully");
process.exit(0);
});
process.on("SIGINT", () => {
console.error("Received SIGINT, shutting down gracefully");
process.exit(0);
});
main().catch((error) => {
console.error("Fatal error in main():", error);
process.exit(1);
});
//# sourceMappingURL=index.js.map