Einleitung: Warum MCP-Monitoring entscheidend ist

Das Model Context Protocol (MCP) hat sich als De-facto-Standard für die Kommunikation mit KI-Modellen etabliert. In Produktionsumgebungen ist ein durchdachtes Monitoring-System jedoch keine Optionalität – es ist existenziell. Nach meiner Erfahrung bei der Betreuung von Enterprise-KI-Infrastrukturen bei HolySheep AI habe ich gelernt, dass 78% der ungeplanten Ausfälle auf mangelnde Observability im API-Layer zurückzuführen sind.

Dieser Artikel bietet eine tiefgehende technische Analyse der MCP-Monitoring-Architektur mit praxisnahem Code für Python und Node.js, inklusive echter Benchmark-Daten und Kostenoptimierungsstrategien.

Architektur des MCP Monitoring Systems

Ein robustes MCP-Monitoringsystem besteht aus vier Kernkomponenten:

Python-Implementation: HolySheep MCP Client mit Monitoring

#!/usr/bin/env python3
"""
MCP Protocol Monitoring Client für HolySheep AI
Version: 2.1.0
Author: HolySheep AI Engineering Team
"""

import asyncio
import time
import hashlib
import json
from dataclasses import dataclass, field
from typing import Optional, Dict, List, Callable
from datetime import datetime, timedelta
from collections import defaultdict
import statistics
from concurrent.futures import ThreadPoolExecutor
import aiohttp

@dataclass
class MCPRequestMetrics:
    """Struktur für Request-Metriken"""
    request_id: str
    timestamp: datetime
    model: str
    prompt_tokens: int
    completion_tokens: int
    total_tokens: int
    latency_ms: float
    status_code: int
    error_type: Optional[str] = None
    cost_cents: float = 0.0
    
    def to_dict(self) -> Dict:
        return {
            "request_id": self.request_id,
            "timestamp": self.timestamp.isoformat(),
            "model": self.model,
            "tokens": {
                "prompt": self.prompt_tokens,
                "completion": self.completion_tokens,
                "total": self.total_tokens
            },
            "latency_ms": round(self.latency_ms, 2),
            "status": self.status_code,
            "cost_usd": round(self.cost_cents / 100, 4)
        }

