/**
* Data Handlers - Connect MCP tools to data services
* Updated with platform support for Cloud and On-Premise
*/
import { DataCatalogService } from '../services/data-catalog-service.js';
import { QlikAppService } from '../services/qlik-app-service.js';
import { ApiClient } from '../utils/api-client.js';
import { CacheManager } from '../utils/cache-manager.js';
/**
* Handler for get_dataset_details tool
* Get detailed information about a dataset
* Note: Datasets are a Cloud concept, on-premise uses data connections
*/
export async function handleGetDatasetDetails(
apiClient: ApiClient,
cacheManager: CacheManager,
args: any,
platform: 'cloud' | 'on-premise' = 'cloud',
tenantUrl: string = ''
): Promise<{ content: Array<{ type: string; text: string }> }> {
console.error(`[DataHandlers] get_dataset_details called (platform: ${platform})`);
try {
if (!args?.datasetId) {
throw new Error('datasetId is required');
}
if (platform === 'on-premise') {
// On-premise doesn't have datasets in the same way as Cloud
// Try to get data connection details instead
return await handleGetDataConnectionDetails(apiClient, args.datasetId);
}
const catalogService = new DataCatalogService(apiClient, cacheManager);
const details = await catalogService.getDatasetDetails(args.datasetId);
return {
content: [{
type: 'text',
text: JSON.stringify({
success: true,
platform: 'cloud',
dataset: details,
timestamp: new Date().toISOString()
}, null, 2)
}]
};
} catch (error) {
console.error('[DataHandlers] Error in get_dataset_details:', error);
return {
content: [{
type: 'text',
text: JSON.stringify({
success: false,
error: error instanceof Error ? error.message : String(error)
}, null, 2)
}]
};
}
}
/**
* On-Premise: Get data connection details via QRS
*/
async function handleGetDataConnectionDetails(
apiClient: ApiClient,
connectionId: string
): Promise<{ content: Array<{ type: string; text: string }> }> {
try {
const response = await apiClient.makeRequest(`/qrs/dataconnection/${connectionId}`);
const connection = response.data || response;
return {
content: [{
type: 'text',
text: JSON.stringify({
success: true,
platform: 'on-premise',
dataConnection: {
id: connection.id,
name: connection.name,
connectionString: connection.connectionstring,
type: connection.type,
owner: connection.owner?.name,
createdDate: connection.createdDate,
modifiedDate: connection.modifiedDate
},
note: 'On-premise uses Data Connections instead of Datasets. This shows the data connection details.',
timestamp: new Date().toISOString()
}, null, 2)
}]
};
} catch (error) {
return {
content: [{
type: 'text',
text: JSON.stringify({
success: false,
platform: 'on-premise',
error: error instanceof Error ? error.message : String(error),
note: 'On-premise uses Data Connections instead of Datasets. The provided ID may be a Cloud dataset ID.'
}, null, 2)
}]
};
}
}
/**
* Handler for apply_selections tool
* Apply selections to an app
* Note: Uses Engine API - Cloud supported, On-premise requires certificate auth
*/
export async function handleApplySelections(
apiClient: ApiClient,
cacheManager: CacheManager,
args: any,
platform: 'cloud' | 'on-premise' = 'cloud',
tenantUrl: string = ''
): Promise<{ content: Array<{ type: string; text: string }> }> {
console.error(`[DataHandlers] apply_selections called (platform: ${platform})`);
try {
if (!args?.appId || !args?.selections) {
throw new Error('appId and selections are required');
}
// Pass platform to QlikAppService for platform-aware Engine API
const qlikAppService = new QlikAppService(apiClient, cacheManager, platform, tenantUrl);
const result = await qlikAppService.applySelections(args.appId, args.selections);
return {
content: [{
type: 'text',
text: JSON.stringify({
success: true,
platform,
result,
timestamp: new Date().toISOString()
}, null, 2)
}]
};
} catch (error) {
console.error('[DataHandlers] Error in apply_selections:', error);
return {
content: [{
type: 'text',
text: JSON.stringify({
success: false,
error: error instanceof Error ? error.message : String(error)
}, null, 2)
}]
};
}
}
/**
* Handler for clear_selections tool
* Clear all selections in an app
* Note: Uses Engine API - Cloud supported, On-premise requires certificate auth
*/
export async function handleClearSelections(
apiClient: ApiClient,
cacheManager: CacheManager,
args: any,
platform: 'cloud' | 'on-premise' = 'cloud',
tenantUrl: string = ''
): Promise<{ content: Array<{ type: string; text: string }> }> {
console.error(`[DataHandlers] clear_selections called (platform: ${platform})`);
try {
if (!args?.appId) {
throw new Error('appId is required');
}
// Pass platform to QlikAppService for platform-aware Engine API
const qlikAppService = new QlikAppService(apiClient, cacheManager, platform, tenantUrl);
const result = await qlikAppService.clearSelections(args.appId);
return {
content: [{
type: 'text',
text: JSON.stringify({
success: true,
platform,
result,
timestamp: new Date().toISOString()
}, null, 2)
}]
};
} catch (error) {
console.error('[DataHandlers] Error in clear_selections:', error);
return {
content: [{
type: 'text',
text: JSON.stringify({
success: false,
error: error instanceof Error ? error.message : String(error)
}, null, 2)
}]
};
}
}
/**
* Handler for get_current_selections tool
* Get current selections in an app
* Note: Uses Engine API - Cloud supported, On-premise requires certificate auth
*/
export async function handleGetCurrentSelections(
apiClient: ApiClient,
cacheManager: CacheManager,
args: any,
platform: 'cloud' | 'on-premise' = 'cloud',
tenantUrl: string = ''
): Promise<{ content: Array<{ type: string; text: string }> }> {
console.error(`[DataHandlers] get_current_selections called (platform: ${platform})`);
try {
if (!args?.appId) {
throw new Error('appId is required');
}
// Pass platform to QlikAppService for platform-aware Engine API
const qlikAppService = new QlikAppService(apiClient, cacheManager, platform, tenantUrl);
const selections = await qlikAppService.getCurrentSelections(args.appId);
return {
content: [{
type: 'text',
text: JSON.stringify({
success: true,
platform,
selections,
timestamp: new Date().toISOString()
}, null, 2)
}]
};
} catch (error) {
console.error('[DataHandlers] Error in get_current_selections:', error);
return {
content: [{
type: 'text',
text: JSON.stringify({
success: false,
error: error instanceof Error ? error.message : String(error)
}, null, 2)
}]
};
}
}
/**
* Handler for get_available_fields tool
* Get available fields in an app
* Note: Uses Engine API - Cloud supported, On-premise requires certificate auth
*/
export async function handleGetAvailableFields(
apiClient: ApiClient,
cacheManager: CacheManager,
args: any,
platform: 'cloud' | 'on-premise' = 'cloud',
tenantUrl: string = ''
): Promise<{ content: Array<{ type: string; text: string }> }> {
console.error(`[DataHandlers] get_available_fields called (platform: ${platform})`);
try {
if (!args?.appId) {
throw new Error('appId is required');
}
// Pass platform to QlikAppService for platform-aware Engine API
const qlikAppService = new QlikAppService(apiClient, cacheManager, platform, tenantUrl);
const fields = await qlikAppService.getAvailableFields(args.appId);
return {
content: [{
type: 'text',
text: JSON.stringify({
success: true,
platform,
fields,
timestamp: new Date().toISOString()
}, null, 2)
}]
};
} catch (error) {
console.error('[DataHandlers] Error in get_available_fields:', error);
return {
content: [{
type: 'text',
text: JSON.stringify({
success: false,
error: error instanceof Error ? error.message : String(error)
}, null, 2)
}]
};
}
}