@babamba2/mcp-abap-connection 1.5.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +522 -0
  3. package/bin/sap-abap-auth.js +665 -0
  4. package/dist/config/sapConfig.d.ts +5 -0
  5. package/dist/config/sapConfig.d.ts.map +1 -0
  6. package/dist/config/sapConfig.js +26 -0
  7. package/dist/connection/AbapConnection.d.ts +4 -0
  8. package/dist/connection/AbapConnection.d.ts.map +1 -0
  9. package/dist/connection/AbapConnection.js +2 -0
  10. package/dist/connection/AbstractAbapConnection.d.ts +89 -0
  11. package/dist/connection/AbstractAbapConnection.d.ts.map +1 -0
  12. package/dist/connection/AbstractAbapConnection.js +612 -0
  13. package/dist/connection/BaseAbapConnection.d.ts +19 -0
  14. package/dist/connection/BaseAbapConnection.d.ts.map +1 -0
  15. package/dist/connection/BaseAbapConnection.js +65 -0
  16. package/dist/connection/GenericWebSocketTransport.d.ts +46 -0
  17. package/dist/connection/GenericWebSocketTransport.d.ts.map +1 -0
  18. package/dist/connection/GenericWebSocketTransport.js +135 -0
  19. package/dist/connection/JwtAbapConnection.d.ts +37 -0
  20. package/dist/connection/JwtAbapConnection.d.ts.map +1 -0
  21. package/dist/connection/JwtAbapConnection.js +181 -0
  22. package/dist/connection/RfcAbapConnection.d.ts +49 -0
  23. package/dist/connection/RfcAbapConnection.d.ts.map +1 -0
  24. package/dist/connection/RfcAbapConnection.js +322 -0
  25. package/dist/connection/SamlAbapConnection.d.ts +21 -0
  26. package/dist/connection/SamlAbapConnection.d.ts.map +1 -0
  27. package/dist/connection/SamlAbapConnection.js +65 -0
  28. package/dist/connection/connectionFactory.d.ts +8 -0
  29. package/dist/connection/connectionFactory.d.ts.map +1 -0
  30. package/dist/connection/connectionFactory.js +23 -0
  31. package/dist/connection/csrfConfig.d.ts +46 -0
  32. package/dist/connection/csrfConfig.d.ts.map +1 -0
  33. package/dist/connection/csrfConfig.js +48 -0
  34. package/dist/index.d.ts +14 -0
  35. package/dist/index.d.ts.map +1 -0
  36. package/dist/index.js +32 -0
  37. package/dist/logger.d.ts +3 -0
  38. package/dist/logger.d.ts.map +1 -0
  39. package/dist/logger.js +2 -0
  40. package/dist/utils/timeouts.d.ts +5 -0
  41. package/dist/utils/timeouts.d.ts.map +1 -0
  42. package/dist/utils/timeouts.js +21 -0
  43. package/dist/utils/tokenRefresh.d.ts +15 -0
  44. package/dist/utils/tokenRefresh.d.ts.map +1 -0
  45. package/dist/utils/tokenRefresh.js +55 -0
  46. package/package.json +70 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Oleksii Kyslytsia
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,522 @@
1
+ # @mcp-abap-adt/connection
2
+
3
+ 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.
4
+
5
+ ## Key Features
6
+
7
+ - 🔐 **Multiple Authentication Methods**:
8
+ - Basic Auth for on-premise SAP systems
9
+ - JWT/OAuth2 for SAP BTP ABAP Environment
10
+ - SAML session cookies for pre-authenticated enterprise flows
11
+ - 🔄 **Token Management**:
12
+ - Token refresh is handled by `@mcp-abap-adt/auth-broker` package
13
+ - Connection package focuses on HTTP communication only
14
+ - 💾 **Session Management**:
15
+ - Session headers management (cookies, CSRF tokens)
16
+ - Session state persistence is handled by `@mcp-abap-adt/auth-broker` package
17
+ - 🏗️ **Clean Architecture**:
18
+ - Abstract base class for common HTTP/session logic
19
+ - Auth-type specific implementations (BaseAbapConnection, JwtAbapConnection, SamlAbapConnection)
20
+ - Proper separation of concerns - no JWT logic in base class
21
+ - 🔌 **Realtime Transport Scaffold**:
22
+ - Generic `GenericWebSocketTransport` with pluggable WS factory
23
+ - Reusable for debugger/traces and other event-driven flows
24
+ - 📝 **Custom Logging**: Pluggable logger interface for integration with any logging system
25
+ - 🛠️ **CLI Tool**: See [JWT Auth Tools](./docs/JWT_AUTH_TOOLS.md) for obtaining SAP BTP tokens
26
+ - 📦 **TypeScript**: Full TypeScript support with type definitions included
27
+ - ⚡ **Timeout Management**: Configurable timeouts for different operation types
28
+
29
+ ## Architecture
30
+
31
+ The package uses a clean separation of concerns:
32
+
33
+ - **`AbstractAbapConnection`** (abstract, internal only):
34
+ - Common HTTP request logic
35
+ - Session management (cookies, CSRF tokens)
36
+ - CSRF token fetching with retry
37
+ - Auth-agnostic - knows nothing about Basic or JWT
38
+
39
+ - **`BaseAbapConnection`** (concrete, exported):
40
+ - Basic Authentication implementation
41
+ - Simple connect() - fetches CSRF token
42
+ - Suitable for on-premise SAP systems
43
+
44
+ - **`JwtAbapConnection`** (concrete, exported):
45
+ - JWT/OAuth2 Authentication implementation
46
+ - Simple connect() - establishes connection with JWT token
47
+ - Suitable for SAP BTP ABAP Environment
48
+ - Token refresh handled by auth-broker package
49
+
50
+ - **`SamlAbapConnection`** (concrete, exported):
51
+ - Session-cookie-based authentication (`authType: "saml"`)
52
+ - Uses existing SSO/SAML session cookies
53
+ - Fetches CSRF token and executes ADT requests in same HTTP model
54
+
55
+ - **`GenericWebSocketTransport`** (concrete, exported):
56
+ - Transport abstraction for realtime WS message flows
57
+ - Pluggable factory, envelope-based send/receive
58
+ - Intended for higher-level debugger/trace session orchestration
59
+
60
+ ## Responsibilities and Design Principles
61
+
62
+ ### Core Development Principle
63
+
64
+ **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**.
65
+
66
+ This means:
67
+ - Does not know about concrete implementation classes from other packages
68
+ - Does not know about internal data structures or methods not defined in interfaces
69
+ - Does not make assumptions about implementation behavior beyond interface contracts
70
+ - Does not access properties or methods not explicitly defined in interfaces
71
+
72
+ This principle ensures:
73
+ - **Loose coupling**: Connection classes are decoupled from concrete implementations in other packages
74
+ - **Flexibility**: New implementations can be added without modifying connection classes
75
+ - **Testability**: Easy to mock dependencies for testing
76
+ - **Maintainability**: Changes to implementations don't affect connection classes
77
+
78
+ ### Package Responsibilities
79
+
80
+ This package is responsible for:
81
+
82
+ 1. **HTTP communication with SAP systems**: Makes HTTP requests to SAP ABAP systems via ADT protocol
83
+ 2. **Authentication handling**: Supports Basic Auth and JWT/OAuth2 authentication methods
84
+ 3. **Session management**: Manages cookies, CSRF tokens, and session state
85
+ 4. **Error handling**: Handles HTTP errors and connection issues
86
+
87
+ #### What This Package Does
88
+
89
+ - **Provides connection abstraction**: `AbapConnection` interface for interacting with SAP systems
90
+ - **Handles HTTP requests**: Makes requests to SAP ADT endpoints with proper headers and authentication
91
+ - **Manages sessions**: Handles cookies, CSRF tokens, and session state persistence
92
+
93
+ #### What This Package Does NOT Do
94
+
95
+ - **Does NOT obtain tokens**: Token acquisition is handled by `@mcp-abap-adt/auth-providers` and `@mcp-abap-adt/auth-broker`
96
+ - **Does NOT store tokens**: Token storage is handled by `@mcp-abap-adt/auth-stores`
97
+ - **Does NOT refresh tokens**: Token refresh is handled by `@mcp-abap-adt/auth-broker`
98
+ - **Does NOT orchestrate authentication**: Token lifecycle management is handled by `@mcp-abap-adt/auth-broker`
99
+ - **Does NOT know about destinations**: Destination-based authentication is handled by consumers
100
+ - **Does NOT handle OAuth2 flows**: OAuth2 flows are handled by token providers
101
+
102
+ ### External Dependencies
103
+
104
+ This package interacts with external packages **ONLY through interfaces**:
105
+
106
+ - **Logger interface**: Uses `ILogger` interface for logging - does not know about concrete logger implementation
107
+ - **No direct dependencies on auth packages**: All token-related operations are handled through configuration (`SapConfig`) passed by consumers
108
+
109
+ ## Documentation
110
+
111
+ - 📦 **[Installation Guide](./docs/INSTALLATION.md)** - Setup and installation instructions
112
+ - 📚 **[Usage Guide](./docs/USAGE.md)** - Detailed usage examples and API documentation
113
+ - 💡 **[Examples](./examples/)** - Working code examples
114
+
115
+ ## Features
116
+
117
+ - 🔐 **Multiple Authentication Methods**: Basic Auth for on-premise systems, JWT/OAuth2 for SAP BTP ABAP Environment
118
+ - 💾 **Session Management**: Session headers management (cookies, CSRF tokens) for HTTP communication
119
+ - 📝 **Custom Logging**: Pluggable logger interface for integration with any logging system (optional)
120
+ - 📦 **TypeScript**: Full TypeScript support with type definitions included
121
+ - ⚡ **Timeout Management**: Configurable timeouts for different operation types
122
+ - 🌐 **Network Error Detection**: Automatic detection and proper handling of network-level errors (connection refused, timeout, DNS failures)
123
+
124
+ ## Installation
125
+
126
+ ```bash
127
+ npm install @mcp-abap-adt/connection
128
+ ```
129
+
130
+ For detailed installation instructions, see [Installation Guide](./docs/INSTALLATION.md).
131
+
132
+ ## Quick Start
133
+
134
+ ### Basic Usage (On-Premise)
135
+
136
+ ```typescript
137
+ import { createAbapConnection, SapConfig } from "@mcp-abap-adt/connection";
138
+
139
+ const config: SapConfig = {
140
+ url: "https://your-sap-system.com",
141
+ client: "100",
142
+ authType: "basic",
143
+ username: "your-username",
144
+ password: "your-password",
145
+ };
146
+
147
+ // Create a simple logger
148
+ const logger = {
149
+ info: (msg: string, meta?: any) => console.log(msg, meta),
150
+ error: (msg: string, meta?: any) => console.error(msg, meta),
151
+ warn: (msg: string, meta?: any) => console.warn(msg, meta),
152
+ debug: (msg: string, meta?: any) => console.debug(msg, meta),
153
+ };
154
+
155
+ // Create connection
156
+ const connection = createAbapConnection(config, logger);
157
+
158
+ // Make ADT request
159
+ const response = await connection.makeAdtRequest({
160
+ method: "GET",
161
+ url: "/sap/bc/adt/programs/programs/your-program",
162
+ });
163
+ ```
164
+
165
+ ### Cloud Usage (JWT/OAuth2)
166
+
167
+ ```typescript
168
+ import { createAbapConnection, SapConfig } from "@mcp-abap-adt/connection";
169
+
170
+ // JWT configuration
171
+ const config: SapConfig = {
172
+ url: "https://your-instance.abap.cloud.sap",
173
+ client: "100", // Optional
174
+ authType: "jwt",
175
+ jwtToken: "your-jwt-token-here", // Obtained via OAuth2 flow
176
+ };
177
+
178
+ const logger = {
179
+ info: (msg: string, meta?: any) => console.log(msg, meta),
180
+ error: (msg: string, meta?: any) => console.error(msg, meta),
181
+ warn: (msg: string, meta?: any) => console.warn(msg, meta),
182
+ debug: (msg: string, meta?: any) => console.debug(msg, meta),
183
+ };
184
+
185
+ // Logger is optional - if not provided, no logging output
186
+ const connection = createAbapConnection(config, logger);
187
+
188
+ // Note: Token refresh is handled by @mcp-abap-adt/auth-broker package
189
+ const response = await connection.makeAdtRequest({
190
+ method: "GET",
191
+ url: "/sap/bc/adt/programs/programs/your-program",
192
+ });
193
+ ```
194
+
195
+ ### SSO Usage (SAML Session Cookies)
196
+
197
+ ```typescript
198
+ import { createAbapConnection, SapConfig } from "@mcp-abap-adt/connection";
199
+
200
+ const config: SapConfig = {
201
+ url: "https://your-sap-system.com",
202
+ authType: "saml",
203
+ sessionCookies: "MYSAPSSO2=...; SAP_SESSIONID=...",
204
+ };
205
+
206
+ const connection = createAbapConnection(config, logger);
207
+ const response = await connection.makeAdtRequest({
208
+ method: "GET",
209
+ url: "/sap/bc/adt/programs/programs/your-program",
210
+ });
211
+ ```
212
+
213
+ ### Cloud Usage with Automatic Token Refresh
214
+
215
+ For automatic token refresh on 401/403 errors, inject `ITokenRefresher`:
216
+
217
+ ```typescript
218
+ import { JwtAbapConnection, SapConfig } from "@mcp-abap-adt/connection";
219
+ import type { ITokenRefresher } from "@mcp-abap-adt/interfaces";
220
+
221
+ // Token refresher provides token acquisition and refresh
222
+ // (created by @mcp-abap-adt/auth-broker or custom implementation)
223
+ const tokenRefresher: ITokenRefresher = {
224
+ getToken: async () => { /* return current token */ },
225
+ refreshToken: async () => { /* refresh and return new token */ },
226
+ };
227
+
228
+ // JWT configuration
229
+ const config: SapConfig = {
230
+ url: "https://your-instance.abap.cloud.sap",
231
+ authType: "jwt",
232
+ jwtToken: await tokenRefresher.getToken(), // Get initial token
233
+ };
234
+
235
+ // Create connection with token refresher - 401/403 handled automatically
236
+ const connection = new JwtAbapConnection(config, logger, undefined, tokenRefresher);
237
+
238
+ // Requests automatically retry with refreshed token on auth errors
239
+ const response = await connection.makeAdtRequest({
240
+ method: "GET",
241
+ url: "/sap/bc/adt/programs/programs/your-program",
242
+ });
243
+ ```
244
+
245
+ ### Stateful Sessions
246
+
247
+ For operations that require session state (e.g., object modifications), you can enable stateful sessions:
248
+
249
+ ```typescript
250
+ import { createAbapConnection } from "@mcp-abap-adt/connection";
251
+
252
+ const connection = createAbapConnection(config, logger);
253
+
254
+ // Enable stateful session mode (adds x-sap-adt-sessiontype: stateful header)
255
+ connection.setSessionType("stateful");
256
+
257
+ // Make requests - SAP will maintain session state
258
+ await connection.makeAdtRequest({
259
+ method: "POST",
260
+ url: "/sap/bc/adt/objects/domains",
261
+ data: { /* domain data */ },
262
+ });
263
+
264
+ // Note: Session state persistence is handled by @mcp-abap-adt/auth-broker package
265
+ ```
266
+
267
+ ### Custom Logger
268
+
269
+ ```typescript
270
+ import { ILogger } from "@mcp-abap-adt/connection";
271
+
272
+ class MyLogger implements ILogger {
273
+ info(message: string, meta?: any): void {
274
+ // Your logging implementation
275
+ }
276
+
277
+ error(message: string, meta?: any): void {
278
+ // Your logging implementation
279
+ }
280
+
281
+ warn(message: string, meta?: any): void {
282
+ // Your logging implementation
283
+ }
284
+
285
+ debug(message: string, meta?: any): void {
286
+ // Your logging implementation
287
+ }
288
+
289
+ csrfToken(action: "fetch" | "retry" | "success" | "error", message: string, meta?: any): void {
290
+ // CSRF token specific logging
291
+ }
292
+
293
+ tlsConfig(rejectUnauthorized: boolean): void {
294
+ // TLS configuration logging
295
+ }
296
+ }
297
+
298
+ const logger = new MyLogger();
299
+ const connection = createAbapConnection(config, logger);
300
+ ```
301
+
302
+ ## CLI Tool
303
+
304
+ The package includes a CLI tool for authenticating with SAP BTP using service keys:
305
+
306
+ ### Installation Options
307
+
308
+ - **Local project install**
309
+ ```bash
310
+ npm install @mcp-abap-adt/connection --save-dev
311
+ npx sap-abap-auth auth -k path/to/service-key.json
312
+ ```
313
+ - **Global install**
314
+ ```bash
315
+ npm install -g @mcp-abap-adt/connection
316
+ sap-abap-auth auth -k path/to/service-key.json
317
+ ```
318
+ - **On-demand (npx)**
319
+ ```bash
320
+ npx @mcp-abap-adt/connection sap-abap-auth auth -k path/to/service-key.json
321
+ ```
322
+
323
+ ### Usage
324
+
325
+ ```bash
326
+ # Show help
327
+ sap-abap-auth --help
328
+
329
+ # Authenticate with service key
330
+ sap-abap-auth auth -k service-key.json
331
+
332
+ # Specify browser
333
+ sap-abap-auth auth -k service-key.json --browser chrome
334
+
335
+ # Custom output file
336
+ sap-abap-auth auth -k service-key.json --output .env.production
337
+ ```
338
+
339
+ ### Options
340
+
341
+ - `-k, --key <path>` - Path to service key JSON file (required)
342
+ - `-b, --browser <name>` - Browser to open (chrome, edge, firefox, system, none)
343
+ - `-o, --output <path>` - Path to output .env file (default: .env)
344
+ - `-h, --help` - Show help message
345
+
346
+ ### Using via `npx` (without global install)
347
+
348
+ If `@mcp-abap-adt/connection` is listed as a dependency in your project, you can invoke the CLI directly:
349
+
350
+ ```bash
351
+ npx sap-abap-auth auth -k service-key.json
352
+ ```
353
+
354
+ This works even when you do not install the package globally. For one-off usage, you can also run:
355
+
356
+ ```bash
357
+ npx @mcp-abap-adt/connection sap-abap-auth auth -k service-key.json
358
+ ```
359
+
360
+ This will download the package on demand and execute the CLI.
361
+ ## API Reference
362
+
363
+ ### Types
364
+
365
+ #### `SapConfig`
366
+
367
+ Configuration for SAP ABAP connection.
368
+
369
+ ```typescript
370
+ type SapConfig = {
371
+ url: string;
372
+ client?: string;
373
+ authType: "basic" | "jwt" | "saml";
374
+ // For basic auth
375
+ username?: string;
376
+ password?: string;
377
+ // For JWT auth
378
+ jwtToken?: string;
379
+ // For SAML session cookies
380
+ sessionCookies?: string;
381
+ };
382
+ ```
383
+
384
+ #### `AbapConnection`
385
+
386
+ Main interface for ABAP connections.
387
+
388
+ ```typescript
389
+ interface AbapConnection {
390
+ makeAdtRequest(options: AbapRequestOptions): Promise<AxiosResponse>;
391
+ reset(): void;
392
+ setSessionType(type: "stateless" | "stateful"): void; // Switch session type
393
+ getSessionMode(): "stateless" | "stateful"; // Get current session mode
394
+ getSessionId(): string | null; // Get current session ID
395
+ }
396
+ ```
397
+
398
+ **Session Management:**
399
+ - `setSessionType(type)`: Programmatically switch between stateful and stateless modes
400
+ - `getSessionMode()`: Returns current session mode
401
+ - `getSessionId()`: Returns the current session ID (auto-generated UUID)
402
+
403
+ #### `ILogger`
404
+
405
+ Logger interface for custom logging implementations.
406
+
407
+ ```typescript
408
+ interface ILogger {
409
+ info(message: string, meta?: any): void;
410
+ error(message: string, meta?: any): void;
411
+ warn(message: string, meta?: any): void;
412
+ debug(message: string, meta?: any): void;
413
+ csrfToken?(action: "fetch" | "retry" | "success" | "error", message: string, meta?: any): void;
414
+ tlsConfig?(rejectUnauthorized: boolean): void;
415
+ }
416
+ ```
417
+
418
+ ### Functions
419
+
420
+ #### `createAbapConnection(config, logger?, sessionId?)`
421
+
422
+ Factory function to create an ABAP connection instance.
423
+
424
+ ```typescript
425
+ function createAbapConnection(
426
+ config: SapConfig,
427
+ logger?: ILogger | null,
428
+ sessionId?: string
429
+ ): AbapConnection;
430
+ ```
431
+
432
+ #### `CSRF_CONFIG` and `CSRF_ERROR_MESSAGES`
433
+
434
+ **New in 0.1.13+:** Exported constants for consistent CSRF token handling across different connection implementations.
435
+
436
+ ```typescript
437
+ import { CSRF_CONFIG, CSRF_ERROR_MESSAGES } from '@mcp-abap-adt/connection';
438
+
439
+ // CSRF_CONFIG contains:
440
+ // - RETRY_COUNT: number (default: 3)
441
+ // - RETRY_DELAY: number (default: 1000ms)
442
+ // - ENDPOINT: string (default: '/sap/bc/adt/core/discovery')
443
+ // - REQUIRED_HEADERS: { 'x-csrf-token': 'fetch', 'Accept': 'application/atomsvc+xml' }
444
+
445
+ // CSRF_ERROR_MESSAGES contains:
446
+ // - FETCH_FAILED(attempts: number, cause: string): string
447
+ // - NOT_IN_HEADERS: string
448
+ // - REQUIRED_FOR_MUTATION: string
449
+ ```
450
+
451
+ **Use case:** When implementing custom connection classes (e.g., Cloud SDK-based), you can use these constants to ensure consistent CSRF token handling:
452
+
453
+ ```typescript
454
+ import { CSRF_CONFIG, CSRF_ERROR_MESSAGES } from '@mcp-abap-adt/connection';
455
+
456
+ async function fetchCsrfToken(baseUrl: string): Promise<string> {
457
+ const csrfUrl = `${baseUrl}${CSRF_CONFIG.ENDPOINT}`;
458
+
459
+ for (let attempt = 0; attempt <= CSRF_CONFIG.RETRY_COUNT; attempt++) {
460
+ try {
461
+ const response = await yourHttpClient.get(csrfUrl, {
462
+ headers: CSRF_CONFIG.REQUIRED_HEADERS
463
+ });
464
+
465
+ const token = response.headers['x-csrf-token'];
466
+ if (!token) {
467
+ if (attempt < CSRF_CONFIG.RETRY_COUNT) {
468
+ await new Promise(resolve => setTimeout(resolve, CSRF_CONFIG.RETRY_DELAY));
469
+ continue;
470
+ }
471
+ throw new Error(CSRF_ERROR_MESSAGES.NOT_IN_HEADERS);
472
+ }
473
+
474
+ return token;
475
+ } catch (error) {
476
+ if (attempt >= CSRF_CONFIG.RETRY_COUNT) {
477
+ throw new Error(
478
+ CSRF_ERROR_MESSAGES.FETCH_FAILED(
479
+ CSRF_CONFIG.RETRY_COUNT + 1,
480
+ error instanceof Error ? error.message : String(error)
481
+ )
482
+ );
483
+ }
484
+ await new Promise(resolve => setTimeout(resolve, CSRF_CONFIG.RETRY_DELAY));
485
+ }
486
+ }
487
+ }
488
+ ```
489
+
490
+ See [PR Proposal](./PR_PROPOSAL_CSRF_CONFIG.md) for more details.
491
+
492
+ ## Requirements
493
+
494
+ - Node.js >= 18.0.0
495
+ - Access to SAP ABAP system (on-premise or BTP)
496
+
497
+ ## Changelog
498
+
499
+ See [CHANGELOG.md](./CHANGELOG.md) for detailed version history and breaking changes.
500
+
501
+ **Latest version: 0.2.0**
502
+ - Removed token refresh functionality (handled by `@mcp-abap-adt/auth-broker`)
503
+ - Removed session storage functionality (handled by `@mcp-abap-adt/auth-broker`)
504
+ - Logger is now optional
505
+ - See [CHANGELOG.md](./CHANGELOG.md) for full details
506
+
507
+ ## Documentation
508
+
509
+ - [Examples](./examples/README.md) - Working code examples
510
+ - [Changelog](./CHANGELOG.md) - Version history and release notes
511
+
512
+ ## License
513
+
514
+ MIT
515
+
516
+ ## Repository
517
+
518
+ https://github.com/fr0ster/mcp-abap-adt
519
+
520
+ ## Related Projects
521
+
522
+ - [mcp-abap-adt](https://github.com/fr0ster/mcp-abap-adt) - Main MCP server for ABAP ADT