UNPKG

@handle-ai/mcp

Version:

Handle AI MCP Server - Direct API integration for Claude Desktop

494 lines (454 loc) 18.8 kB
#!/usr/bin/env node /** * Handle AI MCP Server * * A downloadable MCP server that connects Claude Desktop directly to Handle AI's * compliance analysis API. No WebSockets, no timeouts, just simple HTTP calls. */ import { Server } from '@modelcontextprotocol/sdk/server/index.js'; import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; import { CallToolRequestSchema, ListToolsRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema } from '@modelcontextprotocol/sdk/types.js'; import fetch from 'node-fetch'; class HandleAIMCPServer { constructor() { this.apiKey = process.env.HANDLE_AI_API_KEY; this.baseURL = process.env.HANDLE_AI_API_URL || 'https://handle-ai.com/api'; if (!this.apiKey) { console.error('❌ HANDLE_AI_API_KEY environment variable is required'); console.error('Set your API key: export HANDLE_AI_API_KEY=hak_live_xxx'); process.exit(1); } console.error('🚀 Starting Handle AI MCP Server...'); console.error(`🔗 API Base URL: ${this.baseURL}`); console.error(`🔑 API Key: ${this.apiKey.substring(0, 8)}...`); this.server = new Server( { name: 'handle-ai-mcp', version: '1.0.0', description: 'Handle AI Professional Compliance Analysis' }, { capabilities: { tools: {}, resources: {} } } ); this.setupHandlers(); } async callAPI(endpoint, data = {}, method = 'POST') { try { const url = `${this.baseURL}${endpoint}`; console.error(`📡 API Call: ${method} ${endpoint}`); const options = { method, headers: { 'Content-Type': 'application/json', 'X-API-Key': this.apiKey, 'User-Agent': 'Handle-AI-MCP/1.0.0' } }; if (method !== 'GET' && Object.keys(data).length > 0) { options.body = JSON.stringify(data); } const response = await fetch(url, options); if (!response.ok) { throw new Error(`HTTP ${response.status}: ${response.statusText}`); } const result = await response.json(); console.error(`✅ API Success: ${endpoint}`); return result; } catch (error) { console.error(`❌ API Error: ${endpoint} - ${error.message}`); throw error; } } setupHandlers() { // List available tools this.server.setRequestHandler(ListToolsRequestSchema, async () => { return { tools: [ { name: 'professional-gdpr-analysis', description: 'Start a comprehensive GDPR compliance analysis. IMPORTANT: Ask the user to provide: (1) App name, (2) Platform used (bubble/webflow/glide/softr/other), (3) App features (like user-registration, payment-processing, email-marketing), (4) Data types collected (like email, name, phone, health_data, payment_info). Example: "To analyze your app for GDPR compliance, I need some details: What\'s your app name? What platform did you build it on? What features does it have? What types of data do you collect?"', inputSchema: { type: 'object', properties: { appName: { type: 'string', description: 'Name of the application to analyze (ask user: "What is your app called?")' }, platform: { type: 'string', enum: ['bubble', 'webflow', 'glide', 'softr', 'other'], description: 'Platform used to build the app (ask user: "What platform did you use to build it - Bubble, Webflow, Glide, Softr, or something else?")' }, features: { type: 'array', items: { type: 'string' }, description: 'App functionality (ask user: "What features does your app have?" Examples: user-registration, payment-processing, email-marketing, data-storage, analytics, third-party-integrations)' }, dataTypes: { type: 'array', items: { type: 'string' }, description: 'Types of user data collected (ask user: "What personal information do you collect?" Examples: email, name, phone, address, payment_info, health_data, location, cookies)' }, url: { type: 'string', description: 'Optional: Live application URL for automated analysis' }, description: { type: 'string', description: 'Optional: Brief description of what the app does' } }, required: ['appName', 'platform', 'features', 'dataTypes'] } }, { name: 'analyze-url-compliance', description: 'Analyze a live website URL for compliance issues. Ask the user: "What\'s the URL of your website or application that you\'d like me to analyze for compliance?" This tool will automatically detect if it needs GDPR, HIPAA, or Financial compliance checks based on the content.', inputSchema: { type: 'object', properties: { url: { type: 'string', description: 'Website URL to analyze (ask user: "What\'s the URL of your website or app?")' }, complianceType: { type: 'string', enum: ['GDPR', 'HIPAA', 'Financial', 'auto'], description: 'Compliance framework (default: auto-detect). Ask only if user has specific requirements.' } }, required: ['url'] } }, { name: 'multi-compliance-analysis', description: 'Analyze an application for ALL compliance frameworks (GDPR, HIPAA, Financial) at once. Perfect for healthcare apps, fintech, or apps handling sensitive data. Ask user: "I\'ll check your app against multiple compliance frameworks. What\'s your app name? What types of data do you collect? What features does it have? What region do you operate in?"', inputSchema: { type: 'object', properties: { appName: { type: 'string', description: 'Application name (ask user: "What\'s your app called?")' }, url: { type: 'string', description: 'Optional: Live application URL' }, description: { type: 'string', description: 'What the app does (ask user: "Can you briefly describe what your app does?")' }, dataTypes: { type: 'array', items: { type: 'string' }, description: 'Data collected (ask user: "What types of data do you collect?" Examples: health_records, payment_info, personal_data, financial_data, medical_data)' }, features: { type: 'array', items: { type: 'string' }, description: 'App capabilities (ask user: "What can users do in your app?" Examples: data-storage, payment-processing, third-party-sharing, analytics, user-authentication)' }, region: { type: 'string', enum: ['US', 'EU', 'UK', 'Global'], description: 'Operating region (ask user: "Where do your users primarily come from - US, EU, UK, or Global?")' } }, required: ['appName', 'dataTypes', 'features'] } }, { name: 'complete-compliance-assessment', description: 'Complete a compliance assessment after the user has answered follow-up questions. Use this ONLY after running professional-gdpr-analysis first. The user should have been given specific questions to answer.', inputSchema: { type: 'object', properties: { sessionId: { type: 'string', description: 'Session ID from the initial analysis (provided in previous analysis results)' }, responses: { type: 'object', description: 'User answers to compliance questions (ask user to answer the specific questions from the initial analysis)', additionalProperties: { type: 'string' } } }, required: ['sessionId', 'responses'] } }, { name: 'handle-ai-system-status', description: 'Check the Handle AI system status, your API usage, and available compliance analysis credits. Use this to see how many analyses you have left and your account status.', inputSchema: { type: 'object', properties: {}, additionalProperties: false } }, { name: 'list-user-projects', description: 'Show all your previous compliance analyses and their results. Great for reviewing past work or finding a specific analysis.', inputSchema: { type: 'object', properties: { limit: { type: 'number', description: 'How many projects to show (default: 10)' }, offset: { type: 'number', description: 'Skip this many projects (for pagination)' } } } }, { name: 'get-project-details', description: 'Get the full compliance analysis report for a specific project. Ask user: "Which project would you like to see the detailed report for?" if they don\'t provide a project ID.', inputSchema: { type: 'object', properties: { projectId: { type: 'string', description: 'Project ID to get details for (ask user: "What\'s the project ID you want to see details for?")' } }, required: ['projectId'] } } ] }; }); // Handle tool calls this.server.setRequestHandler(CallToolRequestSchema, async (request) => { const { name, arguments: args } = request.params; console.error(`🔧 Tool called: ${name}`); try { let result; switch (name) { case 'professional-gdpr-analysis': result = await this.callAPI('/gdpr/analyze', { appName: args.appName, platform: args.platform, features: args.features, dataTypes: args.dataTypes, url: args.url || '', description: args.description || '', source: 'mcp-downloadable' }); break; case 'analyze-url-compliance': result = await this.callAPI('/url-check', { url: args.url, save: true }); break; case 'multi-compliance-analysis': result = await this.callAPI('/project/multi-agent', { name: args.appName, url: args.url || '', description: args.description || '', clientType: 'web-app', region: args.region || 'US', dataTypes: args.dataTypes, features: args.features, complianceType: 'auto' }); break; case 'complete-compliance-assessment': result = await this.callAPI(`/gdpr/session/${args.sessionId}/responses`, { responses: args.responses }); break; case 'handle-ai-system-status': result = await this.callAPI('/usage/summary', {}, 'GET'); break; case 'list-user-projects': const params = new URLSearchParams(); if (args.limit) params.append('limit', args.limit.toString()); if (args.offset) params.append('offset', args.offset.toString()); result = await this.callAPI(`/projects?${params.toString()}`, {}, 'GET'); break; case 'get-project-details': result = await this.callAPI(`/projects/${args.projectId}`, {}, 'GET'); break; default: throw new Error(`Unknown tool: ${name}`); } return { content: [ { type: 'text', text: JSON.stringify({ tool: name, timestamp: new Date().toISOString(), server: 'Handle AI MCP (Downloadable)', result: result }, null, 2) } ] }; } catch (error) { console.error(`❌ Tool execution failed: ${name}`, error); return { content: [ { type: 'text', text: JSON.stringify({ tool: name, error: 'Tool execution failed', message: error.message, timestamp: new Date().toISOString(), server: 'Handle AI MCP (Downloadable)' }, null, 2) } ], isError: true }; } }); // List resources this.server.setRequestHandler(ListResourcesRequestSchema, async () => { return { resources: [ { uri: 'handle-ai://compliance-knowledge', name: 'Handle AI Compliance Knowledge Base', description: 'Comprehensive compliance knowledge for GDPR, HIPAA, and Financial regulations', mimeType: 'application/json' }, { uri: 'handle-ai://api-documentation', name: 'Handle AI API Documentation', description: 'Complete API documentation and usage examples', mimeType: 'application/json' } ] }; }); // Read resources this.server.setRequestHandler(ReadResourceRequestSchema, async (request) => { const { uri } = request.params; switch (uri) { case 'handle-ai://compliance-knowledge': return { contents: [ { uri: 'handle-ai://compliance-knowledge', mimeType: 'application/json', text: JSON.stringify({ frameworks: { GDPR: { description: 'General Data Protection Regulation (EU)', key_principles: [ 'Lawfulness, fairness and transparency', 'Purpose limitation', 'Data minimisation', 'Accuracy', 'Storage limitation', 'Integrity and confidentiality', 'Accountability' ], rights: [ 'Right to be informed', 'Right of access', 'Right to rectification', 'Right to erasure', 'Right to restrict processing', 'Right to data portability', 'Right to object', 'Rights in relation to automated decision making' ] }, HIPAA: { description: 'Health Insurance Portability and Accountability Act (US)', key_requirements: [ 'Administrative safeguards', 'Physical safeguards', 'Technical safeguards' ] }, Financial: { description: 'Financial Services Regulations', frameworks: ['SOX', 'PCI DSS', 'Investment Adviser Act'] } }, handle_ai_capabilities: [ 'Multi-agent compliance analysis', 'Real-time website scanning', 'Automated risk assessment', 'Compliance report generation', 'Follow-up question handling' ] }, null, 2) } ] }; case 'handle-ai://api-documentation': return { contents: [ { uri: 'handle-ai://api-documentation', mimeType: 'application/json', text: JSON.stringify({ api_base: 'https://handle-ai.com/api', authentication: 'API Key in X-API-Key header', endpoints: { '/gdpr/analyze': 'GDPR compliance analysis', '/url-check': 'Website URL compliance scanning', '/project/multi-agent': 'Multi-framework analysis', '/usage/summary': 'API usage and limits', '/projects': 'List user projects' }, mcp_server: { name: 'Handle AI MCP Server', version: '1.0.0', type: 'Downloadable (HTTP-based)', installation: 'npm install -g @handle-ai/mcp' } }, null, 2) } ] }; default: throw new Error(`Unknown resource: ${uri}`); } }); } async start() { try { const transport = new StdioServerTransport(); await this.server.connect(transport); console.error('✅ Handle AI MCP Server started successfully'); console.error('🎯 All 7 compliance tools are ready'); console.error('🔗 Connected to Handle AI API'); } catch (error) { console.error('❌ Failed to start MCP server:', error); process.exit(1); } } } // Handle graceful shutdown process.on('SIGINT', () => { console.error('👋 Handle AI MCP Server shutting down...'); process.exit(0); }); process.on('SIGTERM', () => { console.error('👋 Handle AI MCP Server terminated'); process.exit(0); }); // Start the server const server = new HandleAIMCPServer(); server.start().catch((error) => { console.error('💥 Fatal error:', error); process.exit(1); });