# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Overview InfluxDB MCP Server - A Model Context Protocol server that enables AI assistants to interact with InfluxDB v2 time-series databases. Built with TypeScript, using the MCP SDK, axios for HTTP, and zod for validation. ## Build and Development Commands ```bash # Install dependencies npm install # Build TypeScript to JavaScript npm run build # Watch mode for development (rebuilds on file changes) npm run watch # Run the compiled server npm start # Run with custom environment variables INFLUX_URL=http://localhost:8086 INFLUX_TOKEN=your_token INFLUX_ORG=your_org node dist/index.js ``` ## Architecture Overview ### Three-Layer Structure 1. **index.ts** - MCP Server Implementation - Defines MCP resources (read-only URIs like `influx://health`, `influx://buckets`) - Defines MCP tools (actions like `query_flux`, `write_data`, `create_bucket`) - Handles tool execution and resource reading via request handlers - Environment variable validation using Zod schema - Startup health check verifies InfluxDB connection before serving 2. **influx-client.ts** - InfluxDB REST API Client - Axios-based HTTP client with token authentication - Methods for all InfluxDB v2 API endpoints (query, write, buckets, orgs, tasks, dashboards) - Query response parsing from JSON format - Centralized error formatting via `formatError()` static method - Schema discovery using Flux `schema.measurements()`, `schema.measurementTagKeys()`, `schema.measurementFieldKeys()` 3. **types.ts** - TypeScript Type Definitions - Complete interfaces for all InfluxDB entities - InfluxConfig, HealthStatus, Organization, Bucket, Task, Dashboard - QueryResult, QueryTable for query responses - BucketSchema, Measurement, FieldInfo for schema discovery - WritePrecision type: 'ns' | 'us' | 'ms' | 's' ### Communication Flow ``` MCP Client → stdio → InfluxDBMCPServer → InfluxDBClient → InfluxDB REST API ``` The server runs on stdio (stdin/stdout) for MCP protocol communication. All logging goes to stderr to avoid interfering with the protocol. ## Key Implementation Details ### Environment Configuration Required environment variables validated at startup: - `INFLUX_URL` - InfluxDB server URL (must be valid URL) - `INFLUX_TOKEN` - Authentication token (required) - `INFLUX_ORG` - Organization name (optional, can be provided per-request) Configuration is validated using Zod schema in `loadConfig()` function. ### MCP Resources vs Tools **Resources** are read-only URIs that expose InfluxDB state: - `influx://health` - Server health - `influx://buckets` - All buckets - `influx://buckets/{id}` - Specific bucket - `influx://orgs` - All organizations - `influx://tasks` - Scheduled tasks - `influx://dashboards` - Dashboards **Tools** are actions that can modify state or query data: - `query_flux` - Execute Flux queries (requires query string, optional org) - `write_data` - Write line protocol data (requires bucket, org, data, optional precision) - `create_bucket` - Create bucket (requires name, org_id, optional retention_seconds, description) - `delete_bucket` - Delete bucket (requires bucket_id) - `list_measurements` - List measurements in bucket (requires bucket, optional start/stop) - `get_bucket_schema` - Get schema info (requires bucket, optional start/stop) ### Error Handling Pattern All errors are centralized through `InfluxDBClient.formatError()`: - Axios errors → extracted response message or request error - InfluxDB API errors → formatted with status code and message - All errors wrapped in `McpError` with appropriate error codes ### Query Response Parsing InfluxDB returns JSON when Accept header is `application/json`. The `parseQueryResponse()` method in influx-client.ts handles multiple response formats: - Array of records - Single object - Nested structure with `records` array Returns structured `QueryResult` with tables containing columns and records. ### Schema Discovery Implementation `getBucketSchema()` performs multiple queries: 1. Lists all measurements using `schema.measurements()` 2. For each measurement, queries tags and fields in parallel 3. Combines results into structured `BucketSchema` Time ranges default to -7d for schema, -30d for measurements. ## Line Protocol Format When writing data, use InfluxDB line protocol: ``` measurement[,tag=value...] field=value[,field=value...] [timestamp] ``` Examples: ``` temperature,location=office value=22.5 cpu,host=server1 usage=45.2 1672531200000000000 weather,location=garden temperature=22.5,humidity=65.2 ``` ## TypeScript Configuration - Target: ES2022 - Module: Node16 (ES modules with .js extensions in imports) - Strict mode enabled - Source maps and declarations generated - Output: `dist/` directory All imports must use `.js` extension (e.g., `import { X } from './types.js'`) even though source files are `.ts`. ## Common Development Tasks ### Adding a New MCP Tool 1. Add tool definition to `ListToolsRequestSchema` handler in index.ts 2. Add case to switch statement in `CallToolRequestSchema` handler 3. Implement method in InfluxDBClient if calling new InfluxDB API 4. Add types to types.ts if needed ### Adding a New MCP Resource 1. Add resource definition to `ListResourcesRequestSchema` handler 2. Add URI handling in `ReadResourceRequestSchema` handler 3. Implement method in InfluxDBClient to fetch data 4. Return formatted JSON response ### Testing Changes After modifying code: 1. Run `npm run build` to compile 2. Test with: `INFLUX_URL=... INFLUX_TOKEN=... INFLUX_ORG=... node dist/index.js` 3. Server will log connection success to stderr 4. Test in Claude Desktop or other MCP client ## Flux Query Language Notes Flux is InfluxDB's query language. Common patterns: ```flux // Basic range query from(bucket: "my-bucket") |> range(start: -1h) |> filter(fn: (r) => r._measurement == "cpu") // Aggregation from(bucket: "my-bucket") |> range(start: -24h) |> aggregateWindow(every: 1h, fn: mean) // Schema discovery import "influxdata/influxdb/schema" schema.measurements(bucket: "my-bucket", start: -30d) ``` Time formats: Relative (`-1h`, `-7d`, `-30d`) or absolute (`2024-01-01T00:00:00Z`) ## Important Constraints - **Bucket Creation**: Requires organization ID (not name). Use `getOrgByName()` or read `influx://orgs` resource first. - **Query Organization**: If `INFLUX_ORG` not set in environment, must provide `org` parameter to `query_flux` tool. - **Write Precision**: Defaults to nanoseconds ('ns'). Timestamps must match specified precision. - **Server Communication**: MCP protocol on stdout/stdin, all logs to stderr. - **No Pagination**: Large result sets not automatically paginated. Users should specify appropriate time ranges. ## Code Style - Use async/await for all I/O operations - Validate inputs before processing - Return structured JSON for tool responses - Include descriptive error messages - TypeScript strict mode compliance - ES modules with explicit .js imports