arc-1 0.1.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.
- package/LICENSE +21 -0
- package/README.md +222 -0
- package/bin/arc1.js +12 -0
- package/dist/adt/btp.d.ts +122 -0
- package/dist/adt/btp.d.ts.map +1 -0
- package/dist/adt/btp.js +392 -0
- package/dist/adt/btp.js.map +1 -0
- package/dist/adt/client.d.ts +89 -0
- package/dist/adt/client.d.ts.map +1 -0
- package/dist/adt/client.js +208 -0
- package/dist/adt/client.js.map +1 -0
- package/dist/adt/codeintel.d.ts +38 -0
- package/dist/adt/codeintel.d.ts.map +1 -0
- package/dist/adt/codeintel.js +61 -0
- package/dist/adt/codeintel.js.map +1 -0
- package/dist/adt/config.d.ts +65 -0
- package/dist/adt/config.d.ts.map +1 -0
- package/dist/adt/config.js +35 -0
- package/dist/adt/config.js.map +1 -0
- package/dist/adt/cookies.d.ts +27 -0
- package/dist/adt/cookies.d.ts.map +1 -0
- package/dist/adt/cookies.js +67 -0
- package/dist/adt/cookies.js.map +1 -0
- package/dist/adt/crud.d.ts +35 -0
- package/dist/adt/crud.d.ts.map +1 -0
- package/dist/adt/crud.js +87 -0
- package/dist/adt/crud.js.map +1 -0
- package/dist/adt/devtools.d.ts +32 -0
- package/dist/adt/devtools.d.ts.map +1 -0
- package/dist/adt/devtools.js +154 -0
- package/dist/adt/devtools.js.map +1 -0
- package/dist/adt/errors.d.ts +49 -0
- package/dist/adt/errors.d.ts.map +1 -0
- package/dist/adt/errors.js +80 -0
- package/dist/adt/errors.js.map +1 -0
- package/dist/adt/features.d.ts +44 -0
- package/dist/adt/features.d.ts.map +1 -0
- package/dist/adt/features.js +173 -0
- package/dist/adt/features.js.map +1 -0
- package/dist/adt/http.d.ts +116 -0
- package/dist/adt/http.d.ts.map +1 -0
- package/dist/adt/http.js +374 -0
- package/dist/adt/http.js.map +1 -0
- package/dist/adt/safety.d.ts +70 -0
- package/dist/adt/safety.d.ts.map +1 -0
- package/dist/adt/safety.js +222 -0
- package/dist/adt/safety.js.map +1 -0
- package/dist/adt/transport.d.ts +18 -0
- package/dist/adt/transport.d.ts.map +1 -0
- package/dist/adt/transport.js +66 -0
- package/dist/adt/transport.js.map +1 -0
- package/dist/adt/types.d.ts +91 -0
- package/dist/adt/types.d.ts.map +1 -0
- package/dist/adt/types.js +9 -0
- package/dist/adt/types.js.map +1 -0
- package/dist/adt/xml-parser.d.ts +109 -0
- package/dist/adt/xml-parser.d.ts.map +1 -0
- package/dist/adt/xml-parser.js +283 -0
- package/dist/adt/xml-parser.js.map +1 -0
- package/dist/cache/cache.d.ts +61 -0
- package/dist/cache/cache.d.ts.map +1 -0
- package/dist/cache/cache.js +14 -0
- package/dist/cache/cache.js.map +1 -0
- package/dist/cache/memory.d.ts +25 -0
- package/dist/cache/memory.d.ts.map +1 -0
- package/dist/cache/memory.js +69 -0
- package/dist/cache/memory.js.map +1 -0
- package/dist/cache/sqlite.d.ts +26 -0
- package/dist/cache/sqlite.d.ts.map +1 -0
- package/dist/cache/sqlite.js +130 -0
- package/dist/cache/sqlite.js.map +1 -0
- package/dist/cli.d.ts +14 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +101 -0
- package/dist/cli.js.map +1 -0
- package/dist/context/compressor.d.ts +33 -0
- package/dist/context/compressor.d.ts.map +1 -0
- package/dist/context/compressor.js +208 -0
- package/dist/context/compressor.js.map +1 -0
- package/dist/context/contract.d.ts +14 -0
- package/dist/context/contract.d.ts.map +1 -0
- package/dist/context/contract.js +202 -0
- package/dist/context/contract.js.map +1 -0
- package/dist/context/deps.d.ts +32 -0
- package/dist/context/deps.d.ts.map +1 -0
- package/dist/context/deps.js +240 -0
- package/dist/context/deps.js.map +1 -0
- package/dist/context/types.d.ts +56 -0
- package/dist/context/types.d.ts.map +1 -0
- package/dist/context/types.js +10 -0
- package/dist/context/types.js.map +1 -0
- package/dist/handlers/intent.d.ts +46 -0
- package/dist/handlers/intent.d.ts.map +1 -0
- package/dist/handlers/intent.js +539 -0
- package/dist/handlers/intent.js.map +1 -0
- package/dist/handlers/tools.d.ts +21 -0
- package/dist/handlers/tools.d.ts.map +1 -0
- package/dist/handlers/tools.js +260 -0
- package/dist/handlers/tools.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/lint/lint.d.ts +35 -0
- package/dist/lint/lint.d.ts.map +1 -0
- package/dist/lint/lint.js +67 -0
- package/dist/lint/lint.js.map +1 -0
- package/dist/server/audit.d.ts +96 -0
- package/dist/server/audit.d.ts.map +1 -0
- package/dist/server/audit.js +27 -0
- package/dist/server/audit.js.map +1 -0
- package/dist/server/config.d.ts +19 -0
- package/dist/server/config.d.ts.map +1 -0
- package/dist/server/config.js +101 -0
- package/dist/server/config.js.map +1 -0
- package/dist/server/context.d.ts +20 -0
- package/dist/server/context.d.ts.map +1 -0
- package/dist/server/context.js +20 -0
- package/dist/server/context.js.map +1 -0
- package/dist/server/elicit.d.ts +43 -0
- package/dist/server/elicit.d.ts.map +1 -0
- package/dist/server/elicit.js +183 -0
- package/dist/server/elicit.js.map +1 -0
- package/dist/server/http.d.ts +34 -0
- package/dist/server/http.d.ts.map +1 -0
- package/dist/server/http.js +328 -0
- package/dist/server/http.js.map +1 -0
- package/dist/server/logger.d.ts +57 -0
- package/dist/server/logger.d.ts.map +1 -0
- package/dist/server/logger.js +129 -0
- package/dist/server/logger.js.map +1 -0
- package/dist/server/server.d.ts +25 -0
- package/dist/server/server.d.ts.map +1 -0
- package/dist/server/server.js +307 -0
- package/dist/server/server.js.map +1 -0
- package/dist/server/sinks/btp-auditlog.d.ts +48 -0
- package/dist/server/sinks/btp-auditlog.d.ts.map +1 -0
- package/dist/server/sinks/btp-auditlog.js +232 -0
- package/dist/server/sinks/btp-auditlog.js.map +1 -0
- package/dist/server/sinks/file.d.ts +22 -0
- package/dist/server/sinks/file.d.ts.map +1 -0
- package/dist/server/sinks/file.js +59 -0
- package/dist/server/sinks/file.js.map +1 -0
- package/dist/server/sinks/stderr.d.ts +19 -0
- package/dist/server/sinks/stderr.d.ts.map +1 -0
- package/dist/server/sinks/stderr.js +63 -0
- package/dist/server/sinks/stderr.js.map +1 -0
- package/dist/server/sinks/types.d.ts +14 -0
- package/dist/server/sinks/types.d.ts.map +1 -0
- package/dist/server/sinks/types.js +8 -0
- package/dist/server/sinks/types.js.map +1 -0
- package/dist/server/types.d.ts +54 -0
- package/dist/server/types.d.ts.map +1 -0
- package/dist/server/types.js +42 -0
- package/dist/server/types.js.map +1 -0
- package/dist/server/xsuaa.d.ts +77 -0
- package/dist/server/xsuaa.d.ts.map +1 -0
- package/dist/server/xsuaa.js +364 -0
- package/dist/server/xsuaa.js.map +1 -0
- package/package.json +66 -0
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* XSUAA OAuth proxy for MCP-native clients.
|
|
3
|
+
*
|
|
4
|
+
* Enables Claude Desktop, Cursor, VS Code, and MCP Inspector to authenticate
|
|
5
|
+
* via BTP XSUAA using the MCP specification's OAuth discovery (RFC 8414).
|
|
6
|
+
*
|
|
7
|
+
* Uses the MCP SDK's ProxyOAuthServerProvider to delegate the OAuth flow
|
|
8
|
+
* to XSUAA, and @sap/xssec for SAP-specific JWT validation.
|
|
9
|
+
*
|
|
10
|
+
* Design decisions:
|
|
11
|
+
*
|
|
12
|
+
* 1. @sap/xssec for token validation (not jose):
|
|
13
|
+
* - SAP-specific x5t thumbprint and proof-of-possession validation
|
|
14
|
+
* - Proper XSUAA audience format handling
|
|
15
|
+
* - Offline validation with automatic JWKS caching
|
|
16
|
+
* - checkLocalScope() for scope enforcement
|
|
17
|
+
*
|
|
18
|
+
* 2. In-memory client store for dynamic registration:
|
|
19
|
+
* - MCP clients (Claude Desktop, Cursor) register dynamically via RFC 7591
|
|
20
|
+
* - Registrations are lost on restart — clients re-register on reconnect
|
|
21
|
+
* - XSUAA clientId is pre-registered as the default client
|
|
22
|
+
*
|
|
23
|
+
* 3. Chained token verifier:
|
|
24
|
+
* - Tries XSUAA → Entra ID OIDC → API key in order
|
|
25
|
+
* - All three auth modes coexist on the same /mcp endpoint
|
|
26
|
+
*/
|
|
27
|
+
import { ProxyOAuthServerProvider } from '@modelcontextprotocol/sdk/server/auth/providers/proxyProvider.js';
|
|
28
|
+
import { XsuaaService } from '@sap/xssec';
|
|
29
|
+
import { logger } from './logger.js';
|
|
30
|
+
// ─── In-Memory Client Store ──────────────────────────────────────────
|
|
31
|
+
/**
|
|
32
|
+
* In-memory store for OAuth client registrations.
|
|
33
|
+
*
|
|
34
|
+
* MCP clients dynamically register via RFC 7591. The XSUAA service binding
|
|
35
|
+
* clientId is pre-registered as the default client so that clients can
|
|
36
|
+
* use it directly without registration.
|
|
37
|
+
*/
|
|
38
|
+
export class InMemoryClientStore {
|
|
39
|
+
clients = new Map();
|
|
40
|
+
constructor(xsuaaClientId, xsuaaClientSecret) {
|
|
41
|
+
// Pre-register the XSUAA client so MCP clients that use it directly work.
|
|
42
|
+
// The redirect_uris MUST include all URIs that MCP clients will use,
|
|
43
|
+
// because the MCP SDK validates redirect_uri against this list BEFORE
|
|
44
|
+
// calling our authorize override. These must also be registered in xs-security.json.
|
|
45
|
+
this.clients.set(xsuaaClientId, {
|
|
46
|
+
client_id: xsuaaClientId,
|
|
47
|
+
client_secret: xsuaaClientSecret,
|
|
48
|
+
redirect_uris: [
|
|
49
|
+
'http://localhost:6274/oauth/callback', // MCP Inspector
|
|
50
|
+
'http://localhost:3000/oauth/callback', // Local dev servers
|
|
51
|
+
'https://claude.ai/api/mcp/auth_callback', // Claude Desktop
|
|
52
|
+
'cursor://anysphere.cursor-retrieval/oauth/callback', // Cursor
|
|
53
|
+
'vscode://vscode.microsoft-authentication/callback', // VS Code
|
|
54
|
+
],
|
|
55
|
+
grant_types: ['authorization_code', 'refresh_token'],
|
|
56
|
+
response_types: ['code'],
|
|
57
|
+
token_endpoint_auth_method: 'client_secret_post',
|
|
58
|
+
client_name: 'ARC-1 XSUAA Default Client',
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
async getClient(clientId) {
|
|
62
|
+
const client = this.clients.get(clientId);
|
|
63
|
+
logger.debug('OAuth client lookup', {
|
|
64
|
+
clientId,
|
|
65
|
+
found: !!client,
|
|
66
|
+
clientName: client?.client_name,
|
|
67
|
+
registeredClients: [...this.clients.keys()],
|
|
68
|
+
});
|
|
69
|
+
return client;
|
|
70
|
+
}
|
|
71
|
+
async registerClient(client) {
|
|
72
|
+
const clientId = `arc1-${crypto.randomUUID().slice(0, 8)}`;
|
|
73
|
+
const clientSecret = crypto.randomUUID();
|
|
74
|
+
const fullClient = {
|
|
75
|
+
...client,
|
|
76
|
+
client_id: clientId,
|
|
77
|
+
client_secret: clientSecret,
|
|
78
|
+
client_id_issued_at: Math.floor(Date.now() / 1000),
|
|
79
|
+
};
|
|
80
|
+
this.clients.set(clientId, fullClient);
|
|
81
|
+
logger.debug('OAuth client registered', { clientId, clientName: client.client_name });
|
|
82
|
+
return fullClient;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
// ─── XSUAA Token Verifier ────────────────────────────────────────────
|
|
86
|
+
/**
|
|
87
|
+
* Verify a JWT token using @sap/xssec.
|
|
88
|
+
*
|
|
89
|
+
* Creates a security context from the token using the XSUAA service,
|
|
90
|
+
* then maps it to the MCP SDK's AuthInfo format.
|
|
91
|
+
*/
|
|
92
|
+
export function createXsuaaTokenVerifier(credentials) {
|
|
93
|
+
const xsuaaService = new XsuaaService({
|
|
94
|
+
clientid: credentials.clientid,
|
|
95
|
+
clientsecret: credentials.clientsecret,
|
|
96
|
+
url: credentials.url,
|
|
97
|
+
xsappname: credentials.xsappname,
|
|
98
|
+
uaadomain: credentials.uaadomain,
|
|
99
|
+
});
|
|
100
|
+
return async (token) => {
|
|
101
|
+
logger.debug('XSUAA token verification: creating security context');
|
|
102
|
+
const securityContext = await xsuaaService.createSecurityContext(token, { jwt: token });
|
|
103
|
+
// Extract scopes (remove xsappname prefix for local scope names)
|
|
104
|
+
const grantedScopes = [];
|
|
105
|
+
// The token contains scopes like "arc1-mcp!b12345.read"
|
|
106
|
+
// checkLocalScope strips the prefix for us
|
|
107
|
+
for (const scope of ['read', 'write', 'admin']) {
|
|
108
|
+
if (securityContext.checkLocalScope(scope)) {
|
|
109
|
+
grantedScopes.push(scope);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
const expiresAt = securityContext.token?.payload?.exp;
|
|
113
|
+
const authInfo = {
|
|
114
|
+
token,
|
|
115
|
+
clientId: securityContext.getClientId(),
|
|
116
|
+
scopes: grantedScopes,
|
|
117
|
+
expiresAt: typeof expiresAt === 'number' ? expiresAt : undefined,
|
|
118
|
+
extra: {
|
|
119
|
+
userName: securityContext.getLogonName?.() ?? undefined,
|
|
120
|
+
email: securityContext.getEmail?.() ?? undefined,
|
|
121
|
+
},
|
|
122
|
+
};
|
|
123
|
+
logger.debug('XSUAA token verified', {
|
|
124
|
+
clientId: authInfo.clientId,
|
|
125
|
+
scopes: grantedScopes,
|
|
126
|
+
userName: authInfo.extra.userName,
|
|
127
|
+
email: authInfo.extra.email,
|
|
128
|
+
});
|
|
129
|
+
return authInfo;
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
// ─── Chained Token Verifier ──────────────────────────────────────────
|
|
133
|
+
/**
|
|
134
|
+
* Create a token verifier that chains multiple auth methods.
|
|
135
|
+
*
|
|
136
|
+
* Tries in order:
|
|
137
|
+
* 1. XSUAA (@sap/xssec) — if XSUAA credentials are available
|
|
138
|
+
* 2. Entra ID OIDC (jose) — if SAP_OIDC_ISSUER is configured
|
|
139
|
+
* 3. API Key — if ARC1_API_KEY is configured
|
|
140
|
+
*/
|
|
141
|
+
export function createChainedTokenVerifier(config, xsuaaVerifier, oidcVerifier) {
|
|
142
|
+
return async (token) => {
|
|
143
|
+
const tokenPreview = `${token.slice(0, 20)}...${token.slice(-10)}`;
|
|
144
|
+
logger.debug('Chained token verifier: starting', { tokenPreview });
|
|
145
|
+
// 1. Try XSUAA
|
|
146
|
+
if (xsuaaVerifier) {
|
|
147
|
+
try {
|
|
148
|
+
const result = await xsuaaVerifier(token);
|
|
149
|
+
logger.debug('Chained token verifier: XSUAA succeeded', {
|
|
150
|
+
clientId: result.clientId,
|
|
151
|
+
scopes: result.scopes,
|
|
152
|
+
user: result.extra?.email || result.extra?.userName,
|
|
153
|
+
});
|
|
154
|
+
return result;
|
|
155
|
+
}
|
|
156
|
+
catch (err) {
|
|
157
|
+
logger.debug('Chained token verifier: XSUAA failed, trying next', {
|
|
158
|
+
error: err instanceof Error ? err.message : String(err),
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
// 2. Try Entra ID OIDC
|
|
163
|
+
if (oidcVerifier) {
|
|
164
|
+
try {
|
|
165
|
+
const result = await oidcVerifier(token);
|
|
166
|
+
logger.debug('Chained token verifier: OIDC succeeded', {
|
|
167
|
+
clientId: result.clientId,
|
|
168
|
+
scopes: result.scopes,
|
|
169
|
+
});
|
|
170
|
+
return result;
|
|
171
|
+
}
|
|
172
|
+
catch (err) {
|
|
173
|
+
logger.debug('Chained token verifier: OIDC failed, trying next', {
|
|
174
|
+
error: err instanceof Error ? err.message : String(err),
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
// 3. Try API key
|
|
179
|
+
if (config.apiKey && token === config.apiKey) {
|
|
180
|
+
logger.debug('Chained token verifier: API key matched');
|
|
181
|
+
return {
|
|
182
|
+
token,
|
|
183
|
+
clientId: 'api-key',
|
|
184
|
+
scopes: ['read', 'write', 'admin'],
|
|
185
|
+
// MCP SDK's requireBearerAuth requires expiresAt — set to 1 year
|
|
186
|
+
expiresAt: Math.floor(Date.now() / 1000) + 365 * 24 * 60 * 60,
|
|
187
|
+
extra: {},
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
logger.debug('Chained token verifier: all methods failed', { tokenPreview });
|
|
191
|
+
throw new Error('Token validation failed: not a valid XSUAA, OIDC, or API key token');
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
// ─── OAuth Provider Factory ──────────────────────────────────────────
|
|
195
|
+
/**
|
|
196
|
+
* Create a ProxyOAuthServerProvider that proxies OAuth to XSUAA.
|
|
197
|
+
*/
|
|
198
|
+
/**
|
|
199
|
+
* XSUAA-proxying OAuth provider.
|
|
200
|
+
*
|
|
201
|
+
* Extends ProxyOAuthServerProvider to replace the MCP client's local client_id
|
|
202
|
+
* with the XSUAA service binding client_id when forwarding to XSUAA.
|
|
203
|
+
*
|
|
204
|
+
* Problem: MCP clients register via DCR and get a local client_id (e.g., "arc1-f63afbab").
|
|
205
|
+
* But XSUAA only knows about its own client_id ("sb-arc1-mcp!t498139").
|
|
206
|
+
* The standard ProxyOAuthServerProvider forwards the local client_id to XSUAA, which rejects it.
|
|
207
|
+
*
|
|
208
|
+
* Solution: Override authorize() to swap the client_id and use a custom fetch() for
|
|
209
|
+
* the token exchange to inject the XSUAA credentials.
|
|
210
|
+
*/
|
|
211
|
+
class XsuaaProxyOAuthProvider extends ProxyOAuthServerProvider {
|
|
212
|
+
xsuaaClientId;
|
|
213
|
+
xsuaaClientSecret;
|
|
214
|
+
xsuaaTokenUrl;
|
|
215
|
+
xsuaaAuthUrl;
|
|
216
|
+
xsuaaXsappname;
|
|
217
|
+
_localClientStore;
|
|
218
|
+
constructor(credentials, verifier, localClientStore) {
|
|
219
|
+
const authUrl = `${credentials.url}/oauth/authorize`;
|
|
220
|
+
const tokenUrl = `${credentials.url}/oauth/token`;
|
|
221
|
+
super({
|
|
222
|
+
endpoints: {
|
|
223
|
+
authorizationUrl: authUrl,
|
|
224
|
+
tokenUrl: tokenUrl,
|
|
225
|
+
revocationUrl: `${credentials.url}/oauth/revoke`,
|
|
226
|
+
},
|
|
227
|
+
verifyAccessToken: verifier,
|
|
228
|
+
getClient: (clientId) => localClientStore.getClient(clientId),
|
|
229
|
+
});
|
|
230
|
+
this.xsuaaClientId = credentials.clientid;
|
|
231
|
+
this.xsuaaClientSecret = credentials.clientsecret;
|
|
232
|
+
this.xsuaaTokenUrl = tokenUrl;
|
|
233
|
+
this.xsuaaAuthUrl = authUrl;
|
|
234
|
+
this.xsuaaXsappname = credentials.xsappname;
|
|
235
|
+
this._localClientStore = localClientStore;
|
|
236
|
+
this.skipLocalPkceValidation = true;
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Override clientsStore to expose registerClient for DCR.
|
|
240
|
+
* The MCP SDK checks this to decide whether to advertise
|
|
241
|
+
* registration_endpoint in OAuth metadata and handle POST /register.
|
|
242
|
+
*/
|
|
243
|
+
get clientsStore() {
|
|
244
|
+
return this._localClientStore;
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Override authorize to replace the MCP client's local client_id
|
|
248
|
+
* with the XSUAA service binding client_id.
|
|
249
|
+
*/
|
|
250
|
+
async authorize(_client, params, res) {
|
|
251
|
+
const targetUrl = new URL(this.xsuaaAuthUrl);
|
|
252
|
+
const searchParams = new URLSearchParams({
|
|
253
|
+
client_id: this.xsuaaClientId, // Use XSUAA client, not local DCR client
|
|
254
|
+
response_type: 'code',
|
|
255
|
+
redirect_uri: params.redirectUri,
|
|
256
|
+
code_challenge: params.codeChallenge,
|
|
257
|
+
code_challenge_method: 'S256',
|
|
258
|
+
});
|
|
259
|
+
if (params.state)
|
|
260
|
+
searchParams.set('state', params.state);
|
|
261
|
+
if (params.scopes?.length) {
|
|
262
|
+
// Qualify short scope names (read, write, admin) with XSUAA xsappname prefix.
|
|
263
|
+
// XSUAA rejects unqualified scopes like "admin" — it needs "arc1-mcp!t498139.admin".
|
|
264
|
+
// Filter out empty strings (Copilot Studio sends scope="" which splits to [""]).
|
|
265
|
+
const qualifiedScopes = params.scopes
|
|
266
|
+
.filter((s) => s.length > 0)
|
|
267
|
+
.map((s) => (s.includes('.') ? s : `${this.xsuaaXsappname}.${s}`));
|
|
268
|
+
if (qualifiedScopes.length > 0) {
|
|
269
|
+
searchParams.set('scope', qualifiedScopes.join(' '));
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
if (params.resource)
|
|
273
|
+
searchParams.set('resource', params.resource.toString());
|
|
274
|
+
targetUrl.search = searchParams.toString();
|
|
275
|
+
logger.debug('XSUAA authorize redirect', {
|
|
276
|
+
xsuaaClient: this.xsuaaClientId,
|
|
277
|
+
redirectUri: params.redirectUri,
|
|
278
|
+
});
|
|
279
|
+
res.redirect(targetUrl.toString());
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Override exchangeAuthorizationCode to use XSUAA credentials
|
|
283
|
+
* instead of the local DCR client credentials.
|
|
284
|
+
*/
|
|
285
|
+
async exchangeAuthorizationCode(_client, authorizationCode, codeVerifier, redirectUri) {
|
|
286
|
+
logger.debug('XSUAA token exchange: authorization_code', {
|
|
287
|
+
hasCodeVerifier: !!codeVerifier,
|
|
288
|
+
redirectUri,
|
|
289
|
+
});
|
|
290
|
+
const params = new URLSearchParams({
|
|
291
|
+
grant_type: 'authorization_code',
|
|
292
|
+
code: authorizationCode,
|
|
293
|
+
client_id: this.xsuaaClientId,
|
|
294
|
+
client_secret: this.xsuaaClientSecret,
|
|
295
|
+
});
|
|
296
|
+
if (codeVerifier)
|
|
297
|
+
params.set('code_verifier', codeVerifier);
|
|
298
|
+
if (redirectUri)
|
|
299
|
+
params.set('redirect_uri', redirectUri);
|
|
300
|
+
const response = await fetch(this.xsuaaTokenUrl, {
|
|
301
|
+
method: 'POST',
|
|
302
|
+
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
303
|
+
body: params.toString(),
|
|
304
|
+
});
|
|
305
|
+
if (!response.ok) {
|
|
306
|
+
const text = await response.text();
|
|
307
|
+
logger.error('XSUAA token exchange failed', { status: response.status, body: text.slice(0, 200) });
|
|
308
|
+
throw new Error(`XSUAA token exchange failed: ${response.status}`);
|
|
309
|
+
}
|
|
310
|
+
const data = (await response.json());
|
|
311
|
+
logger.debug('XSUAA token exchange: success', {
|
|
312
|
+
tokenType: data.token_type,
|
|
313
|
+
expiresIn: data.expires_in,
|
|
314
|
+
hasRefreshToken: !!data.refresh_token,
|
|
315
|
+
scope: data.scope,
|
|
316
|
+
});
|
|
317
|
+
return {
|
|
318
|
+
access_token: data.access_token,
|
|
319
|
+
token_type: data.token_type ?? 'bearer',
|
|
320
|
+
expires_in: data.expires_in,
|
|
321
|
+
refresh_token: data.refresh_token,
|
|
322
|
+
scope: data.scope,
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Override exchangeRefreshToken to use XSUAA credentials.
|
|
327
|
+
*/
|
|
328
|
+
async exchangeRefreshToken(_client, refreshToken, _scopes) {
|
|
329
|
+
const params = new URLSearchParams({
|
|
330
|
+
grant_type: 'refresh_token',
|
|
331
|
+
refresh_token: refreshToken,
|
|
332
|
+
client_id: this.xsuaaClientId,
|
|
333
|
+
client_secret: this.xsuaaClientSecret,
|
|
334
|
+
});
|
|
335
|
+
const response = await fetch(this.xsuaaTokenUrl, {
|
|
336
|
+
method: 'POST',
|
|
337
|
+
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
338
|
+
body: params.toString(),
|
|
339
|
+
});
|
|
340
|
+
if (!response.ok) {
|
|
341
|
+
throw new Error(`XSUAA refresh token exchange failed: ${response.status}`);
|
|
342
|
+
}
|
|
343
|
+
const data = (await response.json());
|
|
344
|
+
return {
|
|
345
|
+
access_token: data.access_token,
|
|
346
|
+
token_type: data.token_type ?? 'bearer',
|
|
347
|
+
expires_in: data.expires_in,
|
|
348
|
+
refresh_token: data.refresh_token,
|
|
349
|
+
scope: data.scope,
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
export function createXsuaaOAuthProvider(credentials, appUrl) {
|
|
354
|
+
const clientStore = new InMemoryClientStore(credentials.clientid, credentials.clientsecret);
|
|
355
|
+
const verifier = createXsuaaTokenVerifier(credentials);
|
|
356
|
+
const provider = new XsuaaProxyOAuthProvider(credentials, verifier, clientStore);
|
|
357
|
+
logger.info('XSUAA OAuth provider created', {
|
|
358
|
+
xsappname: credentials.xsappname,
|
|
359
|
+
authorizationUrl: `${credentials.url}/oauth/authorize`,
|
|
360
|
+
appUrl,
|
|
361
|
+
});
|
|
362
|
+
return { provider, clientStore };
|
|
363
|
+
}
|
|
364
|
+
//# sourceMappingURL=xsuaa.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"xsuaa.js","sourceRoot":"","sources":["../../ts-src/server/xsuaa.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "arc-1",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "ARC-1 — MCP Server for SAP ABAP Systems",
|
|
5
|
+
"author": "Marian Zeis",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"engines": {
|
|
9
|
+
"node": ">=20.0.0"
|
|
10
|
+
},
|
|
11
|
+
"bin": {
|
|
12
|
+
"arc1": "./bin/arc1.js"
|
|
13
|
+
},
|
|
14
|
+
"main": "./dist/index.js",
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"files": [
|
|
17
|
+
"dist",
|
|
18
|
+
"bin",
|
|
19
|
+
"README.md",
|
|
20
|
+
"LICENSE"
|
|
21
|
+
],
|
|
22
|
+
"publishConfig": {
|
|
23
|
+
"access": "public"
|
|
24
|
+
},
|
|
25
|
+
"scripts": {
|
|
26
|
+
"build": "tsc",
|
|
27
|
+
"dev": "tsx ts-src/index.ts",
|
|
28
|
+
"dev:http": "tsx ts-src/index.ts --transport http-streamable",
|
|
29
|
+
"start": "node dist/index.js",
|
|
30
|
+
"test": "vitest run",
|
|
31
|
+
"test:watch": "vitest",
|
|
32
|
+
"test:integration": "vitest run --config vitest.integration.config.ts",
|
|
33
|
+
"test:coverage": "vitest run --coverage",
|
|
34
|
+
"lint": "biome check .",
|
|
35
|
+
"lint:fix": "biome check --write .",
|
|
36
|
+
"format": "biome format --write .",
|
|
37
|
+
"typecheck": "tsc --noEmit",
|
|
38
|
+
"cli": "tsx ts-src/cli.ts",
|
|
39
|
+
"prepublishOnly": "npm run build"
|
|
40
|
+
},
|
|
41
|
+
"dependencies": {
|
|
42
|
+
"@abaplint/core": "^2.115.27",
|
|
43
|
+
"@modelcontextprotocol/sdk": "^1.28.0",
|
|
44
|
+
"@sap/xsenv": "^6.1.0",
|
|
45
|
+
"@sap/xssec": "^4.13.0",
|
|
46
|
+
"axios": "^1.13.6",
|
|
47
|
+
"better-sqlite3": "^12.8.0",
|
|
48
|
+
"commander": "^14.0.3",
|
|
49
|
+
"dotenv": "^17.3.1",
|
|
50
|
+
"express": "^5.2.1",
|
|
51
|
+
"fast-xml-parser": "^5.5.9",
|
|
52
|
+
"jose": "^6.2.2",
|
|
53
|
+
"zod": "^3.24.0"
|
|
54
|
+
},
|
|
55
|
+
"devDependencies": {
|
|
56
|
+
"@biomejs/biome": "^2.4.8",
|
|
57
|
+
"@types/better-sqlite3": "^7.6.13",
|
|
58
|
+
"@types/express": "^5.0.6",
|
|
59
|
+
"@types/node": "^22.0.0",
|
|
60
|
+
"@types/supertest": "^7.2.0",
|
|
61
|
+
"supertest": "^7.2.2",
|
|
62
|
+
"tsx": "^4.21.0",
|
|
63
|
+
"typescript": "~5.8.0",
|
|
64
|
+
"vitest": "^4.1.1"
|
|
65
|
+
}
|
|
66
|
+
}
|