# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Project Overview

This is an MCP (Model Context Protocol) server that enables AI assistants to create, manage, and monitor n8n workflows through natural language interactions. It acts as a bridge between AI interfaces (Claude AI, Cursor IDE) and n8n automation platform instances.

**Current Version:** 0.9.0
**Tested with:** n8n version 1.82.3
**Protocol:** JSON-RPC 2.0 over stdio (MCP) and HTTP

## Development Commands

### Build & Development
```bash
npm run clean          # Remove build artifacts
npm run build          # Compile TypeScript to JavaScript
npm run dev            # Watch mode for development
npm start              # Run compiled server
```

### Testing
```bash
node test-mcp-tools.js          # Comprehensive MCP tool testing
node test-comprehensive.js      # Full integration tests
node test-notification.js       # Notification handler tests
```

### Publishing
```bash
npm run prepublishOnly  # Auto-clean and build (runs automatically)
npm run publish         # Publish to npm registry
```

## Architecture & Code Organization

### Core Architecture Layers

**Layer 1: MCP Protocol (`src/index.ts`)**
- Entry point implementing MCP server using `@modelcontextprotocol/sdk`
- Dual transport: stdio (for Claude/Cursor) and HTTP/JSON-RPC
- Handles tool registration, resource provisioning, and prompt templates
- JSON-RPC 2.0 notification handler support (v0.9.0)

**Layer 2: Multi-Instance Management**
- `ConfigLoader` (`src/config/configLoader.ts`): Discovers and loads multi-instance configurations
- `EnvironmentManager` (`src/services/environmentManager.ts`): Caches API instances and routes requests
- `N8NApiWrapper` (`src/services/n8nApiWrapper.ts`): Unified API interface with instance routing

**Layer 3: Business Logic**
- `WorkflowBuilder` (`src/services/workflowBuilder.ts`): Workflow construction utilities
- `PromptsService` (`src/services/promptsService.ts`): Predefined workflow templates
- `validation.ts` (`src/utils/validation.ts`): Data transformation and validation

**Layer 4: N8N API Integration**
- Direct axios-based HTTP communication with n8n REST API
- Supports workflows, executions, and tag management
- Multi-instance routing with connection pooling

### Configuration System

**Priority Order:**
1. `.config.json` (multi-instance) - Primary
2. `.env` (single-instance) - Fallback for backward compatibility

**Multi-Instance Format (`.config.json`):**
```json
{
  "environments": {
    "production": {
      "n8n_host": "https://n8n.example.com",
      "n8n_api_key": "prod_key"
    },
    "staging": {...}
  },
  "defaultEnv": "production"
}
```

**Important:** Always provide the base URL without `/api/v1`. The server automatically appends `/api/v1` to construct the full API endpoint.

**Key Pattern:** Singleton pattern with `ConfigLoader.getInstance()` and `EnvironmentManager.getInstance()`

## Important Technical Constraints

### n8n API Compatibility (v1.82.3)

**Trigger Node Requirements:**
- Workflows MUST have valid trigger nodes to activate
- `manualTrigger` is NOT recognized as valid by n8n API v1.82.3
- Valid triggers: `scheduleTrigger`, `webhook`, service-specific triggers
- The server automatically adds valid triggers if missing during activation

**Workflow Execution Limitation:**
- Manual trigger workflows CANNOT be executed through REST API
- Execution must occur through n8n web interface
- `execute_workflow` tool provides helpful guidance instead of failing

**Connection Format Transformation:**
- **Input:** Array format `[{source, target, sourceOutput, targetInput}]`
- **n8n API:** Object format `{[sourceName]: {main: [[{node, type, index}]]}}`
- Automatic bidirectional conversion in `validation.ts`

**Set Node Parameter Handling:**
- Supports both legacy array format and modern object-based format
- Automatic parameter restructuring in `validation.ts`
- Critical for n8n compatibility

### Logging Convention

**CRITICAL:** All logging uses `console.error()` to avoid interfering with JSON-RPC on stdout
- Debug mode: `DEBUG=true` environment variable
- Never use `console.log()` - it breaks MCP protocol communication

### Performance Optimization (v0.8.0)

**list_workflows Performance:**
- Returns streamlined metadata only (ID, name, status, dates, node count, tags)
- NEVER return full workflow JSON - it crashes Claude Desktop with large datasets
- 90%+ data reduction for large workflow lists

