Skip to main content
Glama

SAP OData to MCP Server

by Raistlin82
sap-entity-manager.ts6.42 kB
import { SAPClient } from '../services/sap-client.js'; import { Logger } from '../utils/logger.js'; import { EntityType, ODataService } from '../types/sap-types.js'; /** * SAP Entity Manager - Handles entity metadata and operations */ export class SAPEntityManager { constructor( private sapClient: SAPClient, private logger: Logger ) {} /** * Get entity metadata for a specific entity type */ async getEntityMetadata(entityType: string): Promise<EntityType | null> { try { this.logger.debug(`Getting metadata for entity type: ${entityType}`); // This is a simplified implementation that would normally query the SAP system // For now, return a mock entity metadata structure const mockMetadata: EntityType = { name: entityType, namespace: 'SAP', entitySet: `${entityType}Set`, keys: ['ID'], properties: [ { name: 'ID', type: 'Edm.String', nullable: false, maxLength: '10', }, { name: 'Name', type: 'Edm.String', nullable: true, maxLength: '255', }, { name: 'Description', type: 'Edm.String', nullable: true, maxLength: '1000', }, { name: 'CreatedAt', type: 'Edm.DateTimeOffset', nullable: true, }, { name: 'UpdatedAt', type: 'Edm.DateTimeOffset', nullable: true, }, ], navigationProperties: [], creatable: true, updatable: true, deletable: true, addressable: true, }; return mockMetadata; } catch (error) { this.logger.error(`Error getting entity metadata for ${entityType}:`, error); return null; } } /** * Get all available services */ async getAvailableServices(): Promise<ODataService[]> { try { this.logger.debug('Getting available SAP services'); // This would normally query the SAP system for available services // For now, return mock services const mockServices: ODataService[] = [ { id: 'CUSTOMER_SERVICE', title: 'Customer Service', description: 'Manage customer data and relationships', url: '/sap/opu/odata/customer/', version: '1.0', odataVersion: 'v2', metadataUrl: '/sap/opu/odata/customer/$metadata', entitySets: ['CustomerSet'], metadata: { entityTypes: [ { name: 'Customer', namespace: 'SAP.Customer', entitySet: 'CustomerSet', keys: ['CustomerID'], properties: [ { name: 'CustomerID', type: 'Edm.String', nullable: false, maxLength: '10' }, { name: 'CompanyName', type: 'Edm.String', nullable: false, maxLength: '255' }, { name: 'ContactPerson', type: 'Edm.String', nullable: true, maxLength: '100' }, ], navigationProperties: [], creatable: true, updatable: true, deletable: true, addressable: true, }, ], entitySets: [{ CustomerSet: 'Customer' }], version: '1.0', namespace: 'SAP.Customer', }, }, { id: 'SALES_ORDER_SERVICE', title: 'Sales Order Service', description: 'Handle sales orders and related operations', url: '/sap/opu/odata/sales/', version: '1.0', odataVersion: 'v2', metadataUrl: '/sap/opu/odata/sales/$metadata', entitySets: ['SalesOrderSet'], metadata: { entityTypes: [ { name: 'SalesOrder', namespace: 'SAP.Sales', entitySet: 'SalesOrderSet', keys: ['OrderID'], properties: [ { name: 'OrderID', type: 'Edm.String', nullable: false, maxLength: '10' }, { name: 'CustomerID', type: 'Edm.String', nullable: false, maxLength: '10' }, { name: 'OrderDate', type: 'Edm.DateTimeOffset', nullable: false }, { name: 'TotalAmount', type: 'Edm.Decimal', nullable: false }, ], navigationProperties: [], creatable: true, updatable: true, deletable: false, addressable: true, }, ], entitySets: [{ SalesOrderSet: 'SalesOrder' }], version: '1.0', namespace: 'SAP.Sales', }, }, ]; return mockServices; } catch (error) { this.logger.error('Error getting available services:', error); return []; } } /** * Validate entity fields against schema */ validateEntityFields( entityType: string, fields: Record<string, any> ): { valid: boolean; errors: string[] } { try { const errors: string[] = []; // This would normally validate against the actual entity schema // For now, perform basic validation if (!fields || Object.keys(fields).length === 0) { errors.push('No fields provided'); } // Check for required ID field (simplified validation) if (!fields.ID && !fields.id) { errors.push('ID field is required'); } return { valid: errors.length === 0, errors, }; } catch (error) { this.logger.error(`Error validating fields for ${entityType}:`, error); return { valid: false, errors: ['Validation error occurred'], }; } } /** * Get field types for an entity */ async getEntityFieldTypes(entityType: string): Promise<Record<string, string>> { try { const metadata = await this.getEntityMetadata(entityType); if (!metadata) { return {}; } const fieldTypes: Record<string, string> = {}; metadata.properties.forEach(prop => { fieldTypes[prop.name] = prop.type; }); return fieldTypes; } catch (error) { this.logger.error(`Error getting field types for ${entityType}:`, error); return {}; } } }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Raistlin82/btp-sap-odata-to-mcp-server-optimized'

If you have feedback or need assistance with the MCP directory API, please join our Discord server