Skip to main content
Glama

mcp-server-neon

Official
initConfig.ts3.96 kB
import path from 'node:path'; import os from 'node:os'; import fs from 'node:fs'; import chalk from 'chalk'; import { fileURLToPath } from 'url'; import { logger } from './utils/logger.js'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const packageJson = JSON.parse( fs.readFileSync(path.join(__dirname, '..', 'package.json'), 'utf8'), ); // Determine Claude config path based on OS platform let claudeConfigPath: string; const platform = os.platform(); if (platform === 'win32') { // Windows path - using %APPDATA% // For Node.js, we access %APPDATA% via process.env.APPDATA claudeConfigPath = path.join( process.env.APPDATA || '', 'Claude', 'claude_desktop_config.json', ); } else { // macOS and Linux path (according to official docs) claudeConfigPath = path.join( os.homedir(), 'Library', 'Application Support', 'Claude', 'claude_desktop_config.json', ); } const MCP_NEON_SERVER = 'neon'; type Args = | { command: 'start:sse'; analytics: boolean; } | { command: 'start'; neonApiKey: string; analytics: boolean; } | { command: 'init'; executablePath: string; neonApiKey: string; analytics: boolean; } | { command: 'export-tools'; }; const commands = ['init', 'start', 'start:sse', 'export-tools'] as const; export const parseArgs = (): Args => { const args = process.argv; if (args.length < 3) { logger.error('Invalid number of arguments'); process.exit(1); } if (args.length === 3 && args[2] === 'start:sse') { return { command: 'start:sse', analytics: true, }; } if (args.length === 3 && args[2] === 'export-tools') { return { command: 'export-tools', }; } const command = args[2]; if (!commands.includes(command as (typeof commands)[number])) { logger.error(`Invalid command: ${command}`); process.exit(1); } if (command === 'export-tools') { return { command: 'export-tools', }; } if (args.length < 4) { logger.error( 'Please provide a NEON_API_KEY as a command-line argument - you can get one through the Neon console: https://neon.tech/docs/manage/api-keys', ); process.exit(1); } return { executablePath: args[1], command: args[2] as 'start' | 'init', neonApiKey: args[3], analytics: !args[4]?.includes('no-analytics'), }; }; export function handleInit({ executablePath, neonApiKey, analytics, }: { executablePath: string; neonApiKey: string; analytics: boolean; }) { // If the executable path is a local path to the dist/index.js file, use it directly // Otherwise, use the name of the package to always load the latest version from remote const serverPath = executablePath.includes('dist/index.js') ? executablePath : packageJson.name; const neonConfig = { command: 'npx', args: [ '-y', serverPath, 'start', neonApiKey, analytics ? '' : '--no-analytics', ], }; const configDir = path.dirname(claudeConfigPath); if (!fs.existsSync(configDir)) { console.log(chalk.blue('Creating Claude config directory...')); fs.mkdirSync(configDir, { recursive: true }); } const existingConfig = fs.existsSync(claudeConfigPath) ? JSON.parse(fs.readFileSync(claudeConfigPath, 'utf8')) : { mcpServers: {} }; if (MCP_NEON_SERVER in (existingConfig?.mcpServers || {})) { console.log(chalk.yellow('Replacing existing Neon MCP config...')); } const newConfig = { ...existingConfig, mcpServers: { ...existingConfig.mcpServers, [MCP_NEON_SERVER]: neonConfig, }, }; fs.writeFileSync(claudeConfigPath, JSON.stringify(newConfig, null, 2)); console.log(chalk.green(`Config written to: ${claudeConfigPath}`)); console.log( chalk.blue( 'The Neon MCP server will start automatically the next time you open Claude.', ), ); }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/neondatabase-labs/mcp-server-neon'

If you have feedback or need assistance with the MCP directory API, please join our Discord server