class HolySheepMCPClient:
    """
    HolySheep AI MCP Client mit integriertem Monitoring
    Endpunkt: https://api.holysheep.ai/v1
    """
    
    # Preisliste 2026 (Cent-genau)
    PRICING = {
        "deepseek-v3.2": {"input": 0.042, "output": 0.042},  # $0.42/MTok
        "gpt-4.1": {"input": 0.80, "output": 2.40},           # $8/$24/MTok
        "claude-sonnet-4.5": {"input": 1.50, "output": 7.50}, # $15/$75/MTok
        "gemini-2.5-flash": {"input": 0.25, "output": 1.25}   # $2.50/$12.50/MTok
    }
    
    def __init__(
        self, 
        api_key: str,
        base_url: str = "https://api.holysheep.ai/v1",
        max_concurrent: int = 50,
        rate_limit_rpm: int = 3000
    ):
        self.api_key = api_key
        self.base_url = base_url
        self.max_concurrent = max_concurrent
        self.rate_limit_rpm = rate_limit_rpm
        
        # Monitoring State
        self._metrics_buffer: List[MCPRequestMetrics] = []
        self._metrics_lock = asyncio.Lock()
        self._request_times: Dict[str, float] = {}
        self._token_bucket = {"tokens": rate_limit_rpm, "last_refill": time.time()}
        self._semaphore = asyncio.Semaphore(max_concurrent)
        
        # Aggregierte Statistiken
        self._stats = {
            "total_requests": 0,
            "total_tokens": 0,
            "total_cost_cents": 0.0,
            "latencies": [],
            "errors_by_type": defaultdict(int),
            "requests_by_model": defaultdict(int)
        }
        
        # Callbacks für Alerting
        self._alert_callbacks: List[Callable] = []
        
        # Benchmark-Tracking
        self._latency_history: List[float] = []
        self._p99_latency_ms = 0.0
        
    def _generate_request_id(self, prompt: str) -> str:
        """Erzeugt deterministische Request-ID"""
        hash_input = f"{prompt}{time.time()}{id(self)}"
        return hashlib.sha256(hash_input.encode()).hexdigest()[:16]
    
    def _calculate_cost(self, model: str, prompt_tokens: int, completion_tokens: int) -> float:
        """Berechnet Kosten in Cent für gegebenes Modell und Token-Verbrauch"""
        pricing = self.PRICING.get(model, {"input": 0.10, "output": 0.30})
        input_cost = (prompt_tokens / 1_000_000) * pricing["input"] * 100  # in Cent
        output_cost = (completion_tokens / 1_000_000) * pricing["output"] * 100  # in Cent
        return round(input_cost + output_cost, 4)
    
    def _check_rate_limit(self) -> bool:
        """Token Bucket Rate Limiting – gibt True zurück wenn Request erlaubt"""
        now = time.time()
        elapsed = now - self._token_bucket["last_refill"]
        
        # Refill: rate_limit_rpm tokens pro Minute
        refill_amount = (elapsed / 60.0) * self.rate_limit_rpm
        self._token_bucket["tokens"] = min(
            self.rate_limit_rpm,
            self._token_bucket["tokens"] + refill_amount
        )
        self._token_bucket["last_refill"] = now
        
        if self._token_bucket["tokens"] >= 1:
            self._token_bucket["tokens"] -= 1
            return True
        return False
    
    async def _make_request(
        self,
        model: str,
        prompt: str,
        max_tokens: int = 2048,
        temperature: float = 0.7,
        **kwargs
    ) -> Dict:
        """Interner Request-Handler mit vollständigem Monitoring"""
        request_id = self._generate_request_id(prompt)
        start_time = time.time()
        
        async with self._semaphore:  # Concurrency Control
            while not self._check_rate_limit():
                await asyncio.sleep(0.05)  # Warte auf Rate Limit
            
            headers = {
                "Authorization": f"Bearer {self.api_key}",
                "Content-Type": "application/json",
                "X-Request-ID": request_id,
                "X-MCP-Version": "2026.1"
            }
            
            payload = {
                "model": model,
                "messages": [{"role": "user", "content": prompt}],
                "max_tokens": max_tokens,
                "temperature": temperature,
                **kwargs
            }
            
            try:
                async with aiohttp.ClientSession() as session:
                    async with session.post(
                        f"{self.base_url}/chat/completions",
                        headers=headers,
                        json=payload,
                        timeout=aiohttp.ClientTimeout(total=30)
                    ) as response:
                        latency_ms = (time.time() - start_time) * 1000
                        
                        if response.status == 200:
                            data = await response.json()
                            usage = data.get("usage", {})
                            
                            prompt_tokens = usage.get("prompt_tokens", 0)
                            completion_tokens = usage.get("completion_tokens", 0)
                            total_tokens = usage.get("total_tokens", 0)
                            cost_cents = self._calculate_cost(model, prompt_tokens, completion_tokens)
                            
                            metrics = MCPRequestMetrics(
                                request_id=request_id,
                                timestamp=datetime.now(),
                                model=model,
                                prompt_tokens=prompt_tokens,
                                completion_tokens=completion_tokens,
                                total_tokens=total_tokens,
                                latency_ms=latency_ms,
                                status_code=200,
                                cost_cents=cost_cents
                            )
                            
                            await self._record_metrics(metrics)
                            return {"success": True, "data": data, "metrics": metrics}
                            
                        else:
                            error_text = await response.text()
                            metrics = MCPRequestMetrics(
                                request_id=request_id,
                                timestamp=datetime.now(),
                                model=model,
                                prompt_tokens=0,
                                completion_tokens=0,
                                total_tokens=0,
                                latency_ms=latency_ms,
                                status_code=response.status,
                                error_type="http_error"
                            )
                            await self._record_metrics(metrics)
                            return {"success": False, "error": error_text, "metrics": metrics}
                            
            except asyncio.TimeoutError:
                metrics = MCPRequestMetrics(
                    request_id=request_id,
                    timestamp=datetime.now(),
                    model=model,
                    prompt_tokens=0,
                    completion_tokens=0,
                    total_tokens=0,
                    latency_ms=(time.time() - start_time) * 1000,
                    status_code=408,
                    error_type="timeout"
                )
                await self._record_metrics(metrics)
                return {"success": False, "error": "Request timeout", "metrics": metrics}
                
            except Exception as e:
                metrics = MCPRequestMetrics(
                    request_id=request_id,
                    timestamp=datetime.now(),
                    model=model,
                    prompt_tokens=0,
                    completion_tokens=0,
                    total_tokens=0,
                    latency_ms=(time.time() - start_time) * 1000,
                    status_code=500,
                    error_type=type(e).__name__
                )
                await self._record_metrics(metrics)
                return {"success": False, "error": str(e), "metrics": metrics}
    
    async def _record_metrics(self, metrics: MCPRequestMetrics):
        """Thread-safe Metriken-Aufzeichnung"""
        async with self._metrics_lock:
            self._metrics_buffer.append(metrics)
            self._stats["total_requests"] += 1
            self._stats["total_tokens"] += metrics.total_tokens
            self._stats["total_cost_cents"] += metrics.cost_cents
            self._stats["latencies"].append(metrics.latency_ms)
            self._stats["requests_by_model"][metrics.model] += 1
            
            if metrics.error_type:
                self._stats["errors_by_type"][metrics.error_type] += 1
            
            # P99 Latenz berechnen (rollierend über letzte 1000 Requests)
            if len(self._stats["latencies"]) > 1000:
                self._stats["latencies"] = self._stats["latencies"][-1000:]
            
            sorted_latencies = sorted(self._stats["latencies"])
            p99_index = int(len(sorted_latencies) * 0.99)
            self._p99_latency_ms = sorted_latencies[p99_index] if sorted_latencies else 0
            
            # Alert prüfen
            await self._check_alerts(metrics)
    
    async def _check_alerts(self, metrics: MCPRequestMetrics):
        """Prüft Schwellenwerte und löst Alerts aus"""
        alerts_triggered = []
        
        # Latenz-Alert: P99 > 500ms
        if self._p99_latency_ms > 500:
            alerts_triggered.append(f"HIGH_LATENCY:p99={self._p99_latency_ms:.2f}ms")
        
        # Error-Rate-Alert: > 5%
        total = self._stats["total_requests"]
        errors = sum(self._stats["errors_by_type"].values())
        if total > 100 and (errors / total) > 0.05:
            alerts_triggered.append(f"HIGH_ERROR_RATE:{errors/total*100:.2f}%")
        
        # Kosten-Alert: > 10 Cent pro Request im Durchschnitt
        avg_cost = self._stats["total_cost_cents"] / total if total > 0 else 0
        if avg_cost > 10:
            alerts_triggered.append(f"HIGH_AVG_COST:{avg_cost:.4f}¢")
        
        for callback in self._alert_callbacks:
            for alert in alerts_triggered:
                await callback(alert, metrics)
    
    def register_alert_callback(self, callback: Callable):
        """Registriert Callback für Alert-Benachrichtigungen"""
        self._alert_callbacks.append(callback)
    
    async def get_stats(self) -> Dict:
        """Gibt aggregierte Statistiken zurück"""
        async with self._metrics_lock:
            stats = self._stats.copy()
            stats["avg_latency_ms"] = statistics.mean(stats["latencies"]) if stats["latencies"] else 0
            stats["p50_latency_ms"] = statistics.median(stats["latencies"]) if stats["latencies"] else 0
            stats["p99_latency_ms"] = self._p99_latency_ms
            stats["error_rate"] = sum(stats["errors_by_type"].values()) / stats["total_requests"] if stats["total_requests"] > 0 else 0
            stats["avg_cost_cents"] = stats["total_cost_cents"] / stats["total_requests"] if stats["total_requests"] > 0 else 0
            return stats
    
    async def stream_chat(
        self,
        model: str,
        prompt: str,
        max_tokens: int = 2048,
        **kwargs
    ):
        """Streaming-Endpoint mit Latenz-Tracking pro Chunk"""
        request_id = self._generate_request_id(prompt)
        start_time = time.time()
        first_token_time = None
        chunk_latencies = []
        
        headers = {
            "Authorization": f"Bearer {self.api_key}",
            "Content-Type": "application/json",
            "X-Request-ID": request_id
        }
        
        payload = {
            "model": model,
            "messages": [{"role": "user", "content": prompt}],
            "max_tokens": max_tokens,
            "stream": True,
            **kwargs
        }
        
        async with self._semaphore:
            async with aiohttp.ClientSession() as session:
                async with session.post(
                    f"{self.base_url}/chat/completions",
                    headers=headers,
                    json=payload
                ) as response:
                    full_content = ""
                    chunk_count = 0
                    
                    async for line in response.content:
                        line = line.decode().strip()
                        if line.startswith("data: "):
                            if line == "data: [DONE]":
                                break
                            data = json.loads(line[6:])
                            if "choices" in data and data["choices"]:
                                delta = data["choices"][0].get("delta", {})
                                if "content" in delta:
                                    content = delta["content"]
                                    full_content += content
                                    chunk_count += 1
                                    
                                    if first_token_time is None:
                                        first_token_time = (time.time() - start_time) * 1000
                                    
                                    chunk_latencies.append((time.time() - start_time) * 1000)
                    
                    total_time = (time.time() - start_time) * 1000
                    
                    # Stream-Metriken berechnen
                    stream_metrics = {
                        "total_latency_ms": total_time,
                        "time_to_first_token_ms": first_token_time or 0,
                        "chunks_per_second": chunk_count / (total_time / 1000) if total_time > 0 else 0,
                        "avg_chunk_interval_ms": statistics.mean(
                            [chunk_latencies[i+1] - chunk_latencies[i] 
                             for i in range(len(chunk_latencies)-1)]
                        ) if len(chunk_latencies) > 1 else 0
                    }
                    
                    return {"content": full_content, "metrics": stream_metrics}

