@leonailtd/priority-mcp-client 0.3.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin.js +8 -6
- package/dist/bin.js.map +1 -1
- package/package.json +1 -1
package/dist/bin.js
CHANGED
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
ListPromptsRequestSchema,
|
|
15
15
|
GetPromptRequestSchema
|
|
16
16
|
} from "@modelcontextprotocol/sdk/types.js";
|
|
17
|
+
var MCP_SERVER_URL = "https://priority-mcp.leonai.io/";
|
|
17
18
|
var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
18
19
|
function isRetryableError(error) {
|
|
19
20
|
if (!error) return false;
|
|
@@ -95,7 +96,7 @@ function getErrorHint(error, context) {
|
|
|
95
96
|
return "Token is valid but lacks permission. Contact your administrator.";
|
|
96
97
|
}
|
|
97
98
|
if (errorStr.includes("404")) {
|
|
98
|
-
return "Server endpoint not found.
|
|
99
|
+
return "Server endpoint not found. Contact info@leonai.io if issue persists.";
|
|
99
100
|
}
|
|
100
101
|
if (errorStr.includes("timeout") || errorStr.includes("etimedout")) {
|
|
101
102
|
return "Request timed out. Server may be slow or overloaded.";
|
|
@@ -111,7 +112,7 @@ function getErrorHint(error, context) {
|
|
|
111
112
|
}
|
|
112
113
|
return "See error details above";
|
|
113
114
|
}
|
|
114
|
-
program.name("priority-mcp-client").description("MCP client that proxies Claude Desktop to Priority MCP server").requiredOption("--
|
|
115
|
+
program.name("priority-mcp-client").description("MCP client that proxies Claude Desktop to Priority MCP server").requiredOption("--token <token>", "Authentication token (sk-cust-...)").requiredOption("--priority-url <url>", "Priority ERP base URL").requiredOption("--priority-company <company>", "Priority company name").requiredOption("--priority-username <username>", "Priority API username").requiredOption("--priority-password <password>", "Priority API password").option("--debug", "Enable debug logging").option("--verbose", "Enable verbose logging (includes request/response details)").parse();
|
|
115
116
|
var options = program.opts();
|
|
116
117
|
async function main() {
|
|
117
118
|
try {
|
|
@@ -119,13 +120,13 @@ async function main() {
|
|
|
119
120
|
const verbose = options.verbose || false;
|
|
120
121
|
if (debug) {
|
|
121
122
|
console.error("[DEBUG] Starting Priority MCP Client v1.0.0");
|
|
122
|
-
console.error(`[DEBUG] Server URL: ${
|
|
123
|
+
console.error(`[DEBUG] Server URL: ${MCP_SERVER_URL}`);
|
|
123
124
|
}
|
|
124
125
|
if (debug) {
|
|
125
126
|
console.error("[DEBUG] Performing health check...");
|
|
126
127
|
}
|
|
127
128
|
try {
|
|
128
|
-
const healthUrl = `${
|
|
129
|
+
const healthUrl = `${MCP_SERVER_URL}/health`;
|
|
129
130
|
const healthResponse = await retryWithBackoff(
|
|
130
131
|
async () => {
|
|
131
132
|
const response = await fetch(healthUrl);
|
|
@@ -151,7 +152,7 @@ async function main() {
|
|
|
151
152
|
console.error("[ERROR] Server health check failed");
|
|
152
153
|
console.error("[ERROR]", error);
|
|
153
154
|
console.error("[HINT]", getErrorHint(error, "health check"));
|
|
154
|
-
console.error("[HINT] Verify server is running: curl", `${
|
|
155
|
+
console.error("[HINT] Verify server is running: curl", `${MCP_SERVER_URL}/health`);
|
|
155
156
|
process.exit(1);
|
|
156
157
|
}
|
|
157
158
|
const connectionMonitor = new ConnectionMonitor(debug);
|
|
@@ -165,6 +166,7 @@ async function main() {
|
|
|
165
166
|
const tenantIdSource = `${options.priorityCompany.toLowerCase()}@${options.priorityUrl.toLowerCase()}`;
|
|
166
167
|
const tenantId = crypto.createHash("sha256").update(tenantIdSource).digest("hex").substring(0, 16);
|
|
167
168
|
const headers = {
|
|
169
|
+
"User-Agent": "leonai-priority-mcp-client",
|
|
168
170
|
"Authorization": `Bearer ${options.token}`,
|
|
169
171
|
"X-Tenant-ID": tenantId,
|
|
170
172
|
// Unique identifier for rate limiting/tracking
|
|
@@ -176,7 +178,7 @@ async function main() {
|
|
|
176
178
|
if (debug) {
|
|
177
179
|
console.error("[DEBUG] Headers prepared (credentials hidden)");
|
|
178
180
|
}
|
|
179
|
-
const mcpUrl = new URL("/mcp",
|
|
181
|
+
const mcpUrl = new URL("/mcp", MCP_SERVER_URL);
|
|
180
182
|
const controller = new AbortController();
|
|
181
183
|
const timeoutId = setTimeout(() => controller.abort(), 3e4);
|
|
182
184
|
const transport = new StreamableHTTPClientTransport(mcpUrl, {
|
package/dist/bin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/bin.ts"],"sourcesContent":["#!/usr/bin/env node\r\n\r\nimport { program } from 'commander';\r\nimport { Client } from '@modelcontextprotocol/sdk/client/index.js';\r\nimport { Server } from '@modelcontextprotocol/sdk/server/index.js';\r\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\r\nimport { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';\r\nimport {\r\n ListToolsRequestSchema,\r\n CallToolRequestSchema,\r\n ListResourcesRequestSchema,\r\n ReadResourceRequestSchema,\r\n ListPromptsRequestSchema,\r\n GetPromptRequestSchema\r\n} from '@modelcontextprotocol/sdk/types.js';\r\n\r\n// Helper: Sleep for specified milliseconds\r\nconst sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));\r\n\r\n// Helper: Check if error is retryable\r\nfunction isRetryableError(error: any): boolean {\r\n if (!error) return false;\r\n\r\n const errorStr = String(error).toLowerCase();\r\n const retryablePatterns = [\r\n 'econnreset',\r\n 'econnrefused',\r\n 'etimedout',\r\n 'timeout',\r\n 'network',\r\n 'socket hang up',\r\n '502',\r\n '503',\r\n '504'\r\n ];\r\n\r\n return retryablePatterns.some(pattern => errorStr.includes(pattern));\r\n}\r\n\r\n// Helper: Retry with exponential backoff\r\nasync function retryWithBackoff<T>(\r\n fn: () => Promise<T>,\r\n maxRetries: number = 3,\r\n baseDelay: number = 1000,\r\n debug: boolean = false\r\n): Promise<T> {\r\n let lastError: any;\r\n\r\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\r\n try {\r\n return await fn();\r\n } catch (error) {\r\n lastError = error;\r\n\r\n if (attempt >= maxRetries) {\r\n throw error;\r\n }\r\n\r\n if (!isRetryableError(error)) {\r\n throw error;\r\n }\r\n\r\n const delay = Math.min(baseDelay * Math.pow(2, attempt), 30000); // Max 30s\r\n const jitter = Math.random() * 0.25 * delay;\r\n const totalDelay = Math.floor(delay + jitter);\r\n\r\n if (debug) {\r\n console.error(`[DEBUG] Retry attempt ${attempt + 1}/${maxRetries} after ${totalDelay}ms`);\r\n }\r\n\r\n await sleep(totalDelay);\r\n }\r\n }\r\n\r\n throw lastError;\r\n}\r\n\r\n// Helper: Connection monitor\r\nclass ConnectionMonitor {\r\n private lastSuccessfulCall: number = Date.now();\r\n private failureCount: number = 0;\r\n private totalCalls: number = 0;\r\n private debug: boolean;\r\n\r\n constructor(debug: boolean = false) {\r\n this.debug = debug;\r\n }\r\n\r\n async monitorCall<T>(operation: string, fn: () => Promise<T>): Promise<T> {\r\n this.totalCalls++;\r\n const startTime = Date.now();\r\n\r\n try {\r\n const result = await fn();\r\n this.lastSuccessfulCall = Date.now();\r\n this.failureCount = 0;\r\n\r\n const duration = Date.now() - startTime;\r\n if (this.debug && duration > 5000) {\r\n console.error(`[WARNING] Slow operation: ${operation} took ${duration}ms`);\r\n }\r\n\r\n return result;\r\n } catch (error) {\r\n this.failureCount++;\r\n\r\n const timeSinceSuccess = Date.now() - this.lastSuccessfulCall;\r\n if (timeSinceSuccess > 60000 && this.failureCount >= 3) {\r\n console.error('[WARNING] Connection appears degraded');\r\n console.error(`[WARNING] ${this.failureCount} failures in the last ${Math.floor(timeSinceSuccess / 1000)}s`);\r\n }\r\n\r\n throw error;\r\n }\r\n }\r\n}\r\n\r\n// Helper: Enhanced error message\r\nfunction getErrorHint(error: any, context: string): string {\r\n const errorStr = String(error).toLowerCase();\r\n\r\n if (errorStr.includes('401') || errorStr.includes('unauthorized')) {\r\n return 'Check your API token (--token sk-cust-...)';\r\n }\r\n if (errorStr.includes('403') || errorStr.includes('forbidden')) {\r\n return 'Token is valid but lacks permission. Contact your administrator.';\r\n }\r\n if (errorStr.includes('404')) {\r\n return 'Server endpoint not found. Verify --url is correct.';\r\n }\r\n if (errorStr.includes('timeout') || errorStr.includes('etimedout')) {\r\n return 'Request timed out. Server may be slow or overloaded.';\r\n }\r\n if (errorStr.includes('econnrefused')) {\r\n return 'Connection refused. Verify server is running and URL is correct.';\r\n }\r\n if (errorStr.includes('econnreset') || errorStr.includes('socket hang up')) {\r\n return 'Connection lost. Check network connectivity.';\r\n }\r\n if (errorStr.includes('dns') || errorStr.includes('getaddrinfo')) {\r\n return 'DNS lookup failed. Check server URL spelling.';\r\n }\r\n\r\n return 'See error details above';\r\n}\r\n\r\n// Parse command-line arguments\r\nprogram\r\n .name('priority-mcp-client')\r\n .description('MCP client that proxies Claude Desktop to Priority MCP server')\r\n .requiredOption('--url <url>', 'Priority MCP server URL (e.g., https://priority-mcp.leonai.io)')\r\n .requiredOption('--token <token>', 'Authentication token (sk-cust-...)')\r\n .requiredOption('--priority-url <url>', 'Priority ERP base URL')\r\n .requiredOption('--priority-company <company>', 'Priority company name')\r\n .requiredOption('--priority-username <username>', 'Priority API username')\r\n .requiredOption('--priority-password <password>', 'Priority API password')\r\n .option('--debug', 'Enable debug logging')\r\n .option('--verbose', 'Enable verbose logging (includes request/response details)')\r\n .parse();\r\n\r\nconst options = program.opts();\r\n\r\nasync function main() {\r\n try {\r\n const debug = options.debug || options.verbose || false;\r\n const verbose = options.verbose || false;\r\n\r\n if (debug) {\r\n console.error('[DEBUG] Starting Priority MCP Client v1.0.0');\r\n console.error(`[DEBUG] Server URL: ${options.url}`);\r\n }\r\n\r\n // Health check on startup\r\n if (debug) {\r\n console.error('[DEBUG] Performing health check...');\r\n }\r\n\r\n try {\r\n const healthUrl = `${options.url}/health`;\r\n const healthResponse = await retryWithBackoff(\r\n async () => {\r\n const response = await fetch(healthUrl);\r\n if (!response.ok) {\r\n throw new Error(`Health check failed: ${response.status} ${response.statusText}`);\r\n }\r\n return response.json();\r\n },\r\n 2, // 2 retries for health check\r\n 500, // 500ms base delay\r\n debug\r\n );\r\n\r\n if (debug) {\r\n console.error('[DEBUG] Health check passed:', JSON.stringify(healthResponse));\r\n }\r\n\r\n if (healthResponse.status !== 'healthy') {\r\n console.error('[WARNING] Server health check returned non-healthy status');\r\n console.error('[WARNING] Service may be degraded');\r\n }\r\n } catch (error) {\r\n console.error('[ERROR] Server health check failed');\r\n console.error('[ERROR]', error);\r\n console.error('[HINT]', getErrorHint(error, 'health check'));\r\n console.error('[HINT] Verify server is running: curl', `${options.url}/health`);\r\n process.exit(1);\r\n }\r\n\r\n // Initialize connection monitor\r\n const connectionMonitor = new ConnectionMonitor(debug);\r\n\r\n // Create MCP client that will connect to remote Priority server\r\n const client = new Client({\r\n name: 'priority-mcp-client',\r\n version: '1.0.0'\r\n }, {\r\n capabilities: {}\r\n });\r\n\r\n // Generate tenant ID from company+url for uniqueness\r\n // This allows server to track/rate-limit per customer without storing credentials\r\n const crypto = await import('crypto');\r\n const tenantIdSource = `${options.priorityCompany.toLowerCase()}@${options.priorityUrl.toLowerCase()}`;\r\n const tenantId = crypto.createHash('sha256').update(tenantIdSource).digest('hex').substring(0, 16);\r\n\r\n // Prepare headers for authentication\r\n const headers = {\r\n 'Authorization': `Bearer ${options.token}`,\r\n 'X-Tenant-ID': tenantId, // Unique identifier for rate limiting/tracking\r\n 'X-Priority-URL': options.priorityUrl,\r\n 'X-Priority-Company': options.priorityCompany,\r\n 'X-Priority-Username': options.priorityUsername,\r\n 'X-Priority-Password': options.priorityPassword\r\n };\r\n\r\n if (debug) {\r\n console.error('[DEBUG] Headers prepared (credentials hidden)');\r\n }\r\n\r\n // Connect to remote Priority MCP server via Streamable HTTP with timeout\r\n const mcpUrl = new URL('/mcp', options.url);\r\n const controller = new AbortController();\r\n const timeoutId = setTimeout(() => controller.abort(), 30000); // 30 second timeout\r\n\r\n const transport = new StreamableHTTPClientTransport(mcpUrl, {\r\n requestInit: {\r\n headers: headers,\r\n signal: controller.signal\r\n }\r\n });\r\n\r\n try {\r\n await retryWithBackoff(\r\n () => client.connect(transport),\r\n 3, // 3 retries for connection\r\n 1000, // 1s base delay\r\n debug\r\n );\r\n clearTimeout(timeoutId);\r\n\r\n if (debug) {\r\n console.error('[DEBUG] Connected to remote Priority MCP server');\r\n }\r\n } catch (error) {\r\n clearTimeout(timeoutId);\r\n console.error('[ERROR] Failed to connect to Priority MCP server');\r\n console.error('[ERROR]', error);\r\n console.error('[HINT]', getErrorHint(error, 'connection'));\r\n throw error;\r\n }\r\n\r\n // Create stdio server for Claude Desktop\r\n const server = new Server({\r\n name: 'priority-mcp-proxy',\r\n version: '1.0.0'\r\n }, {\r\n capabilities: {\r\n tools: {},\r\n resources: {},\r\n prompts: {}\r\n }\r\n });\r\n\r\n // Set up request handlers with retry logic and monitoring\r\n\r\n // List tools\r\n server.setRequestHandler(ListToolsRequestSchema, async () => {\r\n if (debug) console.error('[DEBUG] Forwarding tools/list');\r\n return await connectionMonitor.monitorCall('tools/list', async () => {\r\n return await retryWithBackoff(() => client.listTools(), 2, 500, debug);\r\n });\r\n });\r\n\r\n // Call tool (with retries for transient failures)\r\n server.setRequestHandler(CallToolRequestSchema, async (request) => {\r\n if (debug) console.error(`[DEBUG] Forwarding tools/call: ${request.params.name}`);\r\n if (verbose) console.error(`[VERBOSE] Tool params:`, JSON.stringify(request.params));\r\n\r\n try {\r\n const result = await connectionMonitor.monitorCall(`tools/call/${request.params.name}`, async () => {\r\n return await retryWithBackoff(() => client.callTool(request.params), 3, 1000, debug);\r\n });\r\n\r\n if (verbose) console.error(`[VERBOSE] Tool result:`, JSON.stringify(result).slice(0, 500));\r\n return result;\r\n } catch (error) {\r\n console.error(`[ERROR] Tool call failed: ${request.params.name}`);\r\n console.error(`[HINT]`, getErrorHint(error, 'tool call'));\r\n throw error;\r\n }\r\n });\r\n\r\n // List resources\r\n server.setRequestHandler(ListResourcesRequestSchema, async () => {\r\n if (debug) console.error('[DEBUG] Forwarding resources/list');\r\n return await connectionMonitor.monitorCall('resources/list', async () => {\r\n return await retryWithBackoff(() => client.listResources(), 2, 500, debug);\r\n });\r\n });\r\n\r\n // Read resource\r\n server.setRequestHandler(ReadResourceRequestSchema, async (request) => {\r\n if (debug) console.error(`[DEBUG] Forwarding resources/read: ${request.params.uri}`);\r\n return await connectionMonitor.monitorCall(`resources/read/${request.params.uri}`, async () => {\r\n return await retryWithBackoff(() => client.readResource(request.params), 3, 1000, debug);\r\n });\r\n });\r\n\r\n // List prompts\r\n server.setRequestHandler(ListPromptsRequestSchema, async () => {\r\n if (debug) console.error('[DEBUG] Forwarding prompts/list');\r\n return await connectionMonitor.monitorCall('prompts/list', async () => {\r\n return await retryWithBackoff(() => client.listPrompts(), 2, 500, debug);\r\n });\r\n });\r\n\r\n // Get prompt\r\n server.setRequestHandler(GetPromptRequestSchema, async (request) => {\r\n if (debug) console.error(`[DEBUG] Forwarding prompts/get: ${request.params.name}`);\r\n return await connectionMonitor.monitorCall(`prompts/get/${request.params.name}`, async () => {\r\n return await retryWithBackoff(() => client.getPrompt(request.params), 2, 500, debug);\r\n });\r\n });\r\n\r\n // Connect server to stdio for Claude Desktop\r\n const stdioTransport = new StdioServerTransport();\r\n await server.connect(stdioTransport);\r\n\r\n if (debug) {\r\n console.error('[DEBUG] Stdio server ready, proxy active');\r\n }\r\n\r\n // Keep process running\r\n process.on('SIGINT', async () => {\r\n if (debug) console.error('[DEBUG] Shutting down...');\r\n await server.close();\r\n await client.close();\r\n process.exit(0);\r\n });\r\n\r\n } catch (error) {\r\n console.error('Failed to start Priority MCP client:', error);\r\n process.exit(1);\r\n }\r\n}\r\n\r\nmain().catch((error) => {\r\n console.error('Fatal error:', error);\r\n process.exit(1);\r\n});\r\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/bin.ts"],"sourcesContent":["#!/usr/bin/env node\r\n\r\nimport { program } from 'commander';\r\nimport { Client } from '@modelcontextprotocol/sdk/client/index.js';\r\nimport { Server } from '@modelcontextprotocol/sdk/server/index.js';\r\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\r\nimport { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';\r\nimport {\r\n ListToolsRequestSchema,\r\n CallToolRequestSchema,\r\n ListResourcesRequestSchema,\r\n ReadResourceRequestSchema,\r\n ListPromptsRequestSchema,\r\n GetPromptRequestSchema\r\n} from '@modelcontextprotocol/sdk/types.js';\r\n\r\n// MCP Server URL (hardcoded - customers don't need to know backend infrastructure)\r\nconst MCP_SERVER_URL = 'https://priority-mcp.leonai.io/';\r\n\r\n// Helper: Sleep for specified milliseconds\r\nconst sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));\r\n\r\n// Helper: Check if error is retryable\r\nfunction isRetryableError(error: any): boolean {\r\n if (!error) return false;\r\n\r\n const errorStr = String(error).toLowerCase();\r\n const retryablePatterns = [\r\n 'econnreset',\r\n 'econnrefused',\r\n 'etimedout',\r\n 'timeout',\r\n 'network',\r\n 'socket hang up',\r\n '502',\r\n '503',\r\n '504'\r\n ];\r\n\r\n return retryablePatterns.some(pattern => errorStr.includes(pattern));\r\n}\r\n\r\n// Helper: Retry with exponential backoff\r\nasync function retryWithBackoff<T>(\r\n fn: () => Promise<T>,\r\n maxRetries: number = 3,\r\n baseDelay: number = 1000,\r\n debug: boolean = false\r\n): Promise<T> {\r\n let lastError: any;\r\n\r\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\r\n try {\r\n return await fn();\r\n } catch (error) {\r\n lastError = error;\r\n\r\n if (attempt >= maxRetries) {\r\n throw error;\r\n }\r\n\r\n if (!isRetryableError(error)) {\r\n throw error;\r\n }\r\n\r\n const delay = Math.min(baseDelay * Math.pow(2, attempt), 30000); // Max 30s\r\n const jitter = Math.random() * 0.25 * delay;\r\n const totalDelay = Math.floor(delay + jitter);\r\n\r\n if (debug) {\r\n console.error(`[DEBUG] Retry attempt ${attempt + 1}/${maxRetries} after ${totalDelay}ms`);\r\n }\r\n\r\n await sleep(totalDelay);\r\n }\r\n }\r\n\r\n throw lastError;\r\n}\r\n\r\n// Helper: Connection monitor\r\nclass ConnectionMonitor {\r\n private lastSuccessfulCall: number = Date.now();\r\n private failureCount: number = 0;\r\n private totalCalls: number = 0;\r\n private debug: boolean;\r\n\r\n constructor(debug: boolean = false) {\r\n this.debug = debug;\r\n }\r\n\r\n async monitorCall<T>(operation: string, fn: () => Promise<T>): Promise<T> {\r\n this.totalCalls++;\r\n const startTime = Date.now();\r\n\r\n try {\r\n const result = await fn();\r\n this.lastSuccessfulCall = Date.now();\r\n this.failureCount = 0;\r\n\r\n const duration = Date.now() - startTime;\r\n if (this.debug && duration > 5000) {\r\n console.error(`[WARNING] Slow operation: ${operation} took ${duration}ms`);\r\n }\r\n\r\n return result;\r\n } catch (error) {\r\n this.failureCount++;\r\n\r\n const timeSinceSuccess = Date.now() - this.lastSuccessfulCall;\r\n if (timeSinceSuccess > 60000 && this.failureCount >= 3) {\r\n console.error('[WARNING] Connection appears degraded');\r\n console.error(`[WARNING] ${this.failureCount} failures in the last ${Math.floor(timeSinceSuccess / 1000)}s`);\r\n }\r\n\r\n throw error;\r\n }\r\n }\r\n}\r\n\r\n// Helper: Enhanced error message\r\nfunction getErrorHint(error: any, context: string): string {\r\n const errorStr = String(error).toLowerCase();\r\n\r\n if (errorStr.includes('401') || errorStr.includes('unauthorized')) {\r\n return 'Check your API token (--token sk-cust-...)';\r\n }\r\n if (errorStr.includes('403') || errorStr.includes('forbidden')) {\r\n return 'Token is valid but lacks permission. Contact your administrator.';\r\n }\r\n if (errorStr.includes('404')) {\r\n return 'Server endpoint not found. Contact info@leonai.io if issue persists.';\r\n }\r\n if (errorStr.includes('timeout') || errorStr.includes('etimedout')) {\r\n return 'Request timed out. Server may be slow or overloaded.';\r\n }\r\n if (errorStr.includes('econnrefused')) {\r\n return 'Connection refused. Verify server is running and URL is correct.';\r\n }\r\n if (errorStr.includes('econnreset') || errorStr.includes('socket hang up')) {\r\n return 'Connection lost. Check network connectivity.';\r\n }\r\n if (errorStr.includes('dns') || errorStr.includes('getaddrinfo')) {\r\n return 'DNS lookup failed. Check server URL spelling.';\r\n }\r\n\r\n return 'See error details above';\r\n}\r\n\r\n// Parse command-line arguments\r\nprogram\r\n .name('priority-mcp-client')\r\n .description('MCP client that proxies Claude Desktop to Priority MCP server')\r\n .requiredOption('--token <token>', 'Authentication token (sk-cust-...)')\r\n .requiredOption('--priority-url <url>', 'Priority ERP base URL')\r\n .requiredOption('--priority-company <company>', 'Priority company name')\r\n .requiredOption('--priority-username <username>', 'Priority API username')\r\n .requiredOption('--priority-password <password>', 'Priority API password')\r\n .option('--debug', 'Enable debug logging')\r\n .option('--verbose', 'Enable verbose logging (includes request/response details)')\r\n .parse();\r\n\r\nconst options = program.opts();\r\n\r\nasync function main() {\r\n try {\r\n const debug = options.debug || options.verbose || false;\r\n const verbose = options.verbose || false;\r\n\r\n if (debug) {\r\n console.error('[DEBUG] Starting Priority MCP Client v1.0.0');\r\n console.error(`[DEBUG] Server URL: ${MCP_SERVER_URL}`);\r\n }\r\n\r\n // Health check on startup\r\n if (debug) {\r\n console.error('[DEBUG] Performing health check...');\r\n }\r\n\r\n try {\r\n const healthUrl = `${MCP_SERVER_URL}/health`;\r\n const healthResponse = await retryWithBackoff(\r\n async () => {\r\n const response = await fetch(healthUrl);\r\n if (!response.ok) {\r\n throw new Error(`Health check failed: ${response.status} ${response.statusText}`);\r\n }\r\n return response.json();\r\n },\r\n 2, // 2 retries for health check\r\n 500, // 500ms base delay\r\n debug\r\n );\r\n\r\n if (debug) {\r\n console.error('[DEBUG] Health check passed:', JSON.stringify(healthResponse));\r\n }\r\n\r\n if (healthResponse.status !== 'healthy') {\r\n console.error('[WARNING] Server health check returned non-healthy status');\r\n console.error('[WARNING] Service may be degraded');\r\n }\r\n } catch (error) {\r\n console.error('[ERROR] Server health check failed');\r\n console.error('[ERROR]', error);\r\n console.error('[HINT]', getErrorHint(error, 'health check'));\r\n console.error('[HINT] Verify server is running: curl', `${MCP_SERVER_URL}/health`);\r\n process.exit(1);\r\n }\r\n\r\n // Initialize connection monitor\r\n const connectionMonitor = new ConnectionMonitor(debug);\r\n\r\n // Create MCP client that will connect to remote Priority server\r\n const client = new Client({\r\n name: 'priority-mcp-client',\r\n version: '1.0.0'\r\n }, {\r\n capabilities: {}\r\n });\r\n\r\n // Generate tenant ID from company+url for uniqueness\r\n // This allows server to track/rate-limit per customer without storing credentials\r\n const crypto = await import('crypto');\r\n const tenantIdSource = `${options.priorityCompany.toLowerCase()}@${options.priorityUrl.toLowerCase()}`;\r\n const tenantId = crypto.createHash('sha256').update(tenantIdSource).digest('hex').substring(0, 16);\r\n\r\n // Prepare headers for authentication\r\n const headers = {\r\n 'User-Agent': 'leonai-priority-mcp-client',\r\n 'Authorization': `Bearer ${options.token}`,\r\n 'X-Tenant-ID': tenantId, // Unique identifier for rate limiting/tracking\r\n 'X-Priority-URL': options.priorityUrl,\r\n 'X-Priority-Company': options.priorityCompany,\r\n 'X-Priority-Username': options.priorityUsername,\r\n 'X-Priority-Password': options.priorityPassword\r\n };\r\n\r\n if (debug) {\r\n console.error('[DEBUG] Headers prepared (credentials hidden)');\r\n }\r\n\r\n // Connect to remote Priority MCP server via Streamable HTTP with timeout\r\n const mcpUrl = new URL('/mcp', MCP_SERVER_URL);\r\n const controller = new AbortController();\r\n const timeoutId = setTimeout(() => controller.abort(), 30000); // 30 second timeout\r\n\r\n const transport = new StreamableHTTPClientTransport(mcpUrl, {\r\n requestInit: {\r\n headers: headers,\r\n signal: controller.signal\r\n }\r\n });\r\n\r\n try {\r\n await retryWithBackoff(\r\n () => client.connect(transport),\r\n 3, // 3 retries for connection\r\n 1000, // 1s base delay\r\n debug\r\n );\r\n clearTimeout(timeoutId);\r\n\r\n if (debug) {\r\n console.error('[DEBUG] Connected to remote Priority MCP server');\r\n }\r\n } catch (error) {\r\n clearTimeout(timeoutId);\r\n console.error('[ERROR] Failed to connect to Priority MCP server');\r\n console.error('[ERROR]', error);\r\n console.error('[HINT]', getErrorHint(error, 'connection'));\r\n throw error;\r\n }\r\n\r\n // Create stdio server for Claude Desktop\r\n const server = new Server({\r\n name: 'priority-mcp-proxy',\r\n version: '1.0.0'\r\n }, {\r\n capabilities: {\r\n tools: {},\r\n resources: {},\r\n prompts: {}\r\n }\r\n });\r\n\r\n // Set up request handlers with retry logic and monitoring\r\n\r\n // List tools\r\n server.setRequestHandler(ListToolsRequestSchema, async () => {\r\n if (debug) console.error('[DEBUG] Forwarding tools/list');\r\n return await connectionMonitor.monitorCall('tools/list', async () => {\r\n return await retryWithBackoff(() => client.listTools(), 2, 500, debug);\r\n });\r\n });\r\n\r\n // Call tool (with retries for transient failures)\r\n server.setRequestHandler(CallToolRequestSchema, async (request) => {\r\n if (debug) console.error(`[DEBUG] Forwarding tools/call: ${request.params.name}`);\r\n if (verbose) console.error(`[VERBOSE] Tool params:`, JSON.stringify(request.params));\r\n\r\n try {\r\n const result = await connectionMonitor.monitorCall(`tools/call/${request.params.name}`, async () => {\r\n return await retryWithBackoff(() => client.callTool(request.params), 3, 1000, debug);\r\n });\r\n\r\n if (verbose) console.error(`[VERBOSE] Tool result:`, JSON.stringify(result).slice(0, 500));\r\n return result;\r\n } catch (error) {\r\n console.error(`[ERROR] Tool call failed: ${request.params.name}`);\r\n console.error(`[HINT]`, getErrorHint(error, 'tool call'));\r\n throw error;\r\n }\r\n });\r\n\r\n // List resources\r\n server.setRequestHandler(ListResourcesRequestSchema, async () => {\r\n if (debug) console.error('[DEBUG] Forwarding resources/list');\r\n return await connectionMonitor.monitorCall('resources/list', async () => {\r\n return await retryWithBackoff(() => client.listResources(), 2, 500, debug);\r\n });\r\n });\r\n\r\n // Read resource\r\n server.setRequestHandler(ReadResourceRequestSchema, async (request) => {\r\n if (debug) console.error(`[DEBUG] Forwarding resources/read: ${request.params.uri}`);\r\n return await connectionMonitor.monitorCall(`resources/read/${request.params.uri}`, async () => {\r\n return await retryWithBackoff(() => client.readResource(request.params), 3, 1000, debug);\r\n });\r\n });\r\n\r\n // List prompts\r\n server.setRequestHandler(ListPromptsRequestSchema, async () => {\r\n if (debug) console.error('[DEBUG] Forwarding prompts/list');\r\n return await connectionMonitor.monitorCall('prompts/list', async () => {\r\n return await retryWithBackoff(() => client.listPrompts(), 2, 500, debug);\r\n });\r\n });\r\n\r\n // Get prompt\r\n server.setRequestHandler(GetPromptRequestSchema, async (request) => {\r\n if (debug) console.error(`[DEBUG] Forwarding prompts/get: ${request.params.name}`);\r\n return await connectionMonitor.monitorCall(`prompts/get/${request.params.name}`, async () => {\r\n return await retryWithBackoff(() => client.getPrompt(request.params), 2, 500, debug);\r\n });\r\n });\r\n\r\n // Connect server to stdio for Claude Desktop\r\n const stdioTransport = new StdioServerTransport();\r\n await server.connect(stdioTransport);\r\n\r\n if (debug) {\r\n console.error('[DEBUG] Stdio server ready, proxy active');\r\n }\r\n\r\n // Keep process running\r\n process.on('SIGINT', async () => {\r\n if (debug) console.error('[DEBUG] Shutting down...');\r\n await server.close();\r\n await client.close();\r\n process.exit(0);\r\n });\r\n\r\n } catch (error) {\r\n console.error('Failed to start Priority MCP client:', error);\r\n process.exit(1);\r\n }\r\n}\r\n\r\nmain().catch((error) => {\r\n console.error('Fatal error:', error);\r\n process.exit(1);\r\n});\r\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED