@mcp-abap-adt/proxy 1.6.2 → 1.6.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/CHANGELOG.md +20 -0
- package/README.md +1 -1
- package/bin/mcp-abap-adt-proxy.js +7 -64
- package/dist/index.js +3 -0
- package/package.json +2 -3
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,26 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [1.6.3] - 2026-07-27
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
- **Stopping the proxy left it running, holding its ports.** `bin/mcp-abap-adt-proxy.js` spawned the server as a child process and forwarded only `SIGINT`. Everything that stops a process with `SIGTERM` — `kill`, `pkill`, a service manager, an MCP client shutting the server down — killed the launcher while the server survived, re-parented to `init`/`systemd`, still holding both the HTTP port and the OAuth callback port. A later start then failed with `Port <n> is already in use`, naming the port from `browserAuthPort`.
|
|
14
|
+
|
|
15
|
+
The orphan was easy to miss: in `ps` it appears as `dist/index.js`, not `mcp-abap-adt-proxy`, and it is no longer attached to the terminal it was started from. Only `Ctrl+C` shut down cleanly.
|
|
16
|
+
|
|
17
|
+
The launcher no longer spawns anything — it loads the server in the same process, so signals reach the shutdown handler that was already there and already correct. It used the same Node executable, an unmodified environment, inherited stdio and the same arguments, so the child bought nothing.
|
|
18
|
+
|
|
19
|
+
- **Closing a terminal mid-login left the proxy running for another 30 seconds.** `SIGHUP` is now handled alongside `SIGINT` and `SIGTERM`. It previously did not terminate the proxy at all during a login: `@mcp-abap-adt/auth-providers` registers its own `SIGHUP` listener while the callback server is open, and any registered listener suppresses Node's default terminate. The process lingered — holding its ports — until the authentication timeout exited it with code 1.
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
- Updated dev/runtime dependencies to latest within their semver ranges (axios, zod, js-yaml, `@mcp-abap-adt/interfaces`, biome, jest toolchain, tsx, `@types/node`). Runtime `dependencies` ranges are unchanged, so consumer installs are unaffected.
|
|
23
|
+
- Bumped `@modelcontextprotocol/inspector` (dev) to `^0.22.0`.
|
|
24
|
+
- Removed unused `commander` dev dependency.
|
|
25
|
+
|
|
26
|
+
### Notes
|
|
27
|
+
- The `browserAuthPort` collision that remains is by design: the callback port is held for the whole interactive login, so two proxies whose login windows overlap cannot share one. Give each config its own, or stagger the logins.
|
|
28
|
+
- Not addressed here, and tracked for `@mcp-abap-adt/auth-providers`: a callback that arrives without a `code` parameter leaves the callback socket open for the lifetime of the process, and a failed token exchange releases it about 300 ms after the login promise has already been rejected.
|
|
29
|
+
|
|
10
30
|
## [1.6.2] - 2026-06-08
|
|
11
31
|
|
|
12
32
|
### Fixed
|
package/README.md
CHANGED
|
@@ -91,7 +91,7 @@ For detailed setup instructions for Cline and GitHub Copilot, see the **[Client
|
|
|
91
91
|
- `--btp=<destination>` - Overrides `x-sap-destination` header (takes precedence)
|
|
92
92
|
- `--url=<url>` - Overrides MCP server URL (required if service key lacks URL)
|
|
93
93
|
- `--browser=<browser>` - Browser to use: `system` (default), `chrome`, `edge`, `firefox`, `headless`
|
|
94
|
-
- `--browser-auth-port=<port>` - Port for OAuth2 callback (default: 3333)
|
|
94
|
+
- `--browser-auth-port=<port>` - Port for the OAuth2 callback (default: 3333). Bound only while you are logging in, then released — see [How long the callback port is held](./docs/CONFIGURATION.md#how-long-the-callback-port-is-held)
|
|
95
95
|
- `--unsafe` - Enables file-based session storage (persists tokens to disk). By default, sessions are stored in-memory (secure, lost on restart)
|
|
96
96
|
|
|
97
97
|
**Default Headers:**
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
/**
|
|
4
4
|
* MCP ABAP ADT Proxy Server Launcher
|
|
5
5
|
*
|
|
6
|
-
*
|
|
6
|
+
* Parses --help/--version, then loads the main server in-process.
|
|
7
7
|
*
|
|
8
8
|
* Usage:
|
|
9
9
|
* mcp-abap-adt-proxy [options]
|
|
@@ -13,7 +13,6 @@
|
|
|
13
13
|
|
|
14
14
|
const path = require('path');
|
|
15
15
|
const fs = require('fs');
|
|
16
|
-
const { spawn } = require('child_process');
|
|
17
16
|
|
|
18
17
|
// Parse command line arguments
|
|
19
18
|
function parseArgs() {
|
|
@@ -158,68 +157,12 @@ function main() {
|
|
|
158
157
|
return;
|
|
159
158
|
}
|
|
160
159
|
|
|
161
|
-
//
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
if (!fs.existsSync(resolvedServerPath)) {
|
|
168
|
-
process.stderr.write(`[MCP Proxy] ✗ Server file not found: ${resolvedServerPath}\n`);
|
|
169
|
-
if (process.platform === 'win32') {
|
|
170
|
-
setTimeout(() => process.exit(1), 30000);
|
|
171
|
-
} else {
|
|
172
|
-
process.exit(1);
|
|
173
|
-
}
|
|
174
|
-
return;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
const serverEnv = {
|
|
178
|
-
...process.env,
|
|
179
|
-
};
|
|
180
|
-
|
|
181
|
-
// Debug logging for Windows
|
|
182
|
-
if (process.platform === 'win32') {
|
|
183
|
-
process.stderr.write(`[MCP Proxy] Spawning server: ${nodeExecPath} ${resolvedServerPath}\n`);
|
|
184
|
-
process.stderr.write(`[MCP Proxy] CWD: ${process.cwd()}\n`);
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
// Spawn the server process
|
|
188
|
-
const serverProcess = spawn(nodeExecPath, [resolvedServerPath, ...serverArgs], {
|
|
189
|
-
stdio: ['inherit', 'inherit', 'inherit'],
|
|
190
|
-
env: serverEnv,
|
|
191
|
-
cwd: process.cwd(),
|
|
192
|
-
shell: false,
|
|
193
|
-
});
|
|
194
|
-
|
|
195
|
-
// Handle server process exit
|
|
196
|
-
serverProcess.on('close', (code) => {
|
|
197
|
-
if (code !== 0 && code !== null) {
|
|
198
|
-
process.stderr.write(`[MCP Proxy] Server exited with code: ${code}\n`);
|
|
199
|
-
}
|
|
200
|
-
process.exit(code || 0);
|
|
201
|
-
});
|
|
202
|
-
|
|
203
|
-
// Handle server process errors
|
|
204
|
-
serverProcess.on('error', (error) => {
|
|
205
|
-
process.stderr.write(`[MCP Proxy] ✗ Failed to start server: ${error.message}\n`);
|
|
206
|
-
if (error.stack) {
|
|
207
|
-
process.stderr.write(error.stack + '\n');
|
|
208
|
-
}
|
|
209
|
-
if (process.platform === 'win32') {
|
|
210
|
-
setTimeout(() => process.exit(1), 30000);
|
|
211
|
-
} else {
|
|
212
|
-
process.exit(1);
|
|
213
|
-
}
|
|
214
|
-
});
|
|
215
|
-
|
|
216
|
-
// Forward SIGINT (Ctrl+C) to server process
|
|
217
|
-
process.on('SIGINT', () => {
|
|
218
|
-
serverProcess.kill('SIGINT');
|
|
219
|
-
setTimeout(() => {
|
|
220
|
-
process.exit(0);
|
|
221
|
-
}, 500);
|
|
222
|
-
});
|
|
160
|
+
// The server is loaded in this process, not spawned as a child. A child
|
|
161
|
+
// would be orphaned by any signal the launcher does not forward — SIGTERM
|
|
162
|
+
// from `kill`/`pkill`, SIGHUP from a closing terminal, or an MCP client
|
|
163
|
+
// stopping the server — and would keep holding the HTTP and OAuth callback
|
|
164
|
+
// ports. In-process, signals reach the server's own handler directly.
|
|
165
|
+
require(serverPath);
|
|
223
166
|
}
|
|
224
167
|
|
|
225
168
|
// Run launcher
|
package/dist/index.js
CHANGED
|
@@ -747,6 +747,9 @@ if (process.env.MCP_SKIP_AUTO_START !== 'true') {
|
|
|
747
747
|
};
|
|
748
748
|
process.on('SIGINT', onSignal);
|
|
749
749
|
process.on('SIGTERM', onSignal);
|
|
750
|
+
// A closing terminal should release the OAuth callback port and the HTTP
|
|
751
|
+
// listener the same way an explicit stop does.
|
|
752
|
+
process.on('SIGHUP', onSignal);
|
|
750
753
|
server.run().catch((error) => {
|
|
751
754
|
logger_js_1.logger?.error('Fatal error while running MCP proxy server', {
|
|
752
755
|
type: 'SERVER_FATAL_ERROR',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mcp-abap-adt/proxy",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.3",
|
|
4
4
|
"description": "MCP proxy server for SAP ABAP ADT - proxies local requests to cloud-llm-hub with JWT authentication",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -45,11 +45,10 @@
|
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@biomejs/biome": "^2.4.12",
|
|
47
47
|
"@jest/globals": "^30.2.0",
|
|
48
|
-
"@modelcontextprotocol/inspector": "^0.
|
|
48
|
+
"@modelcontextprotocol/inspector": "^0.22.0",
|
|
49
49
|
"@types/jest": "^30.0.0",
|
|
50
50
|
"@types/js-yaml": "^4.0.9",
|
|
51
51
|
"@types/node": "^25.2.3",
|
|
52
|
-
"commander": "^14.0.3",
|
|
53
52
|
"cors": "^2.8.6",
|
|
54
53
|
"cross-env": "^10.1.0",
|
|
55
54
|
"express": "^5.1.0",
|