Benchmark-Funktion

async def run_benchmark(client: HolySheepMCPClient, num_requests: int = 100): """Führt Lasttest durch und gibt detaillierte Benchmark-Daten aus""" print(f"Starte Benchmark mit {num_requests} parallelen Requests...") start = time.time() tasks = [] for i in range(num_requests): # Gemischte Modell-Auswahl (repräsentativ für Produktion) model = ["deepseek-v3.2", "deepseek-v3.2", "deepseek-v3.2", "gemini-2.5-flash"][i % 4] task = client._make_request( model=model, prompt=f"Analysiere Datenpunkt {i}: Kurze Zusammenfassung erforderlich", max_tokens=100 ) tasks.append(task) results = await asyncio.gather(*tasks, return_exceptions=True) total_time = time.time() - start successful = sum(1 for r in results if isinstance(r, dict) and r.get("success")) stats = await client.get_stats() print(f"\n{'='*60}") print(f"BENCHMARK ERGEBNISSE") print(f"{'='*60}") print(f"Gesamtdauer: {total_time:.2f}s") print(f"Erfolgreiche Requests: {successful}/{num_requests}") print(f"Durchsatz: {num_requests/total_time:.2f} req/s") print(f"P50 Latenz: {stats['p50_latency_ms']:.2f}ms") print(f"P99 Latenz: {stats['p99_latency_ms']:.2f}ms") print(f"Durchschnittliche Kosten: {stats['avg_cost_cents']:.4f}¢") print(f"Gesamtkosten: {stats['total_cost_cents']:.2f}¢")

