CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-finos--calm-cli

A comprehensive command-line interface for working with the Common Architecture Language Model (CALM)

Overview
Eval results
Files

server-command.mddocs/

Server Command

NOTE: This is a CLI-only command. @finos/calm-cli does not export functions for programmatic use.

The server command starts an HTTP server providing REST API access to CALM validation operations. This experimental feature enables programmatic validation through HTTP requests, useful for integrating CALM validation into web applications, microservices, or CI/CD pipelines.

Capabilities

Server Command

Start an HTTP server to provide REST API access to validation operations.

/**
 * Start a HTTP server to proxy CLI commands (experimental)
 * @command calm server [options]
 */
interface ServerCommandOptions {
  /** Server port
   * CLI flags: --port <port>
   * Default: "3000"
   */
  port?: string;

  /** Path to directory containing meta schemas
   * CLI flags: -s, --schema-directory <path>
   * Required: yes
   */
  schemaDirectory: string;

  /** Enable verbose logging
   * CLI flags: -v, --verbose
   * Default: false
   */
  verbose?: boolean;
}

Usage Examples:

# Start server on default port 3000
calm server -s ./calm/schemas

# Start server on custom port
calm server --port 8080 -s ./calm/schemas

# Start with verbose logging
calm server --port 3000 -s ./calm/schemas -v

API Endpoints

Health Check

Check server health status.

/**
 * GET /health
 * Health check endpoint
 * @returns StatusResponse with status "OK"
 */
interface HealthCheckEndpoint {
  method: 'GET';
  path: '/health';
  response: StatusResponse;
}

interface StatusResponse {
  status: string;  // "OK"
}

Example Request:

curl http://localhost:3000/health

Example Response:

{
  "status": "OK"
}

Validate Architecture

Validate a CALM architecture against its embedded schema.

/**
 * POST /calm/validate
 * Validate CALM architecture
 * @rateLimit 100 requests per 15 minutes per IP
 * @returns ValidationOutcome on success or ErrorResponse on failure
 */
interface ValidateEndpoint {
  method: 'POST';
  path: '/calm/validate';
  headers: {
    'Content-Type': 'application/json';
  };
  body: ValidationRequest;
  response: ValidationOutcome | ErrorResponse;
  statusCodes: {
    201: 'Validation completed successfully';
    400: 'Invalid request (missing $schema, invalid JSON)';
    429: 'Rate limit exceeded';
    500: 'Server error (schema loading failed, validation error)';
  };
}

interface ValidationRequest {
  /** JSON string containing CALM architecture */
  architecture: string;
}

interface ErrorResponse {
  error: string;
}

Example Request:

curl -X POST http://localhost:3000/calm/validate \
  -H "Content-Type: application/json" \
  -d '{
    "architecture": "{\"$schema\":\"https://calm.finos.org/schemas/calm-v1.json\",\"nodes\":[]}"
  }'

Example Success Response (201):

{
  "jsonSchemaValidationOutputs": [],
  "spectralSchemaValidationOutputs": [],
  "hasErrors": false,
  "hasWarnings": false
}

Example Error Response (400):

{
  "error": "The \"$schema\" field is missing from the request body"
}

Example Error Response (429):

{
  "error": "Too many requests, please try again later."
}

Configuration

CALMHub Integration

The server command uses CALMHub URL from the user configuration file for remote pattern and schema loading:

Via User Configuration File (~/.calm.json):

{
  "calmHubUrl": "https://calmhub.example.com"
}

Important Distinction from Generate Command:

Unlike the generate command which accepts both a -c, --calm-hub-url command-line option and configuration file setting, the server command does NOT accept --calm-hub-url as a command-line option. The server will only use the CALMHub URL from the ~/.calm.json configuration file if present.

Rationale: The server needs a consistent configuration that doesn't change per-request. Since the server runs continuously and handles multiple validation requests, having a stable, file-based configuration is more appropriate than per-invocation command-line options.

