breathe-api
Version:
Model Context Protocol server for Breathe HR APIs with Swagger/OpenAPI support - also works with custom APIs
130 lines • 5.49 kB
JavaScript
import { breathePrompts, generatePromptMessage } from './index.js';
export async function handleListPrompts(_request) {
return {
prompts: breathePrompts.map(prompt => ({
name: prompt.name,
description: prompt.description,
arguments: prompt.arguments,
})),
};
}
export async function handleGetPrompt(request) {
const { name, arguments: args } = request.params;
const prompt = breathePrompts.find(p => p.name === name);
if (!prompt) {
throw new Error(`Prompt template '${name}' not found`);
}
try {
const messages = generatePromptMessage(name, args);
return {
description: prompt.description,
messages,
};
}
catch (error) {
if (error instanceof Error) {
throw new Error(`Failed to generate prompt: ${error.message}`);
}
throw new Error('Failed to generate prompt');
}
}
export function getPromptCategories() {
const categories = {
'Employee Management': [],
'Time & Attendance': [],
'Recognition': [],
'Integration & Setup': [],
'Troubleshooting': [],
};
breathePrompts.forEach(prompt => {
switch (prompt.name) {
case 'setup-employee-onboarding':
case 'employee-directory':
categories['Employee Management'].push(prompt);
break;
case 'implement-leave-management':
case 'setup-timesheet-system':
case 'shift-scheduling':
categories['Time & Attendance'].push(prompt);
break;
case 'kudos-recognition-system':
categories['Recognition'].push(prompt);
break;
case 'hr-dashboard':
case 'api-integration-guide':
case 'migrate-to-breathe':
categories['Integration & Setup'].push(prompt);
break;
case 'troubleshoot-api':
categories['Troubleshooting'].push(prompt);
break;
}
});
return categories;
}
export function searchPrompts(query) {
const lowercaseQuery = query.toLowerCase();
return breathePrompts.filter(prompt => prompt.name.toLowerCase().includes(lowercaseQuery) ||
prompt.description?.toLowerCase().includes(lowercaseQuery) ||
prompt.arguments?.some(arg => arg.name.toLowerCase().includes(lowercaseQuery) ||
arg.description?.toLowerCase().includes(lowercaseQuery)));
}
export function getPromptSuggestions(context) {
const suggestions = [];
if (context.recentTools?.includes('generate_api_client')) {
const integrationGuide = breathePrompts.find(p => p.name === 'api-integration-guide');
if (integrationGuide)
suggestions.push(integrationGuide);
}
if (context.lastError) {
if (context.lastError.includes('auth') || context.lastError.includes('401')) {
const troubleshoot = breathePrompts.find(p => p.name === 'troubleshoot-api');
if (troubleshoot)
suggestions.push(troubleshoot);
}
}
if (context.platform) {
const platformPrompts = breathePrompts.filter(p => p.arguments?.some(arg => arg.name === 'platform'));
suggestions.push(...platformPrompts.slice(0, 3));
}
return Array.from(new Set(suggestions));
}
export function validatePromptArguments(promptName, args) {
const prompt = breathePrompts.find(p => p.name === promptName);
if (!prompt) {
return { valid: false, errors: [`Unknown prompt: ${promptName}`] };
}
const errors = [];
const requiredArgs = prompt.arguments?.filter(arg => arg.required) || [];
for (const arg of requiredArgs) {
if (!args[arg.name]) {
errors.push(`Missing required argument: ${arg.name}`);
}
}
if (args.platform && !['react', 'react-native', 'nextjs', 'ruby'].includes(args.platform)) {
errors.push(`Invalid platform: ${args.platform}. Must be one of: react, react-native, nextjs, ruby`);
}
if (args.api_type && !['main-hr', 'elmo-roster', 'both'].includes(args.api_type)) {
errors.push(`Invalid api_type: ${args.api_type}. Must be one of: main-hr, elmo-roster, both`);
}
if (args.issue_type && !['auth', 'rate-limit', 'data-format', 'cors'].includes(args.issue_type)) {
errors.push(`Invalid issue_type: ${args.issue_type}. Must be one of: auth, rate-limit, data-format, cors`);
}
const booleanArgs = ['include_approvals', 'include_calendar', 'include_projects',
'include_leaderboard', 'include_swaps', 'include_org_chart'];
for (const boolArg of booleanArgs) {
if (args[boolArg] && !['true', 'false'].includes(args[boolArg])) {
errors.push(`Invalid ${boolArg}: ${args[boolArg]}. Must be 'true' or 'false'`);
}
}
if (args.approval_levels && (isNaN(parseInt(args.approval_levels)) ||
parseInt(args.approval_levels) < 1 || parseInt(args.approval_levels) > 3)) {
errors.push(`Invalid approval_levels: ${args.approval_levels}. Must be between 1 and 3`);
}
if (args.refresh_interval && (isNaN(parseInt(args.refresh_interval)) ||
parseInt(args.refresh_interval) < 1)) {
errors.push(`Invalid refresh_interval: ${args.refresh_interval}. Must be a positive number`);
}
return { valid: errors.length === 0, errors };
}
//# sourceMappingURL=handler.js.map