@mcp-abap-adt/adt-clients
v0.1.38
Published
ADT clients for SAP ABAP systems - Read-only and CRUD operations
Maintainers
Readme
@mcp-abap-adt/adt-clients
TypeScript clients for SAP ABAP Development Tools (ADT) with a Builder and Client API architecture.
Features
- ✅ Builder API – fluent interface for complex workflows with method chaining (
ClassBuilder,BehaviorImplementationBuilder,ProgramBuilder,UnitTestBuilder, etc.) - ✅ Client API – simplified interface for common operations:
ReadOnlyClient– read operations for all object typesCrudClient– full CRUD operations with method chaining and state management
- ✅ ABAP Unit test support –
UnitTestBuilderfor running and managing ABAP Unit tests (class and CDS view tests) - ✅ Stateful session management – maintains
sap-adt-connection-idacross operations - ✅ Lock registry – persistent
.locks/active-locks.jsonwith CLI tools for recovery - ✅ TypeScript-first – full type safety with comprehensive interfaces
Responsibilities and Design Principles
Core Development Principle
Interface-Only Communication: This package follows a fundamental development principle: all interactions with external dependencies happen ONLY through interfaces. The code knows NOTHING beyond what is defined in the interfaces.
This means:
- Does not know about concrete implementation classes from other packages
- Does not know about internal data structures or methods not defined in interfaces
- Does not make assumptions about implementation behavior beyond interface contracts
- Does not access properties or methods not explicitly defined in interfaces
This principle ensures:
- Loose coupling: Clients are decoupled from concrete implementations in other packages
- Flexibility: New implementations can be added without modifying clients
- Testability: Easy to mock dependencies for testing
- Maintainability: Changes to implementations don't affect clients
Package Responsibilities
This package is responsible for:
- ADT operations: Provides high-level and low-level APIs for interacting with SAP ABAP Development Tools (ADT)
- Object management: CRUD operations for ABAP objects (classes, interfaces, programs, etc.)
- Builder pattern: Fluent interface for complex workflows with method chaining
- Session management: Maintains session state across operations using
sap-adt-connection-id - Lock management: Handles object locking with persistent registry
What This Package Does
- Provides ADT clients:
ReadOnlyClient,CrudClient, and specialized clients for ADT operations - Implements builders: Builder classes for different ABAP object types with method chaining
- Manages locks: Lock registry with persistent storage and CLI tools
- Handles requests: Makes HTTP requests to SAP ADT endpoints through connection interface
- Manages state: Maintains object state across chained operations
What This Package Does NOT Do
- Does NOT handle authentication: Authentication is handled by
@mcp-abap-adt/connection - Does NOT manage connections: Connection management is handled by
@mcp-abap-adt/connection - Does NOT validate headers: Header validation is handled by
@mcp-abap-adt/header-validator - Does NOT store tokens: Token storage is handled by
@mcp-abap-adt/auth-stores - Does NOT orchestrate authentication: Token lifecycle is handled by
@mcp-abap-adt/auth-broker
External Dependencies
This package interacts with external packages ONLY through interfaces:
@mcp-abap-adt/connection: UsesAbapConnectioninterface for HTTP requests - does not know about concrete connection implementation- No direct dependencies on other packages: All interactions happen through well-defined interfaces
Installation
As npm Package
# Install globally for CLI tools
npm install -g @mcp-abap-adt/adt-clients
# Or install in project
npm install @mcp-abap-adt/adt-clientsCLI Tools
After global installation, you get 5 CLI commands:
adt-lock-object- Lock an object and save sessionadt-unlock-object- Unlock using saved sessionadt-manage-locks- View/manage lock registryadt-manage-sessions- View/manage session filesadt-unlock-objects- Cleanup test objects
See CLI Tools documentation for details.
Architecture
Three-Layer API
Builders (Low-level, flexible)
- Direct access to all ADT operations
- Method chaining with Promise support
- Fine-grained control over workflow
- Example:
ProgramBuilder,ClassBuilder,InterfaceBuilder
Clients (High-level, convenient)
- ReadOnlyClient – simple read operations
- CrudClient – unified CRUD operations with chaining
- State management with getters
- Example:
client.createProgram(...).lockProgram(...).updateProgram(...)
Specialized Clients
ManagementClient– activation, syntax checkingLockClient– lock/unlock with registryValidationClient– object name validation
Supported Object Types
| Object Type | Builder | CrudClient | ReadOnlyClient | |------------|---------|------------|----------------| | Classes (CLAS) | ✅ | ✅ | ✅ | | Behavior Implementations (CLAS) | ✅ | ✅ | ✅ | | Behavior Definitions (BDEF) | ✅ | ✅ | ✅ | | Interfaces (INTF) | ✅ | ✅ | ✅ | | Programs (PROG) | ✅ | ✅ | ✅ | | Function Groups (FUGR) | ✅ | ✅ | ✅ | | Function Modules (FUGR/FF) | ✅ | ✅ | ✅ | | Domains (DOMA) | ✅ | ✅ | ✅ | | Data Elements (DTEL) | ✅ | ✅ | ✅ | | Structures (TABL/DS) | ✅ | ✅ | ✅ | | Tables (TABL/DT) | ✅ | ✅ | ✅ | | Views (DDLS) | ✅ | ✅ | ✅ | | Metadata Extensions (DDLX) | ✅ | ✅ | ✅ | | Packages (DEVC) | ✅ | ✅ | ✅ | | Transports (TRNS) | ✅ | ✅ | ✅ |
Quick Start
Using CrudClient (Recommended for most cases)
import { createAbapConnection } from '@mcp-abap-adt/connection';
import { CrudClient } from '@mcp-abap-adt/adt-clients';
const connection = createAbapConnection({
url: 'https://your-sap-system.example.com',
client: '100',
authType: 'basic',
username: process.env.SAP_USERNAME!,
password: process.env.SAP_PASSWORD!
}, console);
const client = new CrudClient(connection);
// Method chaining with state management
await client
.createInterface('ZIF_TEST', 'Test Interface', 'ZPACKAGE', 'TREQ123')
.lockInterface('ZIF_TEST')
.updateInterface('ZIF_TEST', sourceCode)
.unlockInterface('ZIF_TEST')
.activateInterface('ZIF_TEST');
// Access results via getters
const createResult = client.getCreateResult();
const lockHandle = client.getLockHandle();
const activateResult = client.getActivateResult();Using ReadOnlyClient
import { ReadOnlyClient } from '@mcp-abap-adt/adt-clients';
const client = new ReadOnlyClient(connection);
// Simple read operations
const programSource = await client.readProgram('ZTEST_PROGRAM');
const classDefinition = await client.readClass('ZCL_TEST_CLASS');
const interfaceCode = await client.readInterface('ZIF_TEST_INTERFACE');Using Builders (Advanced workflows)
import { ClassBuilder } from '@mcp-abap-adt/adt-clients/core';
const builder = new ClassBuilder(connection, console, {
className: 'ZCL_MY_CLASS',
packageName: 'ZADT_BLD_PKG01',
description: 'Demo builder class',
transportRequest: 'E19K900001'
});
await builder
.setCode(`CLASS zcl_my_class DEFINITION PUBLIC.
PUBLIC SECTION.
METHODS: hello.
ENDCLASS.
CLASS zcl_my_class IMPLEMENTATION.
METHOD hello.
WRITE: 'Hello from builder'.
ENDMETHOD.
ENDCLASS.`)
.validate()
.then(b => b.create())
.then(b => b.lock())
.then(b => b.update())
.then(b => b.unlock())
.then(b => b.activate());Creating Behavior Implementation Classes
import { CrudClient } from '@mcp-abap-adt/adt-clients';
const client = new CrudClient(connection);
// Full workflow: create, lock, update main source, update implementations, unlock, activate
await client.createBehaviorImplementation({
className: 'ZBP_OK_I_CDS_TEST',
packageName: 'ZOK_TEST_PKG_01',
behaviorDefinition: 'ZOK_I_CDS_TEST',
description: 'Behavior Implementation for ZOK_I_CDS_TEST',
transportRequest: 'E19K900001'
});
// Or use builder directly for more control
const builder = client.getBehaviorImplementationBuilderInstance({
className: 'ZBP_OK_I_CDS_TEST',
behaviorDefinition: 'ZOK_I_CDS_TEST'
});
await builder
.createBehaviorImplementation() // Full workflow
.then(b => b.read()) // Read class source
.then(b => b.lock()) // Lock for modification
.then(b => b.updateMainSource()) // Update main source
.then(b => b.updateImplementations()) // Update implementations include
.then(b => b.unlock()) // Unlock
.then(b => b.activate()); // ActivateCLI Tools
After installation, the following commands are available:
Manage Locks
# List all active locks
adt-manage-locks list
# Clean up stale locks
adt-manage-locks cleanup
# Unlock specific object
adt-manage-locks unlock class ZCL_TESTManage Sessions
# List all sessions
adt-manage-sessions list
# Show session details
adt-manage-sessions info <sessionId>
# Clean up stale sessions
adt-manage-sessions cleanupSee bin/README.md for details.
API Reference
CrudClient Methods
Create Operations:
createProgram(name, description, package, transport?)→Promise<this>createClass(name, description, package, transport?)→Promise<this>createBehaviorImplementation(config)→Promise<this>– creates behavior implementation class with full workflow (create, lock, update main source, update implementations, unlock, activate)createInterface(name, description, package, transport?)→Promise<this>- And more for all object types...
Lock Operations:
lockProgram(name)→Promise<this>(stores lockHandle in state)unlockProgram(name, lockHandle?)→Promise<this>- Similar for all object types...
Update Operations:
updateProgram(name, sourceCode, lockHandle?)→Promise<this>updateClass(name, sourceCode, lockHandle?)→Promise<this>- And more...
Activation:
activateProgram(name)→Promise<this>activateClass(name)→Promise<this>- And more...
State Getters:
getCreateResult()→AxiosResponse | undefinedgetLockHandle()→string | undefinedgetUnlockResult()→AxiosResponse | undefinedgetUpdateResult()→AxiosResponse | undefinedgetActivateResult()→AxiosResponse | undefinedgetCheckResult()→AxiosResponse | undefinedgetValidationResult()→any | undefined
ReadOnlyClient Methods
readProgram(name)→Promise<AxiosResponse>readClass(name)→Promise<AxiosResponse>readInterface(name)→Promise<AxiosResponse>readDataElement(name)→Promise<AxiosResponse>readDomain(name)→Promise<AxiosResponse>readStructure(name)→Promise<AxiosResponse>readTable(name)→Promise<AxiosResponse>readView(name)→Promise<AxiosResponse>readFunctionGroup(name)→Promise<AxiosResponse>readFunctionModule(name, functionGroup)→Promise<AxiosResponse>readPackage(name)→Promise<AxiosResponse>readTransport(transportRequest)→Promise<AxiosResponse>
Specialized Clients
- ManagementClient: batch activation + check operations
- LockClient: explicit lock/unlock with
.locksregistry integration - ValidationClient: name validation mirroring ADT validation endpoint
Refer to the TypeScript typings (src/index.ts) for the full API surface.
Type System
Centralized Type Definitions
All type definitions are centralized in module-specific types.ts files:
// Import types from module exports
import {
CreateClassParams, // Low-level function parameters
ClassBuilderConfig, // Builder configuration
ClassBuilderState, // Builder state
ClassBuilder // Builder class
} from '@mcp-abap-adt/adt-clients';Naming Conventions
The package uses dual naming conventions to distinguish API layers:
Low-Level Parameters (snake_case)
Used by internal ADT API functions:
interface CreateClassParams {
class_name: string;
package_name: string;
transport_request?: string;
description?: string;
}Builder Configuration (camelCase)
Used by Builder classes providing fluent API:
interface ClassBuilderConfig {
className: string;
packageName?: string;
transportRequest?: string;
description: string;
sourceCode?: string;
}This dual convention:
- Makes low-level/high-level distinction clear
- Matches SAP ADT XML parameter naming (
class_namein ADT requests) - Provides familiar camelCase for JavaScript/TypeScript consumers
- Enables proper type checking at each layer
See Architecture Documentation for details.
Migration Guide
From v0.1.0 to v0.2.0
Breaking Changes:
Low-level functions removed from exports
// ❌ Before import { createProgram } from '@mcp-abap-adt/adt-clients/core/program'; // ✅ After - Use Builder import { ProgramBuilder } from '@mcp-abap-adt/adt-clients/core'; // ✅ Or use CrudClient import { CrudClient } from '@mcp-abap-adt/adt-clients'; const client = new CrudClient(connection); await client.createProgram(...);Client classes removed
// ❌ Before import { InterfaceClient } from '@mcp-abap-adt/adt-clients'; // ✅ After import { CrudClient } from '@mcp-abap-adt/adt-clients'; const client = new CrudClient(connection);
Non-breaking:
- Builders continue to work as before
- Specialized clients (ManagementClient, LockClient, ValidationClient) unchanged
Documentation
- Stateful Session Guide – how Builders and clients manage
sessionId,lockHandle, and the lock registry - Operation Delays – configurable delays for SAP operations in tests (sequential execution, timing issues)
- Architecture – package structure and design decisions
- Builder Test Pattern – test structure and patterns for contributors
- Test Configuration Schema – YAML test configuration reference
Logging and Debugging
The library uses a 5-tier granular debug flag system for different code layers:
Debug Environment Variables
# Connection package logs (HTTP, sessions, CSRF tokens)
DEBUG_CONNECTORS=true npm test
# Builder implementation and core library logs
DEBUG_ADT_LIBS=true npm test
# Builder test execution logs
DEBUG_ADT_TESTS=true npm test
# E2E integration test logs
DEBUG_ADT_E2E_TESTS=true npm test
# Test helper function logs
DEBUG_ADT_HELPER_TESTS=true npm test
# Enable ALL ADT scopes at once
DEBUG_ADT_TESTS=true npm testLogger Interface
All Builders use a unified IAdtLogger interface:
import { IAdtLogger, emptyLogger } from '@mcp-abap-adt/adt-clients';
// Custom logger example
const logger: IAdtLogger = {
debug: (msg, ...args) => console.debug(msg, ...args),
info: (msg, ...args) => console.info(msg, ...args),
warn: (msg, ...args) => console.warn(msg, ...args),
error: (msg, ...args) => console.error(msg, ...args),
};
// Use with Builders
const builder = new ClassBuilder(connection, config, logger);
// Or use emptyLogger for silent operation
const silentBuilder = new ClassBuilder(connection, config, emptyLogger);Note: All logger methods are optional. Lock handles are always logged in full (not truncated).
See docs/DEBUG.md for detailed debugging guide.
Changelog
See CHANGELOG.md for package-specific release notes.
License
MIT
Author
Oleksii Kyslytsia [email protected]
