Skip to main content
Glama

IT-MCP

by acampkin95
email.ts4.47 kB
import { CommandExecutionError, CommandRunner, type CommandResult } from "../utils/commandRunner.js"; import { shellQuote } from "../utils/shell.js"; export interface MxRecord { readonly priority: number; readonly exchange: string; readonly raw: string; } export interface MxLookupResult { readonly command: string; readonly result: CommandResult; readonly records: MxRecord[]; } export interface TxtLookupResult { readonly command: string; readonly result: CommandResult; readonly values: string[]; } export interface ConnectivityTarget { readonly host: string; readonly port: number; readonly timeoutSeconds: number; } export interface ConnectivityResult { readonly success: boolean; readonly command: string; readonly result: CommandResult; } export interface MailboxUsageResult { readonly targetPath: string; readonly resolvedPath: string; readonly total: CommandResult; readonly breakdown?: CommandResult; } export class EmailService { public constructor(private readonly runner: CommandRunner) {} public async lookupMx(domain: string): Promise<MxLookupResult> { const command = `dig +short MX ${shellQuote(domain)}`; const result = await this.runner.run(command); const records = this.parseMxRecords(result.stdout); return { command, result, records }; } public async lookupTxt(record: string): Promise<TxtLookupResult> { const command = `dig +short TXT ${shellQuote(record)}`; const result = await this.runner.run(command); const values = this.parseTxtRecords(result.stdout); return { command, result, values }; } public async checkSpf(domain: string): Promise<TxtLookupResult> { return this.lookupTxt(domain); } public async checkDmarc(domain: string): Promise<TxtLookupResult> { return this.lookupTxt(`_dmarc.${domain}`); } public async checkDkim(domain: string, selector: string): Promise<TxtLookupResult> { return this.lookupTxt(`${selector}._domainkey.${domain}`); } public async testConnectivity(target: ConnectivityTarget): Promise<ConnectivityResult> { const timeout = Math.max(1, target.timeoutSeconds); const command = `nc -vz -G ${timeout} ${shellQuote(target.host)} ${target.port}`; try { const result = await this.runner.run(command); return { success: true, command, result }; } catch (error) { if (error instanceof CommandExecutionError) { return { success: false, command, result: error.result }; } throw error; } } public async checkMailboxUsage( targetPath: string, includeBreakdown: boolean, ): Promise<MailboxUsageResult> { const resolvedPath = this.resolvePath(targetPath); const normalizedPath = resolvedPath.replace(/\/+$/, ""); const totalCommand = `du -sh ${shellQuote(normalizedPath)}`; const total = await this.runner.run(totalCommand); let breakdown: CommandResult | undefined; if (includeBreakdown) { const breakdownCommand = `find ${shellQuote(normalizedPath)} -mindepth 1 -maxdepth 1 -type d -exec du -sh {} + | sort -h`; try { breakdown = await this.runner.run(breakdownCommand); } catch (error) { if (error instanceof CommandExecutionError) { breakdown = error.result; } else { throw error; } } } return { targetPath, resolvedPath: normalizedPath, total, breakdown, }; } private parseMxRecords(output: string): MxRecord[] { return output .split("\n") .map((line) => line.trim()) .filter(Boolean) .map((line) => { const [priorityStr, ...exchangeParts] = line.split(/\s+/); const priority = Number(priorityStr); const exchange = exchangeParts.join(" ").replace(/\.$/, ""); return { priority: Number.isFinite(priority) ? priority : 0, exchange, raw: line, }; }); } private parseTxtRecords(output: string): string[] { return output .split("\n") .map((line) => line.trim()) .filter(Boolean) .map((line) => line .replace(/^"|"$/g, "") .replace(/" "/g, "") .replace(/\s+/g, " "), ); } private resolvePath(input: string): string { if (input.startsWith("~")) { const home = process.env.HOME; if (home) { return input.replace(/^~(?=$|\/)/, home); } } return input; } }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/acampkin95/MCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server