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,307 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Server for ARC-1.
|
|
3
|
+
*
|
|
4
|
+
* Creates and starts the MCP server with 11 intent-based tools.
|
|
5
|
+
* Supports two transports:
|
|
6
|
+
* - stdio (default): for local MCP clients (Claude Desktop, Claude Code, Cursor)
|
|
7
|
+
* - http-streamable: for remote/containerized deployments
|
|
8
|
+
*/
|
|
9
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
10
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
11
|
+
import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
|
|
12
|
+
import { AdtClient } from '../adt/client.js';
|
|
13
|
+
import { handleToolCall, TOOL_SCOPES } from '../handlers/intent.js';
|
|
14
|
+
import { getToolDefinitions } from '../handlers/tools.js';
|
|
15
|
+
import { initLogger, logger } from './logger.js';
|
|
16
|
+
import { FileSink } from './sinks/file.js';
|
|
17
|
+
/** ARC-1 version */
|
|
18
|
+
export const VERSION = '0.1.0';
|
|
19
|
+
/** Build the base ADT client config (without per-user auth) */
|
|
20
|
+
function buildAdtConfig(config, btpProxy) {
|
|
21
|
+
return {
|
|
22
|
+
baseUrl: config.url,
|
|
23
|
+
username: config.username,
|
|
24
|
+
password: config.password,
|
|
25
|
+
client: config.client,
|
|
26
|
+
language: config.language,
|
|
27
|
+
insecure: config.insecure,
|
|
28
|
+
btpProxy,
|
|
29
|
+
safety: {
|
|
30
|
+
readOnly: config.readOnly,
|
|
31
|
+
blockFreeSQL: config.blockFreeSQL,
|
|
32
|
+
allowedOps: config.allowedOps,
|
|
33
|
+
disallowedOps: config.disallowedOps,
|
|
34
|
+
allowedPackages: config.allowedPackages,
|
|
35
|
+
dryRun: false,
|
|
36
|
+
enableTransports: config.enableTransports,
|
|
37
|
+
transportReadOnly: false,
|
|
38
|
+
allowedTransports: [],
|
|
39
|
+
allowTransportableEdits: config.allowTransportableEdits,
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Create a per-user ADT client for principal propagation.
|
|
45
|
+
*
|
|
46
|
+
* Called per MCP request when ppEnabled=true and user JWT is available.
|
|
47
|
+
* Looks up the BTP Destination with X-User-Token header to get per-user
|
|
48
|
+
* auth tokens, then creates an ADT client that sends the
|
|
49
|
+
* SAP-Connectivity-Authentication header with every request.
|
|
50
|
+
*
|
|
51
|
+
* The Cloud Connector uses this header to generate an X.509 cert
|
|
52
|
+
* mapped to the SAP user via CERTRULE.
|
|
53
|
+
*/
|
|
54
|
+
async function createPerUserClient(config, btpConfig, btpProxy, userJwt) {
|
|
55
|
+
const { lookupDestinationWithUserToken } = await import('../adt/btp.js');
|
|
56
|
+
// Use SAP_BTP_PP_DESTINATION if set, otherwise fall back to SAP_BTP_DESTINATION.
|
|
57
|
+
// This enables a dual-destination approach:
|
|
58
|
+
// - SAP_BTP_DESTINATION = BasicAuth destination (shared client, startup resolution)
|
|
59
|
+
// - SAP_BTP_PP_DESTINATION = PrincipalPropagation destination (per-user, runtime)
|
|
60
|
+
const destName = process.env.SAP_BTP_PP_DESTINATION ?? process.env.SAP_BTP_DESTINATION;
|
|
61
|
+
if (!destName) {
|
|
62
|
+
throw new Error('SAP_BTP_PP_DESTINATION or SAP_BTP_DESTINATION is required for principal propagation');
|
|
63
|
+
}
|
|
64
|
+
const { destination, authTokens } = await lookupDestinationWithUserToken(btpConfig, destName, userJwt);
|
|
65
|
+
const adtConfig = buildAdtConfig(config, btpProxy);
|
|
66
|
+
// Override URL from destination (in case it differs from startup-resolved URL)
|
|
67
|
+
adtConfig.baseUrl = destination.URL;
|
|
68
|
+
// Set per-user auth for principal propagation.
|
|
69
|
+
// Option 1 (Recommended): jwt-bearer exchanged token → Proxy-Authorization
|
|
70
|
+
// Option 2 (Backward compat): SAML assertion → SAP-Connectivity-Authentication
|
|
71
|
+
// Preserve the username for display only (e.g. SAPRead SYSTEM) by extracting it from the JWT.
|
|
72
|
+
// Safety: the JWT signature was already verified by the OIDC middleware in http.ts —
|
|
73
|
+
// we're just reading a claim from an already-trusted token. This value is never used
|
|
74
|
+
// for auth or access control; the actual SAP identity comes from the SAML assertion.
|
|
75
|
+
let displayUsername;
|
|
76
|
+
try {
|
|
77
|
+
const payload = JSON.parse(Buffer.from(userJwt.split('.')[1], 'base64url').toString());
|
|
78
|
+
displayUsername = payload.user_name ?? payload.email ?? undefined;
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
displayUsername = undefined;
|
|
82
|
+
}
|
|
83
|
+
if (authTokens.ppProxyAuth) {
|
|
84
|
+
// Option 1: exchanged token replaces Proxy-Authorization
|
|
85
|
+
adtConfig.ppProxyAuth = authTokens.ppProxyAuth;
|
|
86
|
+
adtConfig.username = displayUsername;
|
|
87
|
+
adtConfig.password = undefined;
|
|
88
|
+
}
|
|
89
|
+
else if (authTokens.sapConnectivityAuth) {
|
|
90
|
+
// Option 2: SAML assertion from Destination Service
|
|
91
|
+
adtConfig.sapConnectivityAuth = authTokens.sapConnectivityAuth;
|
|
92
|
+
adtConfig.username = displayUsername;
|
|
93
|
+
adtConfig.password = undefined;
|
|
94
|
+
}
|
|
95
|
+
else if (authTokens.bearerToken) {
|
|
96
|
+
// TODO: Bearer token auth for OAuth2SAMLBearerAssertion destinations
|
|
97
|
+
// This would replace basic auth with Bearer token
|
|
98
|
+
logger.warn('Bearer token auth from destination not yet implemented — falling back to basic auth');
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
// No per-user auth token received.
|
|
102
|
+
throw new Error(`Principal propagation failed for destination '${destName}': ` +
|
|
103
|
+
'no SAP-Connectivity-Authentication header, Bearer token, or jwt-bearer exchange token returned. ' +
|
|
104
|
+
'Check Cloud Connector status, destination configuration, and user JWT validity.');
|
|
105
|
+
}
|
|
106
|
+
return new AdtClient(adtConfig);
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Create the MCP server with registered tool handlers.
|
|
110
|
+
* @param config Server configuration
|
|
111
|
+
* @param btpProxy Optional BTP connectivity proxy config (resolved at startup)
|
|
112
|
+
* @param btpConfig Optional BTP service config (for per-user destination lookup)
|
|
113
|
+
*/
|
|
114
|
+
export function createServer(config, btpProxy, btpConfig) {
|
|
115
|
+
const server = new Server({ name: 'arc-1', version: VERSION }, { capabilities: { tools: {} } });
|
|
116
|
+
// Create default ADT client (shared, uses startup-time credentials)
|
|
117
|
+
const defaultClient = new AdtClient(buildAdtConfig(config, btpProxy));
|
|
118
|
+
// Register tool listing — filtered by user's scopes when auth is active
|
|
119
|
+
server.setRequestHandler(ListToolsRequestSchema, async (_request, extra) => {
|
|
120
|
+
let tools = getToolDefinitions(config);
|
|
121
|
+
// When authenticated, only show tools the user has scopes for
|
|
122
|
+
if (extra.authInfo) {
|
|
123
|
+
tools = tools.filter((tool) => {
|
|
124
|
+
const requiredScope = TOOL_SCOPES[tool.name];
|
|
125
|
+
return !requiredScope || extra.authInfo.scopes.includes(requiredScope);
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
return { tools };
|
|
129
|
+
});
|
|
130
|
+
// Register tool call handler — passes authInfo for scope enforcement + audit logging
|
|
131
|
+
server.setRequestHandler(CallToolRequestSchema, async (request, extra) => {
|
|
132
|
+
const toolName = request.params.name;
|
|
133
|
+
const args = (request.params.arguments ?? {});
|
|
134
|
+
// Principal propagation: create per-user ADT client if enabled and user JWT available.
|
|
135
|
+
// Only attempt PP when the token is a JWT (3 dot-separated parts), not a plain API key.
|
|
136
|
+
let client = defaultClient;
|
|
137
|
+
const token = extra.authInfo?.token;
|
|
138
|
+
const isJwt = token && token.split('.').length === 3;
|
|
139
|
+
if (config.ppEnabled && btpConfig && isJwt) {
|
|
140
|
+
const ppUser = (extra.authInfo?.extra?.userName ?? extra.authInfo?.clientId);
|
|
141
|
+
const ppDest = process.env.SAP_BTP_PP_DESTINATION ?? process.env.SAP_BTP_DESTINATION ?? '';
|
|
142
|
+
try {
|
|
143
|
+
client = await createPerUserClient(config, btpConfig, btpProxy, token);
|
|
144
|
+
logger.emitAudit({
|
|
145
|
+
timestamp: new Date().toISOString(),
|
|
146
|
+
level: 'info',
|
|
147
|
+
event: 'auth_pp_created',
|
|
148
|
+
user: ppUser,
|
|
149
|
+
destination: ppDest,
|
|
150
|
+
success: true,
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
catch (err) {
|
|
154
|
+
const errMsg = err instanceof Error ? err.message : String(err);
|
|
155
|
+
logger.emitAudit({
|
|
156
|
+
timestamp: new Date().toISOString(),
|
|
157
|
+
level: 'error',
|
|
158
|
+
event: 'auth_pp_created',
|
|
159
|
+
user: ppUser,
|
|
160
|
+
destination: ppDest,
|
|
161
|
+
success: false,
|
|
162
|
+
errorMessage: errMsg,
|
|
163
|
+
});
|
|
164
|
+
if (config.ppStrict) {
|
|
165
|
+
// Strict mode: PP failure is a hard error — never fall back to shared client.
|
|
166
|
+
// This ensures every request runs with the authenticated user's identity.
|
|
167
|
+
return {
|
|
168
|
+
content: [
|
|
169
|
+
{
|
|
170
|
+
type: 'text',
|
|
171
|
+
text: `Principal propagation failed (SAP_PP_STRICT=true): ${errMsg}`,
|
|
172
|
+
},
|
|
173
|
+
],
|
|
174
|
+
isError: true,
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
// Fall back to shared client (service account)
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
else if (config.ppStrict && config.ppEnabled && !isJwt) {
|
|
181
|
+
// Strict mode with non-JWT token (e.g., API key) — reject
|
|
182
|
+
return {
|
|
183
|
+
content: [
|
|
184
|
+
{
|
|
185
|
+
type: 'text',
|
|
186
|
+
text: 'Principal propagation requires a JWT token (SAP_PP_STRICT=true). API key authentication is not supported in strict PP mode.',
|
|
187
|
+
},
|
|
188
|
+
],
|
|
189
|
+
isError: true,
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
const result = await handleToolCall(client, config, toolName, args, extra.authInfo, server);
|
|
193
|
+
return { ...result };
|
|
194
|
+
});
|
|
195
|
+
return server;
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Create and start the MCP server.
|
|
199
|
+
*/
|
|
200
|
+
export async function createAndStartServer(config) {
|
|
201
|
+
initLogger(config.logFormat, config.verbose);
|
|
202
|
+
// Add file sink if configured
|
|
203
|
+
if (config.logFile) {
|
|
204
|
+
logger.addSink(new FileSink(config.logFile));
|
|
205
|
+
logger.info('File logging enabled', { logFile: config.logFile });
|
|
206
|
+
}
|
|
207
|
+
// Add BTP Audit Log sink if auditlog service is bound (auto-detected from VCAP_SERVICES)
|
|
208
|
+
try {
|
|
209
|
+
const { BTPAuditLogSink, parseBTPAuditLogConfig } = await import('./sinks/btp-auditlog.js');
|
|
210
|
+
const auditLogConfig = parseBTPAuditLogConfig();
|
|
211
|
+
if (auditLogConfig) {
|
|
212
|
+
logger.addSink(new BTPAuditLogSink(auditLogConfig));
|
|
213
|
+
logger.info('BTP Audit Log sink enabled', { url: auditLogConfig.url });
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
catch (err) {
|
|
217
|
+
logger.warn('BTP Audit Log sink initialization failed (optional)', {
|
|
218
|
+
error: err instanceof Error ? err.message : String(err),
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
// Emit structured server_start audit event
|
|
222
|
+
logger.emitAudit({
|
|
223
|
+
timestamp: new Date().toISOString(),
|
|
224
|
+
level: 'info',
|
|
225
|
+
event: 'server_start',
|
|
226
|
+
version: VERSION,
|
|
227
|
+
transport: config.transport,
|
|
228
|
+
readOnly: config.readOnly,
|
|
229
|
+
url: config.url || '(not configured)',
|
|
230
|
+
});
|
|
231
|
+
logger.info('ARC-1 starting', {
|
|
232
|
+
version: VERSION,
|
|
233
|
+
transport: config.transport,
|
|
234
|
+
url: config.url || '(not configured)',
|
|
235
|
+
readOnly: config.readOnly,
|
|
236
|
+
});
|
|
237
|
+
// Resolve BTP Destination if configured (overrides SAP_URL/USER/PASSWORD)
|
|
238
|
+
let btpProxy;
|
|
239
|
+
let btpConfig;
|
|
240
|
+
const btpDestination = process.env.SAP_BTP_DESTINATION;
|
|
241
|
+
if (btpDestination) {
|
|
242
|
+
const { resolveBTPDestination, parseVCAPServices } = await import('../adt/btp.js');
|
|
243
|
+
const resolved = await resolveBTPDestination(btpDestination);
|
|
244
|
+
config.url = resolved.url;
|
|
245
|
+
config.username = resolved.username;
|
|
246
|
+
config.password = resolved.password;
|
|
247
|
+
config.client = resolved.client;
|
|
248
|
+
btpProxy = resolved.proxy ?? undefined;
|
|
249
|
+
// Keep btpConfig for per-user destination lookup (principal propagation)
|
|
250
|
+
if (config.ppEnabled) {
|
|
251
|
+
btpConfig = parseVCAPServices() ?? undefined;
|
|
252
|
+
logger.info('Principal propagation enabled', {
|
|
253
|
+
destination: btpDestination,
|
|
254
|
+
hasBtpConfig: !!btpConfig,
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
logger.info('BTP destination resolved', {
|
|
258
|
+
destination: btpDestination,
|
|
259
|
+
url: resolved.url,
|
|
260
|
+
user: resolved.username,
|
|
261
|
+
hasProxy: !!btpProxy,
|
|
262
|
+
ppEnabled: config.ppEnabled,
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
const server = createServer(config, btpProxy, btpConfig);
|
|
266
|
+
if (config.transport === 'stdio') {
|
|
267
|
+
const transport = new StdioServerTransport();
|
|
268
|
+
await server.connect(transport);
|
|
269
|
+
logger.info('ARC-1 MCP server running on stdio');
|
|
270
|
+
}
|
|
271
|
+
else {
|
|
272
|
+
// HTTP Streamable transport — for containerized/BTP deployments
|
|
273
|
+
// Pass the factory function so HTTP server can create fresh server+transport
|
|
274
|
+
// per request. This is required because MCP SDK's Server can only connect
|
|
275
|
+
// to one transport at a time, and clients like Copilot Studio send
|
|
276
|
+
// concurrent requests.
|
|
277
|
+
// Load XSUAA credentials if XSUAA auth is enabled
|
|
278
|
+
let xsuaaCredentials;
|
|
279
|
+
if (config.xsuaaAuth) {
|
|
280
|
+
try {
|
|
281
|
+
const xsenv = await import('@sap/xsenv');
|
|
282
|
+
const services = xsenv.getServices({ uaa: { tag: 'xsuaa' } });
|
|
283
|
+
const uaa = services.uaa;
|
|
284
|
+
xsuaaCredentials = {
|
|
285
|
+
url: uaa.url,
|
|
286
|
+
clientid: uaa.clientid,
|
|
287
|
+
clientsecret: uaa.clientsecret,
|
|
288
|
+
xsappname: uaa.xsappname,
|
|
289
|
+
uaadomain: uaa.uaadomain,
|
|
290
|
+
};
|
|
291
|
+
logger.info('XSUAA credentials loaded', {
|
|
292
|
+
xsappname: xsuaaCredentials.xsappname,
|
|
293
|
+
url: xsuaaCredentials.url,
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
catch (err) {
|
|
297
|
+
logger.error('Failed to load XSUAA credentials — XSUAA auth will not work', {
|
|
298
|
+
error: err instanceof Error ? err.message : String(err),
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
const { startHttpServer } = await import('./http.js');
|
|
303
|
+
await startHttpServer(() => createServer(config, btpProxy, btpConfig), config, xsuaaCredentials);
|
|
304
|
+
}
|
|
305
|
+
return server;
|
|
306
|
+
}
|
|
307
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../ts-src/server/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BTP Audit Log sink for ARC-1.
|
|
3
|
+
*
|
|
4
|
+
* Sends structured audit events to SAP BTP Audit Log Service v2 API.
|
|
5
|
+
* Only activates when running on BTP with an auditlog premium service binding.
|
|
6
|
+
*
|
|
7
|
+
* Maps ARC-1 audit events to BTP Audit Log categories:
|
|
8
|
+
* - security-events: auth failures, scope denials, safety blocks
|
|
9
|
+
* - data-accesses: tool calls that read SAP data
|
|
10
|
+
* - data-modifications: tool calls that write/delete SAP data
|
|
11
|
+
* - configuration-changes: transport releases, activations
|
|
12
|
+
*
|
|
13
|
+
* Authentication uses mTLS (X.509 certificates) via the premium plan binding.
|
|
14
|
+
* Tokens are cached with 60s refresh buffer (same pattern as btp.ts connectivity proxy).
|
|
15
|
+
*
|
|
16
|
+
* All writes are fire-and-forget — errors go to stderr, never block tool calls.
|
|
17
|
+
*/
|
|
18
|
+
import type { AuditEvent } from '../audit.js';
|
|
19
|
+
import type { LogSink } from './types.js';
|
|
20
|
+
/** BTP Audit Log service credentials from VCAP_SERVICES */
|
|
21
|
+
export interface BTPAuditLogConfig {
|
|
22
|
+
url: string;
|
|
23
|
+
uaa: {
|
|
24
|
+
url: string;
|
|
25
|
+
certurl: string;
|
|
26
|
+
clientid: string;
|
|
27
|
+
certificate: string;
|
|
28
|
+
key: string;
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Parse BTP Audit Log credentials from VCAP_SERVICES.
|
|
33
|
+
* Returns undefined if the service is not bound.
|
|
34
|
+
*/
|
|
35
|
+
export declare function parseBTPAuditLogConfig(): BTPAuditLogConfig | undefined;
|
|
36
|
+
export declare class BTPAuditLogSink implements LogSink {
|
|
37
|
+
private config;
|
|
38
|
+
private token;
|
|
39
|
+
private tokenExpiresAt;
|
|
40
|
+
private pendingWrites;
|
|
41
|
+
constructor(config: BTPAuditLogConfig);
|
|
42
|
+
write(event: AuditEvent): void;
|
|
43
|
+
flush(): Promise<void>;
|
|
44
|
+
private sendEvent;
|
|
45
|
+
private buildPayload;
|
|
46
|
+
private getToken;
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=btp-auditlog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"btp-auditlog.d.ts","sourceRoot":"","sources":["../../../ts-src/server/sinks/btp-auditlog.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EACV,UAAU,EAMX,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE1C,2DAA2D;AAC3D,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE;QACH,GAAG,EAAE,MAAM,CAAC;QACZ,OAAO,EAAE,MAAM,CAAC;QAChB,QAAQ,EAAE,MAAM,CAAC;QACjB,WAAW,EAAE,MAAM,CAAC;QACpB,GAAG,EAAE,MAAM,CAAC;KACb,CAAC;CACH;AAgCD;;;GAGG;AACH,wBAAgB,sBAAsB,IAAI,iBAAiB,GAAG,SAAS,CA4BtE;AAED,qBAAa,eAAgB,YAAW,OAAO;IAKjC,OAAO,CAAC,MAAM;IAJ1B,OAAO,CAAC,KAAK,CAAqB;IAClC,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,aAAa,CAAuB;gBAExB,MAAM,EAAE,iBAAiB;IAE7C,KAAK,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAuBxB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YAKd,SAAS;IAmBvB,OAAO,CAAC,YAAY;YAyFN,QAAQ;CAgCvB"}
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BTP Audit Log sink for ARC-1.
|
|
3
|
+
*
|
|
4
|
+
* Sends structured audit events to SAP BTP Audit Log Service v2 API.
|
|
5
|
+
* Only activates when running on BTP with an auditlog premium service binding.
|
|
6
|
+
*
|
|
7
|
+
* Maps ARC-1 audit events to BTP Audit Log categories:
|
|
8
|
+
* - security-events: auth failures, scope denials, safety blocks
|
|
9
|
+
* - data-accesses: tool calls that read SAP data
|
|
10
|
+
* - data-modifications: tool calls that write/delete SAP data
|
|
11
|
+
* - configuration-changes: transport releases, activations
|
|
12
|
+
*
|
|
13
|
+
* Authentication uses mTLS (X.509 certificates) via the premium plan binding.
|
|
14
|
+
* Tokens are cached with 60s refresh buffer (same pattern as btp.ts connectivity proxy).
|
|
15
|
+
*
|
|
16
|
+
* All writes are fire-and-forget — errors go to stderr, never block tool calls.
|
|
17
|
+
*/
|
|
18
|
+
/** Categorize tool by its access pattern */
|
|
19
|
+
function toolCategory(tool) {
|
|
20
|
+
if (['SAPWrite', 'SAPManage'].includes(tool))
|
|
21
|
+
return 'data-modifications';
|
|
22
|
+
if (['SAPTransport', 'SAPActivate'].includes(tool))
|
|
23
|
+
return 'configuration-changes';
|
|
24
|
+
return 'data-accesses';
|
|
25
|
+
}
|
|
26
|
+
/** Map ARC-1 event types to BTP Audit Log categories */
|
|
27
|
+
function categorize(event) {
|
|
28
|
+
switch (event.event) {
|
|
29
|
+
case 'auth_scope_denied':
|
|
30
|
+
case 'safety_blocked':
|
|
31
|
+
return 'security-events';
|
|
32
|
+
case 'tool_call_start':
|
|
33
|
+
case 'tool_call_end':
|
|
34
|
+
return toolCategory(event.tool);
|
|
35
|
+
case 'auth_pp_created':
|
|
36
|
+
return event.level === 'error' ? 'security-events' : null;
|
|
37
|
+
// Don't send http_request, server_start, elicitation events to BTP audit log
|
|
38
|
+
default:
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Parse BTP Audit Log credentials from VCAP_SERVICES.
|
|
44
|
+
* Returns undefined if the service is not bound.
|
|
45
|
+
*/
|
|
46
|
+
export function parseBTPAuditLogConfig() {
|
|
47
|
+
const vcap = process.env.VCAP_SERVICES;
|
|
48
|
+
if (!vcap)
|
|
49
|
+
return undefined;
|
|
50
|
+
try {
|
|
51
|
+
const services = JSON.parse(vcap);
|
|
52
|
+
// Look for auditlog service with premium plan
|
|
53
|
+
const auditlogEntries = services.auditlog ?? services['auditlog-api'] ?? [];
|
|
54
|
+
const premiumBinding = Array.isArray(auditlogEntries)
|
|
55
|
+
? auditlogEntries.find((s) => s.plan === 'premium' || s.plan === 'oauth2')
|
|
56
|
+
: undefined;
|
|
57
|
+
if (!premiumBinding?.credentials)
|
|
58
|
+
return undefined;
|
|
59
|
+
const creds = premiumBinding.credentials;
|
|
60
|
+
return {
|
|
61
|
+
url: creds.url,
|
|
62
|
+
uaa: {
|
|
63
|
+
url: creds.uaa?.url,
|
|
64
|
+
certurl: creds.uaa?.certurl,
|
|
65
|
+
clientid: creds.uaa?.clientid,
|
|
66
|
+
certificate: creds.uaa?.certificate,
|
|
67
|
+
key: creds.uaa?.key,
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
return undefined;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
export class BTPAuditLogSink {
|
|
76
|
+
config;
|
|
77
|
+
token;
|
|
78
|
+
tokenExpiresAt = 0;
|
|
79
|
+
pendingWrites = [];
|
|
80
|
+
constructor(config) {
|
|
81
|
+
this.config = config;
|
|
82
|
+
}
|
|
83
|
+
write(event) {
|
|
84
|
+
const category = categorize(event);
|
|
85
|
+
if (!category)
|
|
86
|
+
return;
|
|
87
|
+
// Fire-and-forget
|
|
88
|
+
const p = this.sendEvent(event, category).catch((err) => {
|
|
89
|
+
process.stderr.write(`[BTPAuditLogSink] Failed to write audit event: ${err}\n`);
|
|
90
|
+
});
|
|
91
|
+
this.pendingWrites.push(p);
|
|
92
|
+
// Cleanup completed promises periodically
|
|
93
|
+
if (this.pendingWrites.length > 50) {
|
|
94
|
+
this.pendingWrites = this.pendingWrites.filter((p) => {
|
|
95
|
+
let settled = false;
|
|
96
|
+
p.then(() => (settled = true), () => (settled = true));
|
|
97
|
+
return !settled;
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
async flush() {
|
|
102
|
+
await Promise.allSettled(this.pendingWrites);
|
|
103
|
+
this.pendingWrites = [];
|
|
104
|
+
}
|
|
105
|
+
async sendEvent(event, category) {
|
|
106
|
+
const token = await this.getToken();
|
|
107
|
+
const payload = this.buildPayload(event);
|
|
108
|
+
const response = await fetch(`${this.config.url}/audit-log/oauth2/v2/${category}`, {
|
|
109
|
+
method: 'POST',
|
|
110
|
+
headers: {
|
|
111
|
+
'Content-Type': 'application/json',
|
|
112
|
+
Authorization: `Bearer ${token}`,
|
|
113
|
+
},
|
|
114
|
+
body: JSON.stringify(payload),
|
|
115
|
+
});
|
|
116
|
+
if (!response.ok) {
|
|
117
|
+
const body = await response.text().catch(() => '');
|
|
118
|
+
throw new Error(`HTTP ${response.status}: ${body.slice(0, 200)}`);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
buildPayload(event) {
|
|
122
|
+
const user = event.user ?? '$USER';
|
|
123
|
+
const base = {
|
|
124
|
+
uuid: crypto.randomUUID(),
|
|
125
|
+
user,
|
|
126
|
+
time: event.timestamp,
|
|
127
|
+
tenant: '$PROVIDER',
|
|
128
|
+
};
|
|
129
|
+
switch (event.event) {
|
|
130
|
+
case 'tool_call_start': {
|
|
131
|
+
const e = event;
|
|
132
|
+
const argsStr = JSON.stringify(e.args);
|
|
133
|
+
const argsSummary = argsStr.length > 500 ? `${argsStr.slice(0, 500)}...` : argsStr;
|
|
134
|
+
return {
|
|
135
|
+
...base,
|
|
136
|
+
object: {
|
|
137
|
+
type: 'MCP Tool Call',
|
|
138
|
+
id: { tool: e.tool, requestId: e.requestId ?? '' },
|
|
139
|
+
},
|
|
140
|
+
attributes: [
|
|
141
|
+
{ name: 'action', new: 'invoke' },
|
|
142
|
+
{ name: 'tool', new: e.tool },
|
|
143
|
+
{ name: 'user', new: user },
|
|
144
|
+
{ name: 'clientId', new: e.clientId ?? '' },
|
|
145
|
+
{ name: 'args', new: argsSummary },
|
|
146
|
+
],
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
case 'tool_call_end': {
|
|
150
|
+
const e = event;
|
|
151
|
+
const attrs = [
|
|
152
|
+
{ name: 'action', new: 'complete' },
|
|
153
|
+
{ name: 'tool', new: e.tool },
|
|
154
|
+
{ name: 'user', new: user },
|
|
155
|
+
{ name: 'clientId', new: e.clientId ?? '' },
|
|
156
|
+
{ name: 'status', new: e.status },
|
|
157
|
+
{ name: 'durationMs', new: String(e.durationMs) },
|
|
158
|
+
{ name: 'resultSize', new: String(e.resultSize ?? 0) },
|
|
159
|
+
];
|
|
160
|
+
if (e.errorMessage) {
|
|
161
|
+
attrs.push({ name: 'error', new: e.errorMessage.slice(0, 500) });
|
|
162
|
+
}
|
|
163
|
+
if (e.errorClass) {
|
|
164
|
+
attrs.push({ name: 'errorClass', new: e.errorClass });
|
|
165
|
+
}
|
|
166
|
+
return {
|
|
167
|
+
...base,
|
|
168
|
+
object: {
|
|
169
|
+
type: 'MCP Tool Call',
|
|
170
|
+
id: { tool: e.tool, requestId: e.requestId ?? '' },
|
|
171
|
+
},
|
|
172
|
+
attributes: attrs,
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
case 'auth_scope_denied': {
|
|
176
|
+
const e = event;
|
|
177
|
+
return {
|
|
178
|
+
...base,
|
|
179
|
+
data: `Access denied: user "${user}" lacks scope "${e.requiredScope}" for tool ${e.tool}. Available scopes: [${e.availableScopes.join(', ')}]`,
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
case 'safety_blocked': {
|
|
183
|
+
const e = event;
|
|
184
|
+
return {
|
|
185
|
+
...base,
|
|
186
|
+
data: `Safety blocked: operation "${e.operation}" denied — ${e.reason}. User: ${user}`,
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
case 'auth_pp_created': {
|
|
190
|
+
const e = event;
|
|
191
|
+
return {
|
|
192
|
+
...base,
|
|
193
|
+
data: `Principal propagation ${e.success ? 'succeeded' : 'failed'} for user "${user}" via destination "${e.destination}"${e.errorMessage ? `: ${e.errorMessage}` : ''}`,
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
default:
|
|
197
|
+
return {
|
|
198
|
+
...base,
|
|
199
|
+
data: `[${event.event}] ${JSON.stringify(event)}`,
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
async getToken() {
|
|
204
|
+
// Return cached token if still valid (with 60s buffer)
|
|
205
|
+
if (this.token && Date.now() < this.tokenExpiresAt - 60_000) {
|
|
206
|
+
return this.token;
|
|
207
|
+
}
|
|
208
|
+
// For mTLS, we'd need to use the certificate and key from the service binding.
|
|
209
|
+
// Node.js fetch doesn't support client certificates directly — in production,
|
|
210
|
+
// the CF buildpack handles certificate injection via the NODE_EXTRA_CA_CERTS
|
|
211
|
+
// and the service binding provides tokens via the bound app's identity.
|
|
212
|
+
// For now, use client_credentials grant with the service binding.
|
|
213
|
+
const tokenUrl = `${this.config.uaa.certurl}/oauth/token`;
|
|
214
|
+
const params = new URLSearchParams({
|
|
215
|
+
grant_type: 'client_credentials',
|
|
216
|
+
client_id: this.config.uaa.clientid,
|
|
217
|
+
});
|
|
218
|
+
const response = await fetch(tokenUrl, {
|
|
219
|
+
method: 'POST',
|
|
220
|
+
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
221
|
+
body: params.toString(),
|
|
222
|
+
});
|
|
223
|
+
if (!response.ok) {
|
|
224
|
+
throw new Error(`Token fetch failed: HTTP ${response.status}`);
|
|
225
|
+
}
|
|
226
|
+
const data = (await response.json());
|
|
227
|
+
this.token = data.access_token;
|
|
228
|
+
this.tokenExpiresAt = Date.now() + data.expires_in * 1000;
|
|
229
|
+
return this.token;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
//# sourceMappingURL=btp-auditlog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"btp-auditlog.js","sourceRoot":"","sources":["../../../ts-src/server/sinks/btp-auditlog.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File log sink for ARC-1.
|
|
3
|
+
*
|
|
4
|
+
* Appends JSON-line audit events to a file.
|
|
5
|
+
* Useful in Docker (mount volume) or for post-hoc log analysis.
|
|
6
|
+
*
|
|
7
|
+
* Writes are fire-and-forget — errors are logged to stderr but never thrown.
|
|
8
|
+
* All events are written regardless of level (file is the full audit trail).
|
|
9
|
+
*/
|
|
10
|
+
import type { AuditEvent } from '../audit.js';
|
|
11
|
+
import type { LogSink } from './types.js';
|
|
12
|
+
export declare class FileSink implements LogSink {
|
|
13
|
+
private filePath;
|
|
14
|
+
private buffer;
|
|
15
|
+
private flushTimer;
|
|
16
|
+
constructor(filePath: string);
|
|
17
|
+
write(event: AuditEvent): void;
|
|
18
|
+
flush(): Promise<void>;
|
|
19
|
+
private flushSync;
|
|
20
|
+
private writeBuffer;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=file.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file.d.ts","sourceRoot":"","sources":["../../../ts-src/server/sinks/file.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE1C,qBAAa,QAAS,YAAW,OAAO;IAI1B,OAAO,CAAC,QAAQ;IAH5B,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,UAAU,CAA6C;gBAE3C,QAAQ,EAAE,MAAM;IAWpC,KAAK,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAIxB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ5B,OAAO,CAAC,SAAS;YAUH,WAAW;CAU1B"}
|