UNPKG

breathe-api

Version:

Model Context Protocol server for Breathe HR APIs with Swagger/OpenAPI support - also works with custom APIs

247 lines 9.9 kB
import { z } from 'zod'; import { resourceManager } from '../utils/resource-manager.js'; export const listEnvironmentsTool = { name: 'list_environments', description: 'List all configured Breathe HR environments with their status and configuration', inputSchema: z.object({}).strict(), handler: async () => { const environments = ['production', 'staging', 'development', 'sandbox']; const activeEnv = resourceManager.getActiveEnvironment(); const envList = environments.map(name => { const env = resourceManager.getEnvironment(name); if (!env) return null; return { name: env.name, displayName: env.displayName, description: env.description, baseUrl: env.baseUrl, isActive: env.name === activeEnv.name, authType: env.auth.type, hasCredentials: !!(env.auth.username || env.auth.token || env.auth.apiKey), metadata: env.metadata }; }).filter(Boolean); return { environments: envList, activeEnvironment: activeEnv.name, totalEnvironments: envList.length }; } }; export const switchEnvironmentTool = { name: 'switch_environment', description: 'Switch the active Breathe HR environment for API calls', inputSchema: z.object({ environment: z.enum(['production', 'staging', 'development', 'sandbox']) .describe('The environment to switch to') }).strict(), handler: async (input) => { const previousEnv = resourceManager.getActiveEnvironment(); resourceManager.setActiveEnvironment(input.environment); const newEnv = resourceManager.getActiveEnvironment(); return { previousEnvironment: previousEnv.name, currentEnvironment: newEnv.name, baseUrl: newEnv.baseUrl, authType: newEnv.auth.type, message: `Switched from ${previousEnv.displayName} to ${newEnv.displayName}` }; } }; export const discoverEndpointsTool = { name: 'discover_endpoints', description: 'Discover available API endpoints for a specific Breathe HR environment by analyzing its Swagger/OpenAPI specification', inputSchema: z.object({ environment: z.enum(['production', 'staging', 'development', 'sandbox']) .describe('The environment to discover endpoints for') .optional(), filter: z.string() .describe('Optional filter to search for specific endpoints') .optional() }).strict(), handler: async (input) => { const targetEnv = input.environment || resourceManager.getActiveEnvironment().name; const discovery = await resourceManager.discoverEndpoints(targetEnv); let endpoints = discovery.endpoints; if (input.filter) { const filterLower = input.filter.toLowerCase(); endpoints = endpoints.filter(ep => ep.path.toLowerCase().includes(filterLower) || ep.description?.toLowerCase().includes(filterLower) || ep.method.toLowerCase().includes(filterLower)); } return { environment: discovery.environment, totalEndpoints: discovery.endpoints.length, filteredEndpoints: endpoints.length, endpoints: endpoints.slice(0, 50), timestamp: discovery.timestamp, filter: input.filter }; } }; export const readResourceTool = { name: 'read_resource', description: 'Read a resource from the Breathe HR API using a resource URI', inputSchema: z.object({ uri: z.string() .describe('Resource URI (e.g., breathe://production/employees, config://staging/environment)') }).strict(), handler: async (input) => { const content = await resourceManager.readResource(input.uri); let parsedContent; try { parsedContent = JSON.parse(content.text || '{}'); } catch { parsedContent = content.text; } return { uri: content.uri, mimeType: content.mimeType, content: parsedContent, size: content.text?.length || content.blob?.length || 0 }; } }; export const configureEnvironmentTool = { name: 'configure_environment', description: 'Update configuration for a Breathe HR environment', inputSchema: z.object({ environment: z.enum(['production', 'staging', 'development', 'sandbox']) .describe('The environment to configure'), baseUrl: z.string() .describe('Base URL for the API') .optional(), authType: z.enum(['basic', 'bearer', 'api-key']) .describe('Authentication type') .optional(), displayName: z.string() .describe('Display name for the environment') .optional(), description: z.string() .describe('Description of the environment') .optional(), metadata: z.object({ region: z.string().optional(), version: z.string().optional(), contact: z.string().optional() }).optional() }).strict(), handler: async (input) => { const { environment, ...updates } = input; const envUpdates = {}; if (updates.baseUrl) envUpdates.baseUrl = updates.baseUrl; if (updates.displayName) envUpdates.displayName = updates.displayName; if (updates.description) envUpdates.description = updates.description; if (updates.metadata) envUpdates.metadata = updates.metadata; if (updates.authType) { const currentEnv = resourceManager.getEnvironment(environment); if (currentEnv) { envUpdates.auth = { ...currentEnv.auth, type: updates.authType }; } } resourceManager.updateEnvironment(environment, envUpdates); const updatedEnv = resourceManager.getEnvironment(environment); return { environment: environment, updated: true, configuration: { displayName: updatedEnv?.displayName, description: updatedEnv?.description, baseUrl: updatedEnv?.baseUrl, authType: updatedEnv?.auth.type, metadata: updatedEnv?.metadata } }; } }; export const testEnvironmentTool = { name: 'test_environment', description: 'Test connectivity and authentication for a Breathe HR environment', inputSchema: z.object({ environment: z.enum(['production', 'staging', 'development', 'sandbox']) .describe('The environment to test') .optional() }).strict(), handler: async (input) => { const targetEnv = input.environment || resourceManager.getActiveEnvironment().name; const results = { environment: targetEnv, tests: { configuration: { passed: false, message: '' }, authentication: { passed: false, message: '' }, swagger: { passed: false, message: '' }, apiAccess: { passed: false, message: '' } } }; try { const env = resourceManager.getEnvironment(targetEnv); if (env) { results.tests.configuration.passed = true; results.tests.configuration.message = 'Environment configured'; } else { results.tests.configuration.message = 'Environment not found'; } } catch (error) { results.tests.configuration.message = error.message; } try { const env = resourceManager.getEnvironment(targetEnv); if (env?.auth) { const hasAuth = !!((env.auth.username && env.auth.password) || env.auth.token || env.auth.apiKey); results.tests.authentication.passed = hasAuth; results.tests.authentication.message = hasAuth ? `${env.auth.type} authentication configured` : 'No authentication credentials found'; } } catch (error) { results.tests.authentication.message = error.message; } try { await resourceManager.readResource(`swagger://${targetEnv}/spec`); results.tests.swagger.passed = true; results.tests.swagger.message = 'Swagger specification accessible'; } catch (error) { results.tests.swagger.message = `Failed to fetch Swagger: ${error.message}`; } try { await resourceManager.readResource(`breathe://${targetEnv}/api/employees`); results.tests.apiAccess.passed = true; results.tests.apiAccess.message = 'API endpoints accessible'; } catch (error) { results.tests.apiAccess.message = `API access failed: ${error.message}`; } const allPassed = Object.values(results.tests).every(test => test.passed); return { ...results, overallStatus: allPassed ? 'healthy' : 'issues detected', recommendation: allPassed ? 'Environment is properly configured and accessible' : 'Check failed tests and ensure proper configuration' }; } }; export const resourceTools = [ listEnvironmentsTool, switchEnvironmentTool, discoverEndpointsTool, readResourceTool, configureEnvironmentTool, testEnvironmentTool ]; //# sourceMappingURL=resource-tools.js.map