Initial commit

This commit is contained in:
Felix Zösch
2025-12-11 20:30:12 +01:00
commit 3e23474476
21 changed files with 5327 additions and 0 deletions

200
CLAUDE.md Normal file
View File

@@ -0,0 +1,200 @@
# 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