To configure CALMHub for the server:

  1. Create or edit ~/.calm.json in your home directory
  2. Add the calmHubUrl property with your CALMHub instance URL
  3. Restart the server to pick up the new configuration

Rate Limiting

The validation endpoint includes rate limiting to prevent abuse:

  • Limit: 100 requests per 15 minutes per IP address
  • Response: 429 Too Many Requests when limit exceeded
  • Headers: Rate limit information included in response headers

Server Architecture

Express Application Structure

/**
 * Express router configuration for all server routes
 */
class CLIServerRoutes {
  router: Router;

  /**
   * @param schemaDirectory - SchemaDirectory instance for validation
   * @param debug - Enable debug logging (default: false)
   */
  constructor(schemaDirectory: SchemaDirectory, debug?: boolean);
}

/**
 * Express router for validation API endpoint
 * Includes rate limiting and error handling
 */
class ValidationRouter {
  /**
   * @param router - Express Router instance
   * @param schemaDirectory - SchemaDirectory instance for validation
   * @param debug - Enable debug logging (default: false)
   */
  constructor(
    router: Router,
    schemaDirectory: SchemaDirectory,
    debug?: boolean
  );
}

/**
 * Express router for health check endpoint
 */
class HealthRouter {
  /**
   * @param router - Express Router instance
   */
  constructor(router: Router);
}

Request/Response Flow

Validation Request Flow

  1. Request Received: POST request to /calm/validate
  2. Rate Limit Check: Verify IP hasn't exceeded rate limit
  3. JSON Parsing: Parse architecture from request body
  4. Schema Extraction: Extract $schema field from architecture
  5. Schema Loading: Load and validate schema from SchemaDirectory
  6. Validation: Perform JSON schema and Spectral validation
  7. Response: Return ValidationOutcome or ErrorResponse

Error Scenarios

Missing $schema Field:

{
  "error": "The \"$schema\" field is missing from the request body"
}

Invalid JSON:

{
  "error": "Invalid JSON format for architecture"
}

Schema Not Available:

{
  "error": "The \"$schema\" field referenced is not available to the server"
}

Validation Failed:

{
  "error": "Validation error message"
}

Integration Examples

Node.js Client

import axios from 'axios';

async function validateArchitecture(architecture: object) {
  try {
    const response = await axios.post('http://localhost:3000/calm/validate', {
      architecture: JSON.stringify(architecture)
    });

    console.log('Validation result:', response.data);
    return response.data;
  } catch (error) {
    if (error.response) {
      console.error('Validation failed:', error.response.data.error);
    } else {
      console.error('Request failed:', error.message);
    }
    throw error;
  }
}

// Usage
const myArchitecture = {
  "$schema": "https://calm.finos.org/schemas/calm-v1.json",
  "nodes": [
    {
      "unique-id": "api-gateway",
      "node-type": "system",
      "name": "API Gateway"
    }
  ]
};

await validateArchitecture(myArchitecture);

Python Client

import requests
import json

def validate_architecture(architecture):
    url = 'http://localhost:3000/calm/validate'
    headers = {'Content-Type': 'application/json'}
    payload = {
        'architecture': json.dumps(architecture)
    }

    response = requests.post(url, json=payload, headers=headers)

    if response.status_code == 201:
        return response.json()
    else:
        raise Exception(f"Validation failed: {response.json()['error']}")

# Usage
my_architecture = {
    "$schema": "https://calm.finos.org/schemas/calm-v1.json",
    "nodes": []
}

result = validate_architecture(my_architecture)
print("Validation result:", result)

cURL Examples

# Valid architecture
curl -X POST http://localhost:3000/calm/validate \
  -H "Content-Type: application/json" \
  -d @- << 'EOF'
{
  "architecture": "{\"$schema\":\"https://calm.finos.org/schemas/calm-v1.json\",\"nodes\":[]}"
}
EOF

# Architecture with validation errors
curl -X POST http://localhost:3000/calm/validate \
  -H "Content-Type: application/json" \
  -d '{"architecture": "{\"nodes\":[]}"}'