## Common Development Patterns

### 1. Multi-Instance Tool Pattern

All MCP tools support optional `instance` parameter:

```typescript
{
  name: "tool_name",
  description: "...",
  inputSchema: {
    type: "object",
    properties: {
      instance: {
        type: "string",
        description: "Instance identifier (optional, uses default if not provided)"
      },
      // ... other parameters
    }
  }
}
```

### 2. Instance Resolution Pattern

```typescript
private async callWithInstance<T>(
  instanceSlug: string | undefined,
  apiCall: () => Promise<T>
): Promise<T> {
  // 1. Validate instance exists if provided
  // 2. Use default environment if no instance specified
  // 3. Execute API call with appropriate configuration
  // 4. Provide detailed error messages with available instances
}
```

### 3. Error Handling Pattern

```typescript
private handleApiError(context: string, error: unknown): never {
  logger.error(`API error during ${context}`);
  if (axios.isAxiosError(error)) {
    logger.error(`Status: ${error.response?.status}`);
    logger.error(`Response: ${JSON.stringify(error.response?.data)}`);
  }
  throw new Error(`API error ${context}: ${error.message}`);
}
```

### 4. Connection Format Conversion

When working with workflow connections:

```typescript
// Always use validation utilities
import { transformConnectionsForN8N, transformConnectionsFromN8N } from './utils/validation';

// Input to n8n API
const n8nFormat = transformConnectionsForN8N(arrayFormat);

// n8n API to output
const arrayFormat = transformConnectionsFromN8N(n8nFormat);
```

### 5. Set Node Parameter Normalization

When handling Set node parameters:

```typescript
import { normalizeSetNodeParameters } from './utils/validation';

// Automatically handles both formats
const normalized = normalizeSetNodeParameters(parameters);
```

### 6. Schema-Driven Credential Creation (Epic 2)

Credential creation follows a schema-driven validation pattern:

```typescript
// Step 1: Get schema to understand required fields
const schema = await getCredentialSchema('httpBasicAuth');
// Returns: { type: 'object', properties: { user: {...}, password: {...} } }

// Step 2: Create credential with validated data
const credential = await createCredential({
  name: 'My API Credential',
  type: 'httpBasicAuth',
  data: {
    user: 'username',
    password: 'securepass'
  }
}, instanceSlug);
// Returns: { id, name, type, createdAt, updatedAt, nodesAccess }

// Step 3: Update credential using DELETE + CREATE pattern (immutability)
await deleteCredential(credential.id, instanceSlug);
const updated = await createCredential({
  name: 'My API Credential',
  type: 'httpBasicAuth',
  data: { user: 'newuser', password: 'newpass' }
}, instanceSlug);
```

**Key Points:**
- **Security:** n8n blocks LIST and GET operations for credential protection
- **Immutability:** Credentials cannot be updated directly (use DELETE + CREATE)
- **Schema-First:** Always check schema before creating complex credentials (OAuth2, etc.)
- **Encryption:** n8n automatically encrypts sensitive credential data

## MCP Tools (17 Total)

**Workflow Management (8 tools):**
- `list_workflows` - Streamlined metadata (performance optimized)
- `create_workflow` - Full workflow creation with validation
- `get_workflow` - Retrieve complete workflow details
- `update_workflow` - Modify existing workflows
- `delete_workflow` - Remove workflows
- `activate_workflow` - Enable workflow (adds trigger if needed)
- `deactivate_workflow` - Disable workflow
- `execute_workflow` - Manual execution (with API limitation guidance)

**Execution Management (4 tools):**
- `list_executions` - Filter and list execution history
- `get_execution` - Detailed execution information
- `delete_execution` - Remove execution records
- `retry_execution` - Retry failed executions (creates new execution as retry of original)

**Tag Management (5 tools):**
- `create_tag` - Create workflow tags
- `get_tags` / `get_tag` - Retrieve tag information
- `update_tag` / `delete_tag` - Modify/remove tags

**Credential Management (6 tools - Epic 2 Complete):**
- `list_credentials` - Security guidance (n8n blocks for security)
- `get_credential` - Security guidance and alternatives
- `create_credential` - Create credentials with schema-driven validation
- `update_credential` - Immutability guidance (DELETE + CREATE pattern)
- `delete_credential` - Remove credentials permanently
- `get_credential_schema` - Get JSON schema for credential types

