@mcp-abap-adt/proxy 0.1.1
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 +89 -0
- package/LICENSE +22 -0
- package/README.md +234 -0
- package/bin/mcp-abap-adt-proxy.js +203 -0
- package/dist/index.d.ts +56 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +645 -0
- package/dist/lib/config.d.ts +33 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +196 -0
- package/dist/lib/errorHandler.d.ts +69 -0
- package/dist/lib/errorHandler.d.ts.map +1 -0
- package/dist/lib/errorHandler.js +202 -0
- package/dist/lib/logger.d.ts +17 -0
- package/dist/lib/logger.d.ts.map +1 -0
- package/dist/lib/logger.js +43 -0
- package/dist/lib/stores.d.ts +18 -0
- package/dist/lib/stores.d.ts.map +1 -0
- package/dist/lib/stores.js +22 -0
- package/dist/lib/transportConfig.d.ts +18 -0
- package/dist/lib/transportConfig.d.ts.map +1 -0
- package/dist/lib/transportConfig.js +124 -0
- package/dist/proxy/cloudLlmHubProxy.d.ts +61 -0
- package/dist/proxy/cloudLlmHubProxy.d.ts.map +1 -0
- package/dist/proxy/cloudLlmHubProxy.js +380 -0
- package/dist/router/directCloudRouter.d.ts +32 -0
- package/dist/router/directCloudRouter.d.ts.map +1 -0
- package/dist/router/directCloudRouter.js +179 -0
- package/dist/router/headerAnalyzer.d.ts +48 -0
- package/dist/router/headerAnalyzer.d.ts.map +1 -0
- package/dist/router/headerAnalyzer.js +124 -0
- package/dist/router/localBasicRouter.d.ts +23 -0
- package/dist/router/localBasicRouter.d.ts.map +1 -0
- package/dist/router/localBasicRouter.js +140 -0
- package/dist/router/requestInterceptor.d.ts +32 -0
- package/dist/router/requestInterceptor.d.ts.map +1 -0
- package/dist/router/requestInterceptor.js +82 -0
- package/package.json +73 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [0.1.1] - 2025-12-02
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- **Local testing mode without BTP authentication**
|
|
14
|
+
- Proxy can now run with only `--mcp` or `x-mcp-destination` (without `--btp` or `x-btp-destination`)
|
|
15
|
+
- Enables local integration testing without BTP authentication
|
|
16
|
+
- MCP server URL can be obtained from MCP destination service key or specified directly via `--mcp-url`
|
|
17
|
+
- **`--mcp-url` parameter support**
|
|
18
|
+
- Direct MCP server URL specification for local testing
|
|
19
|
+
- Auto-generated from ADT server configuration when using `tools/start-servers.js`
|
|
20
|
+
- Can be used instead of service key-based URL lookup
|
|
21
|
+
- Environment variable support: `MCP_URL`
|
|
22
|
+
- **Testing tool: `tools/start-servers.js`**
|
|
23
|
+
- Utility script to start both `mcp-abap-adt` and `mcp-abap-adt-proxy` simultaneously
|
|
24
|
+
- Automatic `mcpUrl` generation based on ADT server configuration
|
|
25
|
+
- Both servers use the same transport protocol (HTTP or SSE)
|
|
26
|
+
- Default configuration: ADT on port 3000 (HTTP), Proxy on port 3001 (HTTP)
|
|
27
|
+
- Available via `npm run test:servers`
|
|
28
|
+
- **Flexible routing requirements**
|
|
29
|
+
- Proxy accepts either `x-btp-destination/--btp`, `x-mcp-destination/--mcp`, or `x-mcp-url/--mcp-url`
|
|
30
|
+
- Removed strict requirement for BTP destination when using MCP destination or URL
|
|
31
|
+
|
|
32
|
+
### Changed
|
|
33
|
+
- **Routing logic updated**
|
|
34
|
+
- `x-btp-destination` is now optional (was required)
|
|
35
|
+
- Proxy can work with only `x-mcp-destination` or `x-mcp-url` for local testing
|
|
36
|
+
- MCP URL can be obtained from multiple sources (priority order):
|
|
37
|
+
1. `x-mcp-url` header or `--mcp-url` parameter (direct URL)
|
|
38
|
+
2. Service key for `x-btp-destination` (if provided)
|
|
39
|
+
3. Service key for `x-mcp-destination` (if only MCP destination is provided)
|
|
40
|
+
- **Token retrieval made optional for MCP destination**
|
|
41
|
+
- Token retrieval for `mcpDestination` is now optional (won't fail if token unavailable)
|
|
42
|
+
- Allows local testing without full service key configuration
|
|
43
|
+
- **Error messages improved**
|
|
44
|
+
- More descriptive error messages when neither BTP nor MCP destination is provided
|
|
45
|
+
- Clear indication of local testing mode vs BTP authentication mode
|
|
46
|
+
|
|
47
|
+
### Fixed
|
|
48
|
+
- Proxy now correctly handles cases where only MCP destination is provided without BTP destination
|
|
49
|
+
- Fixed TypeScript compilation errors in `directCloudRouter.ts` (replaced `routingDecision.destination` with `btpDestination` or `mcpDestination`)
|
|
50
|
+
- Fixed routing decision interface to properly support both BTP and MCP destinations
|
|
51
|
+
|
|
52
|
+
## [0.1.0] - 2025-12-02
|
|
53
|
+
|
|
54
|
+
### Added
|
|
55
|
+
- Initial project setup and infrastructure
|
|
56
|
+
- TypeScript configuration and build scripts
|
|
57
|
+
- Basic project structure (src/, bin/)
|
|
58
|
+
- Logger utility
|
|
59
|
+
- Configuration management (environment variables, config files, command-line arguments)
|
|
60
|
+
- MCP server skeleton with HTTP, SSE, and stdio transport support
|
|
61
|
+
- Launcher script (bin/mcp-abap-adt-proxy.js)
|
|
62
|
+
- Request interception and routing logic
|
|
63
|
+
- JWT token management via `@mcp-abap-adt/auth-broker`
|
|
64
|
+
- Service key-based authentication
|
|
65
|
+
- Error handling with retry logic and circuit breaker
|
|
66
|
+
- **Safe session storage by default** – Session data stored in-memory using `SafeSessionStore`:
|
|
67
|
+
- Session tokens are not persisted to disk by default (secure by default)
|
|
68
|
+
- Session data is lost after server restart (requires re-authentication)
|
|
69
|
+
- File-based storage (`FileSessionStore`) available via `--unsafe` flag
|
|
70
|
+
- **`--unsafe` flag** – Enables file-based session storage (persists tokens to disk):
|
|
71
|
+
- When specified, session data is saved to platform-specific locations
|
|
72
|
+
- Can be set via environment variable: `MCP_PROXY_UNSAFE=true`
|
|
73
|
+
- Use this flag if you need session persistence across server restarts
|
|
74
|
+
- Command-line options: `--btp`, `--mcp`, `--unsafe`
|
|
75
|
+
- Configuration file support (`mcp-proxy-config.json`)
|
|
76
|
+
- README and ROADMAP documentation
|
|
77
|
+
|
|
78
|
+
### Dependencies
|
|
79
|
+
- `@modelcontextprotocol/sdk` - MCP SDK
|
|
80
|
+
- `@mcp-abap-adt/auth-broker` ^0.1.5 - JWT token management
|
|
81
|
+
- Benefits from new `SafeSessionStore` implementation (in-memory, secure)
|
|
82
|
+
- Updated to use new `ISessionStore` interface (replaces `SessionStore`)
|
|
83
|
+
- `@mcp-abap-adt/connection` ^0.1.13 - Connection layer
|
|
84
|
+
- Uses new CSRF token endpoint `/sap/bc/adt/core/discovery` (lighter response, available on all systems)
|
|
85
|
+
- CSRF configuration constants (`CSRF_CONFIG`, `CSRF_ERROR_MESSAGES`) are now exported for consistency
|
|
86
|
+
- `@mcp-abap-adt/header-validator` ^0.1.3 - Header validation
|
|
87
|
+
- `axios` - HTTP client
|
|
88
|
+
- `zod` - Schema validation
|
|
89
|
+
|
package/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 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.
|
|
22
|
+
|
package/README.md
ADDED
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
# @mcp-abap-adt/proxy
|
|
2
|
+
|
|
3
|
+
MCP proxy server for SAP ABAP ADT - proxies local requests to cloud-llm-hub with JWT authentication.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
This package acts as a simple proxy between local MCP clients (like Cline) and any MCP server. It intercepts MCP requests, adds JWT authentication tokens, and forwards them to the target MCP server. The MCP server URL is obtained from the service key for the BTP destination.
|
|
8
|
+
|
|
9
|
+
## Purpose
|
|
10
|
+
|
|
11
|
+
Enable local MCP clients to connect to remote MCP servers (like `cloud-llm-hub`) with automatic JWT token management via `@mcp-abap-adt/auth-broker`. The proxy adds authentication headers and forwards requests transparently.
|
|
12
|
+
|
|
13
|
+
## Features
|
|
14
|
+
|
|
15
|
+
- ✅ **JWT Token Management** - Automatic token retrieval, caching, and refresh via auth-broker
|
|
16
|
+
- ✅ **Service Key Based** - MCP server URL is obtained from service key for BTP destination
|
|
17
|
+
- ✅ **Error Handling** - Retry logic, circuit breaker, and comprehensive error handling
|
|
18
|
+
- ✅ **Multiple Transport Modes** - HTTP, SSE, and stdio support
|
|
19
|
+
- ✅ **Configuration Flexibility** - Environment variables, config files, or defaults
|
|
20
|
+
|
|
21
|
+
## Quick Start
|
|
22
|
+
|
|
23
|
+
### Installation
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npm install -g @mcp-abap-adt/proxy
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### Basic Usage
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
# Start proxy server (in-memory session storage, secure)
|
|
33
|
+
mcp-abap-adt-proxy
|
|
34
|
+
|
|
35
|
+
# With command line overrides
|
|
36
|
+
mcp-abap-adt-proxy --btp=ai --mcp=trial
|
|
37
|
+
|
|
38
|
+
# Enable file-based session storage (persists tokens to disk)
|
|
39
|
+
mcp-abap-adt-proxy --unsafe
|
|
40
|
+
|
|
41
|
+
# With all options
|
|
42
|
+
mcp-abap-adt-proxy --btp=ai --mcp=trial --unsafe
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Client Configuration (Cline)
|
|
46
|
+
|
|
47
|
+
The proxy uses two service keys (URLs are obtained from service keys):
|
|
48
|
+
|
|
49
|
+
```json
|
|
50
|
+
{
|
|
51
|
+
"mcpServers": {
|
|
52
|
+
"mcp-abap-adt-proxy": {
|
|
53
|
+
"disabled": false,
|
|
54
|
+
"timeout": 60,
|
|
55
|
+
"type": "streamableHttp",
|
|
56
|
+
"url": "http://localhost:3001/mcp/stream/http",
|
|
57
|
+
"headers": {
|
|
58
|
+
"x-btp-destination": "btp-cloud",
|
|
59
|
+
"x-mcp-destination": "sap-abap"
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
**Required Headers (one of the following):**
|
|
67
|
+
- `x-btp-destination` - Destination name for BTP Cloud authorization token and MCP server URL (for BTP authentication mode)
|
|
68
|
+
- `x-mcp-destination` - Destination name for SAP ABAP connection (for local testing mode without BTP)
|
|
69
|
+
- `x-mcp-url` - Direct MCP server URL (for local testing mode without authentication)
|
|
70
|
+
|
|
71
|
+
**Optional Headers:**
|
|
72
|
+
- `x-mcp-destination` - Destination name for SAP ABAP connection (optional, provides SAP token and configuration when used with BTP)
|
|
73
|
+
|
|
74
|
+
**Command Line Overrides:**
|
|
75
|
+
- `--btp=<destination>` - Overrides `x-btp-destination` header (for BTP authentication mode, takes precedence)
|
|
76
|
+
- `--mcp=<destination>` - Overrides `x-mcp-destination` header (for local testing or SAP config, takes precedence)
|
|
77
|
+
- `--mcp-url=<url>` - Direct MCP server URL (for local testing without authentication, takes precedence)
|
|
78
|
+
- `--unsafe` - Enables file-based session storage (persists tokens to disk). By default, sessions are stored in-memory (secure, lost on restart)
|
|
79
|
+
|
|
80
|
+
**How It Works:**
|
|
81
|
+
|
|
82
|
+
**BTP Authentication Mode** (with `x-btp-destination` or `--btp`):
|
|
83
|
+
1. `x-btp-destination` (or `--btp`) → Gets JWT token from auth-broker → Adds `Authorization: Bearer <token>` header
|
|
84
|
+
2. `x-mcp-destination` (or `--mcp`) → Gets JWT token and SAP config from auth-broker → Adds SAP headers (`x-sap-jwt-token`, `x-sap-url`, etc.)
|
|
85
|
+
3. MCP server URL obtained from service key for `x-btp-destination`
|
|
86
|
+
|
|
87
|
+
**Local Testing Mode** (with only `x-mcp-destination`/`--mcp` or `x-mcp-url`/`--mcp-url`):
|
|
88
|
+
1. `x-mcp-url` (or `--mcp-url`) → Direct URL to MCP server (no authentication)
|
|
89
|
+
2. `x-mcp-destination` (or `--mcp`) → Gets MCP server URL from service key for MCP destination (optional token)
|
|
90
|
+
3. No BTP authentication required - enables local integration testing
|
|
91
|
+
|
|
92
|
+
## Documentation
|
|
93
|
+
|
|
94
|
+
- **[Configuration Guide](./doc/CONFIGURATION.md)** - Complete configuration reference
|
|
95
|
+
- **[Usage Examples](./doc/USAGE.md)** - Practical usage examples and patterns
|
|
96
|
+
- **[API Documentation](./doc/API.md)** - API reference and interfaces
|
|
97
|
+
- **[Architecture](./doc/ARCHITECTURE.md)** - System architecture and design
|
|
98
|
+
- **[Troubleshooting](./doc/TROUBLESHOOTING.md)** - Common issues and solutions
|
|
99
|
+
- **[Roadmap](./ROADMAP.md)** - Development roadmap and progress
|
|
100
|
+
|
|
101
|
+
## How It Works
|
|
102
|
+
|
|
103
|
+
The proxy performs the following steps for each request:
|
|
104
|
+
|
|
105
|
+
1. **Extract Headers**: Reads `x-btp-destination`, `x-mcp-destination`, and `x-mcp-url` headers
|
|
106
|
+
2. **Apply Command Line Overrides**: `--btp`, `--mcp`, and `--mcp-url` parameters override headers (if provided)
|
|
107
|
+
3. **Validate Routing Requirements**: Requires at least one of: `x-btp-destination/--btp`, `x-mcp-destination/--mcp`, or `x-mcp-url/--mcp-url`
|
|
108
|
+
4. **Get MCP Server URL** (priority order):
|
|
109
|
+
- From `x-mcp-url` header or `--mcp-url` parameter (direct URL)
|
|
110
|
+
- From service key for `x-btp-destination` (if provided)
|
|
111
|
+
- From service key for `x-mcp-destination` (if only MCP destination is provided)
|
|
112
|
+
5. **Get BTP Cloud Token** (if `x-btp-destination` or `--btp` is provided): Retrieves JWT token for BTP Cloud authorization
|
|
113
|
+
6. **Get SAP ABAP Config** (if `x-mcp-destination` or `--mcp` is provided): Retrieves JWT token and SAP configuration (URL, client, etc.) - optional, won't fail if unavailable
|
|
114
|
+
7. **Build Request**:
|
|
115
|
+
- Adds `Authorization: Bearer <token>` from `x-btp-destination` (or `--btp`) - **only if BTP destination is provided**
|
|
116
|
+
- Adds SAP headers (`x-sap-jwt-token`, `x-sap-url`, etc.) from `x-mcp-destination` (or `--mcp`) - **only if provided**
|
|
117
|
+
8. **Forward Request**: Sends request to MCP server URL (from `x-mcp-url`, service key, or direct URL)
|
|
118
|
+
9. **Return Response**: Forwards the response back to the client
|
|
119
|
+
|
|
120
|
+
### Example Request Flow
|
|
121
|
+
|
|
122
|
+
```
|
|
123
|
+
Cline → Proxy (adds BTP token + SAP config) → Target MCP Server → Proxy → Cline
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
The proxy is transparent - it only adds authentication headers and forwards requests.
|
|
127
|
+
|
|
128
|
+
## Configuration
|
|
129
|
+
|
|
130
|
+
### Environment Variables
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
export CLOUD_LLM_HUB_URL="https://cloud-llm-hub.example.com"
|
|
134
|
+
export MCP_HTTP_PORT=3001
|
|
135
|
+
export LOG_LEVEL=info
|
|
136
|
+
export MCP_PROXY_UNSAFE=true # Enable file-based session storage (optional)
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### Configuration File
|
|
140
|
+
|
|
141
|
+
Create `mcp-proxy-config.json`:
|
|
142
|
+
|
|
143
|
+
```json
|
|
144
|
+
{
|
|
145
|
+
"cloudLlmHubUrl": "https://cloud-llm-hub.example.com",
|
|
146
|
+
"httpPort": 3001,
|
|
147
|
+
"logLevel": "info",
|
|
148
|
+
"maxRetries": 3,
|
|
149
|
+
"circuitBreakerThreshold": 5,
|
|
150
|
+
"unsafe": false
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
**Session Storage:**
|
|
155
|
+
- `unsafe: false` (default) - Session data stored in-memory (secure, lost on restart)
|
|
156
|
+
- `unsafe: true` - Session data persisted to disk (tokens saved to `.env` files)
|
|
157
|
+
|
|
158
|
+
See [Configuration Guide](./doc/CONFIGURATION.md) for complete options.
|
|
159
|
+
|
|
160
|
+
## Error Handling & Resilience
|
|
161
|
+
|
|
162
|
+
- **Retry Logic** - Exponential backoff for failed requests
|
|
163
|
+
- **Circuit Breaker** - Prevents cascading failures
|
|
164
|
+
- **Token Refresh** - Automatic token refresh on expiration
|
|
165
|
+
- **Connection Pooling** - Efficient resource management
|
|
166
|
+
- **Request Timeouts** - Configurable timeout handling
|
|
167
|
+
|
|
168
|
+
## Requirements
|
|
169
|
+
|
|
170
|
+
- Node.js >= 18.0.0
|
|
171
|
+
- npm >= 9.0.0
|
|
172
|
+
|
|
173
|
+
## Testing Tools
|
|
174
|
+
|
|
175
|
+
### Start Both Servers for Testing
|
|
176
|
+
|
|
177
|
+
Use the included script to start both `mcp-abap-adt` and `mcp-abap-adt-proxy` simultaneously:
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
# Using npm script
|
|
181
|
+
npm run test:servers
|
|
182
|
+
|
|
183
|
+
# Direct execution
|
|
184
|
+
node tools/start-servers.js
|
|
185
|
+
|
|
186
|
+
# With MCP destination (local testing)
|
|
187
|
+
node tools/start-servers.js --mcp=trial
|
|
188
|
+
|
|
189
|
+
# With SSE transport
|
|
190
|
+
node tools/start-servers.js --transport=sse
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
The script automatically:
|
|
194
|
+
- Starts ADT server on port 3000 (HTTP) or 3001 (SSE)
|
|
195
|
+
- Starts Proxy server on port 3001 (HTTP) or 3002 (SSE)
|
|
196
|
+
- Generates `mcpUrl` based on ADT server configuration
|
|
197
|
+
- Ensures both servers use the same transport protocol
|
|
198
|
+
|
|
199
|
+
See [tools/README.md](./tools/README.md) for complete documentation.
|
|
200
|
+
|
|
201
|
+
## Development Status
|
|
202
|
+
|
|
203
|
+
✅ **Core Features Complete**
|
|
204
|
+
|
|
205
|
+
- ✅ Project Setup & Foundation
|
|
206
|
+
- ✅ Request Interception & Analysis
|
|
207
|
+
- ✅ JWT Token Management & Proxy Forwarding
|
|
208
|
+
- ✅ Local Testing Mode (without BTP authentication)
|
|
209
|
+
- ✅ Configuration & Environment
|
|
210
|
+
- ✅ Error Handling & Resilience
|
|
211
|
+
- ✅ Testing Tools (`tools/start-servers.js`)
|
|
212
|
+
- ✅ Documentation
|
|
213
|
+
|
|
214
|
+
🚧 **Future Work**
|
|
215
|
+
|
|
216
|
+
- ⏳ Unit Tests
|
|
217
|
+
- ⏳ Performance & Optimization
|
|
218
|
+
- ⏳ Deployment & Publishing
|
|
219
|
+
|
|
220
|
+
See [ROADMAP.md](./ROADMAP.md) for details.
|
|
221
|
+
|
|
222
|
+
## License
|
|
223
|
+
|
|
224
|
+
MIT
|
|
225
|
+
|
|
226
|
+
## Links
|
|
227
|
+
|
|
228
|
+
- **Repository**: https://github.com/fr0ster/mcp-abap-adt-proxy
|
|
229
|
+
- **Issues**: https://github.com/fr0ster/mcp-abap-adt-proxy/issues
|
|
230
|
+
- **Related Packages**:
|
|
231
|
+
- [@mcp-abap-adt/auth-broker](https://github.com/fr0ster/mcp-abap-adt-auth-broker)
|
|
232
|
+
- [@mcp-abap-adt/connection](https://github.com/fr0ster/mcp-abap-adt-connection)
|
|
233
|
+
- [@mcp-abap-adt/header-validator](https://github.com/fr0ster/mcp-abap-adt-header-validator)
|
|
234
|
+
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* MCP ABAP ADT Proxy Server Launcher
|
|
5
|
+
*
|
|
6
|
+
* Simple launcher that spawns the main server process.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* mcp-abap-adt-proxy [options]
|
|
10
|
+
* mcp-abap-adt-proxy --transport=stdio
|
|
11
|
+
* mcp-abap-adt-proxy --transport=http
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
const path = require('path');
|
|
15
|
+
const fs = require('fs');
|
|
16
|
+
const { spawn } = require('child_process');
|
|
17
|
+
|
|
18
|
+
// Parse command line arguments
|
|
19
|
+
function parseArgs() {
|
|
20
|
+
const args = process.argv.slice(2);
|
|
21
|
+
const result = {
|
|
22
|
+
help: false,
|
|
23
|
+
version: false,
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
for (let i = 0; i < args.length; i++) {
|
|
27
|
+
const arg = args[i];
|
|
28
|
+
if (arg === '--help' || arg === '-h') {
|
|
29
|
+
result.help = true;
|
|
30
|
+
} else if (arg === '--version' || arg === '-v') {
|
|
31
|
+
result.version = true;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return result;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Show help
|
|
39
|
+
function showHelp() {
|
|
40
|
+
const pkg = require('../package.json');
|
|
41
|
+
console.log(`
|
|
42
|
+
MCP ABAP ADT Proxy Server v${pkg.version}
|
|
43
|
+
|
|
44
|
+
Usage:
|
|
45
|
+
mcp-abap-adt-proxy [options]
|
|
46
|
+
|
|
47
|
+
Options:
|
|
48
|
+
--transport=<type> Transport type: stdio, http, streamable-http, sse
|
|
49
|
+
--http-port=<port> HTTP server port (default: 3001)
|
|
50
|
+
--sse-port=<port> SSE server port (default: 3002)
|
|
51
|
+
--http-host=<host> HTTP server host (default: 0.0.0.0)
|
|
52
|
+
--sse-host=<host> SSE server host (default: 0.0.0.0)
|
|
53
|
+
--cloud-llm-hub-url Cloud LLM Hub URL (default: from env CLOUD_LLM_HUB_URL)
|
|
54
|
+
--btp=<destination> Override x-btp-destination header (for BTP Cloud authorization)
|
|
55
|
+
Optional: either --btp, --mcp, or --mcp-url is required for stdio/SSE transports
|
|
56
|
+
--mcp=<destination> Override x-mcp-destination header (for SAP ABAP connection)
|
|
57
|
+
Optional: either --btp, --mcp, or --mcp-url is required for stdio/SSE transports
|
|
58
|
+
Can be used without --btp for local testing (no BTP authentication)
|
|
59
|
+
--mcp-url=<url> Direct MCP server URL (for local testing without BTP)
|
|
60
|
+
Optional: either --btp, --mcp, or --mcp-url is required for stdio/SSE transports
|
|
61
|
+
Used for local testing without authentication
|
|
62
|
+
--unsafe Enable file-based session storage (persists tokens to disk)
|
|
63
|
+
--help, -h Show this help message
|
|
64
|
+
--version, -v Show version number
|
|
65
|
+
|
|
66
|
+
Environment Variables:
|
|
67
|
+
CLOUD_LLM_HUB_URL Cloud LLM Hub URL
|
|
68
|
+
MCP_HTTP_PORT HTTP server port (default: 3001)
|
|
69
|
+
MCP_SSE_PORT SSE server port (default: 3002)
|
|
70
|
+
MCP_HTTP_HOST HTTP server host (default: 0.0.0.0)
|
|
71
|
+
MCP_SSE_HOST SSE server host (default: 0.0.0.0)
|
|
72
|
+
MCP_TRANSPORT Transport type (stdio|http|sse)
|
|
73
|
+
MCP_PROXY_UNSAFE Enable file-based session storage (set to "true")
|
|
74
|
+
|
|
75
|
+
Examples:
|
|
76
|
+
mcp-abap-adt-proxy # Use default transport
|
|
77
|
+
mcp-abap-adt-proxy --transport=stdio --btp=ai # Use stdio transport with --btp
|
|
78
|
+
mcp-abap-adt-proxy --transport=stdio --mcp=trial # Use stdio with --mcp only (local testing, no BTP auth)
|
|
79
|
+
mcp-abap-adt-proxy --transport=stdio --mcp-url=http://localhost:3000/mcp # Use stdio with direct MCP URL (local testing)
|
|
80
|
+
mcp-abap-adt-proxy --transport=stdio --btp=ai --mcp=trial # Use stdio with both destinations
|
|
81
|
+
mcp-abap-adt-proxy --transport=http # HTTP mode (port 3001)
|
|
82
|
+
mcp-abap-adt-proxy --transport=http --http-port=8080 # HTTP mode on custom port
|
|
83
|
+
mcp-abap-adt-proxy --transport=sse --btp=ai --mcp=trial # SSE mode with destinations
|
|
84
|
+
mcp-abap-adt-proxy --transport=sse --mcp=trial # SSE mode with --mcp only (local testing)
|
|
85
|
+
mcp-abap-adt-proxy --transport=sse --mcp-url=http://localhost:3000/mcp # SSE mode with direct MCP URL
|
|
86
|
+
mcp-abap-adt-proxy --transport=sse --sse-port=3002 # SSE mode on port 3002
|
|
87
|
+
mcp-abap-adt-proxy --btp=ai --mcp=trial # With destination overrides
|
|
88
|
+
mcp-abap-adt-proxy --mcp=trial # Local testing mode (no BTP authentication)
|
|
89
|
+
mcp-abap-adt-proxy --mcp-url=http://localhost:3000/mcp # Local testing with direct MCP URL (no authentication)
|
|
90
|
+
mcp-abap-adt-proxy --btp=ai --mcp=trial --unsafe # With file-based session storage
|
|
91
|
+
|
|
92
|
+
Transport Modes:
|
|
93
|
+
- stdio (default if stdin is not TTY): For MCP clients like Cline/Cursor
|
|
94
|
+
- http / streamable-http: HTTP server (default if stdin is TTY, port 3001)
|
|
95
|
+
- sse: Server-Sent Events server (port 3002)
|
|
96
|
+
|
|
97
|
+
For more information, see: https://github.com/fr0ster/mcp-abap-adt-proxy
|
|
98
|
+
`);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Show version
|
|
102
|
+
function showVersion() {
|
|
103
|
+
const pkg = require('../package.json');
|
|
104
|
+
console.log(pkg.version);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Main launcher logic
|
|
108
|
+
function main() {
|
|
109
|
+
const args = parseArgs();
|
|
110
|
+
|
|
111
|
+
// Handle --help
|
|
112
|
+
if (args.help) {
|
|
113
|
+
showHelp();
|
|
114
|
+
process.exit(0);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Handle --version
|
|
118
|
+
if (args.version) {
|
|
119
|
+
showVersion();
|
|
120
|
+
process.exit(0);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Spawn the main server process
|
|
124
|
+
const serverPath = path.resolve(__dirname, '../dist/index.js');
|
|
125
|
+
|
|
126
|
+
if (!fs.existsSync(serverPath)) {
|
|
127
|
+
process.stderr.write(`[MCP Proxy] ✗ Server not found at: ${serverPath}\n`);
|
|
128
|
+
process.stderr.write(`[MCP Proxy] Make sure to build the project with 'npm run build' first.\n`);
|
|
129
|
+
if (process.platform === 'win32') {
|
|
130
|
+
setTimeout(() => process.exit(1), 30000);
|
|
131
|
+
} else {
|
|
132
|
+
process.exit(1);
|
|
133
|
+
}
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Pass all arguments to server
|
|
138
|
+
const serverArgs = process.argv.slice(2);
|
|
139
|
+
const nodeExecPath = process.execPath;
|
|
140
|
+
const resolvedServerPath = path.resolve(serverPath);
|
|
141
|
+
|
|
142
|
+
// Verify server file exists
|
|
143
|
+
if (!fs.existsSync(resolvedServerPath)) {
|
|
144
|
+
process.stderr.write(`[MCP Proxy] ✗ Server file not found: ${resolvedServerPath}\n`);
|
|
145
|
+
if (process.platform === 'win32') {
|
|
146
|
+
setTimeout(() => process.exit(1), 30000);
|
|
147
|
+
} else {
|
|
148
|
+
process.exit(1);
|
|
149
|
+
}
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const serverEnv = {
|
|
154
|
+
...process.env,
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
// Debug logging for Windows
|
|
158
|
+
if (process.platform === 'win32') {
|
|
159
|
+
process.stderr.write(`[MCP Proxy] Spawning server: ${nodeExecPath} ${resolvedServerPath}\n`);
|
|
160
|
+
process.stderr.write(`[MCP Proxy] CWD: ${process.cwd()}\n`);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Spawn the server process
|
|
164
|
+
const serverProcess = spawn(nodeExecPath, [resolvedServerPath, ...serverArgs], {
|
|
165
|
+
stdio: ['inherit', 'inherit', 'inherit'],
|
|
166
|
+
env: serverEnv,
|
|
167
|
+
cwd: process.cwd(),
|
|
168
|
+
shell: false,
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
// Handle server process exit
|
|
172
|
+
serverProcess.on('close', (code) => {
|
|
173
|
+
if (code !== 0 && code !== null) {
|
|
174
|
+
process.stderr.write(`[MCP Proxy] Server exited with code: ${code}\n`);
|
|
175
|
+
}
|
|
176
|
+
process.exit(code || 0);
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
// Handle server process errors
|
|
180
|
+
serverProcess.on('error', (error) => {
|
|
181
|
+
process.stderr.write(`[MCP Proxy] ✗ Failed to start server: ${error.message}\n`);
|
|
182
|
+
if (error.stack) {
|
|
183
|
+
process.stderr.write(error.stack + '\n');
|
|
184
|
+
}
|
|
185
|
+
if (process.platform === 'win32') {
|
|
186
|
+
setTimeout(() => process.exit(1), 30000);
|
|
187
|
+
} else {
|
|
188
|
+
process.exit(1);
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
// Forward SIGINT (Ctrl+C) to server process
|
|
193
|
+
process.on('SIGINT', () => {
|
|
194
|
+
serverProcess.kill('SIGINT');
|
|
195
|
+
setTimeout(() => {
|
|
196
|
+
process.exit(0);
|
|
197
|
+
}, 500);
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// Run launcher
|
|
202
|
+
main();
|
|
203
|
+
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* MCP ABAP ADT Proxy Server
|
|
4
|
+
*
|
|
5
|
+
* Proxies local MCP requests to MCP servers with optional JWT authentication.
|
|
6
|
+
* Routes requests based on authentication headers:
|
|
7
|
+
* - x-btp-destination (or --btp): BTP Cloud authorization with JWT token
|
|
8
|
+
* - x-mcp-destination (or --mcp): SAP ABAP connection configuration
|
|
9
|
+
*
|
|
10
|
+
* Supports two modes:
|
|
11
|
+
* 1. BTP authentication mode: Requires x-btp-destination or --btp parameter
|
|
12
|
+
* 2. Local testing mode: Works with only x-mcp-destination or --mcp parameter (no BTP authentication)
|
|
13
|
+
*/
|
|
14
|
+
import { TransportConfig } from "./lib/transportConfig.js";
|
|
15
|
+
/**
|
|
16
|
+
* MCP ABAP ADT Proxy Server
|
|
17
|
+
*/
|
|
18
|
+
export declare class McpAbapAdtProxyServer {
|
|
19
|
+
private server;
|
|
20
|
+
private transportConfig;
|
|
21
|
+
private config;
|
|
22
|
+
private httpServer?;
|
|
23
|
+
private cloudLlmHubProxy?;
|
|
24
|
+
constructor(transportConfig?: TransportConfig, configPath?: string);
|
|
25
|
+
/**
|
|
26
|
+
* Setup MCP handlers
|
|
27
|
+
*/
|
|
28
|
+
private setupHandlers;
|
|
29
|
+
/**
|
|
30
|
+
* Handle stdio request by proxying to MCP server
|
|
31
|
+
* Supports both BTP authentication mode (--btp) and local testing mode (--mcp without --btp)
|
|
32
|
+
*/
|
|
33
|
+
private handleStdioRequest;
|
|
34
|
+
/**
|
|
35
|
+
* Run the proxy server
|
|
36
|
+
*/
|
|
37
|
+
run(): Promise<void>;
|
|
38
|
+
/**
|
|
39
|
+
* Start HTTP server with request interception
|
|
40
|
+
*/
|
|
41
|
+
private startHttpServer;
|
|
42
|
+
/**
|
|
43
|
+
* Handle proxy request - add JWT token and forward to MCP server
|
|
44
|
+
*/
|
|
45
|
+
private handleProxyRequest;
|
|
46
|
+
/**
|
|
47
|
+
* Start SSE server
|
|
48
|
+
*/
|
|
49
|
+
private startSseServer;
|
|
50
|
+
/**
|
|
51
|
+
* Shutdown server
|
|
52
|
+
*/
|
|
53
|
+
shutdown(): Promise<void>;
|
|
54
|
+
}
|
|
55
|
+
export default McpAbapAdtProxyServer;
|
|
56
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;GAWG;AAOH,OAAO,EAAwB,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAOjF;;GAEG;AACH,qBAAa,qBAAqB;IAChC,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,eAAe,CAAkB;IACzC,OAAO,CAAC,MAAM,CAAgC;IAC9C,OAAO,CAAC,UAAU,CAAC,CAAa;IAChC,OAAO,CAAC,gBAAgB,CAAC,CAAmB;gBAEhC,eAAe,CAAC,EAAE,eAAe,EAAE,UAAU,CAAC,EAAE,MAAM;IAqClE;;OAEG;IACH,OAAO,CAAC,aAAa;IAMrB;;;OAGG;YACW,kBAAkB;IA4EhC;;OAEG;IACG,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;IAkD1B;;OAEG;YACW,eAAe;IAsH7B;;OAEG;YACW,kBAAkB;IAsEhC;;OAEG;YACW,cAAc;IA+R5B;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAmBhC;AAGD,eAAe,qBAAqB,CAAC"}
|