Skip to main content
Glama
CLAUDE.md9.48 kB
# CLAUDE.md This file provides guidance to AI agents when working with code in this repository. ## Project Overview This is the **Neon MCP Server** - a Model Context Protocol server that bridges natural language requests to the Neon API, enabling LLMs to manage Neon Postgres databases through conversational commands. The project implements both local (stdio) and remote (SSE/Streamable HTTP) MCP server transports with OAuth authentication support. ## Development Commands ### Building and Running ```bash # Install dependencies npm install # Build the project (compiles TypeScript and builds landing page) npm run build # Watch mode for development (auto-recompiles on changes) npm run watch # Type checking without emitting files npm run typecheck # Start local MCP server with API key node dist/index.js start <NEON_API_KEY> # Start SSE transport server node dist/index.js start:sse ``` ### Development with MCP CLI Client The fastest way to iterate on the MCP Server is using the `mcp-client/` CLI: ```bash npm install npm run build npm run watch # Keep this running in one terminal cd mcp-client/ && NEON_API_KEY=<your-key> npm run start:mcp-server-neon ``` This provides an interactive terminal to test MCP tools without restarting Claude Desktop. ### Testing ```bash # Run Braintrust evaluations npm run test # You must configure .env file with: # - BRAINTRUST_API_KEY # - NEON_API_KEY # - ANTHROPIC_API_KEY ``` ### Linting and Formatting ```bash # Run linting and formatting checks npm run lint # Auto-fix linting and formatting issues npm run lint:fix # Format code npm run format ``` ### Single Test Development To develop and test a single tool without running full test suite, modify the test file in `src/tools-evaluations/` and run: ```bash npm run test ``` ## Architecture ### Core Components 1. **MCP Server (`src/server/index.ts`)** - Creates and configures the MCP server instance - Registers all tools and resources from centralized definitions - Implements error handling and observability (Sentry, analytics) - Each tool call is tracked and wrapped in error handling 2. **Tools System (`src/tools/`)** - `definitions.ts`: Exports `NEON_TOOLS` array defining all available tools with their schemas - `tools.ts`: Exports `NEON_HANDLERS` object mapping tool names to handler functions - `toolsSchema.ts`: Zod schemas for tool input validation - `handlers/`: Individual tool handler implementations organized by feature 3. **Transport Layers (`src/transports/`)** - `stdio.ts`: Standard input/output transport for local MCP clients (Claude Desktop, Cursor) - `sse-express.ts`: Server-Sent Events transport for remote MCP server (deprecated) - `stream.ts`: Streamable HTTP transport for remote MCP server (recommended) 4. **OAuth System (`src/oauth/`)** - OAuth 2.0 server implementation for remote MCP authentication - Integrates with Neon's OAuth provider (UPSTREAM_OAUTH_HOST) - Token persistence using Keyv with Postgres backend - Cookie-based client approval tracking 5. **Resources (`src/resources.ts`)** - MCP resources that provide read-only context (like "getting started" guides) - Registered alongside tools but don't execute operations ### Key Architectural Patterns - **Tool Registration Pattern**: All tools are defined in `NEON_TOOLS` array and handlers in `NEON_HANDLERS` object. The server iterates through tools and registers them with their corresponding handlers. - **Error Handling**: Tools throw errors which are caught by the server wrapper, logged to Sentry, and returned as structured error messages to the LLM. - **State Management**: Some tools (migrations, query tuning) create temporary branches and maintain state across multiple tool calls. The LLM is prompted to remember branch IDs from previous calls. - **Analytics & Observability**: Every tool call, resource access, and error is tracked through Segment analytics and Sentry error reporting. ## Adding New Tools 1. Define the tool schema in `src/tools/toolsSchema.ts`: ```typescript export const myNewToolInputSchema = z.object({ project_id: z.string().describe('The Neon project ID'), // ... other fields }); ``` 2. Add the tool definition to `NEON_TOOLS` array in `src/tools/definitions.ts`: ```typescript { name: 'my_new_tool' as const, description: 'Description of what this tool does', inputSchema: myNewToolInputSchema, } ``` 3. Create a handler in `src/tools/handlers/my-new-tool.ts`: ```typescript import { ToolHandler } from '../types.js'; import { myNewToolInputSchema } from '../toolsSchema.js'; export const myNewToolHandler: ToolHandler<'my_new_tool'> = async ( args, neonClient, extra, ) => { // Implementation return { content: [ { type: 'text', text: 'Result message', }, ], }; }; ``` 4. Register the handler in `src/tools/tools.ts`: ```typescript import { myNewToolHandler } from './handlers/my-new-tool.js'; export const NEON_HANDLERS = { // ... existing handlers my_new_tool: myNewToolHandler, }; ``` 5. Add evaluations in `src/tools-evaluations/` to test your tool. ## Environment Configuration See `.env.example` for all configuration options. Key variables: - `NEON_API_KEY`: Required for local development and testing - `BRAINTRUST_API_KEY`: Required for running evaluations - `ANTHROPIC_API_KEY`: Required for running evaluations - `OAUTH_DATABASE_URL`: Required for remote MCP server with OAuth - `COOKIE_SECRET`: Required for remote MCP server OAuth flow - `CLIENT_ID` / `CLIENT_SECRET`: OAuth client credentials ## Project Structure ``` src/ ├── index.ts # Entry point, command parser, transport selection ├── server/ │ ├── index.ts # MCP server creation and tool/resource registration │ └── api.ts # Neon API client factory ├── tools/ │ ├── definitions.ts # Tool definitions (NEON_TOOLS) │ ├── tools.ts # Tool handlers mapping (NEON_HANDLERS) │ ├── toolsSchema.ts # Zod schemas for tool inputs │ └── handlers/ # Individual tool implementations ├── transports/ │ ├── stdio.ts # Local MCP transport │ ├── sse-express.ts # Remote SSE transport │ └── stream.ts # Remote Streamable HTTP transport ├── oauth/ # OAuth 2.0 implementation ├── analytics/ # Segment analytics integration ├── sentry/ # Sentry error tracking └── utils/ # Shared utilities mcp-client/ # CLI client for testing landing/ # Next.js landing page ``` ## Important Notes - **TypeScript Configuration**: Uses ES2022 with Node16 module resolution. All imports must use `.js` extensions (not `.ts`) due to ESM requirements. - **Building**: The build process includes chmod operations to make `dist/index.js` executable, exports tool definitions to `landing/tools.json`, and builds the landing page. - **Logger Behavior**: In stdio mode, the logger is silenced to prevent stderr pollution. In SSE mode, logging is active. - **Migration Pattern**: Tools like `prepare_database_migration` and `prepare_query_tuning` create temporary branches. The LLM must remember these branch IDs to pass to subsequent `complete_*` tools. - **Neon API Client**: Created using `@neondatabase/api-client` package. All tool handlers receive a pre-configured `neonClient` instance. ## Claude Code Review Workflow This repository uses an enhanced Claude Code Review workflow that provides inline feedback on pull requests. ### What Gets Reviewed - Architecture and design patterns (tool registration, handler typing) - Security vulnerabilities (SQL injection, secrets, input validation) - Logic bugs (error handling, state management, edge cases) - Performance issues (N+1 queries, inefficient API usage) - Testing gaps (missing evaluations, uncovered scenarios) - MCP-specific patterns (analytics tracking, error handling, Sentry capture) ### What's Automated (Not Reviewed by Claude) - Linting: `bun run lint` (checked by pr.yml) - Building: `bun run build` (checked by pr.yml) - Formatting: Automated formatting checks ### Review Process 1. Workflow triggers automatically on PR open 2. Claude analyzes changes with full project context 3. Inline comments posted on significant issues 4. Summary comment provides overview and statistics ### Inline Comment Format - **Severity**: 🔴 Critical | 🟡 Important | 🔵 Consider - **Category**: [Security/Logic/Performance/Architecture/Testing/MCP] - **Description**: Clear explanation with context - **Fix**: Actionable code example or reference Example: ``` 🔴 **[Security]**: SQL injection vulnerability - user input concatenated directly into SQL. **Fix:** Use parameterized queries: const result = await query('SELECT * FROM users WHERE name = $1', [userName]); ``` ### Triggering Reviews - **Automatic**: Opens when PR is created - **Manual**: Run workflow via GitHub Actions with PR number - **Security**: Only OWNER/MEMBER/COLLABORATOR PRs (blocks external) ## Testing Strategy Tests use Braintrust for LLM-based evaluations. Each test: 1. Defines a task/prompt 2. Executes it against the MCP server 3. Evaluates the result using Braintrust scoring functions This validates that tools work correctly with realistic LLM interactions.

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