@mcp-abap-adt/connection
v1.5.3
Published
ABAP connection layer for MCP ABAP ADT server
Maintainers
Readme
@mcp-abap-adt/connection
ABAP connection layer for MCP ABAP ADT server. Provides a unified interface for connecting to SAP ABAP systems via ADT (ABAP Development Tools) protocol, supporting both on-premise (Basic Auth) and cloud (JWT/OAuth2) authentication methods.
Key Features
- 🔐 Multiple Authentication Methods:
- Basic Auth for on-premise SAP systems
- JWT/OAuth2 for SAP BTP ABAP Environment
- SAML session cookies for pre-authenticated enterprise flows
- 🔄 Token Management:
- Token refresh is handled by
@mcp-abap-adt/auth-brokerpackage - Connection package focuses on HTTP communication only
- Token refresh is handled by
- 💾 Session Management:
- Session headers management (cookies, CSRF tokens)
- Session state persistence is handled by
@mcp-abap-adt/auth-brokerpackage
- 🏗️ Clean Architecture:
- Abstract base class for common HTTP/session logic
- Auth-type specific implementations (BaseAbapConnection, JwtAbapConnection, SamlAbapConnection)
- Proper separation of concerns - no JWT logic in base class
- 🔌 Realtime Transport Scaffold:
- Generic
GenericWebSocketTransportwith pluggable WS factory - Reusable for debugger/traces and other event-driven flows
- Generic
- 📝 Custom Logging: Pluggable logger interface for integration with any logging system
- 🛠️ CLI Tool: See JWT Auth Tools for obtaining SAP BTP tokens
- 📦 TypeScript: Full TypeScript support with type definitions included
- ⚡ Timeout Management: Configurable timeouts for different operation types
Architecture
The package uses a clean separation of concerns:
AbstractAbapConnection(abstract, internal only):- Common HTTP request logic
- Session management (cookies, CSRF tokens)
- CSRF token fetching with retry
- Auth-agnostic - knows nothing about Basic or JWT
BaseAbapConnection(concrete, exported):- Basic Authentication implementation
- Simple connect() - fetches CSRF token
- Suitable for on-premise SAP systems
JwtAbapConnection(concrete, exported):- JWT/OAuth2 Authentication implementation
- Simple connect() - establishes connection with JWT token
- Suitable for SAP BTP ABAP Environment
- Token refresh handled by auth-broker package
SamlAbapConnection(concrete, exported):- Session-cookie-based authentication (
authType: "saml") - Uses existing SSO/SAML session cookies
- Fetches CSRF token and executes ADT requests in same HTTP model
- Session-cookie-based authentication (
GenericWebSocketTransport(concrete, exported):- Transport abstraction for realtime WS message flows
- Pluggable factory, envelope-based send/receive
- Intended for higher-level debugger/trace session orchestration
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: Connection classes are decoupled from concrete implementations in other packages
- Flexibility: New implementations can be added without modifying connection classes
- Testability: Easy to mock dependencies for testing
- Maintainability: Changes to implementations don't affect connection classes
Package Responsibilities
This package is responsible for:
- HTTP communication with SAP systems: Makes HTTP requests to SAP ABAP systems via ADT protocol
- Authentication handling: Supports Basic Auth and JWT/OAuth2 authentication methods
- Session management: Manages cookies, CSRF tokens, and session state
- Error handling: Handles HTTP errors and connection issues
What This Package Does
- Provides connection abstraction:
AbapConnectioninterface for interacting with SAP systems - Handles HTTP requests: Makes requests to SAP ADT endpoints with proper headers and authentication
- Manages sessions: Handles cookies, CSRF tokens, and session state persistence
What This Package Does NOT Do
- Does NOT obtain tokens: Token acquisition is handled by
@mcp-abap-adt/auth-providersand@mcp-abap-adt/auth-broker - Does NOT store tokens: Token storage is handled by
@mcp-abap-adt/auth-stores - Does NOT refresh tokens: Token refresh is handled by
@mcp-abap-adt/auth-broker - Does NOT orchestrate authentication: Token lifecycle management is handled by
@mcp-abap-adt/auth-broker - Does NOT know about destinations: Destination-based authentication is handled by consumers
- Does NOT handle OAuth2 flows: OAuth2 flows are handled by token providers
External Dependencies
This package interacts with external packages ONLY through interfaces:
- Logger interface: Uses
ILoggerinterface for logging - does not know about concrete logger implementation - No direct dependencies on auth packages: All token-related operations are handled through configuration (
SapConfig) passed by consumers
Documentation
- 📦 Installation Guide - Setup and installation instructions
- 📚 Usage Guide - Detailed usage examples and API documentation
- 💡 Examples - Working code examples
Features
- 🔐 Multiple Authentication Methods: Basic Auth for on-premise systems, JWT/OAuth2 for SAP BTP ABAP Environment
- 💾 Session Management: Session headers management (cookies, CSRF tokens) for HTTP communication
- 📝 Custom Logging: Pluggable logger interface for integration with any logging system (optional)
- 📦 TypeScript: Full TypeScript support with type definitions included
- ⚡ Timeout Management: Configurable timeouts for different operation types
- 🌐 Network Error Detection: Automatic detection and proper handling of network-level errors (connection refused, timeout, DNS failures)
Installation
npm install @mcp-abap-adt/connectionFor detailed installation instructions, see Installation Guide.
Quick Start
Basic Usage (On-Premise)
import { createAbapConnection, SapConfig } from "@mcp-abap-adt/connection";
const config: SapConfig = {
url: "https://your-sap-system.com",
client: "100",
authType: "basic",
username: "your-username",
password: "your-password",
};
// Create a simple logger
const logger = {
info: (msg: string, meta?: any) => console.log(msg, meta),
error: (msg: string, meta?: any) => console.error(msg, meta),
warn: (msg: string, meta?: any) => console.warn(msg, meta),
debug: (msg: string, meta?: any) => console.debug(msg, meta),
};
// Create connection
const connection = createAbapConnection(config, logger);
// Make ADT request
const response = await connection.makeAdtRequest({
method: "GET",
url: "/sap/bc/adt/programs/programs/your-program",
});Cloud Usage (JWT/OAuth2)
import { createAbapConnection, SapConfig } from "@mcp-abap-adt/connection";
// JWT configuration
const config: SapConfig = {
url: "https://your-instance.abap.cloud.sap",
client: "100", // Optional
authType: "jwt",
jwtToken: "your-jwt-token-here", // Obtained via OAuth2 flow
};
const logger = {
info: (msg: string, meta?: any) => console.log(msg, meta),
error: (msg: string, meta?: any) => console.error(msg, meta),
warn: (msg: string, meta?: any) => console.warn(msg, meta),
debug: (msg: string, meta?: any) => console.debug(msg, meta),
};
// Logger is optional - if not provided, no logging output
const connection = createAbapConnection(config, logger);
// Note: Token refresh is handled by @mcp-abap-adt/auth-broker package
const response = await connection.makeAdtRequest({
method: "GET",
url: "/sap/bc/adt/programs/programs/your-program",
});SSO Usage (SAML Session Cookies)
import { createAbapConnection, SapConfig } from "@mcp-abap-adt/connection";
const config: SapConfig = {
url: "https://your-sap-system.com",
authType: "saml",
sessionCookies: "MYSAPSSO2=...; SAP_SESSIONID=...",
};
const connection = createAbapConnection(config, logger);
const response = await connection.makeAdtRequest({
method: "GET",
url: "/sap/bc/adt/programs/programs/your-program",
});Cloud Usage with Automatic Token Refresh
For automatic token refresh on 401/403 errors, inject ITokenRefresher:
import { JwtAbapConnection, SapConfig } from "@mcp-abap-adt/connection";
import type { ITokenRefresher } from "@mcp-abap-adt/interfaces";
// Token refresher provides token acquisition and refresh
// (created by @mcp-abap-adt/auth-broker or custom implementation)
const tokenRefresher: ITokenRefresher = {
getToken: async () => { /* return current token */ },
refreshToken: async () => { /* refresh and return new token */ },
};
// JWT configuration
const config: SapConfig = {
url: "https://your-instance.abap.cloud.sap",
authType: "jwt",
jwtToken: await tokenRefresher.getToken(), // Get initial token
};
// Create connection with token refresher - 401/403 handled automatically
const connection = new JwtAbapConnection(config, logger, undefined, tokenRefresher);
// Requests automatically retry with refreshed token on auth errors
const response = await connection.makeAdtRequest({
method: "GET",
url: "/sap/bc/adt/programs/programs/your-program",
});Stateful Sessions
For operations that require session state (e.g., object modifications), you can enable stateful sessions:
import { createAbapConnection } from "@mcp-abap-adt/connection";
const connection = createAbapConnection(config, logger);
// Enable stateful session mode (adds x-sap-adt-sessiontype: stateful header)
connection.setSessionType("stateful");
// Make requests - SAP will maintain session state
await connection.makeAdtRequest({
method: "POST",
url: "/sap/bc/adt/objects/domains",
data: { /* domain data */ },
});
// Note: Session state persistence is handled by @mcp-abap-adt/auth-broker packageCustom Logger
import { ILogger } from "@mcp-abap-adt/connection";
class MyLogger implements ILogger {
info(message: string, meta?: any): void {
// Your logging implementation
}
error(message: string, meta?: any): void {
// Your logging implementation
}
warn(message: string, meta?: any): void {
// Your logging implementation
}
debug(message: string, meta?: any): void {
// Your logging implementation
}
csrfToken(action: "fetch" | "retry" | "success" | "error", message: string, meta?: any): void {
// CSRF token specific logging
}
tlsConfig(rejectUnauthorized: boolean): void {
// TLS configuration logging
}
}
const logger = new MyLogger();
const connection = createAbapConnection(config, logger);CLI Tool
The package includes a CLI tool for authenticating with SAP BTP using service keys:
Installation Options
- Local project install
npm install @mcp-abap-adt/connection --save-dev npx sap-abap-auth auth -k path/to/service-key.json - Global install
npm install -g @mcp-abap-adt/connection sap-abap-auth auth -k path/to/service-key.json - On-demand (npx)
npx @mcp-abap-adt/connection sap-abap-auth auth -k path/to/service-key.json
Usage
# Show help
sap-abap-auth --help
# Authenticate with service key
sap-abap-auth auth -k service-key.json
# Specify browser
sap-abap-auth auth -k service-key.json --browser chrome
# Custom output file
sap-abap-auth auth -k service-key.json --output .env.productionOptions
-k, --key <path>- Path to service key JSON file (required)-b, --browser <name>- Browser to open (chrome, edge, firefox, system, none)-o, --output <path>- Path to output .env file (default: .env)-h, --help- Show help message
Using via npx (without global install)
If @mcp-abap-adt/connection is listed as a dependency in your project, you can invoke the CLI directly:
npx sap-abap-auth auth -k service-key.jsonThis works even when you do not install the package globally. For one-off usage, you can also run:
npx @mcp-abap-adt/connection sap-abap-auth auth -k service-key.jsonThis will download the package on demand and execute the CLI.
API Reference
Types
SapConfig
Configuration for SAP ABAP connection.
type SapConfig = {
url: string;
client?: string;
authType: "basic" | "jwt" | "saml";
// For basic auth
username?: string;
password?: string;
// For JWT auth
jwtToken?: string;
// For SAML session cookies
sessionCookies?: string;
};AbapConnection
Main interface for ABAP connections.
interface AbapConnection {
makeAdtRequest(options: AbapRequestOptions): Promise<AxiosResponse>;
reset(): void;
setSessionType(type: "stateless" | "stateful"): void; // Switch session type
getSessionMode(): "stateless" | "stateful"; // Get current session mode
getSessionId(): string | null; // Get current session ID
}Session Management:
setSessionType(type): Programmatically switch between stateful and stateless modesgetSessionMode(): Returns current session modegetSessionId(): Returns the current session ID (auto-generated UUID)
ILogger
Logger interface for custom logging implementations.
interface ILogger {
info(message: string, meta?: any): void;
error(message: string, meta?: any): void;
warn(message: string, meta?: any): void;
debug(message: string, meta?: any): void;
csrfToken?(action: "fetch" | "retry" | "success" | "error", message: string, meta?: any): void;
tlsConfig?(rejectUnauthorized: boolean): void;
}Functions
createAbapConnection(config, logger?, sessionId?)
Factory function to create an ABAP connection instance.
function createAbapConnection(
config: SapConfig,
logger?: ILogger | null,
sessionId?: string
): AbapConnection;CSRF_CONFIG and CSRF_ERROR_MESSAGES
New in 0.1.13+: Exported constants for consistent CSRF token handling across different connection implementations.
import { CSRF_CONFIG, CSRF_ERROR_MESSAGES } from '@mcp-abap-adt/connection';
// CSRF_CONFIG contains:
// - RETRY_COUNT: number (default: 3)
// - RETRY_DELAY: number (default: 1000ms)
// - ENDPOINT: string (default: '/sap/bc/adt/core/discovery')
// - REQUIRED_HEADERS: { 'x-csrf-token': 'fetch', 'Accept': 'application/atomsvc+xml' }
// CSRF_ERROR_MESSAGES contains:
// - FETCH_FAILED(attempts: number, cause: string): string
// - NOT_IN_HEADERS: string
// - REQUIRED_FOR_MUTATION: stringUse case: When implementing custom connection classes (e.g., Cloud SDK-based), you can use these constants to ensure consistent CSRF token handling:
import { CSRF_CONFIG, CSRF_ERROR_MESSAGES } from '@mcp-abap-adt/connection';
async function fetchCsrfToken(baseUrl: string): Promise<string> {
const csrfUrl = `${baseUrl}${CSRF_CONFIG.ENDPOINT}`;
for (let attempt = 0; attempt <= CSRF_CONFIG.RETRY_COUNT; attempt++) {
try {
const response = await yourHttpClient.get(csrfUrl, {
headers: CSRF_CONFIG.REQUIRED_HEADERS
});
const token = response.headers['x-csrf-token'];
if (!token) {
if (attempt < CSRF_CONFIG.RETRY_COUNT) {
await new Promise(resolve => setTimeout(resolve, CSRF_CONFIG.RETRY_DELAY));
continue;
}
throw new Error(CSRF_ERROR_MESSAGES.NOT_IN_HEADERS);
}
return token;
} catch (error) {
if (attempt >= CSRF_CONFIG.RETRY_COUNT) {
throw new Error(
CSRF_ERROR_MESSAGES.FETCH_FAILED(
CSRF_CONFIG.RETRY_COUNT + 1,
error instanceof Error ? error.message : String(error)
)
);
}
await new Promise(resolve => setTimeout(resolve, CSRF_CONFIG.RETRY_DELAY));
}
}
}See PR Proposal for more details.
Requirements
- Node.js >= 18.0.0
- Access to SAP ABAP system (on-premise or BTP)
Changelog
See CHANGELOG.md for detailed version history and breaking changes.
Latest version: 0.2.0
- Removed token refresh functionality (handled by
@mcp-abap-adt/auth-broker) - Removed session storage functionality (handled by
@mcp-abap-adt/auth-broker) - Logger is now optional
- See CHANGELOG.md for full details
Documentation
License
MIT
Repository
https://github.com/fr0ster/mcp-abap-adt
Related Projects
- mcp-abap-adt - Main MCP server for ABAP ADT
