@mcp-abap-adt/connection 1.5.2 → 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.
package/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # @mcp-abap-adt/connection
2
2
 
3
+ [![Stand With Ukraine](https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/badges/StandWithUkraine.svg)](https://stand-with-ukraine.pp.ua)
4
+
3
5
  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
6
 
5
7
  ## Key Features
@@ -27,11 +27,13 @@ export declare class RfcAbapConnection implements AbapConnection {
27
27
  private readonly sessionId;
28
28
  private readonly baseUrl;
29
29
  private readonly rfcParams;
30
+ private sessionType;
31
+ private sessionCookie;
30
32
  constructor(config: SapConfig, logger?: ILogger | null);
31
33
  connect(): Promise<void>;
32
34
  getBaseUrl(): Promise<string>;
33
35
  getSessionId(): string | null;
34
- setSessionType(_type: 'stateful' | 'stateless'): void;
36
+ setSessionType(type: 'stateful' | 'stateless'): void;
35
37
  makeAdtRequest<T = any, D = any>(options: IAbapRequestOptions): Promise<IAdtResponse<T, D>>;
36
38
  /**
37
39
  * Reset the connection — for RFC this closes the session.
@@ -1 +1 @@
1
- {"version":3,"file":"RfcAbapConnection.d.ts","sourceRoot":"","sources":["../../src/connection/RfcAbapConnection.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,mBAAmB,EACnB,YAAY,EACb,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AA0F1D;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,iBAAkB,YAAW,cAAc;IAOpD,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAPzB,OAAO,CAAC,SAAS,CAA2B;IAC5C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAsB;gBAG7B,MAAM,EAAE,SAAS,EACjB,MAAM,GAAE,OAAO,GAAG,IAAW;IAa1C,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IA8BxB,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC;IAInC,YAAY,IAAI,MAAM,GAAG,IAAI;IAI7B,cAAc,CAAC,KAAK,EAAE,UAAU,GAAG,WAAW,GAAG,IAAI;IAI/C,cAAc,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,GAAG,EACnC,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IA6J9B;;;OAGG;IACH,KAAK,IAAI,IAAI;IAIb;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAc5B,OAAO,CAAC,MAAM,CAAC,cAAc;CAqB9B"}
1
+ {"version":3,"file":"RfcAbapConnection.d.ts","sourceRoot":"","sources":["../../src/connection/RfcAbapConnection.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,mBAAmB,EACnB,YAAY,EACb,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AA0F1D;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,iBAAkB,YAAW,cAAc;IASpD,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM;IATzB,OAAO,CAAC,SAAS,CAA2B;IAC5C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAsB;IAChD,OAAO,CAAC,WAAW,CAAyC;IAC5D,OAAO,CAAC,aAAa,CAAuB;gBAGzB,MAAM,EAAE,SAAS,EACjB,MAAM,GAAE,OAAO,GAAG,IAAW;IAa1C,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IA8BxB,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC;IAInC,YAAY,IAAI,MAAM,GAAG,IAAI;IAI7B,cAAc,CAAC,IAAI,EAAE,UAAU,GAAG,WAAW,GAAG,IAAI;IAU9C,cAAc,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,GAAG,EACnC,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IA8L9B;;;OAGG;IACH,KAAK,IAAI,IAAI;IAIb;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAc5B,OAAO,CAAC,MAAM,CAAC,cAAc;CAqB9B"}
@@ -81,6 +81,8 @@ class RfcAbapConnection {
81
81
  sessionId;
82
82
  baseUrl;
83
83
  rfcParams;
84
+ sessionType = 'stateless';
85
+ sessionCookie = null;
84
86
  constructor(config, logger = null) {
85
87
  this.config = config;
86
88
  this.logger = logger;
@@ -123,8 +125,15 @@ class RfcAbapConnection {
123
125
  getSessionId() {
124
126
  return this.sessionId;
125
127
  }
126
- setSessionType(_type) {
127
- // No-op — RFC connections are always stateful
128
+ setSessionType(type) {
129
+ this.sessionType = type;
130
+ if (type === 'stateless') {
131
+ this.sessionCookie = null;
132
+ this.logger?.debug('RFC session type: stateless (cookie cleared)');
133
+ }
134
+ else {
135
+ this.logger?.debug('RFC session type: stateful (will capture cookies)');
136
+ }
128
137
  }
129
138
  async makeAdtRequest(options) {
130
139
  if (!this.rfcClient?.alive) {
@@ -152,6 +161,17 @@ class RfcAbapConnection {
152
161
  headerFields.push({ NAME: name, VALUE: value });
153
162
  }
154
163
  }
164
+ // Inject session type header so SAP creates/maintains an ICM session
165
+ if (this.sessionType === 'stateful') {
166
+ headerFields.push({ NAME: 'x-sap-adt-sessiontype', VALUE: 'stateful' });
167
+ }
168
+ // Replay session cookie for stateful operations (cookie captured from LOCK response)
169
+ if (this.sessionCookie) {
170
+ const existingCookie = headerFields.find((h) => h.NAME.toLowerCase() === 'cookie');
171
+ if (!existingCookie) {
172
+ headerFields.push({ NAME: 'Cookie', VALUE: this.sessionCookie });
173
+ }
174
+ }
155
175
  // Ensure Content-Type for body
156
176
  const body = options.data !== undefined && options.data !== null
157
177
  ? String(options.data)
@@ -204,6 +224,21 @@ class RfcAbapConnection {
204
224
  respHeaders[field.NAME.toLowerCase()] = field.VALUE;
205
225
  }
206
226
  }
227
+ // Capture session cookie from LOCK/stateful responses for cookie replay
228
+ if (this.sessionType === 'stateful' && respHeaders['set-cookie']) {
229
+ const setCookieHeader = respHeaders['set-cookie'];
230
+ // Extract cookie name=value pairs (strip attributes like Path, Secure, etc.)
231
+ const cookies = Array.isArray(setCookieHeader)
232
+ ? setCookieHeader
233
+ : [setCookieHeader];
234
+ const cookieValues = cookies
235
+ .map((c) => c.split(';')[0].trim())
236
+ .filter(Boolean);
237
+ if (cookieValues.length > 0) {
238
+ this.sessionCookie = cookieValues.join('; ');
239
+ this.logger?.debug(`RFC: captured session cookie: ${this.sessionCookie}`);
240
+ }
241
+ }
207
242
  // On some systems (e.g. BASIS < 7.50), SADT_REST_RFC_ENDPOINT does not
208
243
  // populate STATUS_LINE, returning status 0. Detect errors from the
209
244
  // response body: ADT exception XML indicates a failed request.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mcp-abap-adt/connection",
3
- "version": "1.5.2",
3
+ "version": "1.5.3",
4
4
  "description": "ABAP connection layer for MCP ABAP ADT server",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",