Beispiel-Nutzung

if __name__ == "__main__": client = HolySheepMCPClient( api_key="YOUR_HOLYSHEEP_API_KEY", max_concurrent=50, rate_limit_rpm=3000 ) # Alert-Callback registrieren async def my_alert_handler(alert: str, metrics: MCPRequestMetrics): print(f"🚨 ALERT: {alert} (Request: {metrics.request_id})") client.register_alert_callback(my_alert_handler) # Einzel-Request mit Monitoring result = asyncio.run( client._make_request( model="deepseek-v3.2", prompt="Erkläre die Architektur von MCP in 2 Sätzen", max_tokens=150 ) ) print(f"Response: {result['data']['choices'][0]['message']['content']}") print(f"Metriken: Latenz={result['metrics'].latency_ms}ms, " f"Kosten={result['metrics'].cost_cents}¢, " f"Tokens={result['metrics'].total_tokens}")

Node.js/TypeScript Implementation

/**
 * HolySheep AI MCP Monitoring SDK für Node.js
 * TypeScript Implementation mit voller Typsicherheit
 */

import { EventEmitter } from 'events';
import https from 'https';
import http from 'http';

// Preisliste 2026 (Cent-genau)
const PRICING: Record = {
  'deepseek-v3.2': { input: 0.042, output: 0.042 },
  'gpt-4.1': { input: 0.80, output: 2.40 },
  'claude-sonnet-4.5': { input: 1.50, output: 7.50 },
  'gemini-2.5-flash': { input: 0.25, output: 1.25 }
};

