From 07a8e623ea36654d41ede8c9016046ef505ad34c Mon Sep 17 00:00:00 2001 From: Matvey-Kuk Date: Sat, 16 Aug 2025 13:46:56 +0100 Subject: [PATCH] Add MCP Catalog Trust Score badge --- README.md | 1 + src/helpers/cli-parser.ts | 34 --------- src/helpers/config-repository.ts | 75 ------------------- src/helpers/mcp-proxy.ts | 122 ------------------------------- src/helpers/utils.ts | 37 ---------- 5 files changed, 1 insertion(+), 268 deletions(-) delete mode 100644 src/helpers/cli-parser.ts delete mode 100644 src/helpers/config-repository.ts delete mode 100644 src/helpers/mcp-proxy.ts delete mode 100644 src/helpers/utils.ts diff --git a/README.md b/README.md index 493de63..744d03f 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ # Sequa MCP +[![Trust Score](https://archestra.ai/mcp-catalog/api/badge/quality/sequa-ai/sequa-mcp)](https://archestra.ai/mcp-catalog/sequa-ai__sequa-mcp) This repository is the **entry point for using Sequa via the Model Context Protocol (MCP)**. If you arrived here looking to "add Sequa as an MCP server" to Cursor, Claude, Windsurf, VSCode, Cline, Highlight, Augment, or any other MCP‑capable client — you are in the right place. diff --git a/src/helpers/cli-parser.ts b/src/helpers/cli-parser.ts deleted file mode 100644 index c1d9919..0000000 --- a/src/helpers/cli-parser.ts +++ /dev/null @@ -1,34 +0,0 @@ -export class CliParser { - public static async parseCommandLineArgs( - args: string[], - usage: string = '', - ): Promise<{ parsedArgs: Record; positionalArgs: string[] }> { - const parsedArgs: Record = {} - const positionalArgs: string[] = [] - - for (let i = 0; i < args.length; i++) { - const arg = args[i] - - if (arg === '-h' || arg === '--help') { - console.error(usage) - process.exit(0) - } - - if (arg.startsWith('-')) { - const isLongOption = arg.startsWith('--') - const optionName = isLongOption ? arg.slice(2) : arg.slice(1) - - if (i + 1 >= args.length || args[i + 1].startsWith('-')) { - parsedArgs[optionName] = true - } else { - parsedArgs[optionName] = args[i + 1] - i++ - } - } else { - positionalArgs.push(arg) - } - } - - return { parsedArgs, positionalArgs } - } -} diff --git a/src/helpers/config-repository.ts b/src/helpers/config-repository.ts deleted file mode 100644 index b5e2fa2..0000000 --- a/src/helpers/config-repository.ts +++ /dev/null @@ -1,75 +0,0 @@ -import fs from 'fs/promises' -import os from 'os' -import path from 'path' - -import { getServerUrlHash, log } from './utils.js' - -export class ConfigRepository { - private readonly version = 3 - private readonly configDir: string - - constructor(private readonly serverUrl: URL) { - this.configDir = path.join(os.homedir(), '.mcp-auth', `${getServerUrlHash(serverUrl)}-v${this.version}`) - } - - public getServerUrl(): URL { - return this.serverUrl - } - - public async readConfig(name: string): Promise { - await this.ensureConfigDir() - - try { - const filePath = this.getConfigFilePath(name) - const content = await fs.readFile(filePath, 'utf-8') - - return JSON.parse(content) as T - } catch (error) { - if ((error as NodeJS.ErrnoException).code === 'ENOENT') { - return undefined - } - - log(`Error reading ${name}:`, error) - - return undefined - } - } - - public async writeConfig(name: string, data: T): Promise { - await this.ensureConfigDir() - - try { - const filePath = this.getConfigFilePath(name) - await fs.writeFile(filePath, JSON.stringify(data, null, 2), 'utf-8') - } catch (error) { - log(`Error writing ${name}:`, error) - - throw error - } - } - - public async deleteConfig(name: string): Promise { - try { - const filePath = this.getConfigFilePath(name) - await fs.unlink(filePath) - } catch (error) { - if ((error as NodeJS.ErrnoException).code !== 'ENOENT') { - log(`Error deleting ${name}:`, error) - } - } - } - - private async ensureConfigDir(): Promise { - try { - await fs.mkdir(this.configDir, { recursive: true }) - } catch (error) { - log('Error creating config directory:', error) - - throw error - } - } - - private getConfigFilePath(name: string): string { - return path.join(this.configDir, `${name}.json`) - } -} diff --git a/src/helpers/mcp-proxy.ts b/src/helpers/mcp-proxy.ts deleted file mode 100644 index 343fbbe..0000000 --- a/src/helpers/mcp-proxy.ts +++ /dev/null @@ -1,122 +0,0 @@ -import type { Transport } from '@modelcontextprotocol/sdk/shared/transport.js' - -import { getTimestamp, log } from './utils.js' - -export class McpProxy { - public static async createProxy( - transportToClient: Transport, - transportToServer: Transport, - onShutdown: () => Promise = async () => {}, - ) { - const proxy = new McpProxy(transportToClient, transportToServer, onShutdown) - await proxy.initialize() - - return proxy - } - - private running = true - - constructor( - private readonly transportToClient: Transport, - private readonly transportToServer: Transport, - private readonly onShutdown: () => Promise, - ) {} - - public async initialize() { - this.transportToClient.onmessage = this.handleClientMessage.bind(this) - this.transportToServer.onmessage = this.handleServerMessage.bind(this) - - this.transportToClient.onclose = this.handleClientClose.bind(this) - this.transportToServer.onclose = this.handleServerClose.bind(this) - - this.transportToClient.onerror = this.handleClientError.bind(this) - this.transportToServer.onerror = this.handleServerError.bind(this) - } - - private async handleClientMessage(message: any) { - if (!this.running) { - return - } - - try { - log(`[${getTimestamp()}] Client -> Server: ${JSON.stringify(message)}`) - - await this.transportToServer.send(message).catch((error) => { - log('Error forwarding message to server:', error) - this.handleServerError(error instanceof Error ? error : new Error(String(error))) - }) - } catch (error) { - await this.handleClientError(error instanceof Error ? error : new Error(String(error))) - } - } - - private async handleServerMessage(message: any) { - if (!this.running) { - return - } - - try { - log(`[${getTimestamp()}] Server -> Client: ${JSON.stringify(message)}`) - - await this.transportToClient.send(message).catch((error) => { - log('Error forwarding message to client:', error) - this.handleClientError(error instanceof Error ? error : new Error(String(error))) - }) - } catch (error) { - await this.handleServerError(error instanceof Error ? error : new Error(String(error))) - } - } - - private async handleClientClose() { - if (!this.running) { - return - } - - log('Client connection closed') - await this.shutdown() - } - - private async handleServerClose() { - if (!this.running) { - return - } - - log('Server connection closed') - await this.shutdown() - } - - private async handleClientError(error: Error) { - if (!this.running) { - return - } - - log('Client error received', error) - await this.shutdown() - } - - private async handleServerError(error: Error) { - if (!this.running) { - return - } - - log('Server error received', error) - await this.shutdown() - } - - private async shutdown(): Promise { - if (this.running) { - this.running = false - - await this.safeClose(this.transportToClient) - await this.safeClose(this.transportToServer) - - await this.onShutdown() - } - } - - private async safeClose(transport: Transport): Promise { - try { - await transport.close() - } catch {} - } -} diff --git a/src/helpers/utils.ts b/src/helpers/utils.ts deleted file mode 100644 index 2b137ca..0000000 --- a/src/helpers/utils.ts +++ /dev/null @@ -1,37 +0,0 @@ -import crypto from 'crypto' - -export function getServerUrlHash(key: URL): string { - return crypto.createHash('sha256').update(key.toString()).digest('hex') -} - -export function getTimestamp(): string { - const now = new Date() - return `${now.getHours().toString().padStart(2, '0')}:${now.getMinutes().toString().padStart(2, '0')}:${now.getSeconds().toString().padStart(2, '0')}.${now.getMilliseconds().toString().padStart(3, '0')}` -} - -export function debugLog(str: string, ...rest: any[]) { - if (!process.env.DEBUG) { - return - } - - console.error(`[DEBUG] [${process.pid}] ${str}`, ...rest) -} - -export function log(str: string, ...rest: unknown[]) { - if (!process.env.LOGGING && !process.env.DEBUG) { - return - } - - console.error(`[LOG] [${process.pid}] ${str}`, ...rest) -} - -export function setupShutdownHook(cleanup: () => Promise) { - const fn = async () => { - log('Shutting down...') - await cleanup() - process.exit(0) - } - - process.on('SIGINT', fn) - process.on('SIGTERM', fn) -}