vip-tools.ts•8.19 kB
/**
* VIP Pipeline MCP Tools
* =======================
*
* Model Context Protocol tools for integrating VIP (Vision Inventory Pipeline)
* dataset generation capabilities into MCP-enabled chat interfaces.
*
* @module vip-tools
*/
import VIPClient, { StartPipelineOptions } from './vip-client.js';
// Initialize VIP client
const vipClient = new VIPClient({
baseUrl: process.env.VIP_API_URL || 'http://localhost:5000',
apiKey: process.env.VIP_API_KEY,
timeout: 60000, // 60 seconds for long operations
});
export const vipTools = [
{
name: 'vip_generate_dataset',
description: 'Generate a synthetic retail dataset using VIP pipeline. Creates thousands of labeled images for computer vision training. Requires a configuration file name (e.g., "template.yaml" or "theprintery_art_supplies.yaml").',
inputSchema: {
type: 'object',
properties: {
config: {
type: 'string',
description: 'Configuration file name (e.g., "template.yaml")',
},
force: {
type: 'boolean',
description: 'Force re-run even if already completed',
default: false,
},
verbose: {
type: 'boolean',
description: 'Enable verbose logging',
default: false,
},
},
required: ['config'],
},
},
{
name: 'vip_check_status',
description: 'Check the current status of a VIP pipeline run. Shows progress, completed phases, and statistics.',
inputSchema: {
type: 'object',
properties: {
config: {
type: 'string',
description: 'Configuration file name to check status for',
},
},
required: ['config'],
},
},
{
name: 'vip_list_datasets',
description: 'List all completed synthetic datasets generated by VIP. Shows dataset names, sizes, and image counts.',
inputSchema: {
type: 'object',
properties: {},
},
},
{
name: 'vip_get_dataset_info',
description: 'Get detailed information about a specific dataset including class names, splits, and metadata.',
inputSchema: {
type: 'object',
properties: {
dataset_name: {
type: 'string',
description: 'Name of the dataset (project name)',
},
},
required: ['dataset_name'],
},
},
{
name: 'vip_stop_pipeline',
description: 'Stop a running VIP pipeline process.',
inputSchema: {
type: 'object',
properties: {
process_id: {
type: 'string',
description: 'Process ID returned when pipeline was started',
},
},
required: ['process_id'],
},
},
{
name: 'vip_validate_config',
description: 'Validate a VIP configuration file before running the pipeline. Checks for errors and warnings.',
inputSchema: {
type: 'object',
properties: {
config: {
type: 'string',
description: 'Configuration file name to validate',
},
},
required: ['config'],
},
},
{
name: 'vip_health_check',
description: 'Check if VIP service is running and available.',
inputSchema: {
type: 'object',
properties: {},
},
},
];
export async function handleVIPTool(name: string, args: any): Promise<string> {
try {
switch (name) {
case 'vip_generate_dataset': {
const options: StartPipelineOptions = {
config: args.config,
force: args.force || false,
verbose: args.verbose || false,
};
// First validate the config
const validation = await vipClient.validateConfig(args.config);
if (!validation.valid) {
return [
'❌ **Configuration Validation Failed**',
'',
'**Errors:**',
...validation.errors.map(e => `• ${e}`),
'',
validation.warnings.length > 0 ? '**Warnings:**' : '',
...validation.warnings.map(w => `• ${w}`),
].join('\n');
}
// Start the pipeline
const processId = await vipClient.startPipeline(options);
if (!processId) {
return '❌ Failed to start pipeline. Check VIP service logs for details.';
}
return [
'✅ **Pipeline Started Successfully!**',
'',
`Process ID: ${processId}`,
`Configuration: ${args.config}`,
'',
'💡 Use `vip_check_status` to monitor progress.',
`💡 Use \`vip_stop_pipeline(process_id="${processId}")\` to cancel.`,
].join('\n');
}
case 'vip_check_status': {
const status = await vipClient.getPipelineStatus(args.config);
if (!status) {
return `❌ Configuration "${args.config}" not found or no pipeline has been run yet.`;
}
return vipClient.formatPipelineStatus(status);
}
case 'vip_list_datasets': {
const datasets = await vipClient.listDatasets();
if (datasets.length === 0) {
return '📦 No datasets found. Generate one using `vip_generate_dataset`.';
}
const lines = [
`📊 **Available Datasets (${datasets.length})**`,
'',
];
for (const dataset of datasets) {
lines.push(vipClient.formatDatasetInfo(dataset));
lines.push('');
}
return lines.join('\n');
}
case 'vip_get_dataset_info': {
const dataset = await vipClient.getDataset(args.dataset_name);
if (!dataset) {
return `❌ Dataset "${args.dataset_name}" not found.`;
}
return [
`📊 **Dataset: ${dataset.name}**`,
'',
`**Statistics:**`,
`• Total Images: ${dataset.stats.total_images}`,
`• Training: ${dataset.stats.train_images} images`,
`• Validation: ${dataset.stats.val_images} images`,
`• Size: ${dataset.stats.dataset_size_mb.toFixed(2)} MB`,
`• Format: ${dataset.format}`,
`• Labels: ${dataset.stats.has_labels ? '✅ Yes' : '❌ No'}`,
'',
`**Classes (${dataset.classes.length}):**`,
dataset.classes.map((c, i) => `${i}. ${c}`).join(', '),
'',
`**Path:** ${dataset.path}`,
`**Completed:** ${dataset.completed_at}`,
'',
'💡 **Ready for Training!**',
'Use this dataset with YOLOv8, Detectron2, or any YOLO-compatible framework.',
].join('\n');
}
case 'vip_stop_pipeline': {
const success = await vipClient.stopPipeline(args.process_id);
if (success) {
return `✅ Pipeline process ${args.process_id} stopped successfully.`;
}
return `❌ Failed to stop pipeline ${args.process_id}. It may have already completed or been stopped.`;
}
case 'vip_validate_config': {
const validation = await vipClient.validateConfig(args.config);
const lines = [
validation.valid ? '✅ **Configuration Valid**' : '❌ **Configuration Invalid**',
'',
];
if (validation.errors.length > 0) {
lines.push('**Errors:**');
lines.push(...validation.errors.map(e => `• ${e}`));
lines.push('');
}
if (validation.warnings.length > 0) {
lines.push('**Warnings:**');
lines.push(...validation.warnings.map(w => `• ${w}`));
lines.push('');
}
if (validation.valid) {
lines.push('💡 Configuration is ready to use with `vip_generate_dataset`');
}
return lines.join('\n');
}
case 'vip_health_check': {
const isHealthy = await vipClient.healthCheck();
if (isHealthy) {
return '✅ VIP service is running and healthy.';
}
return '❌ VIP service is not responding. Make sure it is running on the configured URL.';
}
default:
return `Unknown VIP tool: ${name}`;
}
} catch (error) {
return `❌ Error executing ${name}: ${error instanceof Error ? error.message : String(error)}`;
}
}