@mcp-abap-adt/proxy 1.6.4 → 4.0.0

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 (62) hide show
  1. package/CHANGELOG.md +217 -0
  2. package/LICENSE +669 -17
  3. package/README.md +79 -8
  4. package/bin/mcp-abap-adt-proxy-mcp.js +113 -0
  5. package/dist/index.d.ts +10 -4
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +54 -97
  8. package/dist/lib/stores.d.ts +23 -2
  9. package/dist/lib/stores.d.ts.map +1 -1
  10. package/dist/lib/stores.js +56 -1
  11. package/dist/mcp/cli.d.ts +2 -0
  12. package/dist/mcp/cli.d.ts.map +1 -0
  13. package/dist/mcp/cli.js +21 -0
  14. package/dist/mcp/configs.d.ts +33 -0
  15. package/dist/mcp/configs.d.ts.map +1 -0
  16. package/dist/mcp/configs.js +142 -0
  17. package/dist/mcp/ports.d.ts +15 -0
  18. package/dist/mcp/ports.d.ts.map +1 -0
  19. package/dist/mcp/ports.js +35 -0
  20. package/dist/mcp/registry.d.ts +57 -0
  21. package/dist/mcp/registry.d.ts.map +1 -0
  22. package/dist/mcp/registry.js +145 -0
  23. package/dist/mcp/server.d.ts +34 -0
  24. package/dist/mcp/server.d.ts.map +1 -0
  25. package/dist/mcp/server.js +79 -0
  26. package/dist/mcp/shutdown.d.ts +37 -0
  27. package/dist/mcp/shutdown.d.ts.map +1 -0
  28. package/dist/mcp/shutdown.js +82 -0
  29. package/dist/mcp/supervisor.d.ts +125 -0
  30. package/dist/mcp/supervisor.d.ts.map +1 -0
  31. package/dist/mcp/supervisor.js +330 -0
  32. package/dist/mcp/tools.d.ts +28 -0
  33. package/dist/mcp/tools.d.ts.map +1 -0
  34. package/dist/mcp/tools.js +152 -0
  35. package/dist/proxy/btpProxy.d.ts +24 -73
  36. package/dist/proxy/btpProxy.d.ts.map +1 -1
  37. package/dist/proxy/btpProxy.js +116 -631
  38. package/dist/proxy/credentials.d.ts +45 -0
  39. package/dist/proxy/credentials.d.ts.map +1 -0
  40. package/dist/proxy/credentials.js +41 -0
  41. package/dist/proxy/requestHandler.d.ts +38 -0
  42. package/dist/proxy/requestHandler.d.ts.map +1 -0
  43. package/dist/proxy/requestHandler.js +73 -0
  44. package/dist/proxy/reverseProxy.d.ts +11 -2
  45. package/dist/proxy/reverseProxy.d.ts.map +1 -1
  46. package/dist/proxy/reverseProxy.js +52 -9
  47. package/dist/router/headerAnalyzer.js +2 -2
  48. package/dist/router/requestInterceptor.js +9 -9
  49. package/docs/API.md +172 -0
  50. package/docs/ARCHITECTURE.md +322 -0
  51. package/docs/CLIENT_SETUP.md +413 -0
  52. package/docs/CONFIGURATION.md +258 -0
  53. package/docs/MIGRATION-4.0.md +125 -0
  54. package/docs/ROUTING_LOGIC.md +126 -0
  55. package/docs/TROUBLESHOOTING.md +488 -0
  56. package/docs/USAGE.md +422 -0
  57. package/docs/YAML_CONFIG.md +273 -0
  58. package/docs/mcp-proxy-config.example.yaml +62 -0
  59. package/package.json +17 -10
  60. package/dist/proxy/cloudLlmHubProxy.d.ts +0 -2
  61. package/dist/proxy/cloudLlmHubProxy.d.ts.map +0 -1
  62. package/dist/proxy/cloudLlmHubProxy.js +0 -3
