UNPKG

veas

Version:

Veas CLI - Command-line interface for Veas platform

236 lines 8.52 kB
import { AuthManager } from '../auth/auth-manager.js'; import { logger } from '../utils/logger.js'; export class MCPClient { static instance; authManager; baseUrl; connected = false; constructor(baseUrl) { this.authManager = AuthManager.getInstance(); this.baseUrl = baseUrl || process.env.VEAS_API_URL || 'http://localhost:3000'; } static getInstance() { if (!MCPClient.instance) { MCPClient.instance = new MCPClient(); } return MCPClient.instance; } async initialize() { const credentials = await this.authManager.getCredentials(); const token = credentials?.patToken || credentials?.token || credentials?.accessToken; if (!token) { throw new Error('Not authenticated. Please run "veas login" first.'); } const response = await fetch(`${this.baseUrl}/api/mcp-manual`, { method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}`, }, body: JSON.stringify({ jsonrpc: '2.0', method: 'initialize', params: { protocolVersion: '2024-11-05', capabilities: {}, clientInfo: { name: 'veas-cli', version: '1.0.0', }, }, id: 'init', }), }); if (!response.ok) { if (response.status === 401) { throw new Error('Unauthorized. Please check your authentication.'); } throw new Error(`Initialization failed: ${response.statusText}`); } const result = (await response.json()); if (result?.error) { throw new Error(result.error.message); } this.connected = true; return result?.result; } async listTools() { const credentials = await this.authManager.getCredentials(); const token = credentials?.patToken || credentials?.token || credentials?.accessToken; if (!token) { throw new Error('Authentication token not found. Please run "veas login" first.'); } const response = await fetch(`${this.baseUrl}/api/mcp/mcp`, { method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}`, }, body: JSON.stringify({ jsonrpc: '2.0', method: 'tools/list', params: {}, id: 'list-tools', }), }); if (!response.ok) { throw new Error(`Failed to list tools: ${response.statusText}`); } const result = await response.json(); if (result?.error) { throw new Error(result.error.message); } return result?.result; } async request(method, params, headers) { const credentials = await this.authManager.getCredentials(); const token = credentials?.patToken || credentials?.token || credentials?.accessToken; const response = await fetch(`${this.baseUrl}/api/mcp/mcp`, { method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}`, ...headers, }, body: JSON.stringify({ jsonrpc: '2.0', method, params, id: Date.now().toString(), }), }); return response.json(); } disconnect() { this.connected = false; } isConnected() { return this.connected; } async callTool(toolName, params) { const credentials = await this.authManager.getCredentials(); const token = credentials?.patToken || credentials?.token || credentials?.accessToken; if (!token) { throw new Error('Authentication token not found. Please run "veas login" first.'); } const url = `${this.baseUrl}/api/mcp-manual`; const requestBody = { jsonrpc: '2.0', method: 'tools/call', params: { name: toolName, arguments: params, }, id: Date.now().toString(), }; logger.debug(`Calling MCP tool: ${toolName}`); logger.debug(`API URL: ${url}`); logger.debug(`Using token: ${token ? 'Yes' : 'No'} (length: ${token?.length || 0})`); logger.debug(`Token type: ${credentials?.patToken ? 'PAT' : credentials?.token ? 'Session' : 'None'}`); try { const response = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}`, 'X-MCP-Token': token, }, body: JSON.stringify(requestBody), signal: AbortSignal.timeout(30000), }); const responseText = await response.text(); if (!response.ok) { logger.error(`HTTP ${response.status}: ${responseText}`); throw new Error(`HTTP ${response.status}: ${responseText}`); } let result; try { result = JSON.parse(responseText); } catch (_e) { throw new Error(`Failed to parse response: ${responseText}`); } if (result.error) { logger.debug(`MCP error: ${JSON.stringify(result.error)}`); throw new Error(result.error.message || 'Unknown error'); } logger.debug(`MCP response result:`, JSON.stringify(result.result, null, 2)); return result.result; } catch (error) { logger.error(`MCP call failed: ${error}`); if (error instanceof Error && error.name === 'AbortError') { throw new Error('Request timed out after 30 seconds'); } throw error; } } async callToolSafe(toolName, params) { try { const result = await this.callTool(toolName, params); return { success: true, data: result, }; } catch (error) { return { success: false, error: error instanceof Error ? error.message : String(error), }; } } async listToolsWithResult() { const credentials = await this.authManager.getCredentials(); const token = credentials?.patToken || credentials?.token; if (!token) { throw new Error('Authentication token not found. Please run "veas login" first.'); } const url = `${process.env.VEAS_API_URL || 'https://veas.app'}/api/mcp-simple`; const requestBody = { jsonrpc: '2.0', method: 'tools/list', id: '1', }; try { const response = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}`, 'X-MCP-Token': token, }, body: JSON.stringify(requestBody), }); if (!response.ok) { const errorText = await response.text(); return { success: false, error: `HTTP ${response.status}: ${errorText}`, }; } const result = await response.json(); if (result.error) { return { success: false, error: result.error.message || 'Unknown error', }; } return { success: true, data: result.result, }; } catch (error) { return { success: false, error: error instanceof Error ? error.message : String(error), }; } } } export async function callMCPTool(toolName, params) { const client = MCPClient.getInstance(); return client.callTool(toolName, params); } //# sourceMappingURL=mcp-client.js.map