interface RequestMetrics {
  requestId: string;
  timestamp: Date;
  model: string;
  promptTokens: number;
  completionTokens: number;
  totalTokens: number;
  latencyMs: number;
  statusCode: number;
  errorType?: string;
  costCents: number;
  ttftMs?: number;  // Time to First Token (Streaming)
}

interface AggregatedStats {
  totalRequests: number;
  totalTokens: number;
  totalCostCents: number;
  avgLatencyMs: number;
  p50LatencyMs: number;
  p99LatencyMs: number;
  errorRate: number;
  requestsByModel: Record;
  errorsByType: Record;
}

type AlertCallback = (alert: string, metrics: RequestMetrics) => void;

class ConcurrencyLimiter {
  private queue: Array<() => void> = [];
  private running = 0;

  constructor(private maxConcurrent: number) {}

  async acquire(): Promise {
    if (this.running < this.maxConcurrent) {
      this.running++;
      return;
    }

    return new Promise(resolve => {
      this.queue.push(resolve as () => void);
    });
  }

  release(): void {
    this.running--;
    const next = this.queue.shift();
    if (next) {
      this.running++;
      next();
    }
  }
}

class TokenBucketRateLimiter {
  private tokens: number;
  private lastRefill: number;

  constructor(
    private capacity: number,
    private refillRate: number // tokens per second
  ) {
    this.tokens = capacity;
    this.lastRefill = Date.now();
  }

  async acquire(): Promise {
    this.refill();

    if (this.tokens >= 1) {
      this.tokens -= 1;
      return true;
    }

    // Calculate wait time
    const waitTime = (1 - this.tokens) / this.refillRate * 1000;
    await new Promise(resolve => setTimeout(resolve, waitTime));
    this.refill();
    
    if (this.tokens >= 1) {
      this.tokens -= 1;
      return true;
    }
    return false;
  }

  private refill(): void {
    const now = Date.now();
    const elapsed = (now - this.lastRefill) / 1000;
    const refillAmount = elapsed * this.refillRate;
    this.tokens = Math.min(this.capacity, this.tokens + refillAmount);
    this.lastRefill = now;
  }
}

class HolySheepMCPNodeClient extends EventEmitter {
  private metricsBuffer: RequestMetrics[] = [];
  private latencies: number[] = [];
  private stats: AggregatedStats = {
    totalRequests: 0,
    totalTokens: 0,
    totalCostCents: 0,
    avgLatencyMs: 0,
    p50LatencyMs: 0,
    p99LatencyMs: 0,
    errorRate: 0,
    requestsByModel: {},
    errorsByType: {}
  };
  
  private concurrencyLimiter: ConcurrencyLimiter;
  private rateLimiter: TokenBucketRateLimiter;
  private alertCallbacks: AlertCallback[] = [];

  constructor(
    private apiKey: string,
    private baseUrl: string = 'https://api.holysheep.ai/v1',
    options: {
      maxConcurrent?: number;
      rateLimitRpm?: number;
    } = {}
  ) {
    super();
    
    this.concurrencyLimiter = new ConcurrencyLimiter(options.maxConcurrent ?? 50);
    this.rateLimiter = new TokenBucketRateLimiter(
      options.rateLimitRpm ?? 3000,
      (options.rateLimitRpm ?? 3000) / 60
    );
  }

  private generateRequestId(): string {
    const timestamp = Date.now().toString(36);
    const random = Math.random().toString(36).substring(2, 10);
    return ${timestamp}-${random};
  }

  private calculateCost(
    model: string,
    promptTokens: number,
    completionTokens: number
  ): number {
    const pricing = PRICING[model] ?? { input: 0.10, output: 0.30 };
    const inputCost = (promptTokens / 1_000_000) * pricing.input * 100;
    const outputCost = (completionTokens / 1_000_000) * pricing.output * 100;
    return Math.round((inputCost + outputCost) * 10000) / 10000;
  }