@@ -0,0 +1,413 @@
1
+ # Client Setup Guide
2
+
3
+ This guide provides step-by-step instructions for configuring Cline and GitHub Copilot to connect to MCP servers through the proxy.
4
+
5
+ ## Table of Contents
6
+
7
+ - [Prerequisites](#prerequisites)
8
+ - [Cline Configuration](#cline-configuration)
9
+ - [GitHub Copilot Configuration](#github-copilot-configuration)
10
+ - [Configuration Scenarios](#configuration-scenarios)
11
+ - [Troubleshooting](#troubleshooting)
12
+
13
+ ## Prerequisites
14
+
15
+ 1. **Install the proxy**:
16
+ ```bash
17
+ npm install -g @mcp-abap-adt/proxy
18
+ ```
19
+
20
+ 2. **Set up service keys** (for BTP destination-based authentication):
21
+ - Place service key files in platform-specific directories:
22
+ - **Unix/Linux/macOS**: `~/.config/mcp-abap-adt/service-keys/`
23
+ - **Windows**: `%USERPROFILE%\Documents\mcp-abap-adt\service-keys\`
24
+ - Service key files should be named after the destination (e.g., `btp-cloud.json`)
25
+
26
+ 3. **Start the proxy server** (see scenarios below for specific commands)
27
+
28
+ ## Cline Configuration
29
+
30
+ Cline uses the `streamableHttp` transport type and requires HTTP endpoint configuration.
31
+
32
+ ### Basic Configuration File
33
+
34
+ Cline configuration is typically stored in:
35
+ - **macOS**: `~/Library/Application Support/Cline/cline.json`
36
+ - **Windows**: `%APPDATA%\Cline\cline.json`
37
+ - **Linux**: `~/.config/Cline/cline.json`
38
+
39
+ ### Scenario 1: BTP Auth with Target URL Override
40
+
41
+ **Use Case**: Authenticate with a BTP destination's service key, but forward requests
42
+ to a different URL (e.g. direct OData testing or a non-standard MCP path).
43
+
44
+ **1. Start the proxy**:
45
+ ```bash
46
+ mcp-abap-adt-proxy --btp=btp-cloud \
47
+ --target-url=https://your-service.cfapps.eu10.hana.ondemand.com
48
+ ```
49
+
50
+ **2. Configure Cline** (`cline.json`):
51
+ ```json
52
+ {
53
+ "mcpServers": {
54
+ "mcp-abap-adt-proxy": {
55
+ "disabled": false,
56
+ "timeout": 60,
57
+ "type": "streamableHttp",
58
+ "url": "http://localhost:3001/mcp/stream/http",
59
+ "headers": {
60
+ "x-sap-destination": "btp-cloud",
61
+ "x-target-url": "https://your-service.cfapps.eu10.hana.ondemand.com"
62
+ }
63
+ }
64
+ }
65
+ }
66
+ ```
67
+
68
+ **What happens**:
69
+ - Proxy obtains a BTP token from the `btp-cloud` service key
70
+ - Forwards requests to `x-target-url` instead of the key's `abap.url`, with `Authorization: Bearer <token>`
71
+
72
+ ### Scenario 2: BTP MCP Server with BTP Authentication
73
+
74
+ **Use Case**: Connect to an MCP server deployed on SAP BTP that requires BTP authentication.
75
+
76
+ **1. Set up BTP service key**:
77
+ - Create service key file: `~/.config/mcp-abap-adt/service-keys/btp-cloud.json`
78
+ ```json
79
+ {
80
+ "uaa": {
81
+ "url": "https://your-uaa-url.authentication.eu10.hana.ondemand.com",
82
+ "clientid": "your-client-id",
83
+ "clientsecret": "your-client-secret"
84
+ },
85
+ "abap": {
86
+ "url": "https://mcp-server.cfapps.eu10.hana.ondemand.com"
87
+ }
88
+ }
89
+ ```
90
+
91
+ **2. Start the proxy**:
92
+ ```bash
93
+ mcp-abap-adt-proxy --btp=btp-cloud
94
+ ```
95
+
96
+ **3. Configure Cline** (`cline.json`):
97
+ ```json
98
+ {
99
+ "mcpServers": {
100
+ "mcp-abap-adt-proxy": {
101
+ "disabled": false,
102
+ "timeout": 60,
103
+ "type": "streamableHttp",
104
+ "url": "http://localhost:3001/mcp/stream/http",
105
+ "headers": {
106
+ "x-sap-destination": "btp-cloud"
107
+ }
108
+ }
109
+ }
110
+ }
111
+ ```
112
+
113
+ **Alternative: Use command-line override** (simpler, no headers needed):
114
+ ```bash
115
+ # Start proxy with command-line overrides
116
+ mcp-abap-adt-proxy --btp=btp-cloud
117
+ ```
118
+
119
+ ```json
120
+ {
121
+ "mcpServers": {
122
+ "mcp-abap-adt-proxy": {
123
+ "disabled": false,
124
+ "timeout": 60,
125
+ "type": "streamableHttp",
126
+ "url": "http://localhost:3001/mcp/stream/http"
127
+ }
128
+ }
129
+ }
130
+ ```
131
+
132
+ **What happens**:
133
+ - Proxy gets BTP token from `btp-cloud` destination
134
+ - Adds `Authorization: Bearer <token>` header
135
+ - Gets MCP server URL from service key (`abap.url`)
136
+ - Forwards request to MCP server on BTP
137
+
138
+ ## GitHub Copilot Configuration
139
+
140
+ GitHub Copilot supports multiple transport types. The configuration depends on your setup.
141
+
142
+ ### Configuration File Location
143
+
144
+ GitHub Copilot configuration is typically stored in:
145
+ - **macOS**: `~/Library/Application Support/GitHub Copilot/settings.json`
146
+ - **Windows**: `%APPDATA%\GitHub Copilot\settings.json`
147
+ - **Linux**: `~/.config/GitHub Copilot/settings.json`
148
+
149
+ ### Scenario 1: HTTP Transport (Recommended)
150
+
151
+ **1. Start the proxy** (same as Cline scenarios above):
152
+ ```bash
153
+ mcp-abap-adt-proxy --btp=btp-cloud
154
+ ```
155
+
156
+ **2. Configure GitHub Copilot** (`settings.json`):
157
+ ```json
158
+ {
159
+ "mcpServers": {
160
+ "mcp-abap-adt-proxy": {
161
+ "disabled": false,
162
+ "timeout": 60,
163
+ "type": "streamableHttp",
164
+ "url": "http://localhost:3001/mcp/stream/http",
165
+ "headers": {
166
+ "x-sap-destination": "btp-cloud"
167
+ }
168
+ }
169
+ }
170
+ }
171
+ ```
172
+
173
+ ### Scenario 2: SSE Transport
174
+
175
+ **1. Start the proxy with SSE transport**:
176
+ ```bash
177
+ mcp-abap-adt-proxy --transport=sse --btp=btp-cloud
178
+ ```
179
+
180
+ **2. Configure GitHub Copilot** (`settings.json`):
181
+ ```json
182
+ {
183
+ "mcpServers": {
184
+ "mcp-abap-adt-proxy": {
185
+ "disabled": false,
186
+ "timeout": 60,
187
+ "type": "sse",
188
+ "url": "http://localhost:3002",
189
+ "headers": {
190
+ "x-sap-destination": "btp-cloud"
191
+ }
192
+ }
193
+ }
194
+ }
195
+ ```
196
+
197
+ **Note**: SSE transport uses port 3002 by default (HTTP uses 3001).
198
+
199
+ ### Scenario 3: Stdio Transport
200
+
201
+ **1. Start the proxy with stdio transport**:
202
+ ```bash
203
+ mcp-abap-adt-proxy --transport=stdio --btp=btp-cloud
204
+ ```
205
+
206
+ **2. Configure GitHub Copilot** (`settings.json`):
207
+ ```json
208
+ {
209
+ "mcpServers": {
210
+ "mcp-abap-adt-proxy": {
211
+ "disabled": false,
212
+ "timeout": 60,
213
+ "type": "stdio",
214
+ "command": "mcp-abap-adt-proxy",
215
+ "args": [
216
+ "--transport=stdio",
217
+ "--btp=btp-cloud"
218
+ ]
219
+ }
220
+ }
221
+ }
222
+ ```
223
+
224
+ **Note**: For stdio transport, the destination must be provided via command-line arguments (`--btp`, `--target-url`), not headers.
225
+
226
+ ## The management mode
227
+
228
+ A second command, `mcp-abap-adt-proxy-mcp`, speaks MCP over stdio and its tools
229
+ start and stop proxies. Use it when the client should decide which proxy runs and
230
+ when; use `mcp-abap-adt-proxy` when you want to be proxied.
231
+
232
+ ```json
233
+ {
234
+ "mcpServers": {
235
+ "abap-proxy": { "command": "mcp-abap-adt-proxy-mcp" }
236
+ }
237
+ }
238
+ ```
239
+
240
+ It works from the configs in `~/.config/mcp-abap-adt/proxy/` — the same files
241
+ `--config` takes — so starting a proxy is choosing a name:
242
+
243
+ | Tool | |
244
+ |---|---|
245
+ | `proxy_configs` | the names available; call it first, they cannot be guessed |
246
+ | `proxy_start` | starts one on a **free port** and returns the URL bound |
247
+ | `proxy_stop` | frees the port and releases the credential; never touches another session's proxy |
248
+ | `proxy_status` | this session's proxies and everyone else's, dead records pruned on read |
249
+
250
+ Two things worth knowing before you rely on it:
251
+
252
+ - **The proxies live in the management process.** Closing the session — or
253
+ `SIGINT`, or `SIGTERM` — stops all of them. A stop cuts requests still in
254
+ flight after a short grace, because a streamed response never ends on its own
255
+ and the port has to come back.
256
+ - **`proxy_start` proves the credential before reporting success**, so an
257
+ interactive login happens where you asked for it rather than inside whatever
258
+ tool call happens to make the first request.
259
+
260
+ See [Configuration](./CONFIGURATION.md#the-management-mode) for `idleTimeoutMs`
261
+ and what the mode deliberately ignores from a config.
262
+
263
+ ## Configuration Scenarios Summary
264
+
265
+ | Scenario | BTP Auth | Proxy Command | Headers Required |
266
+ |----------|----------|---------------|------------------|
267
+ | BTP MCP | Yes | `--btp=<dest>` | `x-sap-destination` |
268
+ | BTP MCP + explicit URL | Yes | `--btp=<dest> --target-url=<url>` | `x-sap-destination`, `x-target-url` |
269
+
270
+ ## Advanced Configuration
271
+
272
+ ### Using Environment Variables
273
+
274
+ You can configure the proxy using environment variables:
275
+
276
+ ```bash
277
+ export MCP_HTTP_PORT=8080
278
+ export LOG_LEVEL=debug
279
+ mcp-abap-adt-proxy --btp=btp-cloud
280
+ ```
281
+
282
+ ### Using Configuration File
283
+
284
+ Create `mcp-proxy-config.json`:
285
+
286
+ ```json
287
+ {
288
+ "httpPort": 3001,
289
+ "logLevel": "info",
290
+ "maxRetries": 3,
291
+ "requestTimeout": 60000
292
+ }
293
+ ```
294
+
295
+ Start proxy:
296
+ ```bash
297
+ mcp-abap-adt-proxy --btp=btp-cloud
298
+ ```
299
+
300
+ ### Session Storage
301
+
302
+ By default, sessions are stored in-memory (secure, lost on restart). To persist sessions to disk:
303
+
304
+ ```bash
305
+ mcp-abap-adt-proxy --unsafe --btp=btp-cloud
306
+ ```
307
+
308
+ **Warning**: `--unsafe` mode persists tokens to disk. Use only in development environments.
309
+
310
+ ## Troubleshooting
311
+
312
+ ### Issue: Connection Refused
313
+
314
+ **Symptoms**: Client cannot connect to proxy.
315
+
316
+ **Solutions**:
317
+ 1. Verify proxy is running: `curl http://localhost:3001/mcp/stream/http`
318
+ 2. Check port number matches configuration (default: 3001 for HTTP, 3002 for SSE)
319
+ 3. Verify firewall settings allow connections to proxy port
320
+
321
+ ### Issue: Authentication Failed
322
+
323
+ **Symptoms**: Proxy returns 401/403 errors.
324
+
325
+ **Solutions**:
326
+ 1. Verify service key files exist in correct location
327
+ 2. Check service key format (must contain `uaa` section for BTP destinations)
328
+ 3. Verify destination names match between configuration and service key filenames
329
+ 4. Enable verbose logging: `LOG_LEVEL=debug mcp-abap-adt-proxy ...`
330
+
331
+ ### Issue: MCP Server Not Found
332
+
333
+ **Symptoms**: Proxy cannot reach target MCP server.
334
+
335
+ **Solutions**:
336
+ 1. Verify `abap.url` in the service key (or `x-target-url`/`--target-url` override) points to the MCP server
337
+ 2. Check network connectivity to MCP server
338
+ 3. Verify MCP server is running and accessible
339
+ 4. Verify the BTP destination (`--btp`/`x-sap-destination`) matches an existing service key
340
+
341
+ ### Issue: Headers Not Passed Through
342
+
343
+ **Symptoms**: MCP server doesn't receive expected headers.
344
+
345
+ **Solutions**:
346
+ 1. Remember: Only `x-sap-destination` is validated by proxy
347
+ 2. All other headers are passed directly to MCP server
348
+ 3. Verify headers are correctly formatted in client configuration
349
+ 4. Check proxy logs for routing decisions
350
+
351
+ ### Debug Mode
352
+
353
+ Enable verbose logging to troubleshoot issues:
354
+
355
+ ```bash
356
+ # Environment variable
357
+ LOG_LEVEL=debug mcp-abap-adt-proxy --btp=<dest>
358
+ ```
359
+
360
+ This will output detailed information about:
361
+ - Routing decisions
362
+ - Token retrieval
363
+ - Request forwarding
364
+ - Error details
365
+
366
+ ## Quick Reference
367
+
368
+ ### Proxy Command-Line Options
369
+
370
+ ```bash
371
+ # Basic usage
372
+ mcp-abap-adt-proxy [options]
373
+
374
+ # Transport options
375
+ --transport=streamable-http # HTTP transport (default, port 3001)
376
+ --transport=sse # SSE transport (port 3002)
377
+ --transport=stdio # Stdio transport
378
+
379
+ # Destination overrides
380
+ --btp=<destination> # BTP destination name
381
+ --target-url=<url> # Override target URL (auth still from --btp)
382
+
383
+ # Port configuration
384
+ --http-port=<port> # HTTP port (default: 3001)
385
+ --sse-port=<port> # SSE port (default: 3002)
386
+
387
+ # Session storage
388
+ --unsafe # Enable file-based session storage
389
+
390
+ # Help
391
+ --help # Show help message
392
+ ```
393
+
394
+ ### Client Configuration Headers
395
+
396
+ | Header | Required | Description |
397
+ |--------|----------|-------------|
398
+ | `x-sap-destination` | Required* | BTP destination name for authentication |
399
+ | `x-target-url` | Optional | Override the target URL (auth still from the BTP destination) |
400
+
401
+ \* `x-sap-destination` (or the `--btp` command-line parameter) must be provided.
402
+
403
+ ### Service Key Locations
404
+
405
+ - **Unix/Linux/macOS**: `~/.config/mcp-abap-adt/service-keys/<destination>.json`
406
+ - **Windows**: `%USERPROFILE%\Documents\mcp-abap-adt\service-keys\<destination>.json`
407
+
408
+ ## Additional Resources
409
+
410
+ - [Configuration Guide](./CONFIGURATION.md) - Complete configuration reference
411
+ - [Usage Examples](./USAGE.md) - More usage examples
412
+ - [Routing Logic](./ROUTING_LOGIC.md) - Detailed routing logic
413
+ - [Troubleshooting Guide](./TROUBLESHOOTING.md) - Common issues and solutions
@@ -0,0 +1,258 @@
1
+ # Configuration Guide
2
+
3
+ This guide explains how to configure the MCP ABAP ADT Proxy server.
4
+
5
+ ## The four folders
6
+
7
+ Everything the toolchain keeps on disk lives under one base:
8
+
9
+ ```
10
+ ~/.config/mcp-abap-adt/ (Windows: %USERPROFILE%\Documents\mcp-abap-adt\)
11
+ ├── service-keys/ BTP service keys, one JSON per destination
12
+ ├── sessions/ .env files holding credentials, referenced by a config's envFile
13
+ ├── proxy/ one ready proxy config per proxy — the files --config takes
14
+ └── runtime/ one record per live proxy, so one session can see another's
15
+ ```
16
+
17
+ `AUTH_BROKER_PATH` relocates the base, and all four move with it.
18
+
19
+ `runtime/` is written by the management mode and is not configuration: a file
20
+ per running proxy, holding its pid, port, URL, destination and config name. A
21
+ record is a claim, not a fact — every read checks the process behind it and
22
+ deletes the ones whose writer has died, so a crashed session cannot leave a
23
+ ghost behind.
24
+
25
+ ## Configuration Methods
26
+
27
+ The proxy can be configured from a YAML/JSON file, from CLI parameters, or from a combination of both.
28
+
29
+ ### Mode 1: Config file (`--config` / `-c`)
30
+
31
+ ```bash
32
+ mcp-abap-adt-proxy --config=mcp-proxy-config.yaml
33
+ ```
34
+
35
+ The file provides the baseline values. **CLI flags override values from the file** — handy for tweaking a single setting (port, browser mode, headers) on top of a stable config.
36
+
37
+ ```bash
38
+ # YAML provides everything; CLI overrides browser mode and callback port:
39
+ mcp-abap-adt-proxy --config=mcp-proxy-config.yaml \
40
+ --browser none --browser-auth-port 8888
41
+ ```
42
+
43
+ When CLI values override the file, the proxy logs a `Note: CLI flags override values from <path>: ...` warning so the override is visible.
44
+
45
+ `--header key=value` flags are merged with `defaultHeaders` from the file (CLI keys win on conflict). All other overrides replace the file value entirely.
46
+
47
+ Config string values and `--header` values support `${VAR}` / `${VAR:-default}`
48
+ interpolation, resolved from `process.env` then a `.env` (`envFile` in YAML or
49
+ `--env-file`). `process.env` wins; an unresolved `${VAR}` without a default fails
50
+ at startup. See [YAML Configuration Guide](./YAML_CONFIG.md) for details.
51
+
52
+ See [YAML Configuration Guide](./YAML_CONFIG.md) for the file format.
53
+
54
+ ### Mode 2: CLI params + environment variables + defaults
55
+
56
+ Without `--config`, values come from CLI parameters, environment variables, and
57
+ built-in defaults. The config file is **not** consulted in this mode (and there is
58
+ no auto-discovery).
59
+
60
+ #### CLI parameters
61
+
62
+ | Flag | Description |
63
+ |------|-------------|
64
+ | `--btp=<destination>` | BTP destination for Cloud authorization |
65
+ | `--target-url=<url>` (alias `--url`) | Override target URL |
66
+ | `--unsafe` | Persist tokens to disk (default: in-memory) |
67
+ | `--header key=value` | Default header injected into every request (repeatable) |
68
+ | `--env-file <path>` | Path to a `.env` file supplying variables for `${VAR}` interpolation in config/headers (overrides YAML `envFile`) |
69
+ | `--browser=<type>` | OAuth2 login browser: `system`, `headless`, `chrome`, `edge`, `firefox`, `none` |
70
+ | `--browser-auth-port=<port>` | Port for the local OAuth2 callback server |
71
+ | `--transport`, `--http-port`, `--http-host`, `--sse-port`, `--sse-host` | Transport settings |
72
+
73
+ Run `mcp-abap-adt-proxy --help` for the full list.
74
+
75
+ ### Headless login (`--browser none`)
76
+
77
+ With `--browser none` (or `headless`) the proxy does **not** open a browser. It
78
+ prints the authorization URL to the console and waits. Complete login in one of
79
+ two ways — whichever happens first wins:
80
+
81
+ - **Automatic callback** — open the URL on the **same machine** as the proxy;
82
+ the browser redirects to `http://localhost:<browser-auth-port>/callback`.
83
+ - **Paste form** — if your browser is on a **different machine**, open
84
+ `http://<proxy-host>:<browser-auth-port>/` and paste the `code` from the
85
+ address bar (or the whole redirected URL).
86
+
87
+ As of `@mcp-abap-adt/auth-providers` 2.0.0, pasting the code straight into the
88
+ proxy's terminal is **no longer supported**. The callback strategy reads no
89
+ stdin at all, deliberately: under an MCP stdio transport, stdin carries the
90
+ protocol itself, so a provider that read from it there would corrupt the
91
+ stream. If you relied on terminal paste, use the paste form above instead —
92
+ it covers the same "my browser is somewhere else" case without touching
93
+ stdin.
94
+
95
+ You have **5 minutes** from when the URL is printed to complete the login;
96
+ after that the callback server times out and the attempt fails. Run the same
97
+ command again to retry.
98
+
99
+ ```bash
100
+ mcp-abap-adt-proxy --btp <dest> --browser none --browser-auth-port 3333
101
+ ```
102
+
103
+ #### How long the callback port is held
104
+
105
+ The callback port is bound when the login window opens and released as soon as
106
+ the authorization code arrives — **before** it is exchanged for a token, not
107
+ after. The exchange is a round trip to the identity provider, and holding the
108
+ socket across it would keep the port busy for reasons that have nothing to do
109
+ with receiving the callback. The proxy keeps running without it: this is not a
110
+ listening port of the running proxy, only of the login.
111
+
112
+ The release is also unconditional. Since `auth-providers@1.2.0` the socket has
113
+ one owner and one release point, and it is freed on whatever ends the login
114
+ first — the code arriving, an explicit failure, the timeout, or cancellation —
115
+ so a settled login always means the port is already free.
116
+
117
+ Two consequences:
118
+
119
+ - **Two proxies can share one `browserAuthPort`, as long as their logins do not
120
+ overlap.** Whichever opens its login window first holds the port; a second one
121
+ starting during that window fails with `Port <n> is already in use` and exits.
122
+ Give each config its own port if you start several proxies at once.
123
+ - **A callback port that stays busy after a login means something else holds
124
+ it.** See [Troubleshooting](./TROUBLESHOOTING.md#error-port-n-is-already-in-use-naming-your-browserauthport).
125
+
126
+ Choose a number that no other local service uses. The proxy's callback port and
127
+ some other tool's main port colliding is the most common cause of this error.
128
+
129
+ ## Environment Variables
130
+
131
+ #### Server Configuration
132
+ - `MCP_HTTP_PORT` - HTTP server port (default: `3001`)
133
+ - `MCP_SSE_PORT` - SSE server port (default: `3002`)
134
+ - `MCP_HTTP_HOST` - HTTP server host (default: `127.0.0.1`)
135
+ - `MCP_SSE_HOST` - SSE server host (default: `127.0.0.1`)
136
+
137
+ > **Note:** The default is `127.0.0.1` (loopback only) — the proxy runs locally and holds
138
+ > auth tokens, so it does not listen on all interfaces by default. Set `httpHost`/`sseHost`
139
+ > (or `MCP_HTTP_HOST`/`MCP_SSE_HOST`) to `0.0.0.0` only if you deliberately need to expose
140
+ > it. (SSE additionally rejects non-local connections regardless of host.)
141
+ - `MCP_TRANSPORT` - Transport type: `stdio`, `http`, `streamable-http`, or `sse`
142
+
143
+ #### Session Storage
144
+ - `MCP_PROXY_UNSAFE` - Set to `"true"` to persist tokens to disk (default: in-memory)
145
+
146
+ #### Error Handling & Resilience
147
+ - `MCP_PROXY_MAX_RETRIES` - Maximum number of retry attempts (default: `3`)
148
+ - `MCP_PROXY_RETRY_DELAY` - Delay between retries in milliseconds (default: `1000`)
149
+ - `MCP_PROXY_REQUEST_TIMEOUT` - Request timeout in milliseconds (default: `60000`)
150
+ - ~~`MCP_PROXY_CIRCUIT_BREAKER_THRESHOLD`~~, ~~`MCP_PROXY_CIRCUIT_BREAKER_TIMEOUT`~~ — **no effect since 4.0.0.** Still read, so existing setups load unchanged. The circuit breaker guarded the buffered forward that 4.0.0 removed; the forwarding path now streams and a breaker there would mean buffering the response again
151
+
152
+ #### Logging
153
+ - `LOG_LEVEL` - Logging level: `debug`, `info`, `warn`, `error` (default: `info`)
154
+
155
+ > **Note:** `--config` is the **only** way to load a config file. The
156
+ > `MCP_PROXY_CONFIG` environment variable is **not** honored.
157
+
158
+ ## Configuration File
159
+
160
+ For the YAML/JSON config-file format and the full field reference, see the
161
+ [YAML Configuration Guide](./YAML_CONFIG.md). The file is loaded only via
162
+ `--config=<path>` (or `-c`).
163
+
164
+ ## Examples
165
+
166
+ ### Example 1: CLI parameters
167
+
168
+ ```bash
169
+ mcp-abap-adt-proxy --transport=streamable-http --btp=btp \
170
+ --header x-sap-destination=S4HANA_E19
171
+ ```
172
+
173
+ ### Example 2: Environment variables
174
+
175
+ ```bash
176
+ export MCP_HTTP_PORT=8080
177
+ export LOG_LEVEL=debug
178
+ mcp-abap-adt-proxy --btp=btp
179
+ ```
180
+
181
+ ### Example 3: Config file
182
+
183
+ ```bash
184
+ mcp-abap-adt-proxy --config=mcp-proxy-config.yaml
185
+ ```
186
+
187
+ ### Example 4: Config file with CLI overrides
188
+
189
+ ```bash
190
+ mcp-abap-adt-proxy --config=mcp-proxy-config.yaml \
191
+ --http-port=3003 --browser none --browser-auth-port=8888
192
+ ```
193
+
194
+ YAML supplies the baseline; the four flags override `httpPort`, `browser`, and `browserAuthPort` from the file. See [YAML Configuration Guide](./YAML_CONFIG.md).
195
+
196
+ ## Validation
197
+
198
+ The configuration is validated on server startup. Errors will prevent the server from starting, while warnings will be logged but won't stop the server.
199
+
200
+ ### Common Validation Errors
201
+
202
+ - `MCP_HTTP_PORT must be between 1 and 65535` - Invalid port number
203
+ - `MCP_SSE_PORT must be between 1 and 65535` - Invalid port number
204
+ - `MCP_HTTP_PORT and MCP_SSE_PORT must be different` - Ports must be unique
205
+
206
+ ### Common Validation Warnings
207
+
208
+ - `No BTP destination provided (--btp)` - Proxy won't work unless requests include an `x-sap-destination` header
209
+ - `MCP_PROXY_MAX_RETRIES should be between 0 and 10` - Retry count out of recommended range
210
+ - `MCP_PROXY_RETRY_DELAY should be between 0 and 60000ms` - Retry delay out of recommended range
211
+ - `MCP_PROXY_REQUEST_TIMEOUT should be between 1000 and 300000ms` - Timeout out of recommended range
212
+
213
+ ## Best Practices
214
+
215
+ 1. **Use a config file for stable setups** - Keep per-subaccount settings in a YAML file loaded via `--config`
216
+ 2. **Use CLI params for quick overrides** - CLI flags override matching values from `--config` (handy for one-off tweaks like a different `--browser-auth-port`)
217
+ 3. **Validate configuration** - Check logs for validation warnings on startup
218
+ 4. **Set appropriate timeouts** - Adjust `requestTimeout` based on your network conditions
219
+ 5. **Give each proxy its own `browserAuthPort`** - the callback socket is bound only for the duration of a login, but two logins cannot overlap on one port
220
+
221
+ ## The management mode
222
+
223
+ `mcp-abap-adt-proxy-mcp` starts proxies from the configs in `proxy/` and differs
224
+ from `mcp-abap-adt-proxy` in exactly two ways, both deliberate:
225
+
226
+ - **The port in the config is ignored.** A free one is bound instead and
227
+ `proxy_start` reports the URL it got. Four of eight configs in practice declare
228
+ `httpPort: 3001`, so honouring it is what made running two of them impossible.
229
+ - **`httpHost` is ignored too**; the listener always binds `127.0.0.1`.
230
+
231
+ Everything else — destination, `targetUrl`, `defaultHeaders`, `browser`,
232
+ `browserAuthPort`, timeouts, `envFile` interpolation — comes from the config as
233
+ written.
234
+
235
+ One setting exists only here:
236
+
237
+ | Setting | Default | What it does |
238
+ |---|---|---|
239
+ | `idleTimeoutMs` (a `proxy_start` argument) | `1800000` (30 min) | Stops a proxy after this long with **nothing in flight**. The countdown runs only while no request is being carried, so an open SSE connection — quiet or not — is never called idle. `0` disables it. A backstop for a client that finished and forgot, not a substitute for `proxy_stop` |
240
+
241
+ ## Troubleshooting
242
+
243
+ ### Server won't start
244
+
245
+ - Check configuration validation errors in logs
246
+ - Ensure port numbers are valid and not in use
247
+
248
+ ### Proxy requests failing
249
+
250
+ - Verify the BTP destination (`--btp` or `btpDestination`) matches an existing service key
251
+ - Check network connectivity to the target service
252
+ - Check token expiration errors
253
+
254
+ ### High latency
255
+
256
+ - Increase `requestTimeout` if requests are timing out
257
+ - Adjust `retryDelay` for faster retries
258
+