/**
* MCP Tool: List Ranges
*/
import { RangeLoader } from '../ranges/loader.js';
export class ListRangesTool {
constructor(solverPath) {
this.rangeLoader = new RangeLoader(solverPath);
}
/**
* List available range files
* @param {Object} params
* @returns {Promise<Object>}
*/
async execute(params) {
try {
const { filter, range_set } = params;
let ranges = [];
if (range_set) {
ranges = await this.rangeLoader.getRangesBySet(range_set);
} else if (filter) {
ranges = await this.rangeLoader.filterRanges(filter);
} else {
ranges = await this.rangeLoader.listRangeFiles();
}
// Map to response format
const mappedRanges = ranges.map(range => ({
path: range.path,
full_path: range.full_path,
name: range.name,
scenario: this._inferScenario(range.path),
position: this._inferPosition(range.path)
}));
return {
success: true,
ranges: mappedRanges,
count: mappedRanges.length
};
} catch (error) {
return {
success: false,
error: error.message,
error_type: 'EXECUTION_ERROR'
};
}
}
/**
* Infer scenario from range path
* @private
* @param {string} path
* @returns {string}
*/
_inferScenario(path) {
const lower = path.toLowerCase();
if (lower.includes('open')) return 'Open';
if (lower.includes('3bet')) return '3bet';
if (lower.includes('4bet')) return '4bet';
if (lower.includes('call')) return 'Call';
if (lower.includes('cold')) return 'Cold Call';
return 'Unknown';
}
/**
* Infer position from range path
* @private
* @param {string} path
* @returns {string}
*/
_inferPosition(path) {
const upper = path.toUpperCase();
if (upper.includes('UTG')) return 'UTG';
if (upper.includes('UTG+1')) return 'UTG+1';
if (upper.includes('UTG+2')) return 'UTG+2';
if (upper.includes('MP') && !upper.includes('UTG')) return 'MP';
if (upper.includes('CO')) return 'CO';
if (upper.includes('BTN')) return 'BTN';
if (upper.includes('SB')) return 'SB';
if (upper.includes('BB')) return 'BB';
return 'Unknown';
}
}
/**
* Create the MCP tool definition
* @returns {Object}
*/
export function createListRangesTool() {
return {
name: 'list_ranges',
description: 'List available preflop range files from the TexasSolver ranges directory.',
inputSchema: {
type: 'object',
properties: {
filter: {
type: 'string',
description: 'Filter ranges by name pattern (e.g., "BTN", "6max", "open")'
},
range_set: {
type: 'string',
enum: ['6max', 'qb'],
description: 'Filter by range set: "6max" for 6-max ranges, "qb" for quick bet ranges (optional)'
}
}
}
};
}
export default ListRangesTool;