#!/usr/bin/env node
/**
 * PwC Coding Agents Budget MCP Server
 *
 * Provides budget status information from the PwC AI-CoE Coding Agents Gateway
 * to Claude Code via the Model Context Protocol (MCP).
 *
 * Features:
 * - Queries /quota/status endpoint
 * - Client-side caching (60s TTL) to avoid spamming the API
 * - Exposes budget info as MCP resources and tools
 */
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { CallToolRequestSchema, ListResourcesRequestSchema, ListToolsRequestSchema, ReadResourceRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
import fetch from 'node-fetch';
import { readFileSync } from 'fs';
import { homedir } from 'os';
import { join } from 'path';
// Cache with 60s TTL
let quotaCache = null;
const CACHE_TTL_MS = 60 * 1000; // 60 seconds
/**
 * Read Claude Code settings to get base URL and auth token
 */
function readClaudeSettings() {
    try {
        const settingsPath = join(homedir(), '.claude', 'settings.json');
        const content = readFileSync(settingsPath, 'utf-8');
        return JSON.parse(content);
    }
    catch (error) {
        console.error('Failed to read Claude settings:', error);
        return {};
    }
}
/**
 * Fetch quota status from the gateway with caching
 */
async function fetchQuotaStatus() {
    // Check cache first
    const now = Date.now();
    if (quotaCache && (now - quotaCache.timestamp) < CACHE_TTL_MS) {
        return quotaCache.data;
    }
    // Read settings
    const settings = readClaudeSettings();
    const baseUrl = settings.env?.ANTHROPIC_BASE_URL;
    const authToken = settings.env?.ANTHROPIC_AUTH_TOKEN;
    if (!baseUrl || !authToken) {
        throw new Error('ANTHROPIC_BASE_URL or ANTHROPIC_AUTH_TOKEN not configured in ~/.claude/settings.json');
    }
    // Fetch from API
    const url = `${baseUrl}/quota/status`;
    const response = await fetch(url, {
        headers: {
            'Authorization': `Bearer ${authToken}`,
        },
        signal: AbortSignal.timeout(5000), // 5s timeout
    });
    if (!response.ok) {
        throw new Error(`Failed to fetch quota status: ${response.status} ${response.statusText}`);
    }
    const data = await response.json();
    // Update cache
    quotaCache = {
        data,
        timestamp: now,
    };
    return data;
}
/**
 * Format quota data as a human-readable string
 */
function formatQuotaStatus(quota) {
    if (quota.percent === null) {
        return `**PwC Coding Agents Budget**: N/A\n\nNo quota information available.`;
    }
    const emoji = quota.percent >= 90 ? '🔴' : quota.percent >= 70 ? '🟡' : '🟢';
    return `**PwC Coding Agents Budget**: ${emoji} ${quota.percent}%

**Usage**: €${quota.usage.toFixed(2)}
**Limit**: €${quota.limit.toFixed(2)}
**Remaining**: €${(quota.limit - quota.usage).toFixed(2)}

**Status**:
${quota.percent < 70 ? '- ✅ Budget usage is healthy' : ''}
${quota.percent >= 70 && quota.percent < 90 ? '- ⚠️  Approaching budget limit' : ''}
${quota.percent >= 90 ? '- 🚨 Budget nearly exhausted' : ''}
`;
}
/**
 * Create and configure the MCP server
 */
const server = new Server({
    name: '@pwc/budget-mcp-server',
    version: '1.0.0',
}, {
    capabilities: {
        resources: {},
        tools: {},
    },
});
/**
 * List available resources
 */
server.setRequestHandler(ListResourcesRequestSchema, async () => {
    return {
        resources: [
            {
                uri: 'budget://status',
                name: 'PwC Coding Agents Budget Status',
                description: 'Current budget usage and limits for PwC Coding Agents',
                mimeType: 'text/plain',
            },
        ],
    };
});
/**
 * Read resource content
 */
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
    if (request.params.uri === 'budget://status') {
        const quota = await fetchQuotaStatus();
        return {
            contents: [
                {
                    uri: request.params.uri,
                    mimeType: 'text/plain',
                    text: formatQuotaStatus(quota),
                },
            ],
        };
    }
    throw new Error(`Unknown resource: ${request.params.uri}`);
});
/**
 * List available tools
 */
server.setRequestHandler(ListToolsRequestSchema, async () => {
    return {
        tools: [
            {
                name: 'get_budget_status',
                description: 'Get current PwC Coding Agents budget status including usage, limit, and percentage',
                inputSchema: {
                    type: 'object',
                    properties: {},
                    required: [],
                },
            },
        ],
    };
});
/**
 * Handle tool calls
 */
server.setRequestHandler(CallToolRequestSchema, async (request) => {
    if (request.params.name === 'get_budget_status') {
        const quota = await fetchQuotaStatus();
        return {
            content: [
                {
                    type: 'text',
                    text: formatQuotaStatus(quota),
                },
            ],
        };
    }
    throw new Error(`Unknown tool: ${request.params.name}`);
});
/**
 * Start the server
 */
async function main() {
    const transport = new StdioServerTransport();
    await server.connect(transport);
    console.error('PwC Budget MCP Server running on stdio');
}
main().catch((error) => {
    console.error('Server error:', error);
    process.exit(1);
});
