GetObjectsByType
Retrieves ABAP objects of a specific type within a package or composite object. Enables listing all classes, tables, or programs under a given parent node.
Instructions
[read-only] Retrieves all ABAP objects of a specific type (classes, tables, programs, interfaces, etc.) under a given parent node. Useful for listing all objects of one type within a package or composite object.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| parent_name | Yes | [read-only] Parent object name | |
| parent_tech_name | Yes | [read-only] Parent technical name | |
| parent_type | Yes | [read-only] Parent object type | |
| node_id | Yes | [read-only] Node ID | |
| format | No | [read-only] Output format: 'raw' or 'parsed' | |
| with_short_descriptions | No | [read-only] Include short descriptions |
Implementation Reference
- Main handler function for GetObjectsByType. Validates required params (parent_name, parent_tech_name, parent_type, node_id), creates ADT client, fetches node structure, optionally parses XML to extract objects, formats output grouped by type, and caches results.
export async function handleGetObjectsByType( context: HandlerContext, args: any, ) { const { connection, logger } = context; try { const { parent_name, parent_tech_name, parent_type, node_id, format, with_short_descriptions, } = args; if ( !parent_name || typeof parent_name !== 'string' || parent_name.trim() === '' ) { throw new McpError( ErrorCode.InvalidParams, 'Parameter "parent_name" (string) is required and cannot be empty.', ); } if ( !parent_tech_name || typeof parent_tech_name !== 'string' || parent_tech_name.trim() === '' ) { throw new McpError( ErrorCode.InvalidParams, 'Parameter "parent_tech_name" (string) is required and cannot be empty.', ); } if ( !parent_type || typeof parent_type !== 'string' || parent_type.trim() === '' ) { throw new McpError( ErrorCode.InvalidParams, 'Parameter "parent_type" (string) is required and cannot be empty.', ); } if (!node_id || typeof node_id !== 'string' || node_id.trim() === '') { throw new McpError( ErrorCode.InvalidParams, 'Parameter "node_id" (string) is required and cannot be empty.', ); } const withDescriptions = with_short_descriptions !== undefined ? Boolean(with_short_descriptions) : true; const outputFormat = format || 'parsed'; // 'raw' or 'parsed' // Create AdtClient and get utilities const client = createAdtClient(connection, logger); const utils = client.getUtils(); // Get specific node structure const response = await utils.fetchNodeStructure( parent_type, parent_name.toUpperCase(), node_id, withDescriptions, ); if (outputFormat === 'raw') { const plainResult = return_response(response); objectsListCache.setCache(plainResult); return plainResult; } // Parse and format the response const objects = parseObjectNamesFromXml(response.data); if (objects.length === 0) { const mockResponse = { data: `No objects found for node_id '${node_id}' in ${parent_type} '${parent_name}'.`, status: 200, statusText: 'OK', headers: {}, config: {}, } as any; const plainResult = return_response(mockResponse); objectsListCache.setCache(plainResult); return plainResult; } // Create formatted response let responseText = ''; responseText = `Found ${objects.length} objects for node_id '${node_id}' in ${parent_type} '${parent_name}':\n\n`; // Group by object type if there are multiple types const objectTypes = [...new Set(objects.map((obj) => obj.type))]; if (objectTypes.length > 1) { for (const objType of objectTypes) { const typeObjects = objects.filter((obj) => obj.type === objType); responseText += `š Type: ${objType} (${typeObjects.length} objects)\n`; for (const obj of typeObjects) { responseText += ` ⢠${obj.name}`; if (obj.tech_name !== obj.name) { responseText += ` (${obj.tech_name})`; } if (obj.uri) { responseText += `\n URI: ${obj.uri}`; } responseText += '\n'; } responseText += '\n'; } } else { // Single type, simpler format const objType = objectTypes[0]; responseText += `š Object Type: ${objType}\n\n`; for (const obj of objects) { responseText += ` ⢠${obj.name}`; if (obj.tech_name !== obj.name) { responseText += ` (${obj.tech_name})`; } if (obj.uri) { responseText += `\n URI: ${obj.uri}`; } responseText += '\n'; } } // Add summary responseText += `\nš Summary: ${objects.length} objects found\n`; if (objectTypes.length > 1) { for (const objType of objectTypes) { const count = objects.filter((obj) => obj.type === objType).length; responseText += ` ${objType}: ${count} objects\n`; } } const mockResponse = { data: responseText, status: 200, statusText: 'OK', headers: {}, config: {}, } as any; const finalResult = return_response(mockResponse); objectsListCache.setCache(finalResult); return finalResult; } catch (error) { // MCP-compliant error response: always return content[] with type "text" return { isError: true, content: [ { type: 'text', text: `ADT error: ${String(error)}`, }, ], }; } } - Tool definition (schema) for GetObjectsByType. Defines name, availability, description, and input schema with properties: parent_name, parent_tech_name, parent_type, node_id (required), plus optional format and with_short_descriptions.
export const TOOL_DEFINITION = { name: 'GetObjectsByType', available_in: ['onprem', 'cloud'] as const, description: '[read-only] Retrieves all ABAP objects of a specific type (classes, tables, programs, interfaces, etc.) under a given parent node. Useful for listing all objects of one type within a package or composite object.', inputSchema: { type: 'object', properties: { parent_name: { type: 'string', description: '[read-only] Parent object name', }, parent_tech_name: { type: 'string', description: '[read-only] Parent technical name', }, parent_type: { type: 'string', description: '[read-only] Parent object type', }, node_id: { type: 'string', description: '[read-only] Node ID' }, format: { type: 'string', description: "[read-only] Output format: 'raw' or 'parsed'", }, with_short_descriptions: { type: 'boolean', description: '[read-only] Include short descriptions', }, }, required: ['parent_name', 'parent_tech_name', 'parent_type', 'node_id'], }, } as const; - Helper function that parses XML data to extract object names, types, technical names, and URIs from SEU_ADT_REPOSITORY_OBJ_NODE entries using regex.
function parseObjectNamesFromXml(xmlData: string): Array<{ name: string; type: string; tech_name: string; uri?: string; }> { const objects: Array<{ name: string; type: string; tech_name: string; uri?: string; }> = []; try { // Look for SEU_ADT_REPOSITORY_OBJ_NODE entries const nodeRegex = /<SEU_ADT_REPOSITORY_OBJ_NODE>(.*?)<\/SEU_ADT_REPOSITORY_OBJ_NODE>/gs; const nodeMatches = xmlData.match(nodeRegex); if (nodeMatches) { for (const nodeMatch of nodeMatches) { const objectTypeMatch = nodeMatch.match( /<OBJECT_TYPE>([^<]+)<\/OBJECT_TYPE>/, ); const objectNameMatch = nodeMatch.match( /<OBJECT_NAME>([^<]+)<\/OBJECT_NAME>/, ); const techNameMatch = nodeMatch.match( /<TECH_NAME>([^<]+)<\/TECH_NAME>/, ); const uriMatch = nodeMatch.match(/<OBJECT_URI>([^<]+)<\/OBJECT_URI>/); if (objectTypeMatch && objectNameMatch) { const objectName = decodeURIComponent(objectNameMatch[1]); const techName = techNameMatch ? decodeURIComponent(techNameMatch[1]) : objectName; const uri = uriMatch ? decodeURIComponent(uriMatch[1]) : undefined; objects.push({ name: objectName, type: objectTypeMatch[1], tech_name: techName, uri: uri, }); } } } } catch (_error) { // console.warn('Error parsing XML for object names:', error); } return objects; } - src/lib/handlers/groups/SearchHandlersGroup.ts:22-55 (registration)Registration of GetObjectsByType in the SearchHandlersGroup. Maps the TOOL_DEFINITION (renamed as GetObjectsByType_Tool) to the handleGetObjectsByType handler function. This group is included in both the launcher and EmbeddableMcpServer.
export class SearchHandlersGroup extends BaseHandlerGroup { protected groupName = 'SearchHandlers'; /** * Gets all search handler entries */ getHandlers(): HandlerEntry[] { return [ { toolDefinition: SearchObject_Tool, handler: (args: any) => handleSearchObject(this.context, args), }, // Dynamic import handlers { toolDefinition: GetObjectsList_Tool, handler: (args: any) => { return handleGetObjectsList( this.context, args as { object_type: string }, ); }, }, { toolDefinition: GetObjectsByType_Tool, handler: (args: any) => { return handleGetObjectsByType( this.context, args as { object_type: string }, ); }, }, ]; } }