## MCP Resources (4 Types)

**Static:**
- `/workflows` - List of all workflows
- `/execution-stats` - Execution statistics summary

**Dynamic Templates:**
- `/workflows/{id}` - Specific workflow details
- `/executions/{id}` - Specific execution details

## MCP Prompts (5 Templates)

1. **Schedule Triggered Workflow** - Cron-based automation
2. **HTTP Webhook Workflow** - HTTP endpoint responder
3. **Data Transformation Workflow** - Data processing pipeline
4. **External Service Integration** - API integration workflows
5. **API Data Polling Workflow** - Interval-based API polling

## Testing Strategy

### Test Structure

**test-mcp-tools.js** - Primary test suite:
- Workflow CRUD operations
- Tag management
- Execution tracking
- Automatic cleanup (controlled by `runCleanup` flag)

**Configuration:**
```javascript
const config = {
  mcpServerUrl: 'http://localhost:3456/mcp',
  healthCheckUrl: 'http://localhost:3456/health',
  testWorkflowName: 'Test Workflow MCP',
  testFlags: {
    runWorkflowTests: true,
    runTagTests: true,
    runExecutionTests: true,
    runCleanup: true  // Set to false to keep test data
  }
};
```

### Running Tests

1. Build the project: `npm run build`
2. Start server in separate terminal: `npm start`
3. Run tests: `node test-mcp-tools.js`

**Test Cleanup:** Tests automatically clean up created resources unless `runCleanup: false`

## Known Issues & Workarounds

### Tag Update 409 Conflicts

**Issue:** Updating existing tag names returns 409 Conflict
**Workaround:** Tests use UUID generation for unique tag names

### Manual Trigger Execution

**Issue:** Workflows with only manual triggers cannot be executed via REST API
**Workaround:** `execute_workflow` tool provides clear error message and guidance

### Port Conflicts (v0.7.2+)

**Issue:** Port 3456 might be in use
**Workaround:** Set `MCP_PORT` environment variable to use different port

## Version History Context

**v0.9.0 (Current):**
- Fixed "Method 'notifications/initialized' not found" error
- Full MCP notification handler support
- Package size optimization (1.3MB → 278KB)

**v0.8.0:**
- Multi-instance architecture
- list_workflows performance optimization (critical for Claude Desktop stability)

**v0.7.2:**
- Set node parameter validation fixes
- Port conflict handling

## Security Notes

- Never commit `.config.json` or `.env` files
- Separate API keys per environment in multi-instance setup
- No credentials in logs (error messages avoid exposing sensitive details)
- Instance validation before API calls

## Integration with Claude Desktop

**Example Configuration:**
```json
{
  "mcpServers": {
    "n8n-workflow-builder": {
      "command": "node",
      "args": ["/path/to/build/index.js"],
      "env": {
        "N8N_HOST": "https://n8n.example.com",
        "N8N_API_KEY": "your_key",
        "MCP_PORT": "58921"
      },
      "alwaysAllow": [
        "list_workflows",
        "get_workflow",
        "list_executions",
        "get_execution"
      ]
    }
  }
}
```

## Common Tasks

### Adding a New MCP Tool

1. Add tool definition in `src/index.ts` (CallToolRequestSchema handler)
2. Implement logic in `N8NApiWrapper` or appropriate service
3. Add multi-instance support via `callWithInstance` pattern
4. Update tests in `test-mcp-tools.js`
5. Document in README.md

### Adding a New Workflow Prompt

1. Add template in `PromptsService.getAvailablePrompts()`
2. Define variables with descriptions and defaults
3. Test variable substitution with nested objects/arrays
4. Update README.md prompt documentation

### Debugging Connection Issues

1. Enable debug logging: `DEBUG=true npm start`
2. Check stderr for detailed API error messages
3. Verify n8n host URL ends with `/api/v1/`
4. Validate API key has necessary permissions
5. Test with health check endpoint: `http://localhost:3456/health`

### Performance Troubleshooting

1. Check if returning full workflow JSON (should use metadata only)
2. Verify API instance caching is working (singleton pattern)
3. Monitor connection pooling with axios instances
4. Review n8n API response times in logs