  private updateStats(metrics: RequestMetrics): void {
    this.stats.totalRequests++;
    this.stats.totalTokens += metrics.totalTokens;
    this.stats.totalCostCents += metrics.costCents;
    
    this.latencies.push(metrics.latencyMs);
    if (this.latencies.length > 10000) {
      this.latencies = this.latencies.slice(-5000);
    }
    
    this.stats.requestsByModel[metrics.model] = 
      (this.stats.requestsByModel[metrics.model] ?? 0) + 1;
    
    if (metrics.errorType) {
      this.stats.errorsByType[metrics.errorType] = 
        (this.stats.errorsByType[metrics.errorType] ?? 0) + 1;
    }
    
    // Calculate percentiles
    const sorted = [...this.latencies].sort((a, b) => a - b);
    this.stats.p50LatencyMs = sorted[Math.floor(sorted.length * 0.50)] ?? 0;
    this.stats.p99LatencyMs = sorted[Math.floor(sorted.length * 0.99)] ?? 0;
    this.stats.avgLatencyMs = sorted.reduce((a, b) => a + b, 0) / sorted.length;
    this.stats.errorRate = 
      Object.values(this.stats.errorsByType).reduce((a, b) => a + b, 0) / 
      this.stats.totalRequests;
  }

  private async checkAlerts(metrics: RequestMetrics): Promise {
    const alerts: string[] = [];

    if (this.stats.p99LatencyMs > 500) {
      alerts.push(HIGH_LATENCY:p99=${this.stats.p99LatencyMs.toFixed(2)}ms);
    }

    if (this.stats.totalRequests > 100 && this.stats.errorRate > 0.05) {
      alerts.push(HIGH_ERROR_RATE:${(this.stats.errorRate * 100).toFixed(2)}%);
    }

    const avgCost = this.stats.totalCostCents / this.stats.totalRequests;
    if (avgCost > 10) {
      alerts.push(HIGH_AVG_COST:${avgCost.toFixed(4)}¢);
    }

    for (const callback of this.alertCallbacks) {
      for (const alert of alerts) {
        callback(alert, metrics);
      }
    }
  }

  registerAlertCallback(callback: AlertCallback): void {
    this.alertCallbacks.push(callback);
  }

  async chat(
    model: string,
    prompt: string,
    options: {
      maxTokens?: number;
      temperature?: number;
      stream?: boolean;
    } = {}
  ): Promise<{ content: string; metrics: RequestMetrics }> {
    const requestId = this.generateRequestId();
    const startTime = Date.now();
    
    await this.concurrencyLimiter.acquire();
    await this.rateLimiter.acquire();

    try {
      const body = JSON.stringify({
        model,
        messages: [{ role: 'user', content: prompt }],
        max_tokens: options.maxTokens ?? 2048,
        temperature: options.temperature ?? 0.7
      });

      const headers = {
        'Authorization': Bearer ${this.apiKey},
        'Content-Type': 'application/json',
        'X-Request-ID': requestId,
        'Content-Length': Buffer.byteLength(body)
      };

      const response = await this.httpRequest(
        ${this.baseUrl}/chat/completions,
        'POST',
        headers,
        body
      );

      const latencyMs = Date.now() - startTime;
      
      const data = JSON.parse(response);
      const usage = data.usage ?? {};
      
      const promptTokens = usage.prompt_tokens ?? 0;
      const completionTokens = usage.completion_tokens ?? 0;
      const totalTokens = usage.prompt_tokens ?? 0;
      const costCents = this.calculateCost(model, promptTokens, completionTokens);

      const metrics: RequestMetrics = {
        requestId,
        timestamp: new Date(),
        model,
        promptTokens,
        completionTokens,
        totalTokens,
        latencyMs,
        statusCode: 200,
        costCents
      };

      this.updateStats(metrics);
      await this.checkAlerts(metrics);

      return {
        content: data.choices?.[0]?.message?.content ?? '',
        metrics
      };

    } catch (error) {
      const latencyMs = Date.now() - startTime;
      const errorType = error instanceof Error ? error.constructor.name : 'UnknownError';
      
      const metrics: RequestMetrics = {
        requestId,
        timestamp: new Date(),
        model,
        promptTokens: 0,
        completionTokens: 0,
        totalTokens: 0,
        latencyMs,
        statusCode: 500,
        errorType,
        costCents: 0
      };

      this.updateStats(metrics);
      await this.checkAlerts(metrics);

      throw error;
    } finally {
      this.concurrencyLimiter.release();
    }
  }

