import { RedisClientType } from 'redis';
import { RedisTool } from './base_tool.js';
import { ScanArgs, ToolResponse } from '../interfaces/types.js';
export class ScanTool extends RedisTool {
name = 'scan';
description = 'Scan Redis keys matching a pattern';
inputSchema = {
type: 'object',
properties: {
pattern: {
type: 'string',
description: 'Pattern to match (e.g., "user:*" or "schedule:*")'
},
count: {
type: 'number',
description: 'Number of keys to return per iteration (optional)',
minimum: 1
}
},
required: ['pattern']
};
validateArgs(args: unknown): args is ScanArgs {
return typeof args === 'object' && args !== null &&
'pattern' in args && typeof (args as any).pattern === 'string' &&
(!('count' in args) || typeof (args as any).count === 'number');
}
async execute(args: unknown, client: RedisClientType): Promise<ToolResponse> {
if (!this.validateArgs(args)) {
return this.createErrorResponse('Invalid arguments for scan');
}
try {
const { pattern, count = 100 } = args;
const keys = await client.keys(pattern);
if (keys.length === 0) {
return this.createSuccessResponse('No keys found matching pattern');
}
// Limit keys to at most 10, or less if count is specified and smaller
const maxKeys = Math.min(count || 10, 10);
const limitedKeys = keys.slice(0, maxKeys);
return this.createSuccessResponse(JSON.stringify(limitedKeys, null, 2));
} catch (error) {
return this.createErrorResponse(`Failed to scan keys: ${error}`);
}
}
}