wyreup-mcp
Version:
Production-ready MCP server that transforms automation platform webhooks into reliable, agent-callable tools
105 lines (89 loc) • 2.87 kB
JavaScript
import chalk from 'chalk'
/**
* Simple in-memory rate limiter for webhook tools
* Production systems should use Redis or similar for distributed rate limiting
*/
class RateLimiter {
constructor() {
this.windows = new Map()
}
/**
* Check if request is within rate limit
* @param {string} toolName - Tool identifier
* @param {Object} config - Rate limit config {requests: number, window: number}
* @param {boolean} DEBUG - Debug logging
* @returns {boolean} - True if request is allowed
*/
isAllowed(toolName, config, DEBUG = false) {
if (!config || !config.requests || !config.window) {
return true // No rate limiting configured
}
const now = Date.now()
const windowStart = now - config.window
// Get or create window for this tool
if (!this.windows.has(toolName)) {
this.windows.set(toolName, [])
}
const requests = this.windows.get(toolName)
// Clean old requests outside the window
const validRequests = requests.filter(timestamp => timestamp > windowStart)
this.windows.set(toolName, validRequests)
// Check if we're within limits
if (validRequests.length >= config.requests) {
if (DEBUG) {
console.warn(
chalk.yellowBright(
`[DEBUG] Rate limit exceeded for ${toolName}: ${validRequests.length}/${config.requests} requests in ${config.window}ms window`
)
)
}
return false
}
// Add current request
validRequests.push(now)
this.windows.set(toolName, validRequests)
if (DEBUG) {
console.log(
chalk.blueBright(
`[DEBUG] Rate limit check for ${toolName}: ${validRequests.length}/${config.requests} requests`
)
)
}
return true
}
/**
* Get rate limit status for a tool
* @param {string} toolName - Tool identifier
* @param {Object} config - Rate limit config
* @returns {Object} - Status object with current usage
*/
getStatus(toolName, config) {
if (!config || !this.windows.has(toolName)) {
return { requests: 0, limit: config?.requests || 0, resetTime: null }
}
const now = Date.now()
const windowStart = now - config.window
const requests = this.windows.get(toolName)
const validRequests = requests.filter(timestamp => timestamp > windowStart)
return {
requests: validRequests.length,
limit: config.requests,
resetTime: validRequests.length > 0 ? validRequests[0] + config.window : null
}
}
/**
* Clear rate limiting data for a tool
* @param {string} toolName - Tool identifier
*/
clear(toolName) {
this.windows.delete(toolName)
}
/**
* Clear all rate limiting data
*/
clearAll() {
this.windows.clear()
}
}
// Export singleton instance
export const rateLimiter = new RateLimiter()