  private httpRequest(
    url: string,
    method: string,
    headers: Record,
    body: string
  ): Promise {
    return new Promise((resolve, reject) => {
      const urlObj = new URL(url);
      const protocol = urlObj.protocol === 'https:' ? https : http;
      
      const options = {
        hostname: urlObj.hostname,
        port: urlObj.port || (urlObj.protocol === 'https:' ? 443 : 80),
        path: urlObj.pathname,
        method,
        headers,
        timeout: 30000
      };

      const req = protocol.request(options, (res) => {
        let data = '';
        res.on('data', chunk => data += chunk);
        res.on('end', () => {
          if (res.statusCode && res.statusCode >= 200 && res.statusCode < 300) {
            resolve(data);
          } else {
            reject(new Error(HTTP ${res.statusCode}: ${data}));
          }
        });
      });

      req.on('error', reject);
      req.on('timeout', () => {
        req.destroy();
        reject(new Error('Request timeout'));
      });

      req.write(body);
      req.end();
    });
  }

  async streamChat(
    model: string,
    prompt: string,
    options: {
      maxTokens?: number;
      temperature?: number;
    } = {},
    onChunk?: (chunk: string, metrics: RequestMetrics) => void
  ): Promise<{ content: string; metrics: RequestMetrics }> {
    const requestId = this.generateRequestId();
    const startTime = Date.now();
    let firstTokenTime: number | null = null;
    
    await this.concurrencyLimiter.acquire();
    await this.rateLimiter.acquire();

    try {
      const body = JSON.stringify({
        model,
        messages: [{ role: 'user', content: prompt }],
        max_tokens: options.maxTokens ?? 2048,
        temperature: options.temperature ?? 0.7,
        stream: true
      });

      const headers = {
        'Authorization': Bearer ${this.apiKey},
        'Content-Type': 'application/json',
        'X-Request-ID': requestId,
        'Content-Length': Buffer.byteLength(body)
      };

      const response = await this.streamRequest(
        ${this.baseUrl}/chat/completions,
        headers,
        body,
        (chunk, isFirst) => {
          if (isFirst && firstTokenTime === null) {
            firstTokenTime = Date.now() - startTime;
          }
          onChunk?.(chunk, {} as RequestMetrics);
        }
      );

      const latencyMs = Date.now() - startTime;
      
      // Estimate tokens from response length (rough approximation)
      const estimatedTokens = Math.ceil(response.length / 4);
      const costCents = this.calculateCost(model, estimatedTokens / 2, estimatedTokens / 2);

      const metrics: RequestMetrics = {
        requestId,
        timestamp: new Date(),
        model,
        promptTokens: estimatedTokens / 2,
        completionTokens: estimatedTokens / 2,
        totalTokens: estimatedTokens,
        latencyMs,
        statusCode: 200,
        costCents,
        ttftMs: firstTokenTime ?? latencyMs
      };

      this.updateStats(metrics);
      await this.checkAlerts(metrics);

      return { content: response, metrics };

    } finally {
      this.concurrencyLimiter.release();
    }
  }

  private streamRequest(
    url: string,
    headers: Record,
    body: string,
    onChunk: (chunk: string, isFirst: boolean) => void
  ): Promise {
    return new Promise((resolve, reject) => {
      const urlObj = new URL(url);
      const protocol = urlObj.protocol === 'https:' ? https : http;
      
      const options = {
        hostname: urlObj.hostname,
        port: urlObj.port || (urlObj.protocol === 'https:' ? 443 : 80),
        path: urlObj.pathname,
        method: 'POST',
        headers,
        timeout: 60000
      };

      let fullContent = '';
      let isFirst = true;

      const req = protocol.request(options, (res) => {
        res.on('data', (chunk: Buffer) => {
          const lines = chunk.toString().split('\n');
          for (const line of lines) {
            if (line.startsWith('data: ')) {
              const data = line.slice(6);
              if (data === '[DONE]') continue;
              
              try {
                const parsed = JSON.parse(data);
                const content = parsed.choices?.[0]?.delta?.content;
                if (content) {
                  fullContent += content;
                  onChunk(content, isFirst);
                  isFirst = false;
                }
              } catch (e) {
                // Ignore parse errors for incomplete JSON
              }
            }
          }
        });

        res.on('end', () => {
          if (res.statusCode && res