# Health check
curl http://localhost:3000/health

Configuration

Schema Directory

The server requires a schema directory containing CALM meta schemas:

calm server -s ./calm/release

The schema directory should contain:

  • Meta schemas for CALM architecture validation
  • Pattern schemas
  • Any custom schemas

Port Configuration

Default port is 3000, but can be customized:

calm server --port 8080 -s ./schemas

Important: Ensure the port is not already in use by another application.

Verbose Logging

Enable verbose logging for debugging:

calm server --port 3000 -s ./schemas -v

Verbose mode logs:

  • Schema loading operations
  • Validation requests and results
  • Error details

Deployment Considerations

Production Deployment

For production use, consider:

  1. Reverse Proxy: Use nginx or Apache as reverse proxy
  2. HTTPS: Enable SSL/TLS for secure communication
  3. Authentication: Add authentication middleware
  4. Rate Limiting: Adjust rate limits based on usage patterns
  5. Monitoring: Add application monitoring and health checks
  6. Process Management: Use PM2 or systemd for process management

Docker Deployment

Example Dockerfile:

FROM node:18-alpine

WORKDIR /app

# Install CALM CLI
RUN npm install -g @finos/calm-cli

# Copy schemas
COPY ./schemas /app/schemas

# Expose port
EXPOSE 3000

# Start server
CMD ["calm", "server", "--port", "3000", "-s", "/app/schemas"]

Kubernetes Deployment

Example Kubernetes manifest:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: calm-server
spec:
  replicas: 3
  selector:
    matchLabels:
      app: calm-server
  template:
    metadata:
      labels:
        app: calm-server
    spec:
      containers:
      - name: calm-server
        image: calm-server:latest
        ports:
        - containerPort: 3000
        env:
        - name: PORT
          value: "3000"
---
apiVersion: v1
kind: Service
metadata:
  name: calm-server
spec:
  selector:
    app: calm-server
  ports:
  - port: 80
    targetPort: 3000
  type: LoadBalancer

Limitations

Experimental Feature: The server command is marked as experimental and may have limitations:

  1. Pattern Validation Not Supported: Server only validates against embedded $schema, not separate pattern files
  2. No Authentication: No built-in authentication or authorization
  3. Limited Output Formats: Only JSON output format supported
  4. Basic Rate Limiting: Simple IP-based rate limiting without persistence

Use Cases:

  • Development and testing environments
  • Internal microservice integration
  • CI/CD pipeline integration
  • Web application backends

Not Recommended For:

  • Public internet exposure without additional security
  • High-traffic production environments without load balancing
  • Scenarios requiring pattern-based validation (use CLI directly)

Error Handling

Server Startup Errors

Port Already in Use:

Error: listen EADDRINUSE: address already in use :::3000

Solution: Use a different port or stop the conflicting process.

Schema Directory Not Found:

Error: ENOENT: no such file or directory

Solution: Verify schema directory path is correct.

Permission Denied:

Error: listen EACCES: permission denied

Solution: Use a port number > 1024 or run with appropriate permissions.

Runtime Errors

All runtime errors are caught and returned as ErrorResponse with appropriate HTTP status codes. The server remains running and available for subsequent requests.

Monitoring

Health Check Monitoring

Use the /health endpoint for uptime monitoring:

# Simple health check
curl -f http://localhost:3000/health || echo "Server down"

# With monitoring tool
watch -n 30 'curl -s http://localhost:3000/health | jq .status'

Logging

The server logs important events:

  • Server startup and port binding
  • Schema loading success/failure
  • Validation requests (in verbose mode)
  • Errors and warnings

Access logs through the application's stdout/stderr.

Install with Tessl CLI

npx tessl i tessl/npm-finos--calm-cli

docs

copilot-chatmode-command.md

docify-command.md

generate-command.md

index.md

server-command.md

template-command.md

validate-command.md

tile.json