Skip to main content
Glama
security-limits.ts5.58 kB
/** * Security configuration for request size limits and DoS protection * * These limits help prevent denial-of-service attacks by restricting * the size of batch operations and request payloads. */ /** * Maximum sizes for batch operations by resource type * These limits prevent memory exhaustion and API overload */ export const BATCH_SIZE_LIMITS = { // Universal batch limits DEFAULT: parseInt(process.env.MAX_BATCH_SIZE || '100', 10), // Resource-specific limits (can be more restrictive) COMPANIES: parseInt(process.env.MAX_BATCH_SIZE_COMPANIES || '100', 10), PEOPLE: parseInt(process.env.MAX_BATCH_SIZE_PEOPLE || '100', 10), RECORDS: parseInt(process.env.MAX_BATCH_SIZE_RECORDS || '100', 10), TASKS: parseInt(process.env.MAX_BATCH_SIZE_TASKS || '50', 10), NOTES: parseInt(process.env.MAX_BATCH_SIZE_NOTES || '50', 10), LISTS: parseInt(process.env.MAX_BATCH_SIZE_LISTS || '100', 10), // Search operations (may return many results) SEARCH: parseInt(process.env.MAX_BATCH_SIZE_SEARCH || '50', 10), // Bulk delete operations (more restrictive for safety) DELETE: parseInt(process.env.MAX_BATCH_SIZE_DELETE || '50', 10), } as const; /** * Maximum payload sizes for different operation types * Prevents excessively large requests that could cause memory issues */ export const PAYLOAD_SIZE_LIMITS = { // Maximum size of a single record's data in bytes SINGLE_RECORD: parseInt(process.env.MAX_RECORD_SIZE || '1048576', 10), // 1MB default // Maximum total payload size for batch operations in bytes BATCH_TOTAL: parseInt(process.env.MAX_BATCH_PAYLOAD || '10485760', 10), // 10MB default // Maximum size for search query strings SEARCH_QUERY: parseInt(process.env.MAX_SEARCH_QUERY_SIZE || '1024', 10), // 1KB default // Maximum size for filter objects FILTER_OBJECT: parseInt(process.env.MAX_FILTER_SIZE || '10240', 10), // 10KB default } as const; /** * Rate limiting configuration for batch operations * Helps prevent API rate limit violations and ensures fair usage */ export const RATE_LIMITS = { // Maximum concurrent batch requests MAX_CONCURRENT_REQUESTS: parseInt( process.env.MAX_CONCURRENT_BATCH_REQUESTS || '5', 10 ), // Delay between batch chunks in milliseconds BATCH_DELAY_MS: parseInt(process.env.BATCH_DELAY_MS || '100', 10), // Maximum requests per minute for batch operations MAX_BATCH_REQUESTS_PER_MINUTE: parseInt( process.env.MAX_BATCH_RPM || '60', 10 ), } as const; /** * Validation messages for limit violations */ export const LIMIT_ERROR_MESSAGES = { BATCH_SIZE_EXCEEDED: (size: number, limit: number, operation?: string) => `Batch size (${size}) exceeds maximum allowed (${limit})${ operation ? ` for ${operation}` : '' }. ` + `Please split into smaller batches for security and performance.`, PAYLOAD_SIZE_EXCEEDED: (size: number, limit: number) => `Request payload size (${formatBytes( size )}) exceeds maximum allowed (${formatBytes(limit)}). ` + `Please reduce the amount of data in your request.`, SINGLE_RECORD_SIZE_EXCEEDED: (size: number, limit: number) => `Single record size (${formatBytes( size )}) exceeds maximum allowed (${formatBytes(limit)}). ` + `Please reduce the amount of data in this record.`, SEARCH_QUERY_TOO_LONG: (length: number, limit: number) => `Search query length (${length} characters) exceeds maximum allowed (${limit} characters). ` + `Please use a shorter search query.`, FILTER_TOO_COMPLEX: (size: number, limit: number) => `Filter object size (${formatBytes( size )}) exceeds maximum allowed (${formatBytes(limit)}). ` + `Please simplify your filter criteria.`, RATE_LIMIT_EXCEEDED: (requests: number, limit: number) => `Request rate (${requests} requests) exceeds maximum allowed (${limit} per minute). ` + `Please slow down your requests or use smaller batches.`, } as const; /** * Helper function to format bytes for human-readable error messages */ function formatBytes(bytes: number): string { if (bytes < 1024) return `${bytes} bytes`; if (bytes < 1048576) return `${(bytes / 1024).toFixed(1)} KB`; return `${(bytes / 1048576).toFixed(1)} MB`; } /** * Get the batch size limit for a specific resource type */ export function getBatchSizeLimit(resourceType?: string): number { if (!resourceType) return BATCH_SIZE_LIMITS.DEFAULT; const upperType = resourceType.toUpperCase(); return ( (BATCH_SIZE_LIMITS as Record<string, number>)[upperType] || BATCH_SIZE_LIMITS.DEFAULT ); } /** * Configuration validation on module load */ function validateConfiguration(): void { // Ensure all limits are positive numbers for (const [key, value] of Object.entries(BATCH_SIZE_LIMITS)) { if (value <= 0 || isNaN(value)) { throw new Error(`Invalid batch size limit for ${key}: ${value}`); } } for (const [key, value] of Object.entries(PAYLOAD_SIZE_LIMITS)) { if (value <= 0 || isNaN(value)) { throw new Error(`Invalid payload size limit for ${key}: ${value}`); } } for (const [key, value] of Object.entries(RATE_LIMITS)) { if (value <= 0 || isNaN(value)) { throw new Error(`Invalid rate limit for ${key}: ${value}`); } } } // Validate configuration on module load validateConfiguration(); /** * Export type definitions for use in other modules */ export type BatchSizeLimitKey = keyof typeof BATCH_SIZE_LIMITS; export type PayloadSizeLimitKey = keyof typeof PAYLOAD_SIZE_LIMITS; export type RateLimitKey = keyof typeof RATE_LIMITS;

Latest Blog Posts

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/kesslerio/attio-mcp-server'

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