|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
| 4 | + |
| 5 | +## Project Overview |
| 6 | + |
| 7 | +DeployHQ MCP Server is a Model Context Protocol (MCP) server that enables AI assistants (Claude Desktop and Claude Code) to interact with DeployHQ deployments. It provides two operational modes: |
| 8 | + |
| 9 | +1. **stdio transport** (primary): npm package for direct use with `npx deployhq-mcp-server` |
| 10 | +2. **HTTP/SSE transports** (optional): Express server for hosted deployment |
| 11 | + |
| 12 | +## Development Commands |
| 13 | + |
| 14 | +### Build & Type Checking |
| 15 | +```bash |
| 16 | +npm run build # Compile TypeScript to dist/ |
| 17 | +npm run type-check # Type check without emitting files |
| 18 | +npm run clean # Remove dist/ directory |
| 19 | +``` |
| 20 | + |
| 21 | +### Development & Testing |
| 22 | +```bash |
| 23 | +npm run dev # Watch mode for hosted server (index.ts) |
| 24 | +npm run start # Run compiled hosted server |
| 25 | +npm run lint # ESLint on src/ |
| 26 | +``` |
| 27 | + |
| 28 | +### Testing stdio Transport Locally |
| 29 | +```bash |
| 30 | +# Build first |
| 31 | +npm run build |
| 32 | + |
| 33 | +# Test with environment variables |
| 34 | +DEPLOYHQ_EMAIL="email" DEPLOYHQ_API_KEY="pass" DEPLOYHQ_ACCOUNT="account" node dist/stdio.js |
| 35 | + |
| 36 | +# Or use the test script |
| 37 | +export DEPLOYHQ_EMAIL="email" |
| 38 | +export DEPLOYHQ_API_KEY="pass" |
| 39 | +export DEPLOYHQ_ACCOUNT="account" |
| 40 | +./test-stdio.sh |
| 41 | +``` |
| 42 | + |
| 43 | +### Testing with Claude Desktop |
| 44 | +Edit `~/Library/Application Support/Claude/claude_desktop_config.json`: |
| 45 | +```json |
| 46 | +{ |
| 47 | + "mcpServers": { |
| 48 | + "deployhq-local": { |
| 49 | + "command": "node", |
| 50 | + "args": ["/absolute/path/to/dist/stdio.js"], |
| 51 | + "env": { |
| 52 | + "DEPLOYHQ_EMAIL": "email", |
| 53 | + "DEPLOYHQ_API_KEY": "pass", |
| 54 | + "DEPLOYHQ_ACCOUNT": "account" |
| 55 | + } |
| 56 | + } |
| 57 | + } |
| 58 | +} |
| 59 | +``` |
| 60 | +Restart Claude Desktop to test. |
| 61 | + |
| 62 | +## Architecture |
| 63 | + |
| 64 | +### Core Components |
| 65 | + |
| 66 | +**Two Entry Points:** |
| 67 | +- `src/stdio.ts` → `dist/stdio.js` (bin entry, stdio transport for MCP clients) |
| 68 | +- `src/index.ts` → `dist/index.js` (Express server for hosted deployment) |
| 69 | + |
| 70 | +**Shared Core:** |
| 71 | +- `src/mcp-server.ts`: Factory function `createMCPServer(username, password, account)` that returns a configured MCP Server instance. Used by both stdio and hosted modes. |
| 72 | +- `src/tools.ts`: Defines 6 MCP tools (list_projects, get_project, list_servers, list_deployments, get_deployment, create_deployment) with Zod validation schemas |
| 73 | +- `src/api-client.ts`: DeployHQClient class for HTTP Basic Auth API calls to DeployHQ REST API |
| 74 | + |
| 75 | +**Transport Handlers (hosted mode only):** |
| 76 | +- `src/transports/sse-handler.ts`: Server-Sent Events transport |
| 77 | +- `src/transports/http-handler.ts`: HTTP JSON-RPC transport |
| 78 | + |
| 79 | +### Critical: stdio Transport Logging |
| 80 | + |
| 81 | +**IMPORTANT**: When using stdio transport, stdout is reserved exclusively for JSON-RPC messages. All logging MUST go to stderr. |
| 82 | + |
| 83 | +The `src/utils/logger.ts` uses `console.error()` for all log levels (info, error, debug) to prevent corrupting the JSON-RPC stream. Writing to stdout will cause "Unexpected token" JSON parse errors in Claude Desktop/Code. |
| 84 | + |
| 85 | +❌ **Wrong**: `console.log('[INFO] message')` → breaks stdio |
| 86 | +✅ **Correct**: `console.error('[INFO] message')` → works with stdio |
| 87 | + |
| 88 | +### Tool Call Flow |
| 89 | + |
| 90 | +1. MCP client (Claude Desktop/Code) sends JSON-RPC request via stdin |
| 91 | +2. `StdioServerTransport` receives and parses request |
| 92 | +3. `createMCPServer()` routes to appropriate tool handler in `mcp-server.ts` |
| 93 | +4. Tool validates input with Zod schema from `tools.ts` |
| 94 | +5. `DeployHQClient` makes HTTP request to DeployHQ API with Basic Auth |
| 95 | +6. Response returned as JSON-RPC message via stdout |
| 96 | +7. Logs go to stderr throughout (visible in client logs but not in JSON stream) |
| 97 | + |
| 98 | +### Credential Flow |
| 99 | + |
| 100 | +**stdio mode**: Environment variables → `stdio.ts` reads → passes to `createMCPServer()` |
| 101 | +**hosted mode**: HTTP headers → transport handler extracts → passes to `createMCPServer()` |
| 102 | + |
| 103 | +Per-request client initialization ensures each API call uses the correct user's credentials. |
| 104 | + |
| 105 | +## Key Technical Decisions |
| 106 | + |
| 107 | +### Why stdio for Primary Use Case |
| 108 | +- Simpler than hosted deployment (no infrastructure needed) |
| 109 | +- Credentials stay local (environment variables) |
| 110 | +- Direct process spawning by MCP clients |
| 111 | +- No CORS or authentication complexity |
| 112 | + |
| 113 | +### Why Zod for Validation |
| 114 | +All tool inputs use Zod schemas for runtime validation. Schemas defined once in `tools.ts` and used for both: |
| 115 | +- TypeScript type inference |
| 116 | +- Runtime validation in tool handlers |
| 117 | + |
| 118 | +### Why Separate createMCPServer Factory |
| 119 | +The factory function `createMCPServer()` encapsulates all MCP server logic and is transport-agnostic. This allows: |
| 120 | +- Same business logic for stdio and hosted modes |
| 121 | +- Easy testing (can instantiate server without transport) |
| 122 | +- Clean separation of concerns |
| 123 | + |
| 124 | +## Available MCP Tools |
| 125 | + |
| 126 | +1. **list_projects**: Get all projects (no params) |
| 127 | +2. **get_project**: Get project details (permalink) |
| 128 | +3. **list_servers**: List project servers (project) |
| 129 | +4. **list_deployments**: List deployments with pagination (project, page?, server_uuid?) |
| 130 | +5. **get_deployment**: Get deployment details (project, uuid) |
| 131 | +6. **create_deployment**: Create new deployment (project, parent_identifier, start_revision, end_revision, plus optional params) |
| 132 | + |
| 133 | +All tools require valid DeployHQ credentials and return typed responses matching the DeployHQ API. |
| 134 | + |
| 135 | +## Common Development Patterns |
| 136 | + |
| 137 | +### Adding a New Tool |
| 138 | + |
| 139 | +1. Add Zod schema to `src/tools.ts` (e.g., `export const NewToolSchema = z.object({...})`) |
| 140 | +2. Add tool definition to `tools` array in `src/tools.ts` |
| 141 | +3. Add case to switch statement in `src/mcp-server.ts` CallToolRequestSchema handler |
| 142 | +4. Add corresponding method to `DeployHQClient` in `src/api-client.ts` if needed |
| 143 | +5. Import schema in `mcp-server.ts` and use for validation |
| 144 | + |
| 145 | +### Testing Changes |
| 146 | + |
| 147 | +Always rebuild after TypeScript changes: |
| 148 | +```bash |
| 149 | +npm run build |
| 150 | +``` |
| 151 | + |
| 152 | +For stdio testing, use absolute path to `dist/stdio.js` in client configs to avoid npx caching issues during development. |
| 153 | + |
| 154 | +## Configuration Files |
| 155 | + |
| 156 | +- `docs/claude-config.json`: Universal config template for both Claude Desktop and Claude Code |
| 157 | +- `tsconfig.json`: Targets ES2022, outputs to dist/, includes all src files |
| 158 | +- `package.json`: Dual entry points (main for hosted, bin for stdio) |
| 159 | + |
| 160 | +## Important: Node Version |
| 161 | + |
| 162 | +Requires Node.js >=20.0.0 (specified in package.json engines). The stdio transport uses modern Node.js features. |
0 commit comments