Skip to content

Commit edfe3d4

Browse files
committed
Add pgai mcp install command with support for Cursor, Claude Desktop, VS Code, Windsurf, and Codex
1 parent f00c3b7 commit edfe3d4

File tree

1 file changed

+135
-0
lines changed

1 file changed

+135
-0
lines changed

cli/bin/postgres-ai.ts

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1190,5 +1190,140 @@ mcp
11901190
await startMcpServer(rootOpts, { debug: !!opts.debug });
11911191
});
11921192

1193+
mcp
1194+
.command("install [client]")
1195+
.description("install MCP server configuration for AI coding tool")
1196+
.action(async (client?: string) => {
1197+
const supportedClients = ["cursor", "claude", "vscode", "windsurf", "codex"];
1198+
1199+
// If no client specified, prompt user to choose
1200+
if (!client) {
1201+
console.log("Available AI coding tools:");
1202+
console.log(" 1. Cursor");
1203+
console.log(" 2. Claude Desktop");
1204+
console.log(" 3. VS Code (with Cline/Continue)");
1205+
console.log(" 4. Windsurf");
1206+
console.log(" 5. Codex");
1207+
console.log("");
1208+
1209+
const rl = readline.createInterface({
1210+
input: process.stdin,
1211+
output: process.stdout
1212+
});
1213+
1214+
const answer = await new Promise<string>((resolve) => {
1215+
rl.question("Select your AI coding tool (1-5): ", resolve);
1216+
});
1217+
rl.close();
1218+
1219+
const choices: Record<string, string> = {
1220+
"1": "cursor",
1221+
"2": "claude",
1222+
"3": "vscode",
1223+
"4": "windsurf",
1224+
"5": "codex"
1225+
};
1226+
1227+
client = choices[answer.trim()];
1228+
if (!client) {
1229+
console.error("Invalid selection");
1230+
process.exitCode = 1;
1231+
return;
1232+
}
1233+
}
1234+
1235+
client = client.toLowerCase();
1236+
1237+
if (!supportedClients.includes(client)) {
1238+
console.error(`Unsupported client: ${client}`);
1239+
console.error(`Supported clients: ${supportedClients.join(", ")}`);
1240+
process.exitCode = 1;
1241+
return;
1242+
}
1243+
1244+
try {
1245+
const homeDir = os.homedir();
1246+
let configPath: string;
1247+
let configDir: string;
1248+
1249+
// Determine config file location based on client
1250+
switch (client) {
1251+
case "cursor":
1252+
configPath = path.join(homeDir, ".cursor", "mcp.json");
1253+
configDir = path.dirname(configPath);
1254+
break;
1255+
1256+
case "claude":
1257+
if (process.platform === "darwin") {
1258+
configPath = path.join(homeDir, "Library", "Application Support", "Claude", "claude_desktop_config.json");
1259+
} else if (process.platform === "win32") {
1260+
configPath = path.join(process.env.APPDATA || "", "Claude", "claude_desktop_config.json");
1261+
} else {
1262+
configPath = path.join(homeDir, ".config", "Claude", "claude_desktop_config.json");
1263+
}
1264+
configDir = path.dirname(configPath);
1265+
break;
1266+
1267+
case "vscode":
1268+
configPath = path.join(homeDir, ".vscode", "mcp.json");
1269+
configDir = path.dirname(configPath);
1270+
break;
1271+
1272+
case "windsurf":
1273+
configPath = path.join(homeDir, ".windsurf", "mcp.json");
1274+
configDir = path.dirname(configPath);
1275+
break;
1276+
1277+
case "codex":
1278+
configPath = path.join(homeDir, ".codex", "mcp.json");
1279+
configDir = path.dirname(configPath);
1280+
break;
1281+
1282+
default:
1283+
console.error(`Configuration not implemented for: ${client}`);
1284+
process.exitCode = 1;
1285+
return;
1286+
}
1287+
1288+
// Ensure config directory exists
1289+
if (!fs.existsSync(configDir)) {
1290+
fs.mkdirSync(configDir, { recursive: true });
1291+
}
1292+
1293+
// Read existing config or create new one
1294+
let config: any = { mcpServers: {} };
1295+
if (fs.existsSync(configPath)) {
1296+
try {
1297+
const content = fs.readFileSync(configPath, "utf8");
1298+
config = JSON.parse(content);
1299+
if (!config.mcpServers) {
1300+
config.mcpServers = {};
1301+
}
1302+
} catch (err) {
1303+
console.error(`Warning: Could not parse existing config, creating new one`);
1304+
}
1305+
}
1306+
1307+
// Add or update PostgresAI MCP server configuration
1308+
config.mcpServers.postgresai = {
1309+
command: "pgai",
1310+
args: ["mcp", "start"]
1311+
};
1312+
1313+
// Write updated config
1314+
fs.writeFileSync(configPath, JSON.stringify(config, null, 2), "utf8");
1315+
1316+
console.log(`✓ PostgresAI MCP server configured for ${client}`);
1317+
console.log(` Config file: ${configPath}`);
1318+
console.log("");
1319+
console.log("Please restart your AI coding tool to activate the MCP server");
1320+
1321+
} catch (error) {
1322+
const message = error instanceof Error ? error.message : String(error);
1323+
console.error(`Failed to install MCP server: ${message}`);
1324+
process.exitCode = 1;
1325+
}
1326+
});
1327+
11931328
program.parseAsync(process.argv);
11941329

0 commit comments

Comments
 (0)