67
Total
4
Critical
28
High
35
Medium
Findings
unknownEnvironment file access
Detected by automated pattern matching (rule DE-002) with medium confidence. May be a false positive.
1195: async function main() {
1196: const email = cliOptions.email || process.env.UPSTASH_EMAIL;
>>> 1197: const apiKey = cliOptions.apiKey || process.env.UPSTASH_API_KEY;
1198: if (!email || !apiKey) {
1199: console.error(Report false positiveEnvironment file access
Detected by automated pattern matching (rule DE-002) with medium confidence. May be a false positive.
1194: })();
1195: async function main() {
>>> 1196: const email = cliOptions.email || process.env.UPSTASH_EMAIL;
1197: const apiKey = cliOptions.apiKey || process.env.UPSTASH_API_KEY;
1198: if (!email || !apiKey) {Report false positiveEnvironment file access
Detected by automated pattern matching (rule DE-002) with medium confidence. May be a false positive.
179: This will continuously build the project and watch for changes.
180:
>>> 181: For testing, you can create a `.env` file in the same directory as the project with the following content:
182:
183: ```bashReport false positiveEnvironment file access
Detected by automated pattern matching (rule DE-002) with medium confidence. May be a false positive.
>>> 1: {"version":3,"sources":["../src/index.ts","../src/server.ts","../src/log.ts","../src/tools/utils.ts","../src/tools/redis/backup.ts","../src/config.ts","../src/middlewares.ts","../src/http.ts","../src/tools/redis/command.ts","../src/tools/redis/db.ts","../src/utils.ts","../src/tools/redis/index.ts","../src/tools/qstash/qstash.ts","../src/tools/qstash/utils.ts","../src/tools/qstash/workflow.ts","../src/tools/qstash/index.ts","../src/tools/index.ts","../src/settings.ts","../src/tool.ts","../src/test-connection.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { StreamableHTTPServerTransport } from \"@modelcontextprotocol/sdk/server/streamableHttp.js\";\nimport { Command } from \"commander\";\n// eslint-disable-next-line unicorn/prefer-node-protocol\nimport { createServer, type IncomingMessage } from \"http\";\nimport { createServerInstance } from \"./server.js\";\nimport { config } from \"./config\";\nimport { testConnection } from \"./test-connection\";\nimport \"dotenv/config\";\n\n/**\n * Last version of the MCP server required \"run\" command to be used.\n * This is a backwards compatibility fix to allow the MCP server to be used with the old command.\n */\n\n// Handle legacy 'run' command format before parsing\nlet argv = process.argv.slice(2);\n\n// Check for legacy format and transform it to the new format\nif (argv.length >= 3 && argv[0] === \"run\") {\n argv = [\"--email\", argv[1], \"--api-key\", argv[2], ...argv.slice(3)];\n}\n\nconst program = new Command()\n .option(\"--transport <stdio|http>\", \"transport type\", \"stdio\")\n .option(\"--port <number>\", \"port for HTTP transport\", \"3000\")\n .option(\"--email <email>\", \"Upstash email\")\n .option(\"--api-key <key>\", \"Upstash API key\")\n .option(\"--debug\", \"Enable debug mode\")\n .allowUnknownOption(); // let other wrappers pass through extra flags\n\nprogram.parse(argv, { from: \"user\" });\n\nconst cliOptions = program.opts<{\n transport: string;\n port: string;\n email?: string;\n apiKey?: string;\n debug?: boolean;\n}>();\n\nexport const DEBUG = cliOptions.debug ?? false;\n\n// Validate transport option\nconst allowedTransports = [\"stdio\", \"http\"];\nif (!allowedTransports.includes(cliOptions.transport)) {\n console.error(\n `Invalid --transport value: '${cliOptions.transport}'. Must be one of: stdio, http.`\n );\n process.exit(1);\n}\n\n// Transport configuration\nconst TRANSPORT_TYPE = (cliOptions.transport || \"stdio\") as \"stdio\" | \"http\";\n\n// Disallow incompatible flags based on transport\nconst passedPortFlag = process.argv.includes(\"--port\");\n\nif (TRANSPORT_TYPE === \"stdio\" && passedPortFlag) {\n console.error(\"The --port flag is not allowed when using --transport stdio.\");\n process.exit(1);\n}\n\n// HTTP port configuration\nconst CLI_PORT = (() => {\n const parsed = Number.parseInt(cliOptions.port, 10);\n return Number.isNaN(parsed) ? undefined : parsed;\n})();\n\nasync function main() {\n // Get credentials from CLI options or environment\n const email = cliOptions.email || process.env.UPSTASH_EMAIL;\n const apiKey = cliOptions.apiKey || process.env.UPSTASH_API_KEY;\n\n if (!email || !apiKey) {\n console.error(\n \"Missing required credentials. Provide --email and --api-key or set UPSTASH_EMAIL and UPSTASH_API_KEY environment variables.\"\n );\n process.exit(1);\n }\n\n // Set config\n config.email = email;\n config.apiKey = apiKey;\n\n // Test connection\n await testConnection();\n\n const transportType = TRANSPORT_TYPE;\n\n if (transportType === \"http\") {\n // Get initial port from environment or use default\n const initialPort = CLI_PORT ?? 3000;\n // Keep track of which port we end up using\n let actualPort = initialPort;\n const httpServer = createServer(async (req: IncomingMessage, res: any) => {\n const pathname = new (globalThis as any).URL(req.url || \"\", `http://${req.headers.host}`)\n .pathname;\n\n // Set CORS headers for all responses\n res.setHeader(\"Access-Control-Allow-Origin\", \"*\");\n res.setHeader(\"Access-Control-Allow-Methods\", \"GET,POST,OPTIONS,DELETE\");\n res.setHeader(\n \"Access-Control-Allow-Headers\",\n \"Content-Type, MCP-Session-Id, MCP-Protocol-Version, X-Upstash-API-Key, Upstash-API-Key, X-API-Key, Authorization\"\n );\n res.setHeader(\"Access-Control-Expose-Headers\", \"MCP-Session-Id\");\n\n // Handle preflight OPTIONS requests\n if (req.method === \"OPTIONS\") {\n res.writeHead(200);\n res.end();\n return;\n }\n\n try {\n // Create new server instance for each request\n const requestServer = createServerInstance();\n\n if (pathname === \"/mcp\") {\n const transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: undefined,\n });\n await requestServer.connect(transport);\n await transport.handleRequest(req, res);\n } else if (pathname === \"/ping\") {\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ status: \"ok\", message: \"pong\" }));\n } else {\n res.writeHead(404, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: \"Not found\", status: 404 }));\n }\n } catch (error) {\n console.error(\"Error handling request:\", error);\n if (!res.headersSent) {\n res.writeHead(500);\n res.end(\"Internal Server Error\");\n }\n }\n });\n\n // Function to attempt server listen with port fallback\n const startServer = (port: number, maxAttempts = 10) => {\n httpServer.once(\"error\", (err: NodeJS.ErrnoException) => {\n if (err.code === \"EADDRINUSE\" && port < initialPort + maxAttempts) {\n console.warn(`Port ${port} is in use, trying port ${port + 1}...`);\n startServer(port + 1, maxAttempts);\n } else {\n console.error(`Failed to start server: ${err.message}`);\n process.exit(1);\n }\n });\n\n httpServer.listen(port, () => {\n actualPort = port;\n console.error(\n `Upstash MCP Server running on ${transportType.toUpperCase()} at http://localhost:${actualPort}/mcp`\n );\n });\n };\n\n // Start the server with initial port\n startServer(initialPort);\n } else {\n // Stdio transport - this is already stateless by nature\n const server = createServerInstance();\n const transport = new StdioServerTransport();\n\n // Log the RCP messages coming to the transport\n // const originalOnmessage = transport.onmessage;\n // transport.onmessage = (message) => {\n // console.error(\"message\", message);\n\n // originalOnmessage?.(message);\n // };\n\n await server.connect(transport);\n console.error(\"Upstash MCP Server running on stdio\");\n }\n}\n\n// eslint-disable-next-line unicorn/prefer-top-level-await\nmain().catch((error) => {\n console.error(\"Fatal error in main():\", error);\n process.exit(1);\n});\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { log } from \"./log\";\nimport { tools } from \"./tools\";\nimport { handlerResponseToCallResult } from \"./tool\";\nimport z from \"zod\";\nimport { DEBUG } from \".\";\n\n// Function to create a new server instance with all tools registered\nexport function createServerInstance() {\n const server = new McpServer(\n { name: \"upstash\", version: \"0.1.0\" },\n {\n capabilities: {\n tools: {},\n logging: {},\n },\n }\n );\n\n const toolsList = Object.entries(tools).map(([name, tool]) => ({\n name,\n description: tool.description,\n inputSchema: tool.inputSchema,\n tool,\n }));\n\n // Register all tools from the toolsList\n for (const toolDef of toolsList) {\n const toolName = toolDef.name;\n const tool = toolDef.tool;\n\n server.registerTool(\n toolName,\n {\n description: tool.description,\n inputSchema: ((tool.inputSchema ?? z.object({})) as any).shape,\n },\n // @ts-expect-error - Just ignore the types here\n async (args) => {\n log(\"< received tool call:\", toolName, args);\n\n try {\n const result = await tool.handler(args);\n const response = handlerResponseToCallResult(result);\n log(\"> tool result:\", response.content.map((item) => item.text).join(\"\\n\"));\n return response;\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n log(\"> error in tool call:\", msg);\n return {\n content: [\n {\n type: \"text\",\n text: `${error instanceof Error ? error.name : \"Error\"}: ${msg}`,\n },\n ...(DEBUG\n ? [\n {\n type: \"text\",\n text: `\\nStack trace: ${error instanceof Error ? error.stack : \"No stack trace available\"}`,\n },\n ]\n : []),\n ],\n isError: true,\n };\n }\n }\n );\n }\n\n return server;\n}\n","export function log(...args: unknown[]) {\n const msg = `[DEBUG ${new Date().toISOString()}] ${args.map((arg) => (typeof arg === \"string\" ? arg : JSON.stringify(arg))).join(\" \")}\\n`;\n\n for (const [, logs] of logsStore.entries()) {\n logs.push(msg);\n }\n\n process.stderr.write(msg);\n}\n\nconst logsStore = new Map<string, string[]>();\n\nexport function startCollectLogs() {\n const id = Array.from({ length: 10 })\n .fill(0)\n .map(() => Math.random().toString(36).slice(2, 15))\n .join(\"\");\n\n logsStore.set(id, []);\n\n return id;\n}\n\nexport function popLogs(id: string) {\n const logs = logsStore.get(id);\n\n if (!logs) {\n return [];\n }\n\n logsStore.delete(id);\n\n return logs;\n}\n","import { z } from \"zod\";\nimport { tool } from \".\";\n\nexport const utilTools = {\n util_timestamps_to_date: tool({\n description: `Use this tool to convert a timestamp to a human-readable date`,\n inputSchema: z.object({\n timestamps: z.array(z.number()).describe(\"Array of timestamps to convert\"),\n }),\n handler: async ({ timestamps }) => {\n return timestamps.map((timestamp) => new Date(timestamp).toUTCString());\n },\n }),\n util_dates_to_timestamps: tool({\n description: `Use this tool to convert an array of ISO 8601 dates to an array of timestamps`,\n inputSchema: z.object({\n dates: z.array(z.string()).describe(\"Array of dates to convert\"),\n }),\n handler: async ({ dates }) => {\n return dates.map((date) => new Date(date).getTime()).join(\",\");\n },\n }),\n};\n","import { z } from \"zod\";\nimport { json, tool } from \"..\";\nimport { http } from \"../../http\";\nimport type { RedisBackup } from \"./types\";\n\nexport const redisBackupTools = {\n redis_database_manage_backup: tool({\n description: `Create, delete, or restore backups for a specific Upstash redis database. This tool handles all backup operations in one unified interface.`,\n inputSchema: z.object({\n database_id: z.string().describe(\"The ID of the database to manage backups for.\"),\n operation: z\n .union([z.literal(\"create\"), z.literal(\"delete\"), z.literal(\"restore\")])\n .describe(\"The backup operation to perform: create, delete, or restore.\"),\n backup_name: z\n .string()\n .optional()\n .describe(\"Name for the backup (required for create operation).\"),\n backup_id: z\n .string()\n .optional()\n .describe(\"ID of the backup (required for delete and restore operations).\"),\n }),\n handler: async ({ database_id, operation, backup_name, backup_id }) => {\n switch (operation) {\n case \"create\": {\n if (!backup_name) {\n throw new Error(\"backup_name is required for create operation\");\n }\n await http.post([\"v2/redis/create-backup\", database_id], {\n name: backup_name,\n });\n return `Backup \"${backup_name}\" created successfully for database ${database_id}.`;\n }\n\n case \"delete\": {\n if (!backup_id) {\n throw new Error(\"backup_id is required for delete operation\");\n }\n await http.delete([\"v2/redis/delete-backup\", database_id, backup_id]);\n return `Backup ${backup_id} deleted successfully from database ${database_id}.`;\n }\n\n case \"restore\": {\n if (!backup_id) {\n throw new Error(\"backup_id is required for restore operation\");\n }\n await http.post([\"v2/redis/restore-backup\", database_id], {\n backup_id,\n });\n return `Backup ${backup_id} restored successfully to database ${database_id}.`;\n }\n\n default: {\n throw new Error(`Invalid operation: ${operation}. Use create, delete, or restore.`);\n }\n }\n },\n }),\n\n redis_database_list_backups: tool({\n // TODO: Add explanation for fields\n // TODO: Is this in bytes?\n description: `List all backups of a specific Upstash redis database.`,\n inputSchema: z.object({\n database_id: z.string().describe(\"The ID of the database to list backups for.\"),\n }),\n handler: async ({ database_id }) => {\n const backups = await http.get<RedisBackup[]>([\"v2/redis/list-backup\", database_id]);\n\n return json(backups);\n },\n }),\n\n redis_database_set_daily_backup: tool({\n description: `Enable or disable daily backups for a specific Upstash redis database.`,\n inputSchema: z.object({\n database_id: z\n .string()\n .describe(\"The ID of the database to enable or disable daily backups for.\"),\n enable: z.boolean().describe(\"Whether to enable or disable daily backups.\"),\n }),\n handler: async ({ database_id, enable }) => {\n await http.patch([\n `v2/redis/${enable ? \"enable-dailybackup\" : \"disable-dailybackup\"}`,\n database_id,\n ]);\n\n return \"OK\";\n },\n }),\n};\n","export const config = {\n apiKey: \"\",\n email: \"\",\n};\n","import type { UpstashRequest } from \"./http\";\n\ntype Middleware = (req: UpstashRequest, next: () => Promise<unknown>) => Promise<unknown>;\n\nconst formatTimestamps = (obj: unknown): void => {\n if (!obj || typeof obj !== \"object\") {\n return;\n }\n\n // Handle arrays\n if (Array.isArray(obj)) {\n for (const item of obj) {\n formatTimestamps(item);\n }\n return;\n }\n\n // Handle objects\n for (const [key, value] of Object.entries(obj)) {\n // Check if key matches our criteria: contains \"creationTime\" or has \"createdAt\" anywhere (case-insensitive)\n const shouldFormat =\n typeof value === \"number\" &&\n (key === \"creationTime\" ||\n key === \"creation_time\" ||\n key === \"time\" ||\n key.toLowerCase().includes(\"createdat\"));\n\n if (shouldFormat && typeof value === \"number\" && value > 0) {\n // Format timestamp to human readable format\n // Assume timestamps > 1_000_000_000_000 are in milliseconds, otherwise seconds\n const timestamp = value > 1_000_000_000_000 ? value : value * 1000;\n\n // Show milliseconds in the human readable format\n\n const formatted = new Date(timestamp).toLocaleString(\"en-US\", { timeZoneName: \"short\" });\n (obj as any)[key] = `${formatted} (${value})`;\n } else if (value && typeof value === \"object\") {\n // Recursively process nested objects\n formatTimestamps(value);\n }\n }\n};\n\nconst middlewares: Middleware[] = [\n // Middleware to format timestamp fields to human readable format\n async (req, next) => {\n const res = await next();\n formatTimestamps(res);\n return res;\n },\n];\n\nexport const applyMiddlewares = async (\n req: UpstashRequest,\n func: (req: UpstashRequest) => Promise<unknown>\n) => {\n let next = async () => func(req);\n for (const middleware of middlewares.reverse()) {\n const prevNext = next;\n next = async () => middleware(req, prevNext);\n }\n return next();\n};\n","import { config } from \"./config\";\nimport { log } from \"./log\";\nimport { applyMiddlewares } from \"./middlewares\";\nimport type { RequestInit } from \"node-fetch\";\nimport fetch from \"node-fetch\";\nimport { json } from \"./tools\";\n\nexport type UpstashRequest = {\n method: string;\n path?: string[] | string;\n /**\n * Request body will be serialized to json\n */\n body?: unknown;\n /**\n * Query parameters, object and undefined will be ignored\n */\n query?: Record<string, string | number | boolean | undefined | object>;\n /**\n * Custom headers\n */\n headers?: Record<string, string>;\n /**\n * Optional QStash token - if provided, will use Bearer auth instead of Basic auth\n */\n qstashToken?: string;\n};\n\nexport type HttpClientConfig = {\n baseUrl: string;\n /**\n * Optional QStash token for Bearer authentication\n */\n qstashToken?: string;\n};\n\nexport class HttpClient {\n private readonly baseUrl: string;\n private readonly qstashToken?: string;\n\n public constructor(config: HttpClientConfig) {\n this.baseUrl = config.baseUrl.replace(/\\/$/, \"\");\n this.qstashToken = config.qstashToken;\n }\n\n public async get<TResponse>(\n path: string[] | string,\n query?: Record<string, string | number | boolean | undefined | object>\n ): Promise<TResponse> {\n return this.requestWithMiddleware<TResponse>({ method: \"GET\", path, query });\n }\n\n public async post<TResponse>(\n path: string[] | string,\n body?: unknown,\n headers?: Record<string, string>\n ): Promise<TResponse> {\n return this.requestWithMiddleware<TResponse>({ method: \"POST\", path, body, headers });\n }\n\n public async put<TResponse>(\n path: string[] | string,\n body?: unknown,\n headers?: Record<string, string>\n ): Promise<TResponse> {\n return this.requestWithMiddleware<TResponse>({ method: \"PUT\", path, body, headers });\n }\n\n public async patch<TResponse>(path: string[] | string, body?: unknown): Promise<TResponse> {\n return this.requestWithMiddleware<TResponse>({ method: \"PATCH\", path, body });\n }\n\n public async delete<TResponse>(path: string[] | string, body?: unknown): Promise<TResponse> {\n return this.requestWithMiddleware<TResponse>({ method: \"DELETE\", path, body });\n }\n\n private async requestWithMiddleware<TResponse>(req: UpstashRequest): Promise<TResponse> {\n const res = await applyMiddlewares(req, async (req) => {\n return this.request<TResponse>(req);\n });\n\n return res as TResponse;\n }\n\n private async request<TResponse>(req: UpstashRequest): Promise<TResponse> {\n if (!req.path) {\n req.path = [];\n } else if (typeof req.path === \"string\") {\n req.path = [req.path];\n }\n\n let url = [this.baseUrl, ...req.path].join(\"/\");\n\n // Add query parameters\n if (req.query) {\n const queryPairs: string[] = [];\n for (const [key, value] of Object.entries(req.query)) {\n if (value !== undefined && value !== null && typeof value !== \"object\") {\n queryPairs.push(`${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`);\n }\n }\n if (queryPairs.length > 0) {\n url += `?${queryPairs.join(\"&\")}`;\n }\n }\n\n // Determine authentication method\n const qstashToken = req.qstashToken || this.qstashToken;\n let authHeader: string;\n\n if (qstashToken) {\n authHeader = `Bearer ${qstashToken}`;\n } else {\n const token = [config.email, config.apiKey].join(\":\");\n authHeader = `Basic ${Buffer.from(token).toString(\"base64\")}`;\n }\n\n const init: RequestInit = {\n method: req.method,\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: authHeader,\n ...req.headers,\n },\n };\n\n if (req.method !== \"GET\" && req.body !== undefined) {\n init.body = JSON.stringify(req.body);\n }\n\n log(\"-> sending request\", {\n url,\n ...init,\n headers: {\n ...init.headers,\n Authorization: \"***\",\n },\n });\n\n // fetch is defined by isomorphic fetch\n const res = await fetch(url, init);\n if (!res.ok) {\n throw new Error(`Request failed (${res.status} ${res.statusText}): ${await res.text()}`);\n }\n\n // Handle empty responses\n const text = await res.text();\n if (!text) {\n return {} as TResponse;\n }\n\n const result = safeParseJson(text) as TResponse;\n\n if (result) {\n log(\"<- received response\", json(result));\n } else {\n log(\"<- received text response\", text);\n }\n\n return result || (text as TResponse);\n }\n}\n\nconst safeParseJson = <TResponse>(text: string) => {\n try {\n return JSON.parse(text) as TResponse;\n } catch {\n return;\n }\n};\n\nexport const http = new HttpClient({ baseUrl: \"https://api.upstash.com\" });\n\n/**\n * Creates a QStash-enabled HttpClient with the provided token\n */\nexport function createQStashClient({ url, token }: { url?: string; token: string }): HttpClient {\n return new HttpClient({\n baseUrl: url ?? \"https://qstash.upstash.io\",\n qstashToken: token,\n });\n}\n","import { z } from \"zod\";\nimport { json, tool } from \"..\";\nimport { log } from \"../../log\";\nimport { http } from \"../../http\";\nimport type { RedisDatabase } from \"./types\";\nimport fetch from \"node-fetch\";\n\ntype RedisCommandResult =\n | {\n result: unknown;\n }\n | {\n error: string;\n };\n\nexport const redisCommandTools = {\n redis_database_run_redis_commands: tool({\n description: `Run one or more Redis commands on a specific Upstash redis database. Either provide database_id OR both database_rest_url and database_rest_token.\nNOTE: For discovery, use SCAN over KEYS. Use TYPE to get the type of a key.\nNOTE: SCAN cursor [MATCH pattern] [COUNT count] [TYPE type]\nNOTE: Multiple commands will be executed as a pipeline for better performance.`,\n inputSchema: z.object({\n database_id: z.string().optional().describe(\"The ID of the database to run commands on.\"),\n database_rest_url: z\n .string()\n .optional()\n .describe(\"The REST URL of the database. Example: https://***.upstash.io\"),\n database_rest_token: z.string().optional().describe(\"The REST token of the database.\"),\n commands: z\n .array(z.array(z.string()))\n .describe(\n \"The Redis commands to run. For single command: [['SET', 'foo', 'bar']], for multiple: [['SET', 'foo', 'bar'], ['GET', 'foo']]\"\n ),\n }),\n\n handler: async ({ database_id, database_rest_url, database_rest_token, commands }) => {\n if (database_id && (database_rest_url || database_rest_token)) {\n throw new Error(\n \"Either provide database_id OR both database_rest_url and database_rest_token\"\n );\n } else if (!database_id && (!database_rest_url || !database_rest_token)) {\n throw new Error(\n \"Either provide database_id OR both database_rest_url and database_rest_token\"\n );\n }\n\n let restUrl = database_rest_url;\n let restToken = database_rest_token;\n\n // If only database_id is provided, fetch the database details\n if (database_id && (!database_rest_url || !database_rest_token)) {\n log(\"Fetching database details for database_id:\", database_id);\n const db = await http.get<RedisDatabase>([\"v2/redis/database\", database_id]);\n restUrl = \"https://\" + db.endpoint;\n restToken = db.rest_token;\n }\n\n if (!restUrl || !restToken) {\n throw new Error(\"Could not determine REST URL and token for the database\");\n }\n const isSingleCommand = commands.length === 1;\n const url = isSingleCommand ? restUrl : restUrl + \"/pipeline\";\n const body = isSingleCommand ? JSON.stringify(commands[0]) : JSON.stringify(commands);\n\n const req = await fetch(url, {\n method: \"POST\",\n body,\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${restToken}`,\n },\n });\n\n if (isSingleCommand) {\n const result = (await req.json()) as RedisCommandResult;\n\n log(\"command result:\", result);\n\n if (\"error\" in result) {\n throw new Error(\"Redis error: \" + result.error);\n }\n\n const isScanCommand = commands[0][0].toLocaleLowerCase().includes(\"scan\");\n const messages = [json(result)];\n\n if (isScanCommand)\n messages.push(`NOTE: Use the returned cursor to get the next set of keys.\nNOTE: The result might be too large to be returned. If applicable, stop after the second SCAN command and ask the user if they want to continue.`);\n\n return messages;\n } else {\n const result = (await req.json()) as RedisCommandResult[];\n\n log(\"commands result:\", result);\n\n if (result.some((r) => \"error\" in r)) {\n throw new Error(\"Some commands in the pipeline resulted in an error:\\n\" + json(result));\n }\n\n return json(result);\n }\n },\n }),\n};\n","import { z } from \"zod\";\nimport { json, tool } from \"..\";\nimport { http } from \"../../http\";\nimport type { RedisDatabase, RedisUsageResponse, UsageData } from \"./types\";\nimport { pruneFalsy } from \"../../utils\";\n\nconst readRegionSchema = z.union([\n z.literal(\"us-east-1\"),\n z.literal(\"us-west-1\"),\n z.literal(\"us-west-2\"),\n z.literal(\"eu-west-1\"),\n z.literal(\"eu-central-1\"),\n z.literal(\"ap-southeast-1\"),\n z.literal(\"ap-southeast-2\"),\n z.literal(\"sa-east-1\"),\n]);\n\nconst GENERIC_DATABASE_NOTES =\n \"\\nNOTE: Don't show the database ID from the response to the user unless explicitly asked or needed.\\n\";\n\nexport const redisDbOpsTools = {\n redis_database_create_new: tool({\n description: `Create a new Upstash redis database. \nNOTE: Ask user for the region and name of the database.${GENERIC_DATABASE_NOTES}`,\n inputSchema: z.object({\n name: z.string().describe(\"Name of the database.\"),\n primary_region: readRegionSchema.describe(`Primary Region of the Global Database.`),\n read_regions: z\n .array(readRegionSchema)\n .optional()\n .describe(`Array of read regions of the db`),\n }),\n handler: async ({ name, primary_region, read_regions }) => {\n const newDb = await http.post<RedisDatabase>(\"v2/redis/database\", {\n name,\n region: \"global\",\n primary_region,\n read_regions,\n });\n\n return [\n json(newDb),\n `Upstash console url: https://console.upstash.com/redis/${newDb.database_id}`,\n ];\n },\n }),\n\n redis_database_delete: tool({\n description: `Delete an Upstash redis database.`,\n inputSchema: z.object({\n database_id: z.string().describe(\"The ID of the database to delete.\"),\n }),\n handler: async ({ database_id }) => {\n await http.delete([\"v2/redis/database\", database_id]);\n\n return \"Database deleted successfully.\";\n },\n }),\n\n redis_database_list_databases: tool({\n description: `List all Upstash redis databases. Only their names and ids.${GENERIC_DATABASE_NOTES}`,\n handler: async () => {\n const dbs = await http.get<RedisDatabase[]>(\"v2/redis/databases\");\n\n const messages = [\n json(\n dbs.map((db) => {\n const result = {\n database_id: db.database_id,\n database_name: db.database_name,\n state: db.state === \"active\" ? undefined : db.state,\n };\n return pruneFalsy(result);\n })\n ),\n ];\n\n if (dbs.length > 2)\n messages.push(\n `NOTE: If the user did not specify a database name for the next command, ask them to choose a database from the list.`\n );\n messages.push(\n \"NOTE: If the user wants to see dbs in another team, mention that they need to create a new management api key for that team and initialize MCP server with the newly created key.\"\n );\n\n return messages;\n },\n }),\n\n redis_database_get_details: tool({\n description: `Get further details of a specific Upstash redis database. Includes all details of the database including usage statistics.\ndb_disk_threshold: Total disk usage limit.\ndb_memory_threshold: Maximum memory usage.\ndb_daily_bandwidth_limit: Maximum daily network bandwidth usage.\ndb_request_limit: Total number of commands allowed.\nAll sizes are in bytes\n${GENERIC_DATABASE_NOTES}\n `,\n inputSchema: z.object({\n database_id: z.string().describe(\"The ID of the database to get details for.\"),\n }),\n handler: async ({ database_id }) => {\n const db = await http.get<RedisDatabase>([\"v2/redis/database\", database_id]);\n\n return json(db);\n },\n }),\n\n redis_database_update_regions: tool({\n description: `Update the read regions of an Upstash redis database.`,\n inputSchema: z.object({\n id: z.string().describe(\"The ID of your database.\"),\n read_regions: z\n .array(readRegionSchema)\n .describe(\n \"Array of the new read regions of the database. This will replace the old regions array. Available regions: us-east-1, us-west-1, us-west-2, eu-west-1, eu-central-1, ap-southeast-1, ap-southeast-2, sa-east-1\"\n ),\n }),\n handler: async ({ id, read_regions }) => {\n const updatedDb = await http.post<RedisDatabase>([\"v2/redis/update-regions\", id], {\n read_regions,\n });\n\n return json(updatedDb);\n },\n }),\n\n redis_database_reset_password: tool({\n description: `Reset the password of an Upstash redis database.`,\n inputSchema: z.object({\n id: z.string().describe(\"The ID of your database.\"),\n }),\n handler: async ({ id }) => {\n const updatedDb = await http.post<RedisDatabase>([\"v2/redis/reset-password\", id], {});\n\n return json(updatedDb);\n },\n }),\n\n redis_database_get_statistics: tool({\n description: `Get comprehensive usage statistics of an Upstash redis database. Returns both:\n1. PRECISE 5-day usage: Exact command count and bandwidth usage over the last 5 days\n2. SAMPLED period stats: Sampled statistics over a specified period (1h, 3h, 12h, 1d, 3d, 7d) for performance monitoring\n\nFor sampled stats, includes: read_latency_mean, write_latency_mean, keyspace, throughput (cmds/sec), diskusage\nNOTE: If user doesn't specify stat_type, defaults to \"throughput\" for sampled stats.\nNOTE: Ask user first if they want to see stats for each database separately or just for one.`,\n inputSchema: z.object({\n id: z.string().describe(\"The ID of your database.\"),\n period: z\n .union([\n z.literal(\"1h\"),\n z.literal(\"3h\"),\n z.literal(\"12h\"),\n z.literal(\"1d\"),\n z.literal(\"3d\"),\n z.literal(\"7d\"),\n ])\n .describe(\"The period for sampled stats.\"),\n stat_type: z\n .union([\n z.literal(\"read_latency_mean\"),\n z.literal(\"write_latency_mean\"),\n z.literal(\"keyspace\").describe(\"Number of keys in db\"),\n z\n .literal(\"throughput\")\n .describe(\"commands per second (sampled), calculate area for estimated count\"),\n z.literal(\"diskusage\").describe(\"Current disk usage in bytes\"),\n ])\n .optional()\n .describe(\"The type of sampled stat to get (defaults to 'throughput')\"),\n }),\n handler: async ({ id, period, stat_type }) => {\n const statType = stat_type || \"throughput\";\n const stats = await http.get<RedisUsageResponse>([\n \"v2/redis/stats\",\n `${id}?period=${period}`,\n ]);\n\n // Get the sampled stat\n const stat = stats[statType];\n if (!Array.isArray(stat))\n throw new Error(\n `Invalid stat_type provided: ${statType}. Valid keys are: ${Object.keys(stats).join(\", \")}`\n );\n\n // Return both 5-day precise stats and sampled stats\n return [\n json({\n // 5-day precise usage stats\n usage_last_5_days: {\n days: stats.days,\n command_usage: stats.dailyrequests,\n bandwidth_usage: stats.bandwidths,\n },\n // Sampled stats for the specified period and type\n sampled_stats: {\n period,\n stat_type: statType,\n data: parseUsageData(stat),\n },\n }),\n `NOTE: Times are calculated according to UTC+0`,\n `NOTE: Use the timestamps_to_date tool to parse timestamps if needed`,\n `NOTE: Don't try to plot multiple stats in the same chart`,\n ];\n },\n }),\n};\n\nconst parseUsageData = (data: UsageData) => {\n if (!data) return \"NO DATA\";\n if (!Array.isArray(data)) return \"INVALID DATA\";\n if (data.length === 0 || data.length === 1) return \"NO DATA\";\n const filteredData = data.filter((d) => d.x && d.y);\n return {\n start: filteredData[0].x,\n // last one can be null, so use the second last\n // eslint-disable-next-line unicorn/prefer-at\n end: filteredData[filteredData.length - 1]?.x,\n data: data.map((d) => [new Date(d.x).getTime(), d.y]),\n };\n};\n","export function pruneFalsy(obj: Record<string, any>) {\n return Object.fromEntries(Object.entries(obj).filter(([, value]) => value));\n}\n","import { utilTools } from \"../utils\";\nimport { redisBackupTools } from \"./backup\";\nimport { redisCommandTools } from \"./command\";\nimport { redisDbOpsTools } from \"./db\";\nimport type { CustomTool } from \"../../tool\";\n\nexport const redisTools: Record<string, CustomTool> = {\n ...redisDbOpsTools,\n ...redisBackupTools,\n ...redisCommandTools,\n ...utilTools,\n};\n","import { z } from \"zod\";\nimport { json, tool } from \"..\";\nimport { http } from \"../../http\";\nimport { createQStashClientWithToken } from \"./utils\";\nimport type {\n QStashUser,\n QStashLogsResponse,\n QStashDLQResponse,\n QStashDLQMessage,\n QStashSchedule,\n QStashScheduleCreateResponse,\n} from \"./types\";\n\nexport const qstashCreds = {\n qstash_creds: z.undefined(),\n // qstash_creds: z\n // .object({\n // url: z.string(),\n // token: z.string(),\n // })\n // .optional()\n // .describe(\n // \"Optional qstash credentials. Use for local qstash connections and external qstash deployments\"\n // ),\n};\n\n// First, we need to get the QStash token\nexport const qstashTools = {\n qstash_get_user_token: tool({\n description: `Get the QSTASH_TOKEN and QSTASH_URL of the current user. This\n is not needed for the mcp tools since the token is automatically fetched from\n the Upstash API for them.`,\n handler: async () => {\n const user = await http.get<QStashUser>(\"qstash/user\");\n return [json(user)];\n },\n }),\n\n qstash_publish_message: tool({\n description: `Publish a message to a destination URL using QStash. This\n sends an HTTP request to the specified destination via QStash's message\n queue. This can also be used to trigger a upstash workflow run.`,\n inputSchema: z.object({\n destination: z\n .string()\n .describe(\"The destination URL to send the message to (e.g., 'https://example.com')\"),\n body: z.string().optional().describe(\"Request body (JSON string or plain text)\"),\n method: z\n .enum([\"GET\", \"POST\", \"PUT\", \"DELETE\", \"PATCH\"])\n .optional()\n .describe(\"HTTP method (optional, defaults to POST)\")\n .default(\"POST\"),\n delay: z\n .string()\n .optional()\n .describe(\"Delay before message delivery (e.g., '10s', '5m', '1h')\"),\n retries: z.number().optional().describe(\"Number of retries on failure, default is 3\"),\n callback: z\n .string()\n .optional()\n .describe(\"Callback URL that will be called when the message is successfully delivered\"),\n failureCallback: z\n .string()\n .optional()\n .describe(\"Callback URL that will be called when the message is failed to deliver\"),\n timeout: z.string().optional().describe(\"Request timeout (e.g., '30s', '1h')\"),\n queueName: z\n .string()\n .optional()\n .describe(\n \"Queue name to use, you have to first create the queue in upstash. Prefer the flow control key instead\"\n ),\n flow_control: z\n .object({\n key: z\n .string()\n .describe(\"Unique identifier for grouping messages under same flow control rules\"),\n parallelism: z\n .number()\n .optional()\n .describe(\"Max concurrent active calls (default: unlimited)\"),\n rate: z.number().optional().describe(\"Max calls per period (default: unlimited)\"),\n period: z\n .string()\n .optional()\n .describe(\"Time window for rate limit (e.g., '1s', '1m', '1h', default: '1s')\"),\n })\n .optional()\n .describe(\"Flow control for rate limiting and parallelism management\"),\n\n extraHeaders: z.record(z.string()).optional().describe(\"Extra headers to add to the request\"),\n ...qstashCreds,\n }),\n handler: async ({\n destination,\n body,\n method,\n extraHeaders,\n delay,\n retries,\n callback,\n failureCallback,\n timeout,\n queueName,\n flow_control,\n qstash_creds,\n }) => {\n const client = await createQStashClientWithToken(qstash_creds);\n\n const requestHeaders: Record<string, string> = {};\n\n if (method) {\n requestHeaders[\"Upstash-Method\"] = method;\n }\n if (delay) {\n requestHeaders[\"Upstash-Delay\"] = delay;\n }\n if (retries !== undefined) {\n requestHeaders[\"Upstash-Retries\"] = retries.toString();\n }\n if (callback) {\n requestHeaders[\"Upstash-Callback\"] = callback;\n }\n if (failureCallback) {\n requestHeaders[\"Upstash-Failure-Callback\"] = failureCallback;\n }\n if (timeout) {\n requestHeaders[\"Upstash-Timeout\"] = timeout;\n }\n if (queueName) {\n requestHeaders[\"Upstash-Queue-Name\"] = queueName;\n }\n\n // Add flow control headers\n if (flow_control) {\n requestHeaders[\"Upstash-Flow-Control-Key\"] = flow_control.key;\n const value = [\n flow_control.parallelism === undefined\n ? undefined\n : `parallelism=${flow_control.parallelism}`,\n flow_control.rate === undefined ? undefined : `rate=${flow_control.rate}`,\n flow_control.period === undefined ? undefined : `period=${flow_control.period}`,\n ]\n .filter(Boolean)\n .join(\",\");\n requestHeaders[\"Upstash-Flow-Control-Value\"] = value;\n }\n\n // Add custom headers\n if (extraHeaders) {\n for (const [key, value] of Object.entries(extraHeaders)) {\n requestHeaders[key] = value;\n }\n }\n\n const response = await client.post<{ messageId: string }>(\n `v2/publish/${destination}`,\n body || {},\n requestHeaders\n );\n\n return [\n \"Message published successfully\",\n `Message ID: ${response.messageId}`,\n json(response),\n ];\n },\n }),\n\n qstash_logs_list: tool({\n description: `List QStash logs with optional filtering. Returns a paginated list of message logs without their bodies.`,\n inputSchema: z.object({\n cursor: z.string().optional().describe(\"Cursor for pagination\"),\n messageId: z.string().optional().describe(\"Filter logs by message ID\"),\n state: z\n .enum([\n \"CREATED\",\n \"ACTIVE\",\n \"RETRY\",\n \"ERROR\",\n \"IN_PROGRESS\",\n \"DELIVERED\",\n \"FAILED\",\n \"CANCEL_REQUESTED\",\n \"CANCELLED\",\n ])\n .optional()\n .describe(\"Filter logs by state\"),\n url: z.string().optional().describe(\"Filter logs by URL\"),\n topicName: z.string().optional().describe(\"Filter logs by topic name\"),\n scheduleId: z.string().optional().describe(\"Filter logs by schedule ID\"),\n queueName: z.string().optional().describe(\"Filter logs by queue name\"),\n fromDate: z\n .number()\n .optional()\n .describe(\"Filter logs from date (Unix timestamp in milliseconds)\"),\n toDate: z\n .number()\n .optional()\n .describe(\"Filter logs to date (Unix timestamp in milliseconds)\"),\n count: z.number().max(1000).optional().describe(\"Number of logs to return (max 1000)\"),\n ...qstashCreds,\n }),\n handler: async (params) => {\n const client = await createQStashClientWithToken(params.qstash_creds);\n\n const response = await client.get<QStashLogsResponse>(\"v2/logs\", {\n trimBody: 0,\n groupBy: \"messageId\",\n ...params,\n });\n const firstMessageFields = Object.fromEntries(\n Object.entries(response.messages[0] ?? {}).filter(\n ([key, _value]) => !key.toLocaleLowerCase().includes(\"headers\")\n )\n );\n\n const cleanedEvents = response.messages.map((message) => ({\n messageId: message.messageId,\n events: message.events.map((event) => ({\n state: event.state,\n time: event.time,\n })),\n }));\n\n return [\n `Found ${response.messages.length} log entries`,\n response.cursor ? `Pagination cursor: ${response.cursor}` : \"No more entries\",\n json({ ...firstMessageFields, events: cleanedEvents }),\n ];\n },\n }),\n\n qstash_logs_get: tool({\n description: `Get details of a single QStash log item by message ID without trimming the body.`,\n inputSchema: z.object({\n messageId: z.string().describe(\"The message ID to get details for\"),\n ...qstashCreds,\n }),\n handler: async ({ messageId, qstash_creds }) => {\n const client = await createQStashClientWithToken(qstash_creds);\n const response = await client.get<QStashLogsResponse>(\"v2/logs\", { messageId });\n\n if (response.messages.length === 0) {\n return \"No log entry found for the specified message ID\";\n }\n\n const logEntry = response.messages[0];\n return [`Log details for message ID: ${messageId}`, json(logEntry)];\n },\n }),\n\n qstash_dlq_list: tool({\n description: `List messages in the QStash Dead Letter Queue (DLQ) with optional filtering.`,\n inputSchema: z.object({\n cursor: z.string().optional().describe(\"Cursor for pagination\"),\n messageId: z.string().optional().describe(\"Filter DLQ messages by message ID\"),\n url: z.string().optional().describe(\"Filter DLQ messages by URL\"),\n topicName: z.string().optional().describe(\"Filter DLQ messages by topic name\"),\n scheduleId: z.string().optional().describe(\"Filter DLQ messages by schedule ID\"),\n queueName: z.string().optional().describe(\"Filter DLQ messages by queue name\"),\n fromDate: z.number().optional().describe(\"Filter from date (Unix timestamp in milliseconds)\"),\n toDate: z.number().optional().describe(\"Filter to date (Unix timestamp in milliseconds)\"),\n responseStatus: z.number().optional().describe(\"Filter by HTTP response status code\"),\n callerIp: z.string().optional().describe(\"Filter by IP address of the publisher\"),\n count: z.number().max(100).optional().describe(\"Number of messages to return (max 100)\"),\n ...qstashCreds,\n }),\n handler: async (params) => {\n const client = await createQStashClientWithToken(params.qstash_creds);\n\n const response = await client.get<QStashDLQResponse>(\"v2/dlq\", {\n trimBody: 0,\n ...params,\n });\n\n return [\n `Found ${response.messages.length} DLQ messages`,\n response.cursor ? `Pagination cursor: ${response.cursor}` : \"No more entries\",\n json(response.messages),\n ];\n },\n }),\n\n qstash_dlq_get: tool({\n description: `Get details of a single DLQ message by DLQ ID.`,\n inputSchema: z.object({\n dlqId: z.string().describe(\"The DLQ ID of the message to retrieve\"),\n ...qstashCreds,\n }),\n handler: async ({ dlqId, qstash_creds }) => {\n const client = await createQStashClientWithToken(qstash_creds);\n const message = await client.get<QStashDLQMessage>(`v2/dlq/${dlqId}`);\n\n return [`DLQ message details for ID: ${dlqId}`, json(message)];\n },\n }),\n\n qstash_schedules_list: tool({\n description: `List all QStash schedules.`,\n handler: async ({ qstash_creds }) => {\n const client = await createQStashClientWithToken(qstash_creds);\n const schedules = await client.get<QStashSchedule[]>(\"v2/schedules\");\n\n return [`Found ${schedules.length} schedules`, json(schedules)];\n },\n }),\n\n qstash_schedules_manage: tool({\n description: `Create, update, or manage QStash schedules. This tool handles create, update (by providing scheduleId), pause, resume, and delete operations in one unified interface.`,\n inputSchema: z.object({\n operation: z\n .enum([\"create\", \"update\", \"pause\", \"resume\", \"delete\"])\n .describe(\"The operation to perform\"),\n scheduleId: z\n .string()\n .optional()\n .describe(\"Schedule ID (required for update, pause, resume, delete operations)\"),\n destination: z\n .string()\n .optional()\n .describe(\"Destination URL or topic name (required for create/update)\"),\n cron: z.string().optional().describe(\"Cron expression (required for create/update)\"),\n method: z\n .enum([\"GET\", \"POST\", \"PUT\", \"DELETE\", \"PATCH\"])\n .optional()\n .describe(\"HTTP method (optional, defaults to POST)\"),\n headers: z.record(z.string()).optional().describe(\"Request headers as key-value pairs\"),\n body: z.string().optional().describe(\"Request body\"),\n delay: z\n .string()\n .optional()\n .describe(\"Delay before message delivery (e.g., '10s', '5m', '1h')\"),\n retries: z.number().optional().describe(\"Number of retries on failure\"),\n callback: z.string().optional().describe(\"Callback URL for successful delivery\"),\n failureCallback: z.string().optional().describe(\"Callback URL for failed delivery\"),\n timeout: z.string().optional().describe(\"Request timeout (e.g., '30s')\"),\n queueName: z.string().optional().describe(\"Queue name to use\"),\n ...qstashCreds,\n }),\n handler: async ({\n operation,\n scheduleId,\n destination,\n cron,\n method = \"POST\",\n headers,\n body,\n delay,\n retries,\n callback,\n failureCallback,\n timeout,\n queueName,\n qstash_creds,\n }) => {\n const client = await createQStashClientWithToken(qstash_creds);\n\n switch (operation) {\n case \"create\":\n case \"update\": {\n if (!destination || !cron) {\n throw new Error(\"destination and cron are required for create/update operations\");\n }\n\n const requestHeaders: Record<string, string> = {\n \"Upstash-Cron\": cron,\n };\n\n if (method !== \"POST\") {\n requestHeaders[\"Upstash-Method\"] = method;\n }\n if (delay) {\n requestHeaders[\"Upstash-Delay\"] = delay;\n }\n if (retries !== undefined) {\n requestHeaders[\"Upstash-Retries\"] = retries.toString();\n }\n if (callback) {\n requestHeaders[\"Upstash-Callback\"] = callback;\n }\n if (failureCallback) {\n requestHeaders[\"Upstash-Failure-Callback\"] = failureCallback;\n }\n if (timeout) {\n requestHeaders[\"Upstash-Timeout\"] = timeout;\n }\n if (queueName) {\n requestHeaders[\"Upstash-Queue-Name\"] = queueName;\n }\n if (scheduleId && operation === \"update\") {\n requestHeaders[\"Upstash-Schedule-Id\"] = scheduleId;\n }\n\n // Add custom headers\n if (headers) {\n for (const [key, value] of Object.entries(headers)) {\n requestHeaders[key] = value;\n }\n }\n\n const response = await client.post<QStashScheduleCreateResponse>(\n `v2/schedules/${destination}`,\n body || {},\n requestHeaders\n );\n\n return [\n operation === \"create\"\n ? \"Schedule created successfully\"\n : \"Schedule updated successfully\",\n `Schedule ID: ${response.scheduleId}`,\n json(response),\n ];\n }\n\n case \"pause\": {\n if (!scheduleId) {\n throw new Error(\"scheduleId is required for pause operation\");\n }\n\n await client.post(`v2/schedules/${scheduleId}/pause`);\n return `Schedule ${scheduleId} paused successfully`;\n }\n\n case \"resume\": {\n if (!scheduleId) {\n throw new Error(\"scheduleId is required for resume operation\");\n }\n\n await client.post(`v2/schedules/${scheduleId}/resume`);\n return `Schedule ${scheduleId} resumed successfully`;\n }\n\n case \"delete\": {\n if (!scheduleId) {\n throw new Error(\"scheduleId is required for delete operation\");\n }\n\n await client.delete(`v2/schedules/${scheduleId}`);\n return `Schedule ${scheduleId} deleted successfully`;\n }\n\n default: {\n throw new Error(`Unknown operation: ${operation}`);\n }\n }\n },\n }),\n};\n","import { http, createQStashClient, type HttpClient } from \"../../http\";\nimport type { QStashUser } from \"./types\";\n\nlet cachedToken: string | null = null;\nlet tokenExpiry: number = 0;\n\n/**\n * Gets the QStash token from the Upstash API\n * Caches the token for 1 hour to avoid unnecessary API calls\n */\nexport async function getQStashToken(): Promise<string> {\n const now = Date.now();\n\n // Return cached token if it's still valid (cached for 1 hour)\n if (cachedToken && now < tokenExpiry) {\n return cachedToken;\n }\n\n try {\n const user = await http.get<QStashUser>(\"qstash/user\");\n cachedToken = user.token;\n tokenExpiry = now + 60 * 60 * 1000; // Cache for 1 hour\n return user.token;\n } catch (error) {\n throw new Error(\n `Failed to get QStash token: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n}\n\n/**\n * Creates a QStash client with automatically fetched token\n */\nexport async function createQStashClientWithToken(\n creds: {\n url?: string;\n token?: string;\n } = {}\n): Promise<HttpClient> {\n if (!creds?.token) {\n creds.token = await getQStashToken();\n }\n return createQStashClient({\n url: creds?.url,\n token: creds?.token,\n });\n}\n\n/**\n * Clears the cached token (useful for testing or when token becomes invalid)\n */\nexport function clearTokenCache(): void {\n cachedToken = null;\n tokenExpiry = 0;\n}\n","import { z } from \"zod\";\nimport { json, tool } from \"..\";\nimport { createQStashClientWithToken } from \"./utils\";\nimport type { WorkflowLogsResponse, WorkflowDLQResponse, WorkflowDLQMessage } from \"./types\";\nimport { qstashCreds } from \"./qstash\";\n\nexport const workflowTools = {\n workflow_logs_list: tool({\n description: `List Upstash Workflow logs with optional filtering. Returns grouped workflow runs with their execution details.`,\n inputSchema: z.object({\n cursor: z.string().optional().describe(\"Cursor for pagination\"),\n workflowRunId: z.string().optional().describe(\"Filter by specific workflow run ID\"),\n count: z.number().optional().describe(\"Number of workflow runs to return\"),\n state: z\n .enum([\"RUN_STARTED\", \"RUN_SUCCESS\", \"RUN_FAILED\", \"RUN_CANCELED\"])\n .optional()\n .describe(\"Filter by workflow state\"),\n workflowUrl: z.string().optional().describe(\"Filter by workflow URL (exact match)\"),\n workflowCreatedAt: z\n .number()\n .optional()\n .describe(\"Filter by workflow creation timestamp (Unix timestamp)\"),\n ...qstashCreds,\n }),\n handler: async (params) => {\n const client = await createQStashClientWithToken(params.qstash_creds);\n\n const response = await client.get<WorkflowLogsResponse>(\"v2/workflows/events\", {\n trimBody: 0,\n groupBy: \"workflowRunId\",\n ...params,\n });\n\n const cleaned = response.runs.map((run) =>\n Object.fromEntries(Object.entries(run).filter(([key, _value]) => key !== \"steps\"))\n );\n\n return [\n `Found ${response.runs.length} workflow runs`,\n response.cursor ? `Pagination cursor: ${response.cursor}` : \"No more entries\",\n json({\n ...response,\n runs: cleaned,\n }),\n ];\n },\n }),\n\n workflow_logs_get: tool({\n description: `Get details of a single workflow run by workflow run ID. There\n could be multiple workflow runs with the same workflow run ID, so you can\n use the workflowCreatedAt to get the details of the specific workflow run.`,\n inputSchema: z.object({\n workflowRunId: z.string().describe(\"The workflow run ID to get details for\"),\n workflowCreatedAt: z\n .number()\n .optional()\n .describe(\"The workflow creation timestamp (Unix timestamp)\"),\n ...qstashCreds,\n }),\n handler: async (params) => {\n const client = await createQStashClientWithToken(params.qstash_creds);\n const response = await client.get<WorkflowLogsResponse>(\"v2/workflows/logs\", {\n ...params,\n });\n\n if (response.runs.length === 0) {\n return \"No workflow run found\";\n }\n\n const workflowRun = response.runs[0];\n return [\n `Workflow run details for ID: ${params.workflowRunId} created at: ${params.workflowCreatedAt}`,\n json(workflowRun),\n ];\n },\n }),\n\n workflow_dlq_list: tool({\n description: `List failed workflow runs in the Dead Letter Queue (DLQ) with optional filtering.`,\n inputSchema: z.object({\n cursor: z.string().optional().describe(\"Cursor for pagination\"),\n workflowRunId: z.string().optional().describe(\"Filter by workflow run ID\"),\n workflowUrl: z.string().optional().describe(\"Filter by workflow URL\"),\n fromDate: z.number().optional().describe(\"Filter from date (Unix timestamp in milliseconds)\"),\n toDate: z.number().optional().describe(\"Filter to date (Unix timestamp in milliseconds)\"),\n responseStatus: z.number().optional().describe(\"Filter by HTTP response status code\"),\n callerIP: z.string().optional().describe(\"Filter by IP address of the caller\"),\n failureCallbackState: z.string().optional().describe(\"Filter by failure callback state\"),\n count: z.number().optional().describe(\"Number of DLQ messages to return\"),\n ...qstashCreds,\n }),\n handler: async (params) => {\n const client = await createQStashClientWithToken(params.qstash_creds);\n\n const response = await client.get<WorkflowDLQResponse>(\"v2/workflows/dlq\", {\n ...params,\n trimBody: 0,\n });\n\n const cleaned = response.messages.map((message) =>\n Object.fromEntries(Object.entries(message).filter(([key]) => !key.includes(\"header\")))\n );\n\n return [\n `Found ${response.messages.length} failed workflow runs in DLQ`,\n response.cursor ? `Pagination cursor: ${response.cursor}` : \"No more entries\",\n json({\n ...response,\n messages: cleaned,\n }),\n ];\n },\n }),\n\n workflow_dlq_get: tool({\n description: `Get details of a single failed workflow run from the DLQ by DLQ ID.`,\n inputSchema: z.object({\n dlqId: z.string().describe(\"The DLQ ID of the failed workflow run to retrieve\"),\n ...qstashCreds,\n }),\n handler: async (params) => {\n const client = await createQStashClientWithToken(params.qstash_creds);\n const message = await client.get<WorkflowDLQMessage>(`v2/workflows/dlq/${params.dlqId}`);\n\n return [`Failed workflow run details for DLQ ID: ${params.dlqId}`, json(message)];\n },\n }),\n\n workflow_dlq_manage: tool({\n description: `Delete, restart, and resume failed workflow runs in the DLQ using only the DLQ ID.`,\n inputSchema: z.object({\n dlqId: z.string().describe(\"The DLQ ID of the failed workflow run\"),\n action: z\n .enum([\"delete\", \"restart\", \"resume\"])\n .describe(\n \"The action to perform: delete (remove from DLQ), restart (from beginning), or resume (from the failed step)\"\n ),\n ...qstashCreds,\n }),\n handler: async ({ dlqId, action, qstash_creds }) => {\n const client = await createQStashClientWithToken(qstash_creds);\n\n switch (action) {\n case \"delete\": {\n await client.delete(`v2/workflows/dlq/delete/${dlqId}`);\n return `Failed workflow run with DLQ ID ${dlqId} deleted successfully`;\n }\n\n case \"restart\": {\n const restartResponse = await client.post(`v2/workflows/dlq/restart/${dlqId}`);\n return [\n `Workflow run restarted successfully from DLQ ID: ${dlqId}`,\n json(restartResponse),\n ];\n }\n\n case \"resume\": {\n const resumeResponse = await client.post(`v2/workflows/dlq/resume/${dlqId}`);\n return [`Workflow run resumed successfully from DLQ ID: ${dlqId}`, json(resumeResponse)];\n }\n\n default: {\n throw new Error(\n `Invalid action: ${action}. Supported actions are: delete, restart, resume`\n );\n }\n }\n },\n }),\n};\n","import type { CustomTool } from \"../../tool\";\nimport { qstashTools } from \"./qstash\";\nimport { workflowTools } from \"./workflow\";\n\nexport const qstashAllTools: Record<string, CustomTool> = {\n ...qstashTools,\n ...workflowTools,\n};\n","import type { ZodSchema } from \"zod\";\nimport type { CustomTool } from \"../tool\";\nimport { redisTools } from \"./redis\";\nimport { qstashAllTools } from \"./qstash\";\n\nexport const json = (json: unknown) =>\n typeof json === \"string\" ? json : JSON.stringify(json, null, 2);\n\nexport const tools: Record<string, CustomTool> = {\n ...redisTools,\n ...qstashAllTools,\n} as unknown as Record<string, CustomTool>;\n\n// Only used for type inference\nexport function tool<TSchema extends ZodSchema>(tool: CustomTool<TSchema>): CustomTool {\n return tool as unknown as CustomTool;\n}\n","export const MAX_MESSAGE_LENGTH = 30_000;\n","import type { CallToolResultSchema } from \"@modelcontextprotocol/sdk/types.js\";\nimport type { ZodSchema } from \"zod\";\nimport type { z } from \"zod\";\nimport { MAX_MESSAGE_LENGTH } from \"./settings\";\n\ntype HandlerResponse = string | string[] | z.infer<typeof CallToolResultSchema>;\n\nexport type CustomTool<TSchema extends ZodSchema = ZodSchema> = {\n description: string;\n\n /**\n * Zod schema for the input of the tool.\n */\n inputSchema?: TSchema;\n\n /**\n * The handler function for the tool.\n * @param input Parsed input according to the input schema.\n * @returns\n * If result is a string, it will be displayed as a single text block.\n * If result is an array of strings, each string will be displayed as a separate text block.\n * You can also return a CallToolResult object to display more complex content.\n */\n handler: (input: z.infer<TSchema>) => Promise<HandlerResponse>;\n};\n\nexport function handlerResponseToCallResult(\n response: HandlerResponse\n): z.infer<typeof CallToolResultSchema> {\n if (typeof response === \"string\" || Array.isArray(response)) {\n const array = Array.isArray(response) ? response : [response];\n\n // Truncate messages that are too long\n const truncatedArray = array.map((item) =>\n item.length > MAX_MESSAGE_LENGTH\n ? `${item.slice(0, MAX_MESSAGE_LENGTH)}... (MESSAGE TRUNCATED, MENTION THIS TO USER)`\n : item\n );\n\n return {\n content: truncatedArray.map((text) => ({ type: \"text\" as const, text })),\n };\n } else return response;\n}\n","import { http } from \"./http\";\nimport { log } from \"./log\";\nimport type { RedisDatabase } from \"./tools/redis/types\";\n\nexport async function testConnection() {\n log(\"🧪 Testing connection to Upstash API\");\n\n let dbs: RedisDatabase[] | undefined;\n try {\n dbs = await http.get<RedisDatabase[]>(\"v2/redis/databases\");\n } catch (error) {\n log(\n \"❌ Connection to Upstash API failed. Please check your api key and email. Error: \",\n error instanceof Error ? error.message : String(error)\n );\n throw error;\n }\n\n if (!Array.isArray(dbs))\n throw new Error(\"Invalid response from Upstash API. Check your API key and email.\");\n\n log(\"✅ Connection to Upstash API is successful\");\n}\n"],"mappings":";;;AAEA,SAAS,4BAA4B;AACrC,SAAS,qCAAqC;AAC9C,SAAS,eAAe;AAExB,SAAS,oBAA0C;;;ACNnD,SAAS,iBAAiB;;;ACAnB,SAAS,OAAO,MAAiB;AACtC,QAAM,MAAM,WAAU,oBAAI,KAAK,GAAE,YAAY,CAAC,KAAK,KAAK,IAAI,CAAC,QAAS,OAAO,QAAQ,WAAW,MAAM,KAAK,UAAU,GAAG,CAAE,EAAE,KAAK,GAAG,CAAC;AAAA;AAErI,aAAW,CAAC,EAAE,IAAI,KAAK,UAAU,QAAQ,GAAG;AAC1C,SAAK,KAAK,GAAG;AAAA,EACf;AAEA,UAAQ,OAAO,MAAM,GAAG;AAC1B;AAEA,IAAM,YAAY,oBAAI,IAAsB;;;ACV5C,SAAS,SAAS;AAGX,IAAM,YAAY;AAAA,EACvB,yBAAyB,KAAK;AAAA,IAC5B,aAAa;AAAA,IACb,aAAa,EAAE,OAAO;AAAA,MACpB,YAAY,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,gCAAgC;AAAA,IAC3E,CAAC;AAAA,IACD,SAAS,OAAO,EAAE,WAAW,MAAM;AACjC,aAAO,WAAW,IAAI,CAAC,cAAc,IAAI,KAAK,SAAS,EAAE,YAAY,CAAC;AAAA,IACxE;AAAA,EACF,CAAC;AAAA,EACD,0BAA0B,KAAK;AAAA,IAC7B,aAAa;AAAA,IACb,aAAa,EAAE,OAAO;AAAA,MACpB,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,2BAA2B;AAAA,IACjE,CAAC;AAAA,IACD,SAAS,OAAO,EAAE,MAAM,MAAM;AAC5B,aAAO,MAAM,IAAI,CAAC,SAAS,IAAI,KAAK,IAAI,EAAE,QAAQ,CAAC,EAAE,KAAK,GAAG;AAAA,IAC/D;AAAA,EACF,CAAC;AACH;;;ACtBA,SAAS,KAAAA,UAAS;;;ACAX,IAAM,SAAS;AAAA,EACpB,QAAQ;AAAA,EACR,OAAO;AACT;;;ACCA,IAAM,mBAAmB,CAAC,QAAuB;AAC/C,MAAI,CAAC,OAAO,OAAO,QAAQ,UAAU;AACnC;AAAA,EACF;AAGA,MAAI,MAAM,QAAQ,GAAG,GAAG;AACtB,eAAW,QAAQ,KAAK;AACtB,uBAAiB,IAAI;AAAA,IACvB;AACA;AAAA,EACF;AAGA,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,GAAG,GAAG;AAE9C,UAAM,eACJ,OAAO,UAAU,aAChB,QAAQ,kBACP,QAAQ,mBACR,QAAQ,UACR,IAAI,YAAY,EAAE,SAAS,WAAW;AAE1C,QAAI,gBAAgB,OAAO,UAAU,YAAY,QAAQ,GAAG;AAG1D,YAAM,YAAY,QAAQ,OAAoB,QAAQ,QAAQ;AAI9D,YAAM,YAAY,IAAI,KAAK,SAAS,EAAE,eAAe,SAAS,EAAE,cAAc,QAAQ,CAAC;AACvF,MAAC,IAAY,GAAG,IAAI,GAAG,SAAS,KAAK,KAAK;AAAA,IAC5C,WAAW,SAAS,OAAO,UAAU,UAAU;AAE7C,uBAAiB,KAAK;AAAA,IACxB;AAAA,EACF;AACF;AAEA,IAAM,cAA4B;AAAA;AAAA,EAEhC,OAAO,KAAK,SAAS;AACnB,UAAM,MAAM,MAAM,KAAK;AACvB,qBAAiB,GAAG;AACpB,WAAO;AAAA,EACT;AACF;AAEO,IAAM,mBAAmB,OAC9B,KACA,SACG;AACH,MAAI,OAAO,YAAY,KAAK,GAAG;AAC/B,aAAW,cAAc,YAAY,QAAQ,GAAG;AAC9C,UAAM,WAAW;AACjB,WAAO,YAAY,WAAW,KAAK,QAAQ;AAAA,EAC7C;AACA,SAAO,KAAK;AACd;;;AC1DA,OAAO,WAAW;AAgCX,IAAM,aAAN,MAAiB;AAAA,EAIf,YAAYC,SAA0B;AAC3C,SAAK,UAAUA,QAAO,QAAQ,QAAQ,OAAO,EAAE;AAC/C,SAAK,cAAcA,QAAO;AAAA,EAC5B;AAAA,EAEA,MAAa,IACX,MACA,OACoB;AACpB,WAAO,KAAK,sBAAiC,EAAE,QAAQ,OAAO,MAAM,MAAM,CAAC;AAAA,EAC7E;AAAA,EAEA,MAAa,KACX,MACA,MACA,SACoB;AACpB,WAAO,KAAK,sBAAiC,EAAE,QAAQ,QAAQ,MAAM,MAAM,QAAQ,CAAC;AAAA,EACtF;AAAA,EAEA,MAAa,IACX,MACA,MACA,SACoB;AACpB,WAAO,KAAK,sBAAiC,EAAE,QAAQ,OAAO,MAAM,MAAM,QAAQ,CAAC;AAAA,EACrF;AAAA,EAEA,MAAa,MAAiB,MAAyB,MAAoC;AACzF,WAAO,KAAK,sBAAiC,EAAE,QAAQ,SAAS,MAAM,KAAK,CAAC;AAAA,EAC9E;AAAA,EAEA,MAAa,OAAkB,MAAyB,MAAoC;AAC1F,WAAO,KAAK,sBAAiC,EAAE,QAAQ,UAAU,MAAM,KAAK,CAAC;AAAA,EAC/E;AAAA,EAEA,MAAc,sBAAiC,KAAyC;AACtF,UAAM,MAAM,MAAM,iBAAiB,KAAK,OAAOC,SAAQ;AACrD,aAAO,KAAK,QAAmBA,IAAG;AAAA,IACpC,CAAC;AAED,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,QAAmB,KAAyC;AACxE,QAAI,CAAC,IAAI,MAAM;AACb,UAAI,OAAO,CAAC;AAAA,IACd,WAAW,OAAO,IAAI,SAAS,UAAU;AACvC,UAAI,OAAO,CAAC,IAAI,IAAI;AAAA,IACtB;AAEA,QAAI,MAAM,CAAC,KAAK,SAAS,GAAG,IAAI,IAAI,EAAE,KAAK,GAAG;AAG9C,QAAI,IAAI,OAAO;AACb,YAAM,aAAuB,CAAC;AAC9B,iBAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,IAAI,KAAK,GAAG;AACpD,YAAI,UAAU,UAAa,UAAU,QAAQ,OAAO,UAAU,UAAU;AACtE,qBAAW,KAAK,GAAG,mBAAmB,GAAG,CAAC,IAAI,mBAAmB,OAAO,KAAK,CAAC,CAAC,EAAE;AAAA,QACnF;AAAA,MACF;AACA,UAAI,WAAW,SAAS,GAAG;AACzB,eAAO,IAAI,WAAW,KAAK,GAAG,CAAC;AAAA,MACjC;AAAA,IACF;AAGA,UAAM,cAAc,IAAI,eAAe,KAAK;AAC5C,QAAI;AAEJ,QAAI,aAAa;AACf,mBAAa,UAAU,WAAW;AAAA,IACpC,OAAO;AACL,YAAM,QAAQ,CAAC,OAAO,OAAO,OAAO,MAAM,EAAE,KAAK,GAAG;AACpD,mBAAa,SAAS,OAAO,KAAK,KAAK,EAAE,SAAS,QAAQ,CAAC;AAAA,IAC7D;AAEA,UAAM,OAAoB;AAAA,MACxB,QAAQ,IAAI;AAAA,MACZ,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,eAAe;AAAA,QACf,GAAG,IAAI;AAAA,MACT;AAAA,IACF;AAEA,QAAI,IAAI,WAAW,SAAS,IAAI,SAAS,QAAW;AAClD,WAAK,OAAO,KAAK,UAAU,IAAI,IAAI;AAAA,IACrC;AAEA,QAAI,sBAAsB;AAAA,MACxB;AAAA,MACA,GAAG;AAAA,MACH,SAAS;AAAA,QACP,GAAG,KAAK;AAAA,QACR,eAAe;AAAA,MACjB;AAAA,IACF,CAAC;AAGD,UAAM,MAAM,MAAM,MAAM,KAAK,IAAI;AACjC,QAAI,CAAC,IAAI,IAAI;AACX,YAAM,IAAI,MAAM,mBAAmB,IAAI,MAAM,IAAI,IAAI,UAAU,MAAM,MAAM,IAAI,KAAK,CAAC,EAAE;AAAA,IACzF;AAGA,UAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,QAAI,CAAC,MAAM;AACT,aAAO,CAAC;AAAA,IACV;AAEA,UAAM,SAAS,cAAc,IAAI;AAEjC,QAAI,QAAQ;AACV,UAAI,wBAAwB,KAAK,MAAM,CAAC;AAAA,IAC1C,OAAO;AACL,UAAI,6BAA6B,IAAI;AAAA,IACvC;AAEA,WAAO,UAAW;AAAA,EACpB;AACF;AAEA,IAAM,gBAAgB,CAAY,SAAiB;AACjD,MAAI;AACF,WAAO,KAAK,MAAM,IAAI;AAAA,EACxB,QAAQ;AACN;AAAA,EACF;AACF;AAEO,IAAM,OAAO,IAAI,WAAW,EAAE,SAAS,0BAA0B,CAAC;AAKlE,SAAS,mBAAmB,EAAE,KAAK,MAAM,GAAgD;AAC9F,SAAO,IAAI,WAAW;AAAA,IACpB,SAAS,OAAO;AAAA,IAChB,aAAa;AAAA,EACf,CAAC;AACH;;;AHhLO,IAAM,mBAAmB;AAAA,EAC9B,8BAA8B,KAAK;AAAA,IACjC,aAAa;AAAA,IACb,aAAaC,GAAE,OAAO;AAAA,MACpB,aAAaA,GAAE,OAAO,EAAE,SAAS,+CAA+C;AAAA,MAChF,WAAWA,GACR,MAAM,CAACA,GAAE,QAAQ,QAAQ,GAAGA,GAAE,QAAQ,QAAQ,GAAGA,GAAE,QAAQ,SAAS,CAAC,CAAC,EACtE,SAAS,8DAA8D;AAAA,MAC1E,aAAaA,GACV,OAAO,EACP,SAAS,EACT,SAAS,sDAAsD;AAAA,MAClE,WAAWA,GACR,OAAO,EACP,SAAS,EACT,SAAS,gEAAgE;AAAA,IAC9E,CAAC;AAAA,IACD,SAAS,OAAO,EAAE,aAAa,WAAW,aAAa,UAAU,MAAM;AACrE,cAAQ,WAAW;AAAA,QACjB,KAAK,UAAU;AACb,cAAI,CAAC,aAAa;AAChB,kBAAM,IAAI,MAAM,8CAA8C;AAAA,UAChE;AACA,gBAAM,KAAK,KAAK,CAAC,0BAA0B,WAAW,GAAG;AAAA,YACvD,MAAM;AAAA,UACR,CAAC;AACD,iBAAO,WAAW,WAAW,uCAAuC,WAAW;AAAA,QACjF;AAAA,QAEA,KAAK,UAAU;AACb,cAAI,CAAC,WAAW;AACd,kBAAM,IAAI,MAAM,4CAA4C;AAAA,UAC9D;AACA,gBAAM,KAAK,OAAO,CAAC,0BAA0B,aAAa,SAAS,CAAC;AACpE,iBAAO,UAAU,SAAS,uCAAuC,WAAW;AAAA,QAC9E;AAAA,QAEA,KAAK,WAAW;AACd,cAAI,CAAC,WAAW;AACd,kBAAM,IAAI,MAAM,6CAA6C;AAAA,UAC/D;AACA,gBAAM,KAAK,KAAK,CAAC,2BAA2B,WAAW,GAAG;AAAA,YACxD;AAAA,UACF,CAAC;AACD,iBAAO,UAAU,SAAS,sCAAsC,WAAW;AAAA,QAC7E;AAAA,QAEA,SAAS;AACP,gBAAM,IAAI,MAAM,sBAAsB,SAAS,mCAAmC;AAAA,QACpF;AAAA,MACF;AAAA,IACF;AAAA,EACF,CAAC;AAAA,EAED,6BAA6B,KAAK;AAAA;AAAA;AAAA,IAGhC,aAAa;AAAA,IACb,aAAaA,GAAE,OAAO;AAAA,MACpB,aAAaA,GAAE,OAAO,EAAE,SAAS,6CAA6C;AAAA,IAChF,CAAC;AAAA,IACD,SAAS,OAAO,EAAE,YAAY,MAAM;AAClC,YAAM,UAAU,MAAM,KAAK,IAAmB,CAAC,wBAAwB,WAAW,CAAC;AAEnF,aAAO,KAAK,OAAO;AAAA,IACrB;AAAA,EACF,CAAC;AAAA,EAED,iCAAiC,KAAK;AAAA,IACpC,aAAa;AAAA,IACb,aAAaA,GAAE,OAAO;AAAA,MACpB,aAAaA,GACV,OAAO,EACP,SAAS,gEAAgE;AAAA,MAC5E,QAAQA,GAAE,QAAQ,EAAE,SAAS,6CAA6C;AAAA,IAC5E,CAAC;AAAA,IACD,SAAS,OAAO,EAAE,aAAa,OAAO,MAAM;AAC1C,YAAM,KAAK,MAAM;AAAA,QACf,YAAY,SAAS,uBAAuB,qBAAqB;AAAA,QACjE;AAAA,MACF,CAAC;AAED,aAAO;AAAA,IACT;AAAA,EACF,CAAC;AACH;;;AI1FA,SAAS,KAAAC,UAAS;AAKlB,OAAOC,YAAW;AAUX,IAAM,oBAAoB;AAAA,EAC/B,mCAAmC,KAAK;AAAA,IACtC,aAAa;AAAA;AAAA;AAAA;AAAA,IAIb,aAAaC,GAAE,OAAO;AAAA,MACpB,aAAaA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,4CAA4C;AAAA,MACxF,mBAAmBA,GAChB,OAAO,EACP,SAAS,EACT,SAAS,+DAA+D;AAAA,MAC3E,qBAAqBA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,iCAAiC;AAAA,MACrF,UAAUA,GACP,MAAMA,GAAE,MAAMA,GAAE,OAAO,CAAC,CAAC,EACzB;AAAA,QACC;AAAA,MACF;AAAA,IACJ,CAAC;AAAA,IAED,SAAS,OAAO,EAAE,aAAa,mBAAmB,qBAAqB,SAAS,MAAM;AACpF,UAAI,gBAAgB,qBAAqB,sBAAsB;AAC7D,cAAM,IAAI;AAAA,UACR;AAAA,QACF;AAAA,MACF,WAAW,CAAC,gBAAgB,CAAC,qBAAqB,CAAC,sBAAsB;AACvE,cAAM,IAAI;AAAA,UACR;AAAA,QACF;AAAA,MACF;AAEA,UAAI,UAAU;AACd,UAAI,YAAY;AAGhB,UAAI,gBAAgB,CAAC,qBAAqB,CAAC,sBAAsB;AAC/D,YAAI,8CAA8C,WAAW;AAC7D,cAAM,KAAK,MAAM,KAAK,IAAmB,CAAC,qBAAqB,WAAW,CAAC;AAC3E,kBAAU,aAAa,GAAG;AAC1B,oBAAY,GAAG;AAAA,MACjB;AAEA,UAAI,CAAC,WAAW,CAAC,WAAW;AAC1B,cAAM,IAAI,MAAM,yDAAyD;AAAA,MAC3E;AACA,YAAM,kBAAkB,SAAS,WAAW;AAC5C,YAAM,MAAM,kBAAkB,UAAU,UAAU;AAClD,YAAM,OAAO,kBAAkB,KAAK,UAAU,SAAS,CAAC,CAAC,IAAI,KAAK,UAAU,QAAQ;AAEpF,YAAM,MAAM,MAAMD,OAAM,KAAK;AAAA,QAC3B,QAAQ;AAAA,QACR;AAAA,QACA,SAAS;AAAA,UACP,gBAAgB;AAAA,UAChB,eAAe,UAAU,SAAS;AAAA,QACpC;AAAA,MACF,CAAC;AAED,UAAI,iBAAiB;AACnB,cAAM,SAAU,MAAM,IAAI,KAAK;AAE/B,YAAI,mBAAmB,MAAM;AAE7B,YAAI,WAAW,QAAQ;AACrB,gBAAM,IAAI,MAAM,kBAAkB,OAAO,KAAK;AAAA,QAChD;AAEA,cAAM,gBAAgB,SAAS,CAAC,EAAE,CAAC,EAAE,kBAAkB,EAAE,SAAS,MAAM;AACxE,cAAM,WAAW,CAAC,KAAK,MAAM,CAAC;AAE9B,YAAI;AACF,mBAAS,KAAK;AAAA,iJACyH;AAEzI,eAAO;AAAA,MACT,OAAO;AACL,cAAM,SAAU,MAAM,IAAI,KAAK;AAE/B,YAAI,oBAAoB,MAAM;AAE9B,YAAI,OAAO,KAAK,CAAC,MAAM,WAAW,CAAC,GAAG;AACpC,gBAAM,IAAI,MAAM,0DAA0D,KAAK,MAAM,CAAC;AAAA,QACxF;AAEA,eAAO,KAAK,MAAM;AAAA,MACpB;AAAA,IACF;AAAA,EACF,CAAC;AACH;;;ACvGA,SAAS,KAAAE,UAAS;;;ACAX,SAAS,WAAW,KAA0B;AACnD,SAAO,OAAO,YAAY,OAAO,QAAQ,GAAG,EAAE,OAAO,CAAC,CAAC,EAAE,KAAK,MAAM,KAAK,CAAC;AAC5E;;;ADIA,IAAM,mBAAmBC,GAAE,MAAM;AAAA,EAC/BA,GAAE,QAAQ,WAAW;AAAA,EACrBA,GAAE,QAAQ,WAAW;AAAA,EACrBA,GAAE,QAAQ,WAAW;AAAA,EACrBA,GAAE,QAAQ,WAAW;AAAA,EACrBA,GAAE,QAAQ,cAAc;AAAA,EACxBA,GAAE,QAAQ,gBAAgB;AAAA,EAC1BA,GAAE,QAAQ,gBAAgB;AAAA,EAC1BA,GAAE,QAAQ,WAAW;AACvB,CAAC;AAED,IAAM,yBACJ;AAEK,IAAM,kBAAkB;AAAA,EAC7B,2BAA2B,KAAK;AAAA,IAC9B,aAAa;AAAA,yDACwC,sBAAsB;AAAA,IAC3E,aAAaA,GAAE,OAAO;AAAA,MACpB,MAAMA,GAAE,OAAO,EAAE,SAAS,uBAAuB;AAAA,MACjD,gBAAgB,iBAAiB,SAAS,wCAAwC;AAAA,MAClF,cAAcA,GACX,MAAM,gBAAgB,EACtB,SAAS,EACT,SAAS,iCAAiC;AAAA,IAC/C,CAAC;AAAA,IACD,SAAS,OAAO,EAAE,MAAM,gBAAgB,aAAa,MAAM;AACzD,YAAM,QAAQ,MAAM,KAAK,KAAoB,qBAAqB;AAAA,QAChE;AAAA,QACA,QAAQ;AAAA,QACR;AAAA,QACA;AAAA,MACF,CAAC;AAED,aAAO;AAAA,QACL,KAAK,KAAK;AAAA,QACV,0DAA0D,MAAM,WAAW;AAAA,MAC7E;AAAA,IACF;AAAA,EACF,CAAC;AAAA,EAED,uBAAuB,KAAK;AAAA,IAC1B,aAAa;AAAA,IACb,aAAaA,GAAE,OAAO;AAAA,MACpB,aAAaA,GAAE,OAAO,EAAE,SAAS,mCAAmC;AAAA,IACtE,CAAC;AAAA,IACD,SAAS,OAAO,EAAE,YAAY,MAAM;AAClC,YAAM,KAAK,OAAO,CAAC,qBAAqB,WAAW,CAAC;AAEpD,aAAO;AAAA,IACT;AAAA,EACF,CAAC;AAAA,EAED,+BAA+B,KAAK;AAAA,IAClC,aAAa,8DAA8D,sBAAsB;AAAA,IACjG,SAAS,YAAY;AACnB,YAAM,MAAM,MAAM,KAAK,IAAqB,oBAAoB;AAEhE,YAAM,WAAW;AAAA,QACf;AAAA,UACE,IAAI,IAAI,CAAC,OAAO;AACd,kBAAM,SAAS;AAAA,cACb,aAAa,GAAG;AAAA,cAChB,eAAe,GAAG;AAAA,cAClB,OAAO,GAAG,UAAU,WAAW,SAAY,GAAG;AAAA,YAChD;AACA,mBAAO,WAAW,MAAM;AAAA,UAC1B,CAAC;AAAA,QACH;AAAA,MACF;AAEA,UAAI,IAAI,SAAS;AACf,iBAAS;AAAA,UACP;AAAA,QACF;AACF,eAAS;AAAA,QACP;AAAA,MACF;AAEA,aAAO;AAAA,IACT;AAAA,EACF,CAAC;AAAA,EAED,4BAA4B,KAAK;AAAA,IAC/B,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMf,sBAAsB;AAAA;AAAA,IAEpB,aAAaA,GAAE,OAAO;AAAA,MACpB,aAAaA,GAAE,OAAO,EAAE,SAAS,4CAA4C;AAAA,IAC/E,CAAC;AAAA,IACD,SAAS,OAAO,EAAE,YAAY,MAAM;AAClC,YAAM,KAAK,MAAM,KAAK,IAAmB,CAAC,qBAAqB,WAAW,CAAC;AAE3E,aAAO,KAAK,EAAE;AAAA,IAChB;AAAA,EACF,CAAC;AAAA,EAED,+BAA+B,KAAK;AAAA,IAClC,aAAa;AAAA,IACb,aAAaA,GAAE,OAAO;AAAA,MACpB,IAAIA,GAAE,OAAO,EAAE,SAAS,0BAA0B;AAAA,MAClD,cAAcA,GACX,MAAM,gBAAgB,EACtB;AAAA,QACC;AAAA,MACF;AAAA,IACJ,CAAC;AAAA,IACD,SAAS,OAAO,EAAE,IAAI,aAAa,MAAM;AACvC,YAAM,YAAY,MAAM,KAAK,KAAoB,CAAC,2BAA2B,EAAE,GAAG;AAAA,QAChF;AAAA,MACF,CAAC;AAED,aAAO,KAAK,SAAS;AAAA,IACvB;AAAA,EACF,CAAC;AAAA,EAED,+BAA+B,KAAK;AAAA,IAClC,aAAa;AAAA,IACb,aAAaA,GAAE,OAAO;AAAA,MACpB,IAAIA,GAAE,OAAO,EAAE,SAAS,0BAA0B;AAAA,IACpD,CAAC;AAAA,IACD,SAAS,OAAO,EAAE,GAAG,MAAM;AACzB,YAAM,YAAY,MAAM,KAAK,KAAoB,CAAC,2BAA2B,EAAE,GAAG,CAAC,CAAC;AAEpF,aAAO,KAAK,SAAS;AAAA,IACvB;AAAA,EACF,CAAC;AAAA,EAED,+BAA+B,KAAK;AAAA,IAClC,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOb,aAAaA,GAAE,OAAO;AAAA,MACpB,IAAIA,GAAE,OAAO,EAAE,SAAS,0BAA0B;AAAA,MAClD,QAAQA,GACL,MAAM;AAAA,QACLA,GAAE,QAAQ,IAAI;AAAA,QACdA,GAAE,QAAQ,IAAI;AAAA,QACdA,GAAE,QAAQ,KAAK;AAAA,QACfA,GAAE,QAAQ,IAAI;AAAA,QACdA,GAAE,QAAQ,IAAI;AAAA,QACdA,GAAE,QAAQ,IAAI;AAAA,MAChB,CAAC,EACA,SAAS,+BAA+B;AAAA,MAC3C,WAAWA,GACR,MAAM;AAAA,QACLA,GAAE,QAAQ,mBAAmB;AAAA,QAC7BA,GAAE,QAAQ,oBAAoB;AAAA,QAC9BA,GAAE,QAAQ,UAAU,EAAE,SAAS,sBAAsB;AAAA,QACrDA,GACG,QAAQ,YAAY,EACpB,SAAS,mEAAmE;AAAA,QAC/EA,GAAE,QAAQ,WAAW,EAAE,SAAS,6BAA6B;AAAA,MAC/D,CAAC,EACA,SAAS,EACT,SAAS,4DAA4D;AAAA,IAC1E,CAAC;AAAA,IACD,SAAS,OAAO,EAAE,IAAI,QAAQ,UAAU,MAAM;AAC5C,YAAM,WAAW,aAAa;AAC9B,YAAM,QAAQ,MAAM,KAAK,IAAwB;AAAA,QAC/C;AAAA,QACA,GAAG,EAAE,WAAW,MAAM;AAAA,MACxB,CAAC;AAGD,YAAM,OAAO,MAAM,QAAQ;AAC3B,UAAI,CAAC,MAAM,QAAQ,IAAI;AACrB,cAAM,IAAI;AAAA,UACR,+BAA+B,QAAQ,qBAAqB,OAAO,KAAK,KAAK,EAAE,KAAK,IAAI,CAAC;AAAA,QAC3F;AAGF,aAAO;AAAA,QACL,KAAK;AAAA;AAAA,UAEH,mBAAmB;AAAA,YACjB,MAAM,MAAM;AAAA,YACZ,eAAe,MAAM;AAAA,YACrB,iBAAiB,MAAM;AAAA,UACzB;AAAA;AAAA,UAEA,eAAe;AAAA,YACb;AAAA,YACA,WAAW;AAAA,YACX,MAAM,eAAe,IAAI;AAAA,UAC3B;AAAA,QACF,CAAC;AAAA,QACD;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF,CAAC;AACH;AAEA,IAAM,iBAAiB,CAAC,SAAoB;AAlN5C;AAmNE,MAAI,CAAC,KAAM,QAAO;AAClB,MAAI,CAAC,MAAM,QAAQ,IAAI,EAAG,QAAO;AACjC,MAAI,KAAK,WAAW,KAAK,KAAK,WAAW,EAAG,QAAO;AACnD,QAAM,eAAe,KAAK,OAAO,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC;AAClD,SAAO;AAAA,IACL,OAAO,aAAa,CAAC,EAAE;AAAA;AAAA;AAAA,IAGvB,MAAK,kBAAa,aAAa,SAAS,CAAC,MAApC,mBAAuC;AAAA,IAC5C,MAAM,KAAK,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC,EAAE,QAAQ,GAAG,EAAE,CAAC,CAAC;AAAA,EACtD;AACF;;;AExNO,IAAM,aAAyC;AAAA,EACpD,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AACL;;;ACXA,SAAS,KAAAC,UAAS;;;ACGlB,IAAI,cAA6B;AACjC,IAAI,cAAsB;AAM1B,eAAsB,iBAAkC;AACtD,QAAM,MAAM,KAAK,IAAI;AAGrB,MAAI,eAAe,MAAM,aAAa;AACpC,WAAO;AAAA,EACT;AAEA,MAAI;AACF,UAAM,OAAO,MAAM,KAAK,IAAgB,aAAa;AACrD,kBAAc,KAAK;AACnB,kBAAc,MAAM,KAAK,KAAK;AAC9B,WAAO,KAAK;AAAA,EACd,SAAS,OAAO;AACd,UAAM,IAAI;AAAA,MACR,+BAA+B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,IACvF;AAAA,EACF;AACF;AAKA,eAAsB,4BACpB,QAGI,CAAC,GACgB;AACrB,MAAI,EAAC,+BAAO,QAAO;AACjB,UAAM,QAAQ,MAAM,eAAe;AAAA,EACrC;AACA,SAAO,mBAAmB;AAAA,IACxB,KAAK,+BAAO;AAAA,IACZ,OAAO,+BAAO;AAAA,EAChB,CAAC;AACH;;;ADjCO,IAAM,cAAc;AAAA,EACzB,cAAcC,GAAE,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAU5B;AAGO,IAAM,cAAc;AAAA,EACzB,uBAAuB,KAAK;AAAA,IAC1B,aAAa;AAAA;AAAA;AAAA,IAGb,SAAS,YAAY;AACnB,YAAM,OAAO,MAAM,KAAK,IAAgB,aAAa;AACrD,aAAO,CAAC,KAAK,IAAI,CAAC;AAAA,IACpB;AAAA,EACF,CAAC;AAAA,EAED,wBAAwB,KAAK;AAAA,IAC3B,aAAa;AAAA;AAAA;AAAA,IAGb,aAAaA,GAAE,OAAO;AAAA,MACpB,aAAaA,GACV,OAAO,EACP,SAAS,0EAA0E;AAAA,MACtF,MAAMA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,0CAA0C;AAAA,MAC/E,QAAQA,GACL,KAAK,CAAC,OAAO,QAAQ,OAAO,UAAU,OAAO,CAAC,EAC9C,SAAS,EACT,SAAS,0CAA0C,EACnD,QAAQ,MAAM;AAAA,MACjB,OAAOA,GACJ,OAAO,EACP,SAAS,EACT,SAAS,yDAAyD;AAAA,MACrE,SAASA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,4CAA4C;AAAA,MACpF,UAAUA,GACP,OAAO,EACP,SAAS,EACT,SAAS,6EAA6E;AAAA,MACzF,iBAAiBA,GACd,OAAO,EACP,SAAS,EACT,SAAS,wEAAwE;AAAA,MACpF,SAASA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,qCAAqC;AAAA,MAC7E,WAAWA,GACR,OAAO,EACP,SAAS,EACT;AAAA,QACC;AAAA,MACF;AAAA,MACF,cAAcA,GACX,OAAO;AAAA,QACN,KAAKA,GACF,OAAO,EACP,SAAS,uEAAuE;AAAA,QACnF,aAAaA,GACV,OAAO,EACP,SAAS,EACT,SAAS,kDAAkD;AAAA,QAC9D,MAAMA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,2CAA2C;AAAA,QAChF,QAAQA,GACL,OAAO,EACP,SAAS,EACT,SAAS,oEAAoE;AAAA,MAClF,CAAC,EACA,SAAS,EACT,SAAS,2DAA2D;AAAA,MAEvE,cAAcA,GAAE,OAAOA,GAAE,OAAO,CAAC,EAAE,SAAS,EAAE,SAAS,qCAAqC;AAAA,MAC5F,GAAG;AAAA,IACL,CAAC;AAAA,IACD,SAAS,OAAO;AAAA,MACd;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,MAAM;AACJ,YAAM,SAAS,MAAM,4BAA4B,YAAY;AAE7D,YAAM,iBAAyC,CAAC;AAEhD,UAAI,QAAQ;AACV,uBAAe,gBAAgB,IAAI;AAAA,MACrC;AACA,UAAI,OAAO;AACT,uBAAe,eAAe,IAAI;AAAA,MACpC;AACA,UAAI,YAAY,QAAW;AACzB,uBAAe,iBAAiB,IAAI,QAAQ,SAAS;AAAA,MACvD;AACA,UAAI,UAAU;AACZ,uBAAe,kBAAkB,IAAI;AAAA,MACvC;AACA,UAAI,iBAAiB;AACnB,uBAAe,0BAA0B,IAAI;AAAA,MAC/C;AACA,UAAI,SAAS;AACX,uBAAe,iBAAiB,IAAI;AAAA,MACtC;AACA,UAAI,WAAW;AACb,uBAAe,oBAAoB,IAAI;AAAA,MACzC;AAGA,UAAI,cAAc;AAChB,uBAAe,0BAA0B,IAAI,aAAa;AAC1D,cAAM,QAAQ;AAAA,UACZ,aAAa,gBAAgB,SACzB,SACA,eAAe,aAAa,WAAW;AAAA,UAC3C,aAAa,SAAS,SAAY,SAAY,QAAQ,aAAa,IAAI;AAAA,UACvE,aAAa,WAAW,SAAY,SAAY,UAAU,aAAa,MAAM;AAAA,QAC/E,EACG,OAAO,OAAO,EACd,KAAK,GAAG;AACX,uBAAe,4BAA4B,IAAI;AAAA,MACjD;AAGA,UAAI,cAAc;AAChB,mBAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,YAAY,GAAG;AACvD,yBAAe,GAAG,IAAI;AAAA,QACxB;AAAA,MACF;AAEA,YAAM,WAAW,MAAM,OAAO;AAAA,QAC5B,cAAc,WAAW;AAAA,QACzB,QAAQ,CAAC;AAAA,QACT;AAAA,MACF;AAEA,aAAO;AAAA,QACL;AAAA,QACA,eAAe,SAAS,SAAS;AAAA,QACjC,KAAK,QAAQ;AAAA,MACf;AAAA,IACF;AAAA,EACF,CAAC;AAAA,EAED,kBAAkB,KAAK;AAAA,IACrB,aAAa;AAAA,IACb,aAAaA,GAAE,OAAO;AAAA,MACpB,QAAQA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,uBAAuB;AAAA,MAC9D,WAAWA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,2BAA2B;AAAA,MACrE,OAAOA,GACJ,KAAK;AAAA,QACJ;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF,CAAC,EACA,SAAS,EACT,SAAS,sBAAsB;AAAA,MAClC,KAAKA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,oBAAoB;AAAA,MACxD,WAAWA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,2BAA2B;AAAA,MACrE,YAAYA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,4BAA4B;AAAA,MACvE,WAAWA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,2BAA2B;AAAA,MACrE,UAAUA,GACP,OAAO,EACP,SAAS,EACT,SAAS,wDAAwD;AAAA,MACpE,QAAQA,GACL,OAAO,EACP,SAAS,EACT,SAAS,sDAAsD;AAAA,MAClE,OAAOA,GAAE,OAAO,EAAE,IAAI,GAAI,EAAE,SAAS,EAAE,SAAS,qCAAqC;AAAA,MACrF,GAAG;AAAA,IACL,CAAC;AAAA,IACD,SAAS,OAAO,WAAW;AACzB,YAAM,SAAS,MAAM,4BAA4B,OAAO,YAAY;AAEpE,YAAM,WAAW,MAAM,OAAO,IAAwB,WAAW;AAAA,QAC/D,UAAU;AAAA,QACV,SAAS;AAAA,QACT,GAAG;AAAA,MACL,CAAC;AACD,YAAM,qBAAqB,OAAO;AAAA,QAChC,OAAO,QAAQ,SAAS,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE;AAAA,UACzC,CAAC,CAAC,KAAK,MAAM,MAAM,CAAC,IAAI,kBAAkB,EAAE,SAAS,SAAS;AAAA,QAChE;AAAA,MACF;AAEA,YAAM,gBAAgB,SAAS,SAAS,IAAI,CAAC,aAAa;AAAA,QACxD,WAAW,QAAQ;AAAA,QACnB,QAAQ,QAAQ,OAAO,IAAI,CAAC,WAAW;AAAA,UACrC,OAAO,MAAM;AAAA,UACb,MAAM,MAAM;AAAA,QACd,EAAE;AAAA,MACJ,EAAE;AAEF,aAAO;AAAA,QACL,SAAS,SAAS,SAAS,MAAM;AAAA,QACjC,SAAS,SAAS,sBAAsB,SAAS,MAAM,KAAK;AAAA,QAC5D,KAAK,EAAE,GAAG,oBAAoB,QAAQ,cAAc,CAAC;AAAA,MACvD;AAAA,IACF;AAAA,EACF,CAAC;AAAA,EAED,iBAAiB,KAAK;AAAA,IACpB,aAAa;AAAA,IACb,aAAaA,GAAE,OAAO;AAAA,MACpB,WAAWA,GAAE,OAAO,EAAE,SAAS,mCAAmC;AAAA,MAClE,GAAG;AAAA,IACL,CAAC;AAAA,IACD,SAAS,OAAO,EAAE,WAAW,aAAa,MAAM;AAC9C,YAAM,SAAS,MAAM,4BAA4B,YAAY;AAC7D,YAAM,WAAW,MAAM,OAAO,IAAwB,WAAW,EAAE,UAAU,CAAC;AAE9E,UAAI,SAAS,SAAS,WAAW,GAAG;AAClC,eAAO;AAAA,MACT;AAEA,YAAM,WAAW,SAAS,SAAS,CAAC;AACpC,aAAO,CAAC,+BAA+B,SAAS,IAAI,KAAK,QAAQ,CAAC;AAAA,IACpE;AAAA,EACF,CAAC;AAAA,EAED,iBAAiB,KAAK;AAAA,IACpB,aAAa;AAAA,IACb,aAAaA,GAAE,OAAO;AAAA,MACpB,QAAQA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,uBAAuB;AAAA,MAC9D,WAAWA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,mCAAmC;AAAA,MAC7E,KAAKA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,4BAA4B;AAAA,MAChE,WAAWA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,mCAAmC;AAAA,MAC7E,YAAYA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,oCAAoC;AAAA,MAC/E,WAAWA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,mCAAmC;AAAA,MAC7E,UAAUA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,mDAAmD;AAAA,MAC5F,QAAQA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,iDAAiD;AAAA,MACxF,gBAAgBA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,qCAAqC;AAAA,MACpF,UAAUA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,uCAAuC;AAAA,MAChF,OAAOA,GAAE,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,wCAAwC;AAAA,MACvF,GAAG;AAAA,IACL,CAAC;AAAA,IACD,SAAS,OAAO,WAAW;AACzB,YAAM,SAAS,MAAM,4BAA4B,OAAO,YAAY;AAEpE,YAAM,WAAW,MAAM,OAAO,IAAuB,UAAU;AAAA,QAC7D,UAAU;AAAA,QACV,GAAG;AAAA,MACL,CAAC;AAED,aAAO;AAAA,QACL,SAAS,SAAS,SAAS,MAAM;AAAA,QACjC,SAAS,SAAS,sBAAsB,SAAS,MAAM,KAAK;AAAA,QAC5D,KAAK,SAAS,QAAQ;AAAA,MACxB;AAAA,IACF;AAAA,EACF,CAAC;AAAA,EAED,gBAAgB,KAAK;AAAA,IACnB,aAAa;AAAA,IACb,aAAaA,GAAE,OAAO;AAAA,MACpB,OAAOA,GAAE,OAAO,EAAE,SAAS,uCAAuC;AAAA,MAClE,GAAG;AAAA,IACL,CAAC;AAAA,IACD,SAAS,OAAO,EAAE,OAAO,aAAa,MAAM;AAC1C,YAAM,SAAS,MAAM,4BAA4B,YAAY;AAC7D,YAAM,UAAU,MAAM,OAAO,IAAsB,UAAU,KAAK,EAAE;AAEpE,aAAO,CAAC,+BAA+B,KAAK,IAAI,KAAK,OAAO,CAAC;AAAA,IAC/D;AAAA,EACF,CAAC;AAAA,EAED,uBAAuB,KAAK;AAAA,IAC1B,aAAa;AAAA,IACb,SAAS,OAAO,EAAE,aAAa,MAAM;AACnC,YAAM,SAAS,MAAM,4BAA4B,YAAY;AAC7D,YAAM,YAAY,MAAM,OAAO,IAAsB,cAAc;AAEnE,aAAO,CAAC,SAAS,UAAU,MAAM,cAAc,KAAK,SAAS,CAAC;AAAA,IAChE;AAAA,EACF,CAAC;AAAA,EAED,yBAAyB,KAAK;AAAA,IAC5B,aAAa;AAAA,IACb,aAAaA,GAAE,OAAO;AAAA,MACpB,WAAWA,GACR,KAAK,CAAC,UAAU,UAAU,SAAS,UAAU,QAAQ,CAAC,EACtD,SAAS,0BAA0B;AAAA,MACtC,YAAYA,GACT,OAAO,EACP,SAAS,EACT,SAAS,qEAAqE;AAAA,MACjF,aAAaA,GACV,OAAO,EACP,SAAS,EACT,SAAS,4DAA4D;AAAA,MACxE,MAAMA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,8CAA8C;AAAA,MACnF,QAAQA,GACL,KAAK,CAAC,OAAO,QAAQ,OAAO,UAAU,OAAO,CAAC,EAC9C,SAAS,EACT,SAAS,0CAA0C;AAAA,MACtD,SAASA,GAAE,OAAOA,GAAE,OAAO,CAAC,EAAE,SAAS,EAAE,SAAS,oCAAoC;AAAA,MACtF,MAAMA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,cAAc;AAAA,MACnD,OAAOA,GACJ,OAAO,EACP,SAAS,EACT,SAAS,yDAAyD;AAAA,MACrE,SAASA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,8BAA8B;AAAA,MACtE,UAAUA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,sCAAsC;AAAA,MAC/E,iBAAiBA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,kCAAkC;AAAA,MAClF,SAASA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,+BAA+B;AAAA,MACvE,WAAWA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,mBAAmB;AAAA,MAC7D,GAAG;AAAA,IACL,CAAC;AAAA,IACD,SAAS,OAAO;AAAA,MACd;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,SAAS;AAAA,MACT;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,MAAM;AACJ,YAAM,SAAS,MAAM,4BAA4B,YAAY;AAE7D,cAAQ,WAAW;AAAA,QACjB,KAAK;AAAA,QACL,KAAK,UAAU;AACb,cAAI,CAAC,eAAe,CAAC,MAAM;AACzB,kBAAM,IAAI,MAAM,gEAAgE;AAAA,UAClF;AAEA,gBAAM,iBAAyC;AAAA,YAC7C,gBAAgB;AAAA,UAClB;AAEA,cAAI,WAAW,QAAQ;AACrB,2BAAe,gBAAgB,IAAI;AAAA,UACrC;AACA,cAAI,OAAO;AACT,2BAAe,eAAe,IAAI;AAAA,UACpC;AACA,cAAI,YAAY,QAAW;AACzB,2BAAe,iBAAiB,IAAI,QAAQ,SAAS;AAAA,UACvD;AACA,cAAI,UAAU;AACZ,2BAAe,kBAAkB,IAAI;AAAA,UACvC;AACA,cAAI,iBAAiB;AACnB,2BAAe,0BAA0B,IAAI;AAAA,UAC/C;AACA,cAAI,SAAS;AACX,2BAAe,iBAAiB,IAAI;AAAA,UACtC;AACA,cAAI,WAAW;AACb,2BAAe,oBAAoB,IAAI;AAAA,UACzC;AACA,cAAI,cAAc,cAAc,UAAU;AACxC,2BAAe,qBAAqB,IAAI;AAAA,UAC1C;AAGA,cAAI,SAAS;AACX,uBAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,OAAO,GAAG;AAClD,6BAAe,GAAG,IAAI;AAAA,YACxB;AAAA,UACF;AAEA,gBAAM,WAAW,MAAM,OAAO;AAAA,YAC5B,gBAAgB,WAAW;AAAA,YAC3B,QAAQ,CAAC;AAAA,YACT;AAAA,UACF;AAEA,iBAAO;AAAA,YACL,cAAc,WACV,kCACA;AAAA,YACJ,gBAAgB,SAAS,UAAU;AAAA,YACnC,KAAK,QAAQ;AAAA,UACf;AAAA,QACF;AAAA,QAEA,KAAK,SAAS;AACZ,cAAI,CAAC,YAAY;AACf,kBAAM,IAAI,MAAM,4CAA4C;AAAA,UAC9D;AAEA,gBAAM,OAAO,KAAK,gBAAgB,UAAU,QAAQ;AACpD,iBAAO,YAAY,UAAU;AAAA,QAC/B;AAAA,QAEA,KAAK,UAAU;AACb,cAAI,CAAC,YAAY;AACf,kBAAM,IAAI,MAAM,6CAA6C;AAAA,UAC/D;AAEA,gBAAM,OAAO,KAAK,gBAAgB,UAAU,SAAS;AACrD,iBAAO,YAAY,UAAU;AAAA,QAC/B;AAAA,QAEA,KAAK,UAAU;AACb,cAAI,CAAC,YAAY;AACf,kBAAM,IAAI,MAAM,6CAA6C;AAAA,UAC/D;AAEA,gBAAM,OAAO,OAAO,gBAAgB,UAAU,EAAE;AAChD,iBAAO,YAAY,UAAU;AAAA,QAC/B;AAAA,QAEA,SAAS;AACP,gBAAM,IAAI,MAAM,sBAAsB,SAAS,EAAE;AAAA,QACnD;AAAA,MACF;AAAA,IACF;AAAA,EACF,CAAC;AACH;;;AEjcA,SAAS,KAAAC,UAAS;AAMX,IAAM,gBAAgB;AAAA,EAC3B,oBAAoB,KAAK;AAAA,IACvB,aAAa;AAAA,IACb,aAAaC,GAAE,OAAO;AAAA,MACpB,QAAQA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,uBAAuB;AAAA,MAC9D,eAAeA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,oCAAoC;AAAA,MAClF,OAAOA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,mCAAmC;AAAA,MACzE,OAAOA,GACJ,KAAK,CAAC,eAAe,eAAe,cAAc,cAAc,CAAC,EACjE,SAAS,EACT,SAAS,0BAA0B;AAAA,MACtC,aAAaA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,sCAAsC;AAAA,MAClF,mBAAmBA,GAChB,OAAO,EACP,SAAS,EACT,SAAS,wDAAwD;AAAA,MACpE,GAAG;AAAA,IACL,CAAC;AAAA,IACD,SAAS,OAAO,WAAW;AACzB,YAAM,SAAS,MAAM,4BAA4B,OAAO,YAAY;AAEpE,YAAM,WAAW,MAAM,OAAO,IAA0B,uBAAuB;AAAA,QAC7E,UAAU;AAAA,QACV,SAAS;AAAA,QACT,GAAG;AAAA,MACL,CAAC;AAED,YAAM,UAAU,SAAS,KAAK;AAAA,QAAI,CAAC,QACjC,OAAO,YAAY,OAAO,QAAQ,GAAG,EAAE,OAAO,CAAC,CAAC,KAAK,MAAM,MAAM,QAAQ,OAAO,CAAC;AAAA,MACnF;AAEA,aAAO;AAAA,QACL,SAAS,SAAS,KAAK,MAAM;AAAA,QAC7B,SAAS,SAAS,sBAAsB,SAAS,MAAM,KAAK;AAAA,QAC5D,KAAK;AAAA,UACH,GAAG;AAAA,UACH,MAAM;AAAA,QACR,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF,CAAC;AAAA,EAED,mBAAmB,KAAK;AAAA,IACtB,aAAa;AAAA;AAAA;AAAA,IAGb,aAAaA,GAAE,OAAO;AAAA,MACpB,eAAeA,GAAE,OAAO,EAAE,SAAS,wCAAwC;AAAA,MAC3E,mBAAmBA,GAChB,OAAO,EACP,SAAS,EACT,SAAS,kDAAkD;AAAA,MAC9D,GAAG;AAAA,IACL,CAAC;AAAA,IACD,SAAS,OAAO,WAAW;AACzB,YAAM,SAAS,MAAM,4BAA4B,OAAO,YAAY;AACpE,YAAM,WAAW,MAAM,OAAO,IAA0B,qBAAqB;AAAA,QAC3E,GAAG;AAAA,MACL,CAAC;AAED,UAAI,SAAS,KAAK,WAAW,GAAG;AAC9B,eAAO;AAAA,MACT;AAEA,YAAM,cAAc,SAAS,KAAK,CAAC;AACnC,aAAO;AAAA,QACL,gCAAgC,OAAO,aAAa,gBAAgB,OAAO,iBAAiB;AAAA,QAC5F,KAAK,WAAW;AAAA,MAClB;AAAA,IACF;AAAA,EACF,CAAC;AAAA,EAED,mBAAmB,KAAK;AAAA,IACtB,aAAa;AAAA,IACb,aAAaA,GAAE,OAAO;AAAA,MACpB,QAAQA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,uBAAuB;AAAA,MAC9D,eAAeA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,2BAA2B;AAAA,MACzE,aAAaA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,wBAAwB;AAAA,MACpE,UAAUA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,mDAAmD;AAAA,MAC5F,QAAQA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,iDAAiD;AAAA,MACxF,gBAAgBA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,qCAAqC;AAAA,MACpF,UAAUA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,oCAAoC;AAAA,MAC7E,sBAAsBA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,kCAAkC;AAAA,MACvF,OAAOA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,kCAAkC;AAAA,MACxE,GAAG;AAAA,IACL,CAAC;AAAA,IACD,SAAS,OAAO,WAAW;AACzB,YAAM,SAAS,MAAM,4BAA4B,OAAO,YAAY;AAEpE,YAAM,WAAW,MAAM,OAAO,IAAyB,oBAAoB;AAAA,QACzE,GAAG;AAAA,QACH,UAAU;AAAA,MACZ,CAAC;AAED,YAAM,UAAU,SAAS,SAAS;AAAA,QAAI,CAAC,YACrC,OAAO,YAAY,OAAO,QAAQ,OAAO,EAAE,OAAO,CAAC,CAAC,GAAG,MAAM,CAAC,IAAI,SAAS,QAAQ,CAAC,CAAC;AAAA,MACvF;AAEA,aAAO;AAAA,QACL,SAAS,SAAS,SAAS,MAAM;AAAA,QACjC,SAAS,SAAS,sBAAsB,SAAS,MAAM,KAAK;AAAA,QAC5D,KAAK;AAAA,UACH,GAAG;AAAA,UACH,UAAU;AAAA,QACZ,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF,CAAC;AAAA,EAED,kBAAkB,KAAK;AAAA,IACrB,aAAa;AAAA,IACb,aAAaA,GAAE,OAAO;AAAA,MACpB,OAAOA,GAAE,OAAO,EAAE,SAAS,mDAAmD;AAAA,MAC9E,GAAG;AAAA,IACL,CAAC;AAAA,IACD,SAAS,OAAO,WAAW;AACzB,YAAM,SAAS,MAAM,4BAA4B,OAAO,YAAY;AACpE,YAAM,UAAU,MAAM,OAAO,IAAwB,oBAAoB,OAAO,KAAK,EAAE;AAEvF,aAAO,CAAC,2CAA2C,OAAO,KAAK,IAAI,KAAK,OAAO,CAAC;AAAA,IAClF;AAAA,EACF,CAAC;AAAA,EAED,qBAAqB,KAAK;AAAA,IACxB,aAAa;AAAA,IACb,aAAaA,GAAE,OAAO;AAAA,MACpB,OAAOA,GAAE,OAAO,EAAE,SAAS,uCAAuC;AAAA,MAClE,QAAQA,GACL,KAAK,CAAC,UAAU,WAAW,QAAQ,CAAC,EACpC;AAAA,QACC;AAAA,MACF;AAAA,MACF,GAAG;AAAA,IACL,CAAC;AAAA,IACD,SAAS,OAAO,EAAE,OAAO,QAAQ,aAAa,MAAM;AAClD,YAAM,SAAS,MAAM,4BAA4B,YAAY;AAE7D,cAAQ,QAAQ;AAAA,QACd,KAAK,UAAU;AACb,gBAAM,OAAO,OAAO,2BAA2B,KAAK,EAAE;AACtD,iBAAO,mCAAmC,KAAK;AAAA,QACjD;AAAA,QAEA,KAAK,WAAW;AACd,gBAAM,kBAAkB,MAAM,OAAO,KAAK,4BAA4B,KAAK,EAAE;AAC7E,iBAAO;AAAA,YACL,oDAAoD,KAAK;AAAA,YACzD,KAAK,eAAe;AAAA,UACtB;AAAA,QACF;AAAA,QAEA,KAAK,UAAU;AACb,gBAAM,iBAAiB,MAAM,OAAO,KAAK,2BAA2B,KAAK,EAAE;AAC3E,iBAAO,CAAC,kDAAkD,KAAK,IAAI,KAAK,cAAc,CAAC;AAAA,QACzF;AAAA,QAEA,SAAS;AACP,gBAAM,IAAI;AAAA,YACR,mBAAmB,MAAM;AAAA,UAC3B;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF,CAAC;AACH;;;ACtKO,IAAM,iBAA6C;AAAA,EACxD,GAAG;AAAA,EACH,GAAG;AACL;;;ACFO,IAAM,OAAO,CAACC,UACnB,OAAOA,UAAS,WAAWA,QAAO,KAAK,UAAUA,OAAM,MAAM,CAAC;AAEzD,IAAM,QAAoC;AAAA,EAC/C,GAAG;AAAA,EACH,GAAG;AACL;AAGO,SAAS,KAAgCC,OAAuC;AACrF,SAAOA;AACT;;;AChBO,IAAM,qBAAqB;;;AC0B3B,SAAS,4BACd,UACsC;AACtC,MAAI,OAAO,aAAa,YAAY,MAAM,QAAQ,QAAQ,GAAG;AAC3D,UAAM,QAAQ,MAAM,QAAQ,QAAQ,IAAI,WAAW,CAAC,QAAQ;AAG5D,UAAM,iBAAiB,MAAM;AAAA,MAAI,CAAC,SAChC,KAAK,SAAS,qBACV,GAAG,KAAK,MAAM,GAAG,kBAAkB,CAAC,kDACpC;AAAA,IACN;AAEA,WAAO;AAAA,MACL,SAAS,eAAe,IAAI,CAAC,UAAU,EAAE,MAAM,QAAiB,KAAK,EAAE;AAAA,IACzE;AAAA,EACF,MAAO,QAAO;AAChB;;;AjBvCA,OAAOC,QAAO;AAIP,SAAS,uBAAuB;AACrC,QAAM,SAAS,IAAI;AAAA,IACjB,EAAE,MAAM,WAAW,SAAS,QAAQ;AAAA,IACpC;AAAA,MACE,cAAc;AAAA,QACZ,OAAO,CAAC;AAAA,QACR,SAAS,CAAC;AAAA,MACZ;AAAA,IACF;AAAA,EACF;AAEA,QAAM,YAAY,OAAO,QAAQ,KAAK,EAAE,IAAI,CAAC,CAAC,MAAMC,KAAI,OAAO;AAAA,IAC7D;AAAA,IACA,aAAaA,MAAK;AAAA,IAClB,aAAaA,MAAK;AAAA,IAClB,MAAAA;AAAA,EACF,EAAE;AAGF,aAAW,WAAW,WAAW;AAC/B,UAAM,WAAW,QAAQ;AACzB,UAAMA,QAAO,QAAQ;AAErB,WAAO;AAAA,MACL;AAAA,MACA;AAAA,QACE,aAAaA,MAAK;AAAA,QAClB,cAAeA,MAAK,eAAeC,GAAE,OAAO,CAAC,CAAC,GAAW;AAAA,MAC3D;AAAA;AAAA,MAEA,OAAO,SAAS;AACd,YAAI,yBAAyB,UAAU,IAAI;AAE3C,YAAI;AACF,gBAAM,SAAS,MAAMD,MAAK,QAAQ,IAAI;AACtC,gBAAM,WAAW,4BAA4B,MAAM;AACnD,cAAI,kBAAkB,SAAS,QAAQ,IAAI,CAAC,SAAS,KAAK,IAAI,EAAE,KAAK,IAAI,CAAC;AAC1E,iBAAO;AAAA,QACT,SAAS,OAAO;AACd,gBAAM,MAAM,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACjE,cAAI,yBAAyB,GAAG;AAChC,iBAAO;AAAA,YACL,SAAS;AAAA,cACP;AAAA,gBACE,MAAM;AAAA,gBACN,MAAM,GAAG,iBAAiB,QAAQ,MAAM,OAAO,OAAO,KAAK,GAAG;AAAA,cAChE;AAAA,cACA,GAAI,QACA;AAAA,gBACE;AAAA,kBACE,MAAM;AAAA,kBACN,MAAM;AAAA,eAAkB,iBAAiB,QAAQ,MAAM,QAAQ,0BAA0B;AAAA,gBAC3F;AAAA,cACF,IACA,CAAC;AAAA,YACP;AAAA,YACA,SAAS;AAAA,UACX;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;;;AkBpEA,eAAsB,iBAAiB;AACrC,MAAI,6CAAsC;AAE1C,MAAI;AACJ,MAAI;AACF,UAAM,MAAM,KAAK,IAAqB,oBAAoB;AAAA,EAC5D,SAAS,OAAO;AACd;AAAA,MACE;AAAA,MACA,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,IACvD;AACA,UAAM;AAAA,EACR;AAEA,MAAI,CAAC,MAAM,QAAQ,GAAG;AACpB,UAAM,IAAI,MAAM,kEAAkE;AAEpF,MAAI,gDAA2C;AACjD;;;AnBZA,OAAO;AAQP,IAAI,OAAO,QAAQ,KAAK,MAAM,CAAC;AAG/B,IAAI,KAAK,UAAU,KAAK,KAAK,CAAC,MAAM,OAAO;AACzC,SAAO,CAAC,WAAW,KAAK,CAAC,GAAG,aAAa,KAAK,CAAC,GAAG,GAAG,KAAK,MAAM,CAAC,CAAC;AACpE;AAEA,IAAM,UAAU,IAAI,QAAQ,EACzB,OAAO,4BAA4B,kBAAkB,OAAO,EAC5D,OAAO,mBAAmB,2BAA2B,MAAM,EAC3D,OAAO,mBAAmB,eAAe,EACzC,OAAO,mBAAmB,iBAAiB,EAC3C,OAAO,WAAW,mBAAmB,EACrC,mBAAmB;AAEtB,QAAQ,MAAM,MAAM,EAAE,MAAM,OAAO,CAAC;AAEpC,IAAM,aAAa,QAAQ,KAMxB;AAEI,IAAM,QAAQ,WAAW,SAAS;AAGzC,IAAM,oBAAoB,CAAC,SAAS,MAAM;AAC1C,IAAI,CAAC,kBAAkB,SAAS,WAAW,SAAS,GAAG;AACrD,UAAQ;AAAA,IACN,+BAA+B,WAAW,SAAS;AAAA,EACrD;AACA,UAAQ,KAAK,CAAC;AAChB;AAGA,IAAM,iBAAkB,WAAW,aAAa;AAGhD,IAAM,iBAAiB,QAAQ,KAAK,SAAS,QAAQ;AAErD,IAAI,mBAAmB,WAAW,gBAAgB;AAChD,UAAQ,MAAM,8DAA8D;AAC5E,UAAQ,KAAK,CAAC;AAChB;AAGA,IAAM,YAAY,MAAM;AACtB,QAAM,SAAS,OAAO,SAAS,WAAW,MAAM,EAAE;AAClD,SAAO,OAAO,MAAM,MAAM,IAAI,SAAY;AAC5C,GAAG;AAEH,eAAe,OAAO;AAEpB,QAAM,QAAQ,WAAW,SAAS,QAAQ,IAAI;AAC9C,QAAM,SAAS,WAAW,UAAU,QAAQ,IAAI;AAEhD,MAAI,CAAC,SAAS,CAAC,QAAQ;AACrB,YAAQ;AAAA,MACN;AAAA,IACF;AACA,YAAQ,KAAK,CAAC;AAAA,EAChB;AAGA,SAAO,QAAQ;AACf,SAAO,SAAS;AAGhB,QAAM,eAAe;AAErB,QAAM,gBAAgB;AAEtB,MAAI,kBAAkB,QAAQ;AAE5B,UAAM,cAAc,YAAY;AAEhC,QAAI,aAAa;AACjB,UAAM,aAAa,aAAa,OAAO,KAAsB,QAAa;AACxE,YAAM,WAAW,IAAK,WAAmB,IAAI,IAAI,OAAO,IAAI,UAAU,IAAI,QAAQ,IAAI,EAAE,EACrF;AAGH,UAAI,UAAU,+BAA+B,GAAG;AAChD,UAAI,UAAU,gCAAgC,yBAAyB;AACvE,UAAI;AAAA,QACF;AAAA,QACA;AAAA,MACF;AACA,UAAI,UAAU,iCAAiC,gBAAgB;AAG/D,UAAI,IAAI,WAAW,WAAW;AAC5B,YAAI,UAAU,GAAG;AACjB,YAAI,IAAI;AACR;AAAA,MACF;AAEA,UAAI;AAEF,cAAM,gBAAgB,qBAAqB;AAE3C,YAAI,aAAa,QAAQ;AACvB,gBAAM,YAAY,IAAI,8BAA8B;AAAA,YAClD,oBAAoB;AAAA,UACtB,CAAC;AACD,gBAAM,cAAc,QAAQ,SAAS;AACrC,gBAAM,UAAU,cAAc,KAAK,GAAG;AAAA,QACxC,WAAW,aAAa,SAAS;AAC/B,cAAI,UAAU,KAAK,EAAE,gBAAgB,mBAAmB,CAAC;AACzD,cAAI,IAAI,KAAK,UAAU,EAAE,QAAQ,MAAM,SAAS,OAAO,CAAC,CAAC;AAAA,QAC3D,OAAO;AACL,cAAI,UAAU,KAAK,EAAE,gBAAgB,mBAAmB,CAAC;AACzD,cAAI,IAAI,KAAK,UAAU,EAAE,OAAO,aAAa,QAAQ,IAAI,CAAC,CAAC;AAAA,QAC7D;AAAA,MACF,SAAS,OAAO;AACd,gBAAQ,MAAM,2BAA2B,KAAK;AAC9C,YAAI,CAAC,IAAI,aAAa;AACpB,cAAI,UAAU,GAAG;AACjB,cAAI,IAAI,uBAAuB;AAAA,QACjC;AAAA,MACF;AAAA,IACF,CAAC;AAGD,UAAM,cAAc,CAAC,MAAc,cAAc,OAAO;AACtD,iBAAW,KAAK,SAAS,CAAC,QAA+B;AACvD,YAAI,IAAI,SAAS,gBAAgB,OAAO,cAAc,aAAa;AACjE,kBAAQ,KAAK,QAAQ,IAAI,2BAA2B,OAAO,CAAC,KAAK;AACjE,sBAAY,OAAO,GAAG,WAAW;AAAA,QACnC,OAAO;AACL,kBAAQ,MAAM,2BAA2B,IAAI,OAAO,EAAE;AACtD,kBAAQ,KAAK,CAAC;AAAA,QAChB;AAAA,MACF,CAAC;AAED,iBAAW,OAAO,MAAM,MAAM;AAC5B,qBAAa;AACb,gBAAQ;AAAA,UACN,iCAAiC,cAAc,YAAY,CAAC,wBAAwB,UAAU;AAAA,QAChG;AAAA,MACF,CAAC;AAAA,IACH;AAGA,gBAAY,WAAW;AAAA,EACzB,OAAO;AAEL,UAAM,SAAS,qBAAqB;AACpC,UAAM,YAAY,IAAI,qBAAqB;AAU3C,UAAM,OAAO,QAAQ,SAAS;AAC9B,YAAQ,MAAM,qCAAqC;AAAA,EACrD;AACF;AAGA,KAAK,EAAE,MAAM,CAAC,UAAU;AACtB,UAAQ,MAAM,0BAA0B,KAAK;AAC7C,UAAQ,KAAK,CAAC;AAChB,CAAC;","names":["z","config","req","z","z","fetch","z","z","z","z","z","z","z","json","tool","z","tool","z"]}Report false positiveDecoded base64 content: {"command":"npx","args":["-y","@upstash/mcp-server@latest","--email","YOUR_EMAIL","--api-key","YOUR_
Detected by automated pattern matching (rule DO-BAS) with medium confidence. May be a false positive.
Report false positiveDecoded base64 content: Z��~Z0.�,E�)�{
Detected by automated pattern matching (rule DO-BAS) with medium confidence. May be a false positive.
Report false positiveDecoded base64 content: J�b�'���ӭ�즊�
Detected by automated pattern matching (rule DO-BAS) with medium confidence. May be a false positive.
Report false positiveDecoded base64 content: }�����jY[i���^
Detected by automated pattern matching (rule DO-BAS) with medium confidence. May be a false positive.
Report false positiveDecoded base64 content: �o���,��j�ץz
Detected by automated pattern matching (rule DO-BAS) with medium confidence. May be a false positive.
Report false positiveDecoded base64 content: �o���,��j����g�
Detected by automated pattern matching (rule DO-BAS) with medium confidence. May be a false positive.
Report false positiveDecoded base64 content: r���䞮��"{-jw
Detected by automated pattern matching (rule DO-BAS) with medium confidence. May be a false positive.
Report false positiveDecoded base64 content: r���䞮��"{-jw
Detected by automated pattern matching (rule DO-BAS) with medium confidence. May be a false positive.
Report false positiveDecoded base64 content: r���䞮��"{-jw
Detected by automated pattern matching (rule DO-BAS) with medium confidence. May be a false positive.
Report false positiveDecoded base64 content: J�b�'���ӭ�즊�
Detected by automated pattern matching (rule DO-BAS) with medium confidence. May be a false positive.
Report false positiveDecoded base64 content: �����(���yج��&���
Detected by automated pattern matching (rule DO-BAS) with medium confidence. May be a false positive.
Report false positiveDecoded base64 content: �����(���֬�����!
Detected by automated pattern matching (rule DO-BAS) with medium confidence. May be a false positive.
Report false positiveDecoded base64 content: J�b�'���ӭ�즊�
Detected by automated pattern matching (rule DO-BAS) with medium confidence. May be a false positive.
Report false positiveDecoded base64 content: r���䞮��"{-jw
Detected by automated pattern matching (rule DO-BAS) with medium confidence. May be a false positive.
Report false positiveDecoded base64 content: r���䞮��"{-jw
Detected by automated pattern matching (rule DO-BAS) with medium confidence. May be a false positive.
Report false positiveDecoded base64 content: r���䞮��"{-jw
Detected by automated pattern matching (rule DO-BAS) with medium confidence. May be a false positive.
Report false positiveDecoded base64 content: J�b�'���ӭ�즊�
Detected by automated pattern matching (rule DO-BAS) with medium confidence. May be a false positive.
Report false positiveDecoded base64 content: r���䞮��"{-jw
Detected by automated pattern matching (rule DO-BAS) with medium confidence. May be a false positive.
Report false positiveDecoded base64 content: A+Z����n��y�^E�)�{
Detected by automated pattern matching (rule DO-BAS) with medium confidence. May be a false positive.
Report false positiveDecoded base64 content: A+Z����n��y�^E�)�{
Detected by automated pattern matching (rule DO-BAS) with medium confidence. May be a false positive.
Report false positiveDecoded base64 content: Z��~Z0.�,E�)�{
Detected by automated pattern matching (rule DO-BAS) with medium confidence. May be a false positive.
Report false positiveDecoded base64 content: Z��~Z0.�,E�)�{
Detected by automated pattern matching (rule DO-BAS) with medium confidence. May be a false positive.
Report false positiveDecoded base64 content: }�����jY[i���^
Detected by automated pattern matching (rule DO-BAS) with medium confidence. May be a false positive.
Report false positiveDecoded base64 content: �o���,��j�ץz
Detected by automated pattern matching (rule DO-BAS) with medium confidence. May be a false positive.
Report false positiveDecoded base64 content: �o���,��j����g�
Detected by automated pattern matching (rule DO-BAS) with medium confidence. May be a false positive.
Report false positiveDecoded base64 content: �eN�%E�.�Ԝ��
Detected by automated pattern matching (rule DO-BAS) with medium confidence. May be a false positive.
Report false positiveDecoded base64 content: �eN�%E�.�Ԝ��
Detected by automated pattern matching (rule DO-BAS) with medium confidence. May be a false positive.
Report false positiveDecoded base64 content: �eN�%E�.�Ԝ��
Detected by automated pattern matching (rule DO-BAS) with medium confidence. May be a false positive.
Report false positiveHigh-entropy string (4.7 bits/char) — possible encoded payload
Detected by automated pattern matching (rule EN-001) with medium confidence. May be a false positive.
Report false positiveHigh-entropy string (4.8 bits/char) — possible encoded payload
Detected by automated pattern matching (rule EN-001) with medium confidence. May be a false positive.
Report false positiveHigh-entropy string (4.8 bits/char) — possible encoded payload
Detected by automated pattern matching (rule EN-001) with medium confidence. May be a false positive.
Report false positiveHigh-entropy string (4.6 bits/char) — possible encoded payload
Detected by automated pattern matching (rule EN-001) with medium confidence. May be a false positive.
Report false positiveHigh-entropy string (4.8 bits/char) — possible encoded payload
Detected by automated pattern matching (rule EN-001) with medium confidence. May be a false positive.
Report false positiveHigh-entropy string (4.5 bits/char) — possible encoded payload
Detected by automated pattern matching (rule EN-001) with medium confidence. May be a false positive.
Report false positiveHigh-entropy string (4.9 bits/char) — possible encoded payload
Detected by automated pattern matching (rule EN-001) with medium confidence. May be a false positive.
Report false positiveHigh-entropy string (4.8 bits/char) — possible encoded payload
Detected by automated pattern matching (rule EN-001) with medium confidence. May be a false positive.
Report false positiveJavaScript fetch() call
Detected by automated pattern matching (rule NS-003) with medium confidence. May be a false positive.
>>> 1: {"version":3,"sources":["../src/index.ts","../src/server.ts","../src/log.ts","../src/tools/utils.ts","../src/tools/redis/backup.ts","../src/config.ts","../src/middlewares.ts","../src/http.ts","../src/tools/redis/command.ts","../src/tools/redis/db.ts","../src/utils.ts","../src/tools/redis/index.ts","../src/tools/qstash/qstash.ts","../src/tools/qstash/utils.ts","../src/tools/qstash/workflow.ts","../src/tools/qstash/index.ts","../src/tools/index.ts","../src/settings.ts","../src/tool.ts","../src/test-connection.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { StreamableHTTPServerTransport } from \"@modelcontextprotocol/sdk/server/streamableHttp.js\";\nimport { Command } from \"commander\";\n// eslint-disable-next-line unicorn/prefer-node-protocol\nimport { createServer, type IncomingMessage } from \"http\";\nimport { createServerInstance } from \"./server.js\";\nimport { config } from \"./config\";\nimport { testConnection } from \"./test-connection\";\nimport \"dotenv/config\";\n\n/**\n * Last version of the MCP server required \"run\" command to be used.\n * This is a backwards compatibility fix to allow the MCP server to be used with the old command.\n */\n\n// Handle legacy 'run' command format before parsing\nlet argv = process.argv.slice(2);\n\n// Check for legacy format and transform it to the new format\nif (argv.length >= 3 && argv[0] === \"run\") {\n argv = [\"--email\", argv[1], \"--api-key\", argv[2], ...argv.slice(3)];\n}\n\nconst program = new Command()\n .option(\"--transport <stdio|http>\", \"transport type\", \"stdio\")\n .option(\"--port <number>\", \"port for HTTP transport\", \"3000\")\n .option(\"--email <email>\", \"Upstash email\")\n .option(\"--api-key <key>\", \"Upstash API key\")\n .option(\"--debug\", \"Enable debug mode\")\n .allowUnknownOption(); // let other wrappers pass through extra flags\n\nprogram.parse(argv, { from: \"user\" });\n\nconst cliOptions = program.opts<{\n transport: string;\n port: string;\n email?: string;\n apiKey?: string;\n debug?: boolean;\n}>();\n\nexport const DEBUG = cliOptions.debug ?? false;\n\n// Validate transport option\nconst allowedTransports = [\"stdio\", \"http\"];\nif (!allowedTransports.includes(cliOptions.transport)) {\n console.error(\n `Invalid --transport value: '${cliOptions.transport}'. Must be one of: stdio, http.`\n );\n process.exit(1);\n}\n\n// Transport configuration\nconst TRANSPORT_TYPE = (cliOptions.transport || \"stdio\") as \"stdio\" | \"http\";\n\n// Disallow incompatible flags based on transport\nconst passedPortFlag = process.argv.includes(\"--port\");\n\nif (TRANSPORT_TYPE === \"stdio\" && passedPortFlag) {\n console.error(\"The --port flag is not allowed when using --transport stdio.\");\n process.exit(1);\n}\n\n// HTTP port configuration\nconst CLI_PORT = (() => {\n const parsed = Number.parseInt(cliOptions.port, 10);\n return Number.isNaN(parsed) ? undefined : parsed;\n})();\n\nasync function main() {\n // Get credentials from CLI options or environment\n const email = cliOptions.email || process.env.UPSTASH_EMAIL;\n const apiKey = cliOptions.apiKey || process.env.UPSTASH_API_KEY;\n\n if (!email || !apiKey) {\n console.error(\n \"Missing required credentials. Provide --email and --api-key or set UPSTASH_EMAIL and UPSTASH_API_KEY environment variables.\"\n );\n process.exit(1);\n }\n\n // Set config\n config.email = email;\n config.apiKey = apiKey;\n\n // Test connection\n await testConnection();\n\n const transportType = TRANSPORT_TYPE;\n\n if (transportType === \"http\") {\n // Get initial port from environment or use default\n const initialPort = CLI_PORT ?? 3000;\n // Keep track of which port we end up using\n let actualPort = initialPort;\n const httpServer = createServer(async (req: IncomingMessage, res: any) => {\n const pathname = new (globalThis as any).URL(req.url || \"\", `http://${req.headers.host}`)\n .pathname;\n\n // Set CORS headers for all responses\n res.setHeader(\"Access-Control-Allow-Origin\", \"*\");\n res.setHeader(\"Access-Control-Allow-Methods\", \"GET,POST,OPTIONS,DELETE\");\n res.setHeader(\n \"Access-Control-Allow-Headers\",\n \"Content-Type, MCP-Session-Id, MCP-Protocol-Version, X-Upstash-API-Key, Upstash-API-Key, X-API-Key, Authorization\"\n );\n res.setHeader(\"Access-Control-Expose-Headers\", \"MCP-Session-Id\");\n\n // Handle preflight OPTIONS requests\n if (req.method === \"OPTIONS\") {\n res.writeHead(200);\n res.end();\n return;\n }\n\n try {\n // Create new server instance for each request\n const requestServer = createServerInstance();\n\n if (pathname === \"/mcp\") {\n const transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: undefined,\n });\n await requestServer.connect(transport);\n await transport.handleRequest(req, res);\n } else if (pathname === \"/ping\") {\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ status: \"ok\", message: \"pong\" }));\n } else {\n res.writeHead(404, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: \"Not found\", status: 404 }));\n }\n } catch (error) {\n console.error(\"Error handling request:\", error);\n if (!res.headersSent) {\n res.writeHead(500);\n res.end(\"Internal Server Error\");\n }\n }\n });\n\n // Function to attempt server listen with port fallback\n const startServer = (port: number, maxAttempts = 10) => {\n httpServer.once(\"error\", (err: NodeJS.ErrnoException) => {\n if (err.code === \"EADDRINUSE\" && port < initialPort + maxAttempts) {\n console.warn(`Port ${port} is in use, trying port ${port + 1}...`);\n startServer(port + 1, maxAttempts);\n } else {\n console.error(`Failed to start server: ${err.message}`);\n process.exit(1);\n }\n });\n\n httpServer.listen(port, () => {\n actualPort = port;\n console.error(\n `Upstash MCP Server running on ${transportType.toUpperCase()} at http://localhost:${actualPort}/mcp`\n );\n });\n };\n\n // Start the server with initial port\n startServer(initialPort);\n } else {\n // Stdio transport - this is already stateless by nature\n const server = createServerInstance();\n const transport = new StdioServerTransport();\n\n // Log the RCP messages coming to the transport\n // const originalOnmessage = transport.onmessage;\n // transport.onmessage = (message) => {\n // console.error(\"message\", message);\n\n // originalOnmessage?.(message);\n // };\n\n await server.connect(transport);\n console.error(\"Upstash MCP Server running on stdio\");\n }\n}\n\n// eslint-disable-next-line unicorn/prefer-top-level-await\nmain().catch((error) => {\n console.error(\"Fatal error in main():\", error);\n process.exit(1);\n});\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { log } from \"./log\";\nimport { tools } from \"./tools\";\nimport { handlerResponseToCallResult } from \"./tool\";\nimport z from \"zod\";\nimport { DEBUG } from \".\";\n\n// Function to create a new server instance with all tools registered\nexport function createServerInstance() {\n const server = new McpServer(\n { name: \"upstash\", version: \"0.1.0\" },\n {\n capabilities: {\n tools: {},\n logging: {},\n },\n }\n );\n\n const toolsList = Object.entries(tools).map(([name, tool]) => ({\n name,\n description: tool.description,\n inputSchema: tool.inputSchema,\n tool,\n }));\n\n // Register all tools from the toolsList\n for (const toolDef of toolsList) {\n const toolName = toolDef.name;\n const tool = toolDef.tool;\n\n server.registerTool(\n toolName,\n {\n description: tool.description,\n inputSchema: ((tool.inputSchema ?? z.object({})) as any).shape,\n },\n // @ts-expect-error - Just ignore the types here\n async (args) => {\n log(\"< received tool call:\", toolName, args);\n\n try {\n const result = await tool.handler(args);\n const response = handlerResponseToCallResult(result);\n log(\"> tool result:\", response.content.map((item) => item.text).join(\"\\n\"));\n return response;\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n log(\"> error in tool call:\", msg);\n return {\n content: [\n {\n type: \"text\",\n text: `${error instanceof Error ? error.name : \"Error\"}: ${msg}`,\n },\n ...(DEBUG\n ? [\n {\n type: \"text\",\n text: `\\nStack trace: ${error instanceof Error ? error.stack : \"No stack trace available\"}`,\n },\n ]\n : []),\n ],\n isError: true,\n };\n }\n }\n );\n }\n\n return server;\n}\n","export function log(...args: unknown[]) {\n const msg = `[DEBUG ${new Date().toISOString()}] ${args.map((arg) => (typeof arg === \"string\" ? arg : JSON.stringify(arg))).join(\" \")}\\n`;\n\n for (const [, logs] of logsStore.entries()) {\n logs.push(msg);\n }\n\n process.stderr.write(msg);\n}\n\nconst logsStore = new Map<string, string[]>();\n\nexport function startCollectLogs() {\n const id = Array.from({ length: 10 })\n .fill(0)\n .map(() => Math.random().toString(36).slice(2, 15))\n .join(\"\");\n\n logsStore.set(id, []);\n\n return id;\n}\n\nexport function popLogs(id: string) {\n const logs = logsStore.get(id);\n\n if (!logs) {\n return [];\n }\n\n logsStore.delete(id);\n\n return logs;\n}\n","import { z } from \"zod\";\nimport { tool } from \".\";\n\nexport const utilTools = {\n util_timestamps_to_date: tool({\n description: `Use this tool to convert a timestamp to a human-readable date`,\n inputSchema: z.object({\n timestamps: z.array(z.number()).describe(\"Array of timestamps to convert\"),\n }),\n handler: async ({ timestamps }) => {\n return timestamps.map((timestamp) => new Date(timestamp).toUTCString());\n },\n }),\n util_dates_to_timestamps: tool({\n description: `Use this tool to convert an array of ISO 8601 dates to an array of timestamps`,\n inputSchema: z.object({\n dates: z.array(z.string()).describe(\"Array of dates to convert\"),\n }),\n handler: async ({ dates }) => {\n return dates.map((date) => new Date(date).getTime()).join(\",\");\n },\n }),\n};\n","import { z } from \"zod\";\nimport { json, tool } from \"..\";\nimport { http } from \"../../http\";\nimport type { RedisBackup } from \"./types\";\n\nexport const redisBackupTools = {\n redis_database_manage_backup: tool({\n description: `Create, delete, or restore backups for a specific Upstash redis database. This tool handles all backup operations in one unified interface.`,\n inputSchema: z.object({\n database_id: z.string().describe(\"The ID of the database to manage backups for.\"),\n operation: z\n .union([z.literal(\"create\"), z.literal(\"delete\"), z.literal(\"restore\")])\n .describe(\"The backup operation to perform: create, delete, or restore.\"),\n backup_name: z\n .string()\n .optional()\n .describe(\"Name for the backup (required for create operation).\"),\n backup_id: z\n .string()\n .optional()\n .describe(\"ID of the backup (required for delete and restore operations).\"),\n }),\n handler: async ({ database_id, operation, backup_name, backup_id }) => {\n switch (operation) {\n case \"create\": {\n if (!backup_name) {\n throw new Error(\"backup_name is required for create operation\");\n }\n await http.post([\"v2/redis/create-backup\", database_id], {\n name: backup_name,\n });\n return `Backup \"${backup_name}\" created successfully for database ${database_id}.`;\n }\n\n case \"delete\": {\n if (!backup_id) {\n throw new Error(\"backup_id is required for delete operation\");\n }\n await http.delete([\"v2/redis/delete-backup\", database_id, backup_id]);\n return `Backup ${backup_id} deleted successfully from database ${database_id}.`;\n }\n\n case \"restore\": {\n if (!backup_id) {\n throw new Error(\"backup_id is required for restore operation\");\n }\n await http.post([\"v2/redis/restore-backup\", database_id], {\n backup_id,\n });\n return `Backup ${backup_id} restored successfully to database ${database_id}.`;\n }\n\n default: {\n throw new Error(`Invalid operation: ${operation}. Use create, delete, or restore.`);\n }\n }\n },\n }),\n\n redis_database_list_backups: tool({\n // TODO: Add explanation for fields\n // TODO: Is this in bytes?\n description: `List all backups of a specific Upstash redis database.`,\n inputSchema: z.object({\n database_id: z.string().describe(\"The ID of the database to list backups for.\"),\n }),\n handler: async ({ database_id }) => {\n const backups = await http.get<RedisBackup[]>([\"v2/redis/list-backup\", database_id]);\n\n return json(backups);\n },\n }),\n\n redis_database_set_daily_backup: tool({\n description: `Enable or disable daily backups for a specific Upstash redis database.`,\n inputSchema: z.object({\n database_id: z\n .string()\n .describe(\"The ID of the database to enable or disable daily backups for.\"),\n enable: z.boolean().describe(\"Whether to enable or disable daily backups.\"),\n }),\n handler: async ({ database_id, enable }) => {\n await http.patch([\n `v2/redis/${enable ? \"enable-dailybackup\" : \"disable-dailybackup\"}`,\n database_id,\n ]);\n\n return \"OK\";\n },\n }),\n};\n","export const config = {\n apiKey: \"\",\n email: \"\",\n};\n","import type { UpstashRequest } from \"./http\";\n\ntype Middleware = (req: UpstashRequest, next: () => Promise<unknown>) => Promise<unknown>;\n\nconst formatTimestamps = (obj: unknown): void => {\n if (!obj || typeof obj !== \"object\") {\n return;\n }\n\n // Handle arrays\n if (Array.isArray(obj)) {\n for (const item of obj) {\n formatTimestamps(item);\n }\n return;\n }\n\n // Handle objects\n for (const [key, value] of Object.entries(obj)) {\n // Check if key matches our criteria: contains \"creationTime\" or has \"createdAt\" anywhere (case-insensitive)\n const shouldFormat =\n typeof value === \"number\" &&\n (key === \"creationTime\" ||\n key === \"creation_time\" ||\n key === \"time\" ||\n key.toLowerCase().includes(\"createdat\"));\n\n if (shouldFormat && typeof value === \"number\" && value > 0) {\n // Format timestamp to human readable format\n // Assume timestamps > 1_000_000_000_000 are in milliseconds, otherwise seconds\n const timestamp = value > 1_000_000_000_000 ? value : value * 1000;\n\n // Show milliseconds in the human readable format\n\n const formatted = new Date(timestamp).toLocaleString(\"en-US\", { timeZoneName: \"short\" });\n (obj as any)[key] = `${formatted} (${value})`;\n } else if (value && typeof value === \"object\") {\n // Recursively process nested objects\n formatTimestamps(value);\n }\n }\n};\n\nconst middlewares: Middleware[] = [\n // Middleware to format timestamp fields to human readable format\n async (req, next) => {\n const res = await next();\n formatTimestamps(res);\n return res;\n },\n];\n\nexport const applyMiddlewares = async (\n req: UpstashRequest,\n func: (req: UpstashRequest) => Promise<unknown>\n) => {\n let next = async () => func(req);\n for (const middleware of middlewares.reverse()) {\n const prevNext = next;\n next = async () => middleware(req, prevNext);\n }\n return next();\n};\n","import { config } from \"./config\";\nimport { log } from \"./log\";\nimport { applyMiddlewares } from \"./middlewares\";\nimport type { RequestInit } from \"node-fetch\";\nimport fetch from \"node-fetch\";\nimport { json } from \"./tools\";\n\nexport type UpstashRequest = {\n method: string;\n path?: string[] | string;\n /**\n * Request body will be serialized to json\n */\n body?: unknown;\n /**\n * Query parameters, object and undefined will be ignored\n */\n query?: Record<string, string | number | boolean | undefined | object>;\n /**\n * Custom headers\n */\n headers?: Record<string, string>;\n /**\n * Optional QStash token - if provided, will use Bearer auth instead of Basic auth\n */\n qstashToken?: string;\n};\n\nexport type HttpClientConfig = {\n baseUrl: string;\n /**\n * Optional QStash token for Bearer authentication\n */\n qstashToken?: string;\n};\n\nexport class HttpClient {\n private readonly baseUrl: string;\n private readonly qstashToken?: string;\n\n public constructor(config: HttpClientConfig) {\n this.baseUrl = config.baseUrl.replace(/\\/$/, \"\");\n this.qstashToken = config.qstashToken;\n }\n\n public async get<TResponse>(\n path: string[] | string,\n query?: Record<string, string | number | boolean | undefined | object>\n ): Promise<TResponse> {\n return this.requestWithMiddleware<TResponse>({ method: \"GET\", path, query });\n }\n\n public async post<TResponse>(\n path: string[] | string,\n body?: unknown,\n headers?: Record<string, string>\n ): Promise<TResponse> {\n return this.requestWithMiddleware<TResponse>({ method: \"POST\", path, body, headers });\n }\n\n public async put<TResponse>(\n path: string[] | string,\n body?: unknown,\n headers?: Record<string, string>\n ): Promise<TResponse> {\n return this.requestWithMiddleware<TResponse>({ method: \"PUT\", path, body, headers });\n }\n\n public async patch<TResponse>(path: string[] | string, body?: unknown): Promise<TResponse> {\n return this.requestWithMiddleware<TResponse>({ method: \"PATCH\", path, body });\n }\n\n public async delete<TResponse>(path: string[] | string, body?: unknown): Promise<TResponse> {\n return this.requestWithMiddleware<TResponse>({ method: \"DELETE\", path, body });\n }\n\n private async requestWithMiddleware<TResponse>(req: UpstashRequest): Promise<TResponse> {\n const res = await applyMiddlewares(req, async (req) => {\n return this.request<TResponse>(req);\n });\n\n return res as TResponse;\n }\n\n private async request<TResponse>(req: UpstashRequest): Promise<TResponse> {\n if (!req.path) {\n req.path = [];\n } else if (typeof req.path === \"string\") {\n req.path = [req.path];\n }\n\n let url = [this.baseUrl, ...req.path].join(\"/\");\n\n // Add query parameters\n if (req.query) {\n const queryPairs: string[] = [];\n for (const [key, value] of Object.entries(req.query)) {\n if (value !== undefined && value !== null && typeof value !== \"object\") {\n queryPairs.push(`${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`);\n }\n }\n if (queryPairs.length > 0) {\n url += `?${queryPairs.join(\"&\")}`;\n }\n }\n\n // Determine authentication method\n const qstashToken = req.qstashToken || this.qstashToken;\n let authHeader: string;\n\n if (qstashToken) {\n authHeader = `Bearer ${qstashToken}`;\n } else {\n const token = [config.email, config.apiKey].join(\":\");\n authHeader = `Basic ${Buffer.from(token).toString(\"base64\")}`;\n }\n\n const init: RequestInit = {\n method: req.method,\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: authHeader,\n ...req.headers,\n },\n };\n\n if (req.method !== \"GET\" && req.body !== undefined) {\n init.body = JSON.stringify(req.body);\n }\n\n log(\"-> sending request\", {\n url,\n ...init,\n headers: {\n ...init.headers,\n Authorization: \"***\",\n },\n });\n\n // fetch is defined by isomorphic fetch\n const res = await fetch(url, init);\n if (!res.ok) {\n throw new Error(`Request failed (${res.status} ${res.statusText}): ${await res.text()}`);\n }\n\n // Handle empty responses\n const text = await res.text();\n if (!text) {\n return {} as TResponse;\n }\n\n const result = safeParseJson(text) as TResponse;\n\n if (result) {\n log(\"<- received response\", json(result));\n } else {\n log(\"<- received text response\", text);\n }\n\n return result || (text as TResponse);\n }\n}\n\nconst safeParseJson = <TResponse>(text: string) => {\n try {\n return JSON.parse(text) as TResponse;\n } catch {\n return;\n }\n};\n\nexport const http = new HttpClient({ baseUrl: \"https://api.upstash.com\" });\n\n/**\n * Creates a QStash-enabled HttpClient with the provided token\n */\nexport function createQStashClient({ url, token }: { url?: string; token: string }): HttpClient {\n return new HttpClient({\n baseUrl: url ?? \"https://qstash.upstash.io\",\n qstashToken: token,\n });\n}\n","import { z } from \"zod\";\nimport { json, tool } from \"..\";\nimport { log } from \"../../log\";\nimport { http } from \"../../http\";\nimport type { RedisDatabase } from \"./types\";\nimport fetch from \"node-fetch\";\n\ntype RedisCommandResult =\n | {\n result: unknown;\n }\n | {\n error: string;\n };\n\nexport const redisCommandTools = {\n redis_database_run_redis_commands: tool({\n description: `Run one or more Redis commands on a specific Upstash redis database. Either provide database_id OR both database_rest_url and database_rest_token.\nNOTE: For discovery, use SCAN over KEYS. Use TYPE to get the type of a key.\nNOTE: SCAN cursor [MATCH pattern] [COUNT count] [TYPE type]\nNOTE: Multiple commands will be executed as a pipeline for better performance.`,\n inputSchema: z.object({\n database_id: z.string().optional().describe(\"The ID of the database to run commands on.\"),\n database_rest_url: z\n .string()\n .optional()\n .describe(\"The REST URL of the database. Example: https://***.upstash.io\"),\n database_rest_token: z.string().optional().describe(\"The REST token of the database.\"),\n commands: z\n .array(z.array(z.string()))\n .describe(\n \"The Redis commands to run. For single command: [['SET', 'foo', 'bar']], for multiple: [['SET', 'foo', 'bar'], ['GET', 'foo']]\"\n ),\n }),\n\n handler: async ({ database_id, database_rest_url, database_rest_token, commands }) => {\n if (database_id && (database_rest_url || database_rest_token)) {\n throw new Error(\n \"Either provide database_id OR both database_rest_url and database_rest_token\"\n );\n } else if (!database_id && (!database_rest_url || !database_rest_token)) {\n throw new Error(\n \"Either provide database_id OR both database_rest_url and database_rest_token\"\n );\n }\n\n let restUrl = database_rest_url;\n let restToken = database_rest_token;\n\n // If only database_id is provided, fetch the database details\n if (database_id && (!database_rest_url || !database_rest_token)) {\n log(\"Fetching database details for database_id:\", database_id);\n const db = await http.get<RedisDatabase>([\"v2/redis/database\", database_id]);\n restUrl = \"https://\" + db.endpoint;\n restToken = db.rest_token;\n }\n\n if (!restUrl || !restToken) {\n throw new Error(\"Could not determine REST URL and token for the database\");\n }\n const isSingleCommand = commands.length === 1;\n const url = isSingleCommand ? restUrl : restUrl + \"/pipeline\";\n const body = isSingleCommand ? JSON.stringify(commands[0]) : JSON.stringify(commands);\n\n const req = await fetch(url, {\n method: \"POST\",\n body,\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${restToken}`,\n },\n });\n\n if (isSingleCommand) {\n const result = (await req.json()) as RedisCommandResult;\n\n log(\"command result:\", result);\n\n if (\"error\" in result) {\n throw new Error(\"Redis error: \" + result.error);\n }\n\n const isScanCommand = commands[0][0].toLocaleLowerCase().includes(\"scan\");\n const messages = [json(result)];\n\n if (isScanCommand)\n messages.push(`NOTE: Use the returned cursor to get the next set of keys.\nNOTE: The result might be too large to be returned. If applicable, stop after the second SCAN command and ask the user if they want to continue.`);\n\n return messages;\n } else {\n const result = (await req.json()) as RedisCommandResult[];\n\n log(\"commands result:\", result);\n\n if (result.some((r) => \"error\" in r)) {\n throw new Error(\"Some commands in the pipeline resulted in an error:\\n\" + json(result));\n }\n\n return json(result);\n }\n },\n }),\n};\n","import { z } from \"zod\";\nimport { json, tool } from \"..\";\nimport { http } from \"../../http\";\nimport type { RedisDatabase, RedisUsageResponse, UsageData } from \"./types\";\nimport { pruneFalsy } from \"../../utils\";\n\nconst readRegionSchema = z.union([\n z.literal(\"us-east-1\"),\n z.literal(\"us-west-1\"),\n z.literal(\"us-west-2\"),\n z.literal(\"eu-west-1\"),\n z.literal(\"eu-central-1\"),\n z.literal(\"ap-southeast-1\"),\n z.literal(\"ap-southeast-2\"),\n z.literal(\"sa-east-1\"),\n]);\n\nconst GENERIC_DATABASE_NOTES =\n \"\\nNOTE: Don't show the database ID from the response to the user unless explicitly asked or needed.\\n\";\n\nexport const redisDbOpsTools = {\n redis_database_create_new: tool({\n description: `Create a new Upstash redis database. \nNOTE: Ask user for the region and name of the database.${GENERIC_DATABASE_NOTES}`,\n inputSchema: z.object({\n name: z.string().describe(\"Name of the database.\"),\n primary_region: readRegionSchema.describe(`Primary Region of the Global Database.`),\n read_regions: z\n .array(readRegionSchema)\n .optional()\n .describe(`Array of read regions of the db`),\n }),\n handler: async ({ name, primary_region, read_regions }) => {\n const newDb = await http.post<RedisDatabase>(\"v2/redis/database\", {\n name,\n region: \"global\",\n primary_region,\n read_regions,\n });\n\n return [\n json(newDb),\n `Upstash console url: https://console.upstash.com/redis/${newDb.database_id}`,\n ];\n },\n }),\n\n redis_database_delete: tool({\n description: `Delete an Upstash redis database.`,\n inputSchema: z.object({\n database_id: z.string().describe(\"The ID of the database to delete.\"),\n }),\n handler: async ({ database_id }) => {\n await http.delete([\"v2/redis/database\", database_id]);\n\n return \"Database deleted successfully.\";\n },\n }),\n\n redis_database_list_databases: tool({\n description: `List all Upstash redis databases. Only their names and ids.${GENERIC_DATABASE_NOTES}`,\n handler: async () => {\n const dbs = await http.get<RedisDatabase[]>(\"v2/redis/databases\");\n\n const messages = [\n json(\n dbs.map((db) => {\n const result = {\n database_id: db.database_id,\n database_name: db.database_name,\n state: db.state === \"active\" ? undefined : db.state,\n };\n return pruneFalsy(result);\n })\n ),\n ];\n\n if (dbs.length > 2)\n messages.push(\n `NOTE: If the user did not specify a database name for the next command, ask them to choose a database from the list.`\n );\n messages.push(\n \"NOTE: If the user wants to see dbs in another team, mention that they need to create a new management api key for that team and initialize MCP server with the newly created key.\"\n );\n\n return messages;\n },\n }),\n\n redis_database_get_details: tool({\n description: `Get further details of a specific Upstash redis database. Includes all details of the database including usage statistics.\ndb_disk_threshold: Total disk usage limit.\ndb_memory_threshold: Maximum memory usage.\ndb_daily_bandwidth_limit: Maximum daily network bandwidth usage.\ndb_request_limit: Total number of commands allowed.\nAll sizes are in bytes\n${GENERIC_DATABASE_NOTES}\n `,\n inputSchema: z.object({\n database_id: z.string().describe(\"The ID of the database to get details for.\"),\n }),\n handler: async ({ database_id }) => {\n const db = await http.get<RedisDatabase>([\"v2/redis/database\", database_id]);\n\n return json(db);\n },\n }),\n\n redis_database_update_regions: tool({\n description: `Update the read regions of an Upstash redis database.`,\n inputSchema: z.object({\n id: z.string().describe(\"The ID of your database.\"),\n read_regions: z\n .array(readRegionSchema)\n .describe(\n \"Array of the new read regions of the database. This will replace the old regions array. Available regions: us-east-1, us-west-1, us-west-2, eu-west-1, eu-central-1, ap-southeast-1, ap-southeast-2, sa-east-1\"\n ),\n }),\n handler: async ({ id, read_regions }) => {\n const updatedDb = await http.post<RedisDatabase>([\"v2/redis/update-regions\", id], {\n read_regions,\n });\n\n return json(updatedDb);\n },\n }),\n\n redis_database_reset_password: tool({\n description: `Reset the password of an Upstash redis database.`,\n inputSchema: z.object({\n id: z.string().describe(\"The ID of your database.\"),\n }),\n handler: async ({ id }) => {\n const updatedDb = await http.post<RedisDatabase>([\"v2/redis/reset-password\", id], {});\n\n return json(updatedDb);\n },\n }),\n\n redis_database_get_statistics: tool({\n description: `Get comprehensive usage statistics of an Upstash redis database. Returns both:\n1. PRECISE 5-day usage: Exact command count and bandwidth usage over the last 5 days\n2. SAMPLED period stats: Sampled statistics over a specified period (1h, 3h, 12h, 1d, 3d, 7d) for performance monitoring\n\nFor sampled stats, includes: read_latency_mean, write_latency_mean, keyspace, throughput (cmds/sec), diskusage\nNOTE: If user doesn't specify stat_type, defaults to \"throughput\" for sampled stats.\nNOTE: Ask user first if they want to see stats for each database separately or just for one.`,\n inputSchema: z.object({\n id: z.string().describe(\"The ID of your database.\"),\n period: z\n .union([\n z.literal(\"1h\"),\n z.literal(\"3h\"),\n z.literal(\"12h\"),\n z.literal(\"1d\"),\n z.literal(\"3d\"),\n z.literal(\"7d\"),\n ])\n .describe(\"The period for sampled stats.\"),\n stat_type: z\n .union([\n z.literal(\"read_latency_mean\"),\n z.literal(\"write_latency_mean\"),\n z.literal(\"keyspace\").describe(\"Number of keys in db\"),\n z\n .literal(\"throughput\")\n .describe(\"commands per second (sampled), calculate area for estimated count\"),\n z.literal(\"diskusage\").describe(\"Current disk usage in bytes\"),\n ])\n .optional()\n .describe(\"The type of sampled stat to get (defaults to 'throughput')\"),\n }),\n handler: async ({ id, period, stat_type }) => {\n const statType = stat_type || \"throughput\";\n const stats = await http.get<RedisUsageResponse>([\n \"v2/redis/stats\",\n `${id}?period=${period}`,\n ]);\n\n // Get the sampled stat\n const stat = stats[statType];\n if (!Array.isArray(stat))\n throw new Error(\n `Invalid stat_type provided: ${statType}. Valid keys are: ${Object.keys(stats).join(\", \")}`\n );\n\n // Return both 5-day precise stats and sampled stats\n return [\n json({\n // 5-day precise usage stats\n usage_last_5_days: {\n days: stats.days,\n command_usage: stats.dailyrequests,\n bandwidth_usage: stats.bandwidths,\n },\n // Sampled stats for the specified period and type\n sampled_stats: {\n period,\n stat_type: statType,\n data: parseUsageData(stat),\n },\n }),\n `NOTE: Times are calculated according to UTC+0`,\n `NOTE: Use the timestamps_to_date tool to parse timestamps if needed`,\n `NOTE: Don't try to plot multiple stats in the same chart`,\n ];\n },\n }),\n};\n\nconst parseUsageData = (data: UsageData) => {\n if (!data) return \"NO DATA\";\n if (!Array.isArray(data)) return \"INVALID DATA\";\n if (data.length === 0 || data.length === 1) return \"NO DATA\";\n const filteredData = data.filter((d) => d.x && d.y);\n return {\n start: filteredData[0].x,\n // last one can be null, so use the second last\n // eslint-disable-next-line unicorn/prefer-at\n end: filteredData[filteredData.length - 1]?.x,\n data: data.map((d) => [new Date(d.x).getTime(), d.y]),\n };\n};\n","export function pruneFalsy(obj: Record<string, any>) {\n return Object.fromEntries(Object.entries(obj).filter(([, value]) => value));\n}\n","import { utilTools } from \"../utils\";\nimport { redisBackupTools } from \"./backup\";\nimport { redisCommandTools } from \"./command\";\nimport { redisDbOpsTools } from \"./db\";\nimport type { CustomTool } from \"../../tool\";\n\nexport const redisTools: Record<string, CustomTool> = {\n ...redisDbOpsTools,\n ...redisBackupTools,\n ...redisCommandTools,\n ...utilTools,\n};\n","import { z } from \"zod\";\nimport { json, tool } from \"..\";\nimport { http } from \"../../http\";\nimport { createQStashClientWithToken } from \"./utils\";\nimport type {\n QStashUser,\n QStashLogsResponse,\n QStashDLQResponse,\n QStashDLQMessage,\n QStashSchedule,\n QStashScheduleCreateResponse,\n} from \"./types\";\n\nexport const qstashCreds = {\n qstash_creds: z.undefined(),\n // qstash_creds: z\n // .object({\n // url: z.string(),\n // token: z.string(),\n // })\n // .optional()\n // .describe(\n // \"Optional qstash credentials. Use for local qstash connections and external qstash deployments\"\n // ),\n};\n\n// First, we need to get the QStash token\nexport const qstashTools = {\n qstash_get_user_token: tool({\n description: `Get the QSTASH_TOKEN and QSTASH_URL of the current user. This\n is not needed for the mcp tools since the token is automatically fetched from\n the Upstash API for them.`,\n handler: async () => {\n const user = await http.get<QStashUser>(\"qstash/user\");\n return [json(user)];\n },\n }),\n\n qstash_publish_message: tool({\n description: `Publish a message to a destination URL using QStash. This\n sends an HTTP request to the specified destination via QStash's message\n queue. This can also be used to trigger a upstash workflow run.`,\n inputSchema: z.object({\n destination: z\n .string()\n .describe(\"The destination URL to send the message to (e.g., 'https://example.com')\"),\n body: z.string().optional().describe(\"Request body (JSON string or plain text)\"),\n method: z\n .enum([\"GET\", \"POST\", \"PUT\", \"DELETE\", \"PATCH\"])\n .optional()\n .describe(\"HTTP method (optional, defaults to POST)\")\n .default(\"POST\"),\n delay: z\n .string()\n .optional()\n .describe(\"Delay before message delivery (e.g., '10s', '5m', '1h')\"),\n retries: z.number().optional().describe(\"Number of retries on failure, default is 3\"),\n callback: z\n .string()\n .optional()\n .describe(\"Callback URL that will be called when the message is successfully delivered\"),\n failureCallback: z\n .string()\n .optional()\n .describe(\"Callback URL that will be called when the message is failed to deliver\"),\n timeout: z.string().optional().describe(\"Request timeout (e.g., '30s', '1h')\"),\n queueName: z\n .string()\n .optional()\n .describe(\n \"Queue name to use, you have to first create the queue in upstash. Prefer the flow control key instead\"\n ),\n flow_control: z\n .object({\n key: z\n .string()\n .describe(\"Unique identifier for grouping messages under same flow control rules\"),\n parallelism: z\n .number()\n .optional()\n .describe(\"Max concurrent active calls (default: unlimited)\"),\n rate: z.number().optional().describe(\"Max calls per period (default: unlimited)\"),\n period: z\n .string()\n .optional()\n .describe(\"Time window for rate limit (e.g., '1s', '1m', '1h', default: '1s')\"),\n })\n .optional()\n .describe(\"Flow control for rate limiting and parallelism management\"),\n\n extraHeaders: z.record(z.string()).optional().describe(\"Extra headers to add to the request\"),\n ...qstashCreds,\n }),\n handler: async ({\n destination,\n body,\n method,\n extraHeaders,\n delay,\n retries,\n callback,\n failureCallback,\n timeout,\n queueName,\n flow_control,\n qstash_creds,\n }) => {\n const client = await createQStashClientWithToken(qstash_creds);\n\n const requestHeaders: Record<string, string> = {};\n\n if (method) {\n requestHeaders[\"Upstash-Method\"] = method;\n }\n if (delay) {\n requestHeaders[\"Upstash-Delay\"] = delay;\n }\n if (retries !== undefined) {\n requestHeaders[\"Upstash-Retries\"] = retries.toString();\n }\n if (callback) {\n requestHeaders[\"Upstash-Callback\"] = callback;\n }\n if (failureCallback) {\n requestHeaders[\"Upstash-Failure-Callback\"] = failureCallback;\n }\n if (timeout) {\n requestHeaders[\"Upstash-Timeout\"] = timeout;\n }\n if (queueName) {\n requestHeaders[\"Upstash-Queue-Name\"] = queueName;\n }\n\n // Add flow control headers\n if (flow_control) {\n requestHeaders[\"Upstash-Flow-Control-Key\"] = flow_control.key;\n const value = [\n flow_control.parallelism === undefined\n ? undefined\n : `parallelism=${flow_control.parallelism}`,\n flow_control.rate === undefined ? undefined : `rate=${flow_control.rate}`,\n flow_control.period === undefined ? undefined : `period=${flow_control.period}`,\n ]\n .filter(Boolean)\n .join(\",\");\n requestHeaders[\"Upstash-Flow-Control-Value\"] = value;\n }\n\n // Add custom headers\n if (extraHeaders) {\n for (const [key, value] of Object.entries(extraHeaders)) {\n requestHeaders[key] = value;\n }\n }\n\n const response = await client.post<{ messageId: string }>(\n `v2/publish/${destination}`,\n body || {},\n requestHeaders\n );\n\n return [\n \"Message published successfully\",\n `Message ID: ${response.messageId}`,\n json(response),\n ];\n },\n }),\n\n qstash_logs_list: tool({\n description: `List QStash logs with optional filtering. Returns a paginated list of message logs without their bodies.`,\n inputSchema: z.object({\n cursor: z.string().optional().describe(\"Cursor for pagination\"),\n messageId: z.string().optional().describe(\"Filter logs by message ID\"),\n state: z\n .enum([\n \"CREATED\",\n \"ACTIVE\",\n \"RETRY\",\n \"ERROR\",\n \"IN_PROGRESS\",\n \"DELIVERED\",\n \"FAILED\",\n \"CANCEL_REQUESTED\",\n \"CANCELLED\",\n ])\n .optional()\n .describe(\"Filter logs by state\"),\n url: z.string().optional().describe(\"Filter logs by URL\"),\n topicName: z.string().optional().describe(\"Filter logs by topic name\"),\n scheduleId: z.string().optional().describe(\"Filter logs by schedule ID\"),\n queueName: z.string().optional().describe(\"Filter logs by queue name\"),\n fromDate: z\n .number()\n .optional()\n .describe(\"Filter logs from date (Unix timestamp in milliseconds)\"),\n toDate: z\n .number()\n .optional()\n .describe(\"Filter logs to date (Unix timestamp in milliseconds)\"),\n count: z.number().max(1000).optional().describe(\"Number of logs to return (max 1000)\"),\n ...qstashCreds,\n }),\n handler: async (params) => {\n const client = await createQStashClientWithToken(params.qstash_creds);\n\n const response = await client.get<QStashLogsResponse>(\"v2/logs\", {\n trimBody: 0,\n groupBy: \"messageId\",\n ...params,\n });\n const firstMessageFields = Object.fromEntries(\n Object.entries(response.messages[0] ?? {}).filter(\n ([key, _value]) => !key.toLocaleLowerCase().includes(\"headers\")\n )\n );\n\n const cleanedEvents = response.messages.map((message) => ({\n messageId: message.messageId,\n events: message.events.map((event) => ({\n state: event.state,\n time: event.time,\n })),\n }));\n\n return [\n `Found ${response.messages.length} log entries`,\n response.cursor ? `Pagination cursor: ${response.cursor}` : \"No more entries\",\n json({ ...firstMessageFields, events: cleanedEvents }),\n ];\n },\n }),\n\n qstash_logs_get: tool({\n description: `Get details of a single QStash log item by message ID without trimming the body.`,\n inputSchema: z.object({\n messageId: z.string().describe(\"The message ID to get details for\"),\n ...qstashCreds,\n }),\n handler: async ({ messageId, qstash_creds }) => {\n const client = await createQStashClientWithToken(qstash_creds);\n const response = await client.get<QStashLogsResponse>(\"v2/logs\", { messageId });\n\n if (response.messages.length === 0) {\n return \"No log entry found for the specified message ID\";\n }\n\n const logEntry = response.messages[0];\n return [`Log details for message ID: ${messageId}`, json(logEntry)];\n },\n }),\n\n qstash_dlq_list: tool({\n description: `List messages in the QStash Dead Letter Queue (DLQ) with optional filtering.`,\n inputSchema: z.object({\n cursor: z.string().optional().describe(\"Cursor for pagination\"),\n messageId: z.string().optional().describe(\"Filter DLQ messages by message ID\"),\n url: z.string().optional().describe(\"Filter DLQ messages by URL\"),\n topicName: z.string().optional().describe(\"Filter DLQ messages by topic name\"),\n scheduleId: z.string().optional().describe(\"Filter DLQ messages by schedule ID\"),\n queueName: z.string().optional().describe(\"Filter DLQ messages by queue name\"),\n fromDate: z.number().optional().describe(\"Filter from date (Unix timestamp in milliseconds)\"),\n toDate: z.number().optional().describe(\"Filter to date (Unix timestamp in milliseconds)\"),\n responseStatus: z.number().optional().describe(\"Filter by HTTP response status code\"),\n callerIp: z.string().optional().describe(\"Filter by IP address of the publisher\"),\n count: z.number().max(100).optional().describe(\"Number of messages to return (max 100)\"),\n ...qstashCreds,\n }),\n handler: async (params) => {\n const client = await createQStashClientWithToken(params.qstash_creds);\n\n const response = await client.get<QStashDLQResponse>(\"v2/dlq\", {\n trimBody: 0,\n ...params,\n });\n\n return [\n `Found ${response.messages.length} DLQ messages`,\n response.cursor ? `Pagination cursor: ${response.cursor}` : \"No more entries\",\n json(response.messages),\n ];\n },\n }),\n\n qstash_dlq_get: tool({\n description: `Get details of a single DLQ message by DLQ ID.`,\n inputSchema: z.object({\n dlqId: z.string().describe(\"The DLQ ID of the message to retrieve\"),\n ...qstashCreds,\n }),\n handler: async ({ dlqId, qstash_creds }) => {\n const client = await createQStashClientWithToken(qstash_creds);\n const message = await client.get<QStashDLQMessage>(`v2/dlq/${dlqId}`);\n\n return [`DLQ message details for ID: ${dlqId}`, json(message)];\n },\n }),\n\n qstash_schedules_list: tool({\n description: `List all QStash schedules.`,\n handler: async ({ qstash_creds }) => {\n const client = await createQStashClientWithToken(qstash_creds);\n const schedules = await client.get<QStashSchedule[]>(\"v2/schedules\");\n\n return [`Found ${schedules.length} schedules`, json(schedules)];\n },\n }),\n\n qstash_schedules_manage: tool({\n description: `Create, update, or manage QStash schedules. This tool handles create, update (by providing scheduleId), pause, resume, and delete operations in one unified interface.`,\n inputSchema: z.object({\n operation: z\n .enum([\"create\", \"update\", \"pause\", \"resume\", \"delete\"])\n .describe(\"The operation to perform\"),\n scheduleId: z\n .string()\n .optional()\n .describe(\"Schedule ID (required for update, pause, resume, delete operations)\"),\n destination: z\n .string()\n .optional()\n .describe(\"Destination URL or topic name (required for create/update)\"),\n cron: z.string().optional().describe(\"Cron expression (required for create/update)\"),\n method: z\n .enum([\"GET\", \"POST\", \"PUT\", \"DELETE\", \"PATCH\"])\n .optional()\n .describe(\"HTTP method (optional, defaults to POST)\"),\n headers: z.record(z.string()).optional().describe(\"Request headers as key-value pairs\"),\n body: z.string().optional().describe(\"Request body\"),\n delay: z\n .string()\n .optional()\n .describe(\"Delay before message delivery (e.g., '10s', '5m', '1h')\"),\n retries: z.number().optional().describe(\"Number of retries on failure\"),\n callback: z.string().optional().describe(\"Callback URL for successful delivery\"),\n failureCallback: z.string().optional().describe(\"Callback URL for failed delivery\"),\n timeout: z.string().optional().describe(\"Request timeout (e.g., '30s')\"),\n queueName: z.string().optional().describe(\"Queue name to use\"),\n ...qstashCreds,\n }),\n handler: async ({\n operation,\n scheduleId,\n destination,\n cron,\n method = \"POST\",\n headers,\n body,\n delay,\n retries,\n callback,\n failureCallback,\n timeout,\n queueName,\n qstash_creds,\n }) => {\n const client = await createQStashClientWithToken(qstash_creds);\n\n switch (operation) {\n case \"create\":\n case \"update\": {\n if (!destination || !cron) {\n throw new Error(\"destination and cron are required for create/update operations\");\n }\n\n const requestHeaders: Record<string, string> = {\n \"Upstash-Cron\": cron,\n };\n\n if (method !== \"POST\") {\n requestHeaders[\"Upstash-Method\"] = method;\n }\n if (delay) {\n requestHeaders[\"Upstash-Delay\"] = delay;\n }\n if (retries !== undefined) {\n requestHeaders[\"Upstash-Retries\"] = retries.toString();\n }\n if (callback) {\n requestHeaders[\"Upstash-Callback\"] = callback;\n }\n if (failureCallback) {\n requestHeaders[\"Upstash-Failure-Callback\"] = failureCallback;\n }\n if (timeout) {\n requestHeaders[\"Upstash-Timeout\"] = timeout;\n }\n if (queueName) {\n requestHeaders[\"Upstash-Queue-Name\"] = queueName;\n }\n if (scheduleId && operation === \"update\") {\n requestHeaders[\"Upstash-Schedule-Id\"] = scheduleId;\n }\n\n // Add custom headers\n if (headers) {\n for (const [key, value] of Object.entries(headers)) {\n requestHeaders[key] = value;\n }\n }\n\n const response = await client.post<QStashScheduleCreateResponse>(\n `v2/schedules/${destination}`,\n body || {},\n requestHeaders\n );\n\n return [\n operation === \"create\"\n ? \"Schedule created successfully\"\n : \"Schedule updated successfully\",\n `Schedule ID: ${response.scheduleId}`,\n json(response),\n ];\n }\n\n case \"pause\": {\n if (!scheduleId) {\n throw new Error(\"scheduleId is required for pause operation\");\n }\n\n await client.post(`v2/schedules/${scheduleId}/pause`);\n return `Schedule ${scheduleId} paused successfully`;\n }\n\n case \"resume\": {\n if (!scheduleId) {\n throw new Error(\"scheduleId is required for resume operation\");\n }\n\n await client.post(`v2/schedules/${scheduleId}/resume`);\n return `Schedule ${scheduleId} resumed successfully`;\n }\n\n case \"delete\": {\n if (!scheduleId) {\n throw new Error(\"scheduleId is required for delete operation\");\n }\n\n await client.delete(`v2/schedules/${scheduleId}`);\n return `Schedule ${scheduleId} deleted successfully`;\n }\n\n default: {\n throw new Error(`Unknown operation: ${operation}`);\n }\n }\n },\n }),\n};\n","import { http, createQStashClient, type HttpClient } from \"../../http\";\nimport type { QStashUser } from \"./types\";\n\nlet cachedToken: string | null = null;\nlet tokenExpiry: number = 0;\n\n/**\n * Gets the QStash token from the Upstash API\n * Caches the token for 1 hour to avoid unnecessary API calls\n */\nexport async function getQStashToken(): Promise<string> {\n const now = Date.now();\n\n // Return cached token if it's still valid (cached for 1 hour)\n if (cachedToken && now < tokenExpiry) {\n return cachedToken;\n }\n\n try {\n const user = await http.get<QStashUser>(\"qstash/user\");\n cachedToken = user.token;\n tokenExpiry = now + 60 * 60 * 1000; // Cache for 1 hour\n return user.token;\n } catch (error) {\n throw new Error(\n `Failed to get QStash token: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n}\n\n/**\n * Creates a QStash client with automatically fetched token\n */\nexport async function createQStashClientWithToken(\n creds: {\n url?: string;\n token?: string;\n } = {}\n): Promise<HttpClient> {\n if (!creds?.token) {\n creds.token = await getQStashToken();\n }\n return createQStashClient({\n url: creds?.url,\n token: creds?.token,\n });\n}\n\n/**\n * Clears the cached token (useful for testing or when token becomes invalid)\n */\nexport function clearTokenCache(): void {\n cachedToken = null;\n tokenExpiry = 0;\n}\n","import { z } from \"zod\";\nimport { json, tool } from \"..\";\nimport { createQStashClientWithToken } from \"./utils\";\nimport type { WorkflowLogsResponse, WorkflowDLQResponse, WorkflowDLQMessage } from \"./types\";\nimport { qstashCreds } from \"./qstash\";\n\nexport const workflowTools = {\n workflow_logs_list: tool({\n description: `List Upstash Workflow logs with optional filtering. Returns grouped workflow runs with their execution details.`,\n inputSchema: z.object({\n cursor: z.string().optional().describe(\"Cursor for pagination\"),\n workflowRunId: z.string().optional().describe(\"Filter by specific workflow run ID\"),\n count: z.number().optional().describe(\"Number of workflow runs to return\"),\n state: z\n .enum([\"RUN_STARTED\", \"RUN_SUCCESS\", \"RUN_FAILED\", \"RUN_CANCELED\"])\n .optional()\n .describe(\"Filter by workflow state\"),\n workflowUrl: z.string().optional().describe(\"Filter by workflow URL (exact match)\"),\n workflowCreatedAt: z\n .number()\n .optional()\n .describe(\"Filter by workflow creation timestamp (Unix timestamp)\"),\n ...qstashCreds,\n }),\n handler: async (params) => {\n const client = await createQStashClientWithToken(params.qstash_creds);\n\n const response = await client.get<WorkflowLogsResponse>(\"v2/workflows/events\", {\n trimBody: 0,\n groupBy: \"workflowRunId\",\n ...params,\n });\n\n const cleaned = response.runs.map((run) =>\n Object.fromEntries(Object.entries(run).filter(([key, _value]) => key !== \"steps\"))\n );\n\n return [\n `Found ${response.runs.length} workflow runs`,\n response.cursor ? `Pagination cursor: ${response.cursor}` : \"No more entries\",\n json({\n ...response,\n runs: cleaned,\n }),\n ];\n },\n }),\n\n workflow_logs_get: tool({\n description: `Get details of a single workflow run by workflow run ID. There\n could be multiple workflow runs with the same workflow run ID, so you can\n use the workflowCreatedAt to get the details of the specific workflow run.`,\n inputSchema: z.object({\n workflowRunId: z.string().describe(\"The workflow run ID to get details for\"),\n workflowCreatedAt: z\n .number()\n .optional()\n .describe(\"The workflow creation timestamp (Unix timestamp)\"),\n ...qstashCreds,\n }),\n handler: async (params) => {\n const client = await createQStashClientWithToken(params.qstash_creds);\n const response = await client.get<WorkflowLogsResponse>(\"v2/workflows/logs\", {\n ...params,\n });\n\n if (response.runs.length === 0) {\n return \"No workflow run found\";\n }\n\n const workflowRun = response.runs[0];\n return [\n `Workflow run details for ID: ${params.workflowRunId} created at: ${params.workflowCreatedAt}`,\n json(workflowRun),\n ];\n },\n }),\n\n workflow_dlq_list: tool({\n description: `List failed workflow runs in the Dead Letter Queue (DLQ) with optional filtering.`,\n inputSchema: z.object({\n cursor: z.string().optional().describe(\"Cursor for pagination\"),\n workflowRunId: z.string().optional().describe(\"Filter by workflow run ID\"),\n workflowUrl: z.string().optional().describe(\"Filter by workflow URL\"),\n fromDate: z.number().optional().describe(\"Filter from date (Unix timestamp in milliseconds)\"),\n toDate: z.number().optional().describe(\"Filter to date (Unix timestamp in milliseconds)\"),\n responseStatus: z.number().optional().describe(\"Filter by HTTP response status code\"),\n callerIP: z.string().optional().describe(\"Filter by IP address of the caller\"),\n failureCallbackState: z.string().optional().describe(\"Filter by failure callback state\"),\n count: z.number().optional().describe(\"Number of DLQ messages to return\"),\n ...qstashCreds,\n }),\n handler: async (params) => {\n const client = await createQStashClientWithToken(params.qstash_creds);\n\n const response = await client.get<WorkflowDLQResponse>(\"v2/workflows/dlq\", {\n ...params,\n trimBody: 0,\n });\n\n const cleaned = response.messages.map((message) =>\n Object.fromEntries(Object.entries(message).filter(([key]) => !key.includes(\"header\")))\n );\n\n return [\n `Found ${response.messages.length} failed workflow runs in DLQ`,\n response.cursor ? `Pagination cursor: ${response.cursor}` : \"No more entries\",\n json({\n ...response,\n messages: cleaned,\n }),\n ];\n },\n }),\n\n workflow_dlq_get: tool({\n description: `Get details of a single failed workflow run from the DLQ by DLQ ID.`,\n inputSchema: z.object({\n dlqId: z.string().describe(\"The DLQ ID of the failed workflow run to retrieve\"),\n ...qstashCreds,\n }),\n handler: async (params) => {\n const client = await createQStashClientWithToken(params.qstash_creds);\n const message = await client.get<WorkflowDLQMessage>(`v2/workflows/dlq/${params.dlqId}`);\n\n return [`Failed workflow run details for DLQ ID: ${params.dlqId}`, json(message)];\n },\n }),\n\n workflow_dlq_manage: tool({\n description: `Delete, restart, and resume failed workflow runs in the DLQ using only the DLQ ID.`,\n inputSchema: z.object({\n dlqId: z.string().describe(\"The DLQ ID of the failed workflow run\"),\n action: z\n .enum([\"delete\", \"restart\", \"resume\"])\n .describe(\n \"The action to perform: delete (remove from DLQ), restart (from beginning), or resume (from the failed step)\"\n ),\n ...qstashCreds,\n }),\n handler: async ({ dlqId, action, qstash_creds }) => {\n const client = await createQStashClientWithToken(qstash_creds);\n\n switch (action) {\n case \"delete\": {\n await client.delete(`v2/workflows/dlq/delete/${dlqId}`);\n return `Failed workflow run with DLQ ID ${dlqId} deleted successfully`;\n }\n\n case \"restart\": {\n const restartResponse = await client.post(`v2/workflows/dlq/restart/${dlqId}`);\n return [\n `Workflow run restarted successfully from DLQ ID: ${dlqId}`,\n json(restartResponse),\n ];\n }\n\n case \"resume\": {\n const resumeResponse = await client.post(`v2/workflows/dlq/resume/${dlqId}`);\n return [`Workflow run resumed successfully from DLQ ID: ${dlqId}`, json(resumeResponse)];\n }\n\n default: {\n throw new Error(\n `Invalid action: ${action}. Supported actions are: delete, restart, resume`\n );\n }\n }\n },\n }),\n};\n","import type { CustomTool } from \"../../tool\";\nimport { qstashTools } from \"./qstash\";\nimport { workflowTools } from \"./workflow\";\n\nexport const qstashAllTools: Record<string, CustomTool> = {\n ...qstashTools,\n ...workflowTools,\n};\n","import type { ZodSchema } from \"zod\";\nimport type { CustomTool } from \"../tool\";\nimport { redisTools } from \"./redis\";\nimport { qstashAllTools } from \"./qstash\";\n\nexport const json = (json: unknown) =>\n typeof json === \"string\" ? json : JSON.stringify(json, null, 2);\n\nexport const tools: Record<string, CustomTool> = {\n ...redisTools,\n ...qstashAllTools,\n} as unknown as Record<string, CustomTool>;\n\n// Only used for type inference\nexport function tool<TSchema extends ZodSchema>(tool: CustomTool<TSchema>): CustomTool {\n return tool as unknown as CustomTool;\n}\n","export const MAX_MESSAGE_LENGTH = 30_000;\n","import type { CallToolResultSchema } from \"@modelcontextprotocol/sdk/types.js\";\nimport type { ZodSchema } from \"zod\";\nimport type { z } from \"zod\";\nimport { MAX_MESSAGE_LENGTH } from \"./settings\";\n\ntype HandlerResponse = string | string[] | z.infer<typeof CallToolResultSchema>;\n\nexport type CustomTool<TSchema extends ZodSchema = ZodSchema> = {\n description: string;\n\n /**\n * Zod schema for the input of the tool.\n */\n inputSchema?: TSchema;\n\n /**\n * The handler function for the tool.\n * @param input Parsed input according to the input schema.\n * @returns\n * If result is a string, it will be displayed as a single text block.\n * If result is an array of strings, each string will be displayed as a separate text block.\n * You can also return a CallToolResult object to display more complex content.\n */\n handler: (input: z.infer<TSchema>) => Promise<HandlerResponse>;\n};\n\nexport function handlerResponseToCallResult(\n response: HandlerResponse\n): z.infer<typeof CallToolResultSchema> {\n if (typeof response === \"string\" || Array.isArray(response)) {\n const array = Array.isArray(response) ? response : [response];\n\n // Truncate messages that are too long\n const truncatedArray = array.map((item) =>\n item.length > MAX_MESSAGE_LENGTH\n ? `${item.slice(0, MAX_MESSAGE_LENGTH)}... (MESSAGE TRUNCATED, MENTION THIS TO USER)`\n : item\n );\n\n return {\n content: truncatedArray.map((text) => ({ type: \"text\" as const, text })),\n };\n } else return response;\n}\n","import { http } from \"./http\";\nimport { log } from \"./log\";\nimport type { RedisDatabase } from \"./tools/redis/types\";\n\nexport async function testConnection() {\n log(\"🧪 Testing connection to Upstash API\");\n\n let dbs: RedisDatabase[] | undefined;\n try {\n dbs = await http.get<RedisDatabase[]>(\"v2/redis/databases\");\n } catch (error) {\n log(\n \"❌ Connection to Upstash API failed. Please check your api key and email. Error: \",\n error instanceof Error ? error.message : String(error)\n );\n throw error;\n }\n\n if (!Array.isArray(dbs))\n throw new Error(\"Invalid response from Upstash API. Check your API key and email.\");\n\n log(\"✅ Connection to Upstash API is successful\");\n}\n"],"mappings":"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","names":["z","config","req","z","z","fetch","z","z","z","z","z","z","z","json","tool","z","tool","z"]}Report false positiveHigh-entropy string (4.9 bits/char) — possible encoded payload
Detected by automated pattern matching (rule EN-001) with medium confidence. May be a false positive.
Report false positiveHigh-entropy string (4.8 bits/char) — possible encoded payload
Detected by automated pattern matching (rule EN-001) with medium confidence. May be a false positive.
Report false positiveHigh-entropy string (4.7 bits/char) — possible encoded payload
Detected by automated pattern matching (rule EN-001) with medium confidence. May be a false positive.
Report false positiveHigh-entropy string (4.6 bits/char) — possible encoded payload
Detected by automated pattern matching (rule EN-001) with medium confidence. May be a false positive.
Report false positiveHigh-entropy string (4.8 bits/char) — possible encoded payload
Detected by automated pattern matching (rule EN-001) with medium confidence. May be a false positive.
Report false positiveHigh-entropy string (4.9 bits/char) — possible encoded payload
Detected by automated pattern matching (rule EN-001) with medium confidence. May be a false positive.
Report false positiveHigh-entropy string (4.7 bits/char) — possible encoded payload
Detected by automated pattern matching (rule EN-001) with medium confidence. May be a false positive.
Report false positiveHigh-entropy string (4.7 bits/char) — possible encoded payload
Detected by automated pattern matching (rule EN-001) with medium confidence. May be a false positive.
Report false positivePossible Base64-encoded payload (long encoded string)
Detected by automated pattern matching (rule OB-001) with medium confidence. May be a false positive.
1: # Upstash MCP Server
2:
>>> 3: [](https://cursor.com/en/install-mcp?name=upstash&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIkB1cHN0YXNoL21jcC1zZXJ2ZXJAbGF0ZXN0IiwiLS1lbWFpbCIsIllPVVJfRU1BSUwiLCItLWFwaS1rZXkiLCJZT1VSX0FQSV9LRVkiXX0=%3D)
4:
5: [](https://cursor.com/en/install-mcp?name=upstash&config=eyJjb21tYW5kIjoibnB4IC15IEB1cHN0YXNoL21jcC1zZXJ2ZXJAbGF0ZXN0IC0tZW1haWwgWU9VUl9FTUFJTCAtLWFwaS1rZXkgWU9VUl9BUElfS0VZIn0%3D)Report false positivePossible Base64-encoded payload (long encoded string)
Detected by automated pattern matching (rule OB-001) with medium confidence. May be a false positive.
3: [](https://cursor.com/en/install-mcp?name=upstash&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIkB1cHN0YXNoL21jcC1zZXJ2ZXJAbGF0ZXN0IiwiLS1lbWFpbCIsIllPVVJfRU1BSUwiLCItLWFwaS1rZXkiLCJZT1VSX0FQSV9LRVkiXX0=%3D)
4:
>>> 5: [](https://cursor.com/en/install-mcp?name=upstash&config=eyJjb21tYW5kIjoibnB4IC15IEB1cHN0YXNoL21jcC1zZXJ2ZXJAbGF0ZXN0IC0tZW1haWwgWU9VUl9FTUFJTCAtLWFwaS1rZXkgWU9VUl9BUElfS0VZIn0%3D)
6: [<img alt="Install in VS Code (npx)" src="https://img.shields.io/badge/Install%20in%20VS%20Code-0098FF?style=for-the-badge&logo=visualstudiocode&logoColor=white">](https://insiders.vscode.dev/redirect?url=vscode%3Amcp%2Finstall%3F%7B%22name%22%3A%22upstash-mcp%22%2C%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22%40upstash%2Fmcp-server%40latest%22%2C%22--email%22%2C%22YOUR_EMAIL%22%2C%22--api-key%22%2C%22YOUR_API_KEY%22%5D%7D)
7: Report false positiveHigh-entropy string (4.8 bits/char) — possible encoded payload
Detected by automated pattern matching (rule EN-001) with medium confidence. May be a false positive.
Report false positiveHigh-entropy string (5.0 bits/char) — possible encoded payload
Detected by automated pattern matching (rule EN-001) with medium confidence. May be a false positive.
Report false positiveHigh-entropy string (5.2 bits/char) — possible encoded payload
Detected by automated pattern matching (rule EN-001) with medium confidence. May be a false positive.
Report false positiveHigh-entropy string (5.2 bits/char) — possible encoded payload
Detected by automated pattern matching (rule EN-001) with medium confidence. May be a false positive.
Report false positiveHigh-entropy string (4.8 bits/char) — possible encoded payload
Detected by automated pattern matching (rule EN-001) with medium confidence. May be a false positive.
Report false positiveJavaScript fetch() call
Detected by automated pattern matching (rule NS-003) with medium confidence. May be a false positive.
165: }
166: });
>>> 167: const res = await fetch(url, init);
168: if (!res.ok) {
169: throw new Error(`Request failed (${res.status} ${res.statusText}): ${await res.text()}`);Report false positiveHigh-entropy string (4.6 bits/char) — possible encoded payload
Detected by automated pattern matching (rule EN-001) with medium confidence. May be a false positive.
Report false positiveHigh-entropy string (5.0 bits/char) — possible encoded payload
Detected by automated pattern matching (rule EN-001) with medium confidence. May be a false positive.
Report false positiveHigh-entropy string (4.6 bits/char) — possible encoded payload
Detected by automated pattern matching (rule EN-001) with medium confidence. May be a false positive.
Report false positiveHigh-entropy string (4.6 bits/char) — possible encoded payload
Detected by automated pattern matching (rule EN-001) with medium confidence. May be a false positive.
Report false positiveHigh-entropy string (4.8 bits/char) — possible encoded payload
Detected by automated pattern matching (rule EN-001) with medium confidence. May be a false positive.
Report false positiveHigh-entropy string (4.7 bits/char) — possible encoded payload
Detected by automated pattern matching (rule EN-001) with medium confidence. May be a false positive.
Report false positiveHigh-entropy string (4.8 bits/char) — possible encoded payload
Detected by automated pattern matching (rule EN-001) with medium confidence. May be a false positive.
Report false positiveHigh-entropy string (4.7 bits/char) — possible encoded payload
Detected by automated pattern matching (rule EN-001) with medium confidence. May be a false positive.
Report false positiveHigh-entropy string (4.7 bits/char) — possible encoded payload
Detected by automated pattern matching (rule EN-001) with medium confidence. May be a false positive.
Report false positiveHigh-entropy string (4.6 bits/char) — possible encoded payload
Detected by automated pattern matching (rule EN-001) with medium confidence. May be a false positive.
Report false positiveScan History
| Date | Risk | Findings | Files | Duration |
|---|---|---|---|---|
| Feb 25, 2026 | critical | 67 | 7 | 0.00s |
| Feb 23, 2026 | critical | 67 | 7 | 0.00s |
| Feb 22, 2026 | critical | 67 | 7 | 0.00s |