@oobe-protocol-labs/sap-mcp-server 0.7.3 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/CHANGELOG.md +139 -0
  2. package/README.md +14 -7
  3. package/USER_DOCS/00_START_HERE.md +45 -7
  4. package/USER_DOCS/01_HOSTED_REMOTE_MCP.md +2 -0
  5. package/USER_DOCS/03_PAYMENTS_X402_PAYSH.md +13 -5
  6. package/USER_DOCS/04_CLIENT_CONFIGS.md +25 -15
  7. package/USER_DOCS/06_DESKTOP_GUI_WIZARD.md +36 -21
  8. package/assets/logos/drift.svg +12 -0
  9. package/assets/logos/jupiter.ico +0 -0
  10. package/assets/logos/mcp.svg +11 -0
  11. package/assets/logos/meteora.png +0 -0
  12. package/assets/logos/orca.ico +0 -0
  13. package/assets/logos/raydium.ico +0 -0
  14. package/assets/logos/smithery.svg +11 -0
  15. package/assets/oobe-logo.png +0 -0
  16. package/dist/config/mcp-client-injection.d.ts +26 -7
  17. package/dist/config/mcp-client-injection.d.ts.map +1 -1
  18. package/dist/config/mcp-client-injection.js +182 -58
  19. package/dist/config/mcp-client-injection.js.map +1 -1
  20. package/dist/config/wizard.d.ts.map +1 -1
  21. package/dist/config/wizard.js +92 -57
  22. package/dist/config/wizard.js.map +1 -1
  23. package/dist/core/constants.d.ts +1 -1
  24. package/dist/core/constants.js +1 -1
  25. package/dist/payments/pricing.d.ts.map +1 -1
  26. package/dist/payments/pricing.js +11 -0
  27. package/dist/payments/pricing.js.map +1 -1
  28. package/dist/payments/x402-paid-call.d.ts +85 -1
  29. package/dist/payments/x402-paid-call.d.ts.map +1 -1
  30. package/dist/payments/x402-paid-call.js +168 -4
  31. package/dist/payments/x402-paid-call.js.map +1 -1
  32. package/dist/prompts/context/sap-agent-context.prompt.js +6 -3
  33. package/dist/prompts/context/sap-agent-context.prompt.js.map +1 -1
  34. package/dist/remote/public-home/escape.d.ts +11 -0
  35. package/dist/remote/public-home/escape.d.ts.map +1 -0
  36. package/dist/remote/public-home/escape.js +20 -0
  37. package/dist/remote/public-home/escape.js.map +1 -0
  38. package/dist/remote/public-home/index.d.ts +8 -0
  39. package/dist/remote/public-home/index.d.ts.map +1 -0
  40. package/dist/remote/public-home/index.js +57 -0
  41. package/dist/remote/public-home/index.js.map +1 -0
  42. package/dist/remote/public-home/scripts.d.ts +6 -0
  43. package/dist/remote/public-home/scripts.d.ts.map +1 -0
  44. package/dist/remote/public-home/scripts.js +106 -0
  45. package/dist/remote/public-home/scripts.js.map +1 -0
  46. package/dist/remote/public-home/sections.d.ts +67 -0
  47. package/dist/remote/public-home/sections.d.ts.map +1 -0
  48. package/dist/remote/public-home/sections.js +727 -0
  49. package/dist/remote/public-home/sections.js.map +1 -0
  50. package/dist/remote/public-home/styles.d.ts +6 -0
  51. package/dist/remote/public-home/styles.d.ts.map +1 -0
  52. package/dist/remote/public-home/styles.js +1534 -0
  53. package/dist/remote/public-home/styles.js.map +1 -0
  54. package/dist/remote/public-home/types.d.ts +95 -0
  55. package/dist/remote/public-home/types.d.ts.map +1 -0
  56. package/dist/remote/public-home/types.js +2 -0
  57. package/dist/remote/public-home/types.js.map +1 -0
  58. package/dist/remote/server.d.ts +41 -1
  59. package/dist/remote/server.d.ts.map +1 -1
  60. package/dist/remote/server.js +109 -292
  61. package/dist/remote/server.js.map +1 -1
  62. package/dist/security/tool-permissions.d.ts.map +1 -1
  63. package/dist/security/tool-permissions.js +5 -0
  64. package/dist/security/tool-permissions.js.map +1 -1
  65. package/dist/tools/magicblock-tools.js +6 -6
  66. package/dist/tools/magicblock-tools.js.map +1 -1
  67. package/dist/tools/profile-tools.d.ts.map +1 -1
  68. package/dist/tools/profile-tools.js +136 -33
  69. package/dist/tools/profile-tools.js.map +1 -1
  70. package/dist/tools/register-tools.d.ts.map +1 -1
  71. package/dist/tools/register-tools.js +5 -0
  72. package/dist/tools/register-tools.js.map +1 -1
  73. package/dist/tools/x402-paid-call-tool.d.ts +1 -1
  74. package/dist/tools/x402-paid-call-tool.d.ts.map +1 -1
  75. package/dist/tools/x402-paid-call-tool.js +314 -28
  76. package/dist/tools/x402-paid-call-tool.js.map +1 -1
  77. package/dist/wizard-core/desktop-flow.d.ts +40 -1
  78. package/dist/wizard-core/desktop-flow.d.ts.map +1 -1
  79. package/dist/wizard-core/desktop-flow.js +206 -15
  80. package/dist/wizard-core/desktop-flow.js.map +1 -1
  81. package/docs/03_CONFIGURATION_AND_WIZARD.md +6 -2
  82. package/docs/06_PAYMENTS_X402_AND_PAYSH.md +29 -7
  83. package/docs/07_ENDPOINTS_AND_CLIENTS.md +1 -1
  84. package/docs/14_DESKTOP_WIZARD_RELEASE.md +24 -5
  85. package/docs/15_DASHBOARD_SCREENSHARE_SCRIPT.md +137 -0
  86. package/docs/README.md +23 -2
  87. package/package.json +1 -1
  88. package/server.json +3 -3
  89. package/skills/sap-mcp/SKILL.md +23 -7
  90. package/skills/sap-payments-x402/SKILL.md +37 -13
@@ -0,0 +1,11 @@
1
+ <svg width="135" height="159" viewBox="0 0 135 159" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M31.3508 58.4053H0V78.9492C0 90.8872 9.67578 100.563 21.6138 100.563H42.1577V69.2122C42.1577 63.2432 37.3198 58.4053 31.3508 58.4053Z" fill="#FF5601"/>
3
+ <path d="M46.2327 69.2122V100.563H77.5835C83.5525 100.563 88.3904 95.7251 88.3904 89.7561V58.4053H57.0396C51.0706 58.4053 46.2327 63.2432 46.2327 69.2122Z" fill="#FF5601"/>
4
+ <path d="M113.013 58.4053H92.4695V89.7561C92.4695 95.7251 97.3074 100.563 103.276 100.563H134.627V80.0191C134.627 68.0811 124.951 58.4053 113.013 58.4053Z" fill="#FF5601"/>
5
+ <path d="M0.000244141 37.5535V54.351H31.3511C37.3201 54.351 42.158 49.5131 42.158 43.5441V6.01534C40.9332 5.97572 39.6616 5.9541 38.3323 5.9541C17.9865 5.9541 0.000244141 15.9001 0.000244141 37.5535Z" fill="#FF5601"/>
6
+ <path d="M46.2327 43.5332C46.2327 49.5022 51.0706 54.3401 57.0396 54.3401H88.3904V14.4735C71.0993 12.8596 64.1109 7.47418 46.2327 6.21338V43.5368V43.5332Z" fill="#FF5601"/>
7
+ <path d="M98.8636 14.9351C96.5833 14.9351 94.4616 14.8775 92.4695 14.773V54.3443H113.013C124.951 54.3443 134.627 44.6685 134.627 32.7305V0C127.945 8.91209 116.097 14.9351 98.8636 14.9351Z" fill="#FF5601"/>
8
+ <path d="M35.7697 144.068C38.05 144.068 40.1718 144.126 42.1638 144.23V104.659H21.6199C9.68188 104.659 0.00610352 114.335 0.00610352 126.273V159C6.68837 150.088 18.5363 144.065 35.7733 144.065L35.7697 144.068Z" fill="#FF5601"/>
9
+ <path d="M88.3904 115.466C88.3904 109.497 83.5525 104.659 77.5835 104.659H46.2327V144.529C63.5237 146.143 70.5122 151.529 88.3904 152.79V115.466Z" fill="#FF5601"/>
10
+ <path d="M134.627 121.5V104.659H103.276C97.3074 104.659 92.4695 109.497 92.4695 115.466V152.995C93.6943 153.034 94.9659 153.052 96.2951 153.052C116.63 153.052 134.606 143.121 134.627 121.496V121.5Z" fill="#FF5601"/>
11
+ </svg>
Binary file
@@ -80,13 +80,22 @@ export interface ManualMcpClientSnippet {
80
80
  }
81
81
  /**
82
82
  * @name McpClientAddonInstallResult
83
- * @description Files written when the wizard installs a local client addon bundle.
83
+ * @description Files written when the wizard installs a local payment bridge reference bundle.
84
84
  */
85
85
  export interface McpClientAddonInstallResult {
86
86
  addonId: 'x402-paid-call';
87
87
  targetDir: string;
88
88
  files: string[];
89
89
  }
90
+ /**
91
+ * @name HostedPaymentBridgeResolution
92
+ * @description Result produced after building and auto-resolving hosted SAP MCP plus local sap_payments config.
93
+ */
94
+ export interface HostedPaymentBridgeResolution {
95
+ nextContent: string;
96
+ hadSapConfig: boolean;
97
+ resolvedIssues: string[];
98
+ }
90
99
  type SupportedPlatform = NodeJS.Platform;
91
100
  /**
92
101
  * @name HOSTED_SAP_MCP_URL
@@ -115,12 +124,12 @@ export declare function createNpxCodexServerConfig(): McpServerInjectionConfig;
115
124
  export declare function createNpxPaymentBridgeServerConfig(): McpServerInjectionConfig;
116
125
  /**
117
126
  * @name createX402PaidCallAddonSnippets
118
- * @description Builds manual plugin/addon snippets for clients that can call a local x402 payment helper.
127
+ * @description Builds manual snippets for clients that can call the native local SAP MCP payment bridge.
119
128
  */
120
129
  export declare function createX402PaidCallAddonSnippets(): ManualMcpClientSnippet[];
121
130
  /**
122
131
  * @name installX402PaidCallAddon
123
- * @description Installs a portable local addon bundle with manifest and client snippets.
132
+ * @description Installs a portable local reference bundle with manifest and client snippets for bridge repair/custom clients.
124
133
  */
125
134
  export declare function installX402PaidCallAddon(targetDir?: string): McpClientAddonInstallResult;
126
135
  /**
@@ -138,11 +147,21 @@ export declare function discoverMcpClientTargets(homeDir?: string, platform?: Su
138
147
  * @description Detects stale SAP MCP paths and hardcoded environment overrides.
139
148
  */
140
149
  export declare function findLegacySignals(content: string): string[];
150
+ /**
151
+ * @name validateHostedPaymentBridgeContent
152
+ * @description Verifies that a runtime config contains both hosted SAP MCP and the local sap_payments bridge.
153
+ */
154
+ export declare function validateHostedPaymentBridgeContent(target: McpClientTarget, content: string, platform?: SupportedPlatform): string[];
155
+ /**
156
+ * @name resolveHostedPaymentBridgeContent
157
+ * @description Builds hosted SAP MCP plus local sap_payments config and auto-repairs stale runtime config.
158
+ */
159
+ export declare function resolveHostedPaymentBridgeContent(target: McpClientTarget, content: string, platform?: SupportedPlatform): HostedPaymentBridgeResolution;
141
160
  /**
142
161
  * @name buildCodexHostedPaymentBridgeContent
143
162
  * @description Builds Codex TOML with hosted SAP MCP plus a local sap_payments x402 bridge.
144
163
  */
145
- export declare function buildCodexHostedPaymentBridgeContent(content: string, hostedUrl?: string): {
164
+ export declare function buildCodexHostedPaymentBridgeContent(content: string, hostedUrl?: string, platform?: SupportedPlatform): {
146
165
  nextContent: string;
147
166
  hadSapConfig: boolean;
148
167
  };
@@ -150,12 +169,12 @@ export declare function buildCodexHostedPaymentBridgeContent(content: string, ho
150
169
  * @name installCodexHostedPaymentBridgeConfig
151
170
  * @description Writes Codex config.toml with hosted SAP MCP and the local x402 payment bridge.
152
171
  */
153
- export declare function installCodexHostedPaymentBridgeConfig(homeDir?: string): McpClientInjectionResult;
172
+ export declare function installCodexHostedPaymentBridgeConfig(homeDir?: string, platform?: SupportedPlatform): McpClientInjectionResult;
154
173
  /**
155
174
  * @name buildHostedPaymentBridgeContent
156
175
  * @description Builds runtime-specific config with hosted SAP MCP and local x402 bridge.
157
176
  */
158
- export declare function buildHostedPaymentBridgeContent(target: McpClientTarget, content: string): {
177
+ export declare function buildHostedPaymentBridgeContent(target: McpClientTarget, content: string, platform?: SupportedPlatform): {
159
178
  nextContent: string;
160
179
  hadSapConfig: boolean;
161
180
  };
@@ -163,7 +182,7 @@ export declare function buildHostedPaymentBridgeContent(target: McpClientTarget,
163
182
  * @name installHostedPaymentBridgeConfig
164
183
  * @description Installs or repairs hosted SAP MCP plus local x402 bridge config for a concrete runtime target.
165
184
  */
166
- export declare function installHostedPaymentBridgeConfig(target: McpClientTarget): McpClientInjectionResult;
185
+ export declare function installHostedPaymentBridgeConfig(target: McpClientTarget, platform?: SupportedPlatform): McpClientInjectionResult;
167
186
  /**
168
187
  * @name installHostedPaymentBridgeConfigs
169
188
  * @description Installs payment bridge configs for all selected runtime ids and detected/create-capable targets.
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-client-injection.d.ts","sourceRoot":"","sources":["../../src/config/mcp-client-injection.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,QAAQ,GAAG,UAAU,GAAG,OAAO,CAAC;AAErE;;;GAGG;AACH,MAAM,MAAM,qBAAqB,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAE7D;;;GAGG;AACH,MAAM,MAAM,sBAAsB,GAAG,OAAO,GAAG,UAAU,CAAC;AAE1D;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,WAAW,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,qBAAqB,CAAC;IAC9B,MAAM,EAAE,OAAO,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;GAGG;AACH,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC7B;AAED;;;GAGG;AACH,MAAM,WAAW,qBAAqB;IACpC,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,iBAAiB,CAAC;CAC9B;AAED;;;GAGG;AACH,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,eAAe,CAAC;IACxB,IAAI,EAAE,sBAAsB,CAAC;IAC7B,MAAM,EAAE,OAAO,CAAC;IAChB,YAAY,EAAE,OAAO,CAAC;IACtB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;GAGG;AACH,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,eAAe,CAAC;IACxB,IAAI,EAAE,sBAAsB,CAAC;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;GAGG;AACH,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;GAGG;AACH,MAAM,WAAW,2BAA2B;IAC1C,OAAO,EAAE,gBAAgB,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAGD,KAAK,iBAAiB,GAAG,MAAM,CAAC,QAAQ,CAAC;AAWzC;;;GAGG;AACH,eAAO,MAAM,kBAAkB,wCAAwC,CAAC;AA8DxE;;;GAGG;AACH,wBAAgB,2BAA2B,CAAC,aAAa,SAAgB,GAAG,wBAAwB,CAsBnG;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CACzC,SAAS,EAAE,wBAAwB,EACnC,SAAS,SAAqB,GAC7B,sBAAsB,EAAE,CAkE1B;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,IAAI,wBAAwB,CAerE;AAED;;;GAGG;AACH,wBAAgB,kCAAkC,IAAI,wBAAwB,CAgB7E;AAED;;;GAGG;AACH,wBAAgB,+BAA+B,IAAI,sBAAsB,EAAE,CAuH1E;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,SAAS,SAA2E,GACnF,2BAA2B,CAuD7B;AA+BD;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,SAAY,EAAE,QAAQ,GAAE,iBAAoC,GAAG,eAAe,EAAE,CAoD5H;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,SAAY,EAAE,QAAQ,GAAE,iBAAoC,GAAG,eAAe,EAAE,CAY/H;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAgB3D;AA8gBD;;;GAGG;AACH,wBAAgB,oCAAoC,CAClD,OAAO,EAAE,MAAM,EACf,SAAS,SAAqB,GAC7B;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,OAAO,CAAA;CAAE,CAiBhD;AAED;;;GAGG;AACH,wBAAgB,qCAAqC,CAAC,OAAO,SAAY,GAAG,wBAAwB,CA2BnG;AAED;;;GAGG;AACH,wBAAgB,+BAA+B,CAC7C,MAAM,EAAE,eAAe,EACvB,OAAO,EAAE,MAAM,GACd;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,OAAO,CAAA;CAAE,CAchD;AAED;;;GAGG;AACH,wBAAgB,gCAAgC,CAAC,MAAM,EAAE,eAAe,GAAG,wBAAwB,CA4BlG;AAED;;;GAGG;AACH,wBAAgB,iCAAiC,CAC/C,UAAU,EAAE,SAAS,WAAW,EAAE,EAClC,OAAO,SAAY,EACnB,QAAQ,GAAE,iBAAoC,GAC7C,wBAAwB,EAAE,CAM5B;AAoBD;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,eAAe,EACvB,SAAS,EAAE,wBAAwB,EACnC,IAAI,EAAE,sBAAsB,GAC3B,sBAAsB,CAwBxB;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,sBAAsB,GAAG,wBAAwB,CAuB9F"}
1
+ {"version":3,"file":"mcp-client-injection.d.ts","sourceRoot":"","sources":["../../src/config/mcp-client-injection.ts"],"names":[],"mappings":"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"}
@@ -1,15 +1,12 @@
1
1
  import { existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from 'fs';
2
2
  import { homedir } from 'os';
3
3
  import { dirname, join } from 'path';
4
+ import { MCP_SERVER_VERSION } from '../core/constants.js';
4
5
  const SAP_SERVER_NAME = 'sap';
5
6
  const SAP_PAYMENT_BRIDGE_SERVER_NAME = 'sap_payments';
6
7
  const X402_PAID_CALL_ADDON_ID = 'x402-paid-call';
7
8
  const X402_PAID_CALL_COMMAND = 'sap-mcp-x402-paid-call';
8
- const X402_PAYMENT_BRIDGE_TOOLS = [
9
- 'sap_x402_paid_call',
10
- 'sap_profile_current',
11
- 'sap_x402_estimate_cost',
12
- ];
9
+ const SAP_MCP_NPM_PACKAGE = `@oobe-protocol-labs/sap-mcp-server@${MCP_SERVER_VERSION}`;
13
10
  /**
14
11
  * @name HOSTED_SAP_MCP_URL
15
12
  * @description Public OOBE hosted SAP MCP Streamable HTTP endpoint used in manual client setup snippets.
@@ -24,6 +21,13 @@ const LEGACY_ENV_KEYS = new Set([
24
21
  'SAP_MCP_WALLET_PATH',
25
22
  'SAP_NETWORK',
26
23
  ]);
24
+ /**
25
+ * @name getNpxCommand
26
+ * @description Returns the platform-specific npx executable name used by MCP clients.
27
+ */
28
+ function getNpxCommand(platform) {
29
+ return platform === 'win32' ? 'npx.cmd' : 'npx';
30
+ }
27
31
  /**
28
32
  * @name isRecord
29
33
  * @description Narrows unknown data to a JSON-like object.
@@ -169,13 +173,20 @@ export function createManualMcpJsonSnippets(canonical, hostedUrl = HOSTED_SAP_MC
169
173
  * @description Builds a portable Codex stdio config that works without a source checkout.
170
174
  */
171
175
  export function createNpxCodexServerConfig() {
172
- const command = process.platform === 'win32' ? 'npx.cmd' : 'npx';
176
+ return createNpxCodexServerConfigForPlatform(process.platform);
177
+ }
178
+ /**
179
+ * @name createNpxCodexServerConfigForPlatform
180
+ * @description Builds a portable Codex stdio config for a specific host platform.
181
+ */
182
+ function createNpxCodexServerConfigForPlatform(platform) {
183
+ const command = getNpxCommand(platform);
173
184
  return {
174
185
  command,
175
186
  args: [
176
187
  '--yes',
177
188
  '--package',
178
- '@oobe-protocol-labs/sap-mcp-server',
189
+ SAP_MCP_NPM_PACKAGE,
179
190
  'sap-mcp-server',
180
191
  ],
181
192
  env: {
@@ -189,25 +200,33 @@ export function createNpxCodexServerConfig() {
189
200
  * @description Builds a portable local stdio MCP config that exposes only x402 payment helper tools.
190
201
  */
191
202
  export function createNpxPaymentBridgeServerConfig() {
192
- const command = process.platform === 'win32' ? 'npx.cmd' : 'npx';
203
+ return createNpxPaymentBridgeServerConfigForPlatform(process.platform);
204
+ }
205
+ /**
206
+ * @name createNpxPaymentBridgeServerConfigForPlatform
207
+ * @description Builds the local sap_payments bridge command for a specific host platform.
208
+ */
209
+ function createNpxPaymentBridgeServerConfigForPlatform(platform) {
210
+ const command = getNpxCommand(platform);
193
211
  return {
194
212
  command,
195
213
  args: [
196
214
  '--yes',
197
215
  '--package',
198
- '@oobe-protocol-labs/sap-mcp-server',
216
+ SAP_MCP_NPM_PACKAGE,
199
217
  'sap-mcp-server',
200
218
  ],
201
219
  env: {
202
220
  SAP_MCP_ALLOW_ENV_CONFIG_OVERRIDE: 'false',
203
- SAP_ALLOWED_TOOLS: X402_PAYMENT_BRIDGE_TOOLS.join(','),
221
+ SAP_MCP_PAYMENTS_BRIDGE_ONLY: 'true',
222
+ SAP_ALLOWED_TOOLS: 'all',
204
223
  SAP_LOG_LEVEL: 'info',
205
224
  },
206
225
  };
207
226
  }
208
227
  /**
209
228
  * @name createX402PaidCallAddonSnippets
210
- * @description Builds manual plugin/addon snippets for clients that can call a local x402 payment helper.
229
+ * @description Builds manual snippets for clients that can call the native local SAP MCP payment bridge.
211
230
  */
212
231
  export function createX402PaidCallAddonSnippets() {
213
232
  const paymentBridge = createNpxPaymentBridgeServerConfig();
@@ -219,12 +238,12 @@ export function createX402PaidCallAddonSnippets() {
219
238
  },
220
239
  {
221
240
  title: 'Claude Code Payment Bridge Commands',
222
- description: 'Use the official Claude Code MCP CLI flow: add hosted SAP MCP over HTTP, then add this local stdio bridge for x402 payment retries.',
241
+ description: 'Use the official Claude Code MCP CLI flow: add hosted SAP MCP over HTTP, then add this native local stdio bridge for x402 payment retries.',
223
242
  content: [
224
243
  `claude mcp add --transport http ${SAP_SERVER_NAME} ${HOSTED_SAP_MCP_URL}`,
225
244
  `claude mcp add --transport stdio ${SAP_PAYMENT_BRIDGE_SERVER_NAME} -- ${paymentBridge.command} ${paymentBridge.args.map(shellQuote).join(' ')}`,
226
245
  '',
227
- 'Then ask Claude to call sap_payments.sap_x402_paid_call for hosted paid/write SAP MCP tools.',
246
+ 'Then ask Claude to call sap_payments.sap_payments_call_paid_tool for hosted paid/write SAP MCP tools.',
228
247
  '',
229
248
  ].join('\n'),
230
249
  },
@@ -243,7 +262,7 @@ export function createX402PaidCallAddonSnippets() {
243
262
  },
244
263
  {
245
264
  title: 'Hermes Payment Bridge YAML',
246
- description: 'Use this inside Hermes profile config.yaml under mcp_servers when Hermes does not already have the x402 plugin installed.',
265
+ description: 'Use this inside Hermes profile config.yaml under mcp_servers when Hermes cannot natively replay hosted x402 challenges.',
247
266
  content: [
248
267
  'mcp_servers:',
249
268
  ` ${SAP_SERVER_NAME}:`,
@@ -287,8 +306,8 @@ export function createX402PaidCallAddonSnippets() {
287
306
  }),
288
307
  },
289
308
  {
290
- title: 'Hermes Addon: x402_paid_call',
291
- description: 'Use this concept for Hermes plugin/addon registries that expose local command-backed tools.',
309
+ title: 'Hermes Command Wrapper: x402_paid_call',
310
+ description: 'Legacy fallback for Hermes plugin/addon registries that expose local command-backed tools. Prefer the sap_payments MCP bridge when possible.',
292
311
  content: formatJson({
293
312
  plugins: {
294
313
  x402_paid_call: {
@@ -303,8 +322,8 @@ export function createX402PaidCallAddonSnippets() {
303
322
  }),
304
323
  },
305
324
  {
306
- title: 'Claude/Codex/OpenClaw Addon Command',
307
- description: 'Use this command from a local tool/plugin wrapper when the client supports command-backed addons.',
325
+ title: 'Claude/Codex/OpenClaw Command Fallback',
326
+ description: 'Use this command only from a custom local wrapper when the client cannot add the sap_payments MCP bridge.',
308
327
  content: [
309
328
  `${X402_PAID_CALL_COMMAND} \\`,
310
329
  ' --tool sap_list_all_agents \\',
@@ -316,9 +335,9 @@ export function createX402PaidCallAddonSnippets() {
316
335
  },
317
336
  {
318
337
  title: 'Local MCP Tool Alternative',
319
- description: 'When the local SAP MCP stdio server is installed, agents can call sap_x402_paid_call instead of using a runtime-specific plugin.',
338
+ description: 'When the local SAP MCP stdio bridge is installed, agents should call sap_payments_call_paid_tool. The sap_x402_paid_call alias is legacy.',
320
339
  content: formatJson({
321
- name: 'sap_x402_paid_call',
340
+ name: 'sap_payments_call_paid_tool',
322
341
  arguments: {
323
342
  toolName: 'sap_list_all_agents',
324
343
  arguments: { limit: 5 },
@@ -331,7 +350,7 @@ export function createX402PaidCallAddonSnippets() {
331
350
  }
332
351
  /**
333
352
  * @name installX402PaidCallAddon
334
- * @description Installs a portable local addon bundle with manifest and client snippets.
353
+ * @description Installs a portable local reference bundle with manifest and client snippets for bridge repair/custom clients.
335
354
  */
336
355
  export function installX402PaidCallAddon(targetDir = join(homedir(), '.config', 'mcp-sap', 'addons', X402_PAID_CALL_ADDON_ID)) {
337
356
  mkdirSync(targetDir, { recursive: true, mode: 0o700 });
@@ -341,11 +360,11 @@ export function installX402PaidCallAddon(targetDir = join(homedir(), '.config',
341
360
  const files = [manifestPath, readmePath, snippetsPath];
342
361
  writeFileSync(manifestPath, formatJson({
343
362
  id: X402_PAID_CALL_ADDON_ID,
344
- name: 'SAP MCP x402 Paid Call',
363
+ name: 'SAP MCP Local Payment Bridge',
345
364
  command: X402_PAID_CALL_COMMAND,
346
365
  toolName: 'x402_paid_call',
347
366
  localMcpToolName: 'sap_x402_paid_call',
348
- description: 'Local payment helper for hosted SAP MCP paid tools. It signs x402 payment payloads with the user-controlled SAP MCP profile signer.',
367
+ description: 'Native local SAP MCP payment bridge reference bundle for hosted paid tools. The sap_payments MCP server signs x402 payloads with the user-controlled SAP MCP profile signer.',
349
368
  security: {
350
369
  readsLocalKeypairFileForSigning: true,
351
370
  printsKeypairBytes: false,
@@ -355,17 +374,17 @@ export function installX402PaidCallAddon(targetDir = join(homedir(), '.config',
355
374
  },
356
375
  }), { encoding: 'utf-8', mode: 0o600 });
357
376
  writeFileSync(readmePath, [
358
- '# SAP MCP x402 Paid Call Addon',
377
+ '# SAP MCP Local Payment Bridge',
359
378
  '',
360
- 'This addon lets local agent runtimes pay hosted SAP MCP x402 tool challenges without giving OOBE or the hosted server user keypair bytes.',
379
+ 'This reference bundle documents the native local SAP MCP payment bridge for hosted x402 tool challenges. Runtime configs should prefer a local `sap_payments` MCP server exposing `sap_payments_call_paid_tool`.',
361
380
  '',
362
- 'Use the command directly from a runtime-specific plugin wrapper:',
381
+ 'Legacy command fallback for custom wrappers:',
363
382
  '',
364
383
  '```bash',
365
384
  `${X402_PAID_CALL_COMMAND} --tool sap_list_all_agents --arguments '{"limit":5}' --max-usd 0.02 --confirm`,
366
385
  '```',
367
386
  '',
368
- 'Or call the local SAP MCP tool `sap_x402_paid_call` when local stdio SAP MCP is available.',
387
+ 'Prefer calling the local SAP MCP tool `sap_payments_call_paid_tool` when the `sap_payments` MCP bridge is available. `sap_x402_paid_call` remains a backward-compatible alias.',
369
388
  '',
370
389
  'Security rules:',
371
390
  '',
@@ -565,10 +584,10 @@ function hostedJsonServerConfig(target) {
565
584
  * @name buildHostedPaymentBridgeJsonContent
566
585
  * @description Builds JSON config with hosted SAP MCP plus local x402 payment bridge.
567
586
  */
568
- function buildHostedPaymentBridgeJsonContent(content, target) {
587
+ function buildHostedPaymentBridgeJsonContent(content, target, platform) {
569
588
  const parsed = content.trim() ? JSON.parse(content) : {};
570
589
  const root = isRecord(parsed) ? parsed : {};
571
- const paymentBridge = createNpxPaymentBridgeServerConfig();
590
+ const paymentBridge = createNpxPaymentBridgeServerConfigForPlatform(platform);
572
591
  if (target.id === 'openclaw') {
573
592
  return buildOpenClawHostedPaymentBridgeJsonContent(root, paymentBridge);
574
593
  }
@@ -742,9 +761,9 @@ function replaceYamlSapBlock(content, canonical) {
742
761
  * @name replaceYamlHostedPaymentBridgeBlocks
743
762
  * @description Replaces or appends hosted SAP MCP plus local x402 bridge blocks under mcp_servers.
744
763
  */
745
- function replaceYamlHostedPaymentBridgeBlocks(content) {
764
+ function replaceYamlHostedPaymentBridgeBlocks(content, platform) {
746
765
  const lines = content.split(/\r?\n/);
747
- const paymentBridge = createNpxPaymentBridgeServerConfig();
766
+ const paymentBridge = createNpxPaymentBridgeServerConfigForPlatform(platform);
748
767
  const replacement = [
749
768
  ...yamlHostedServerBlock(SAP_SERVER_NAME, 2),
750
769
  ...yamlCommandServerBlock(SAP_PAYMENT_BRIDGE_SERVER_NAME, paymentBridge, 2),
@@ -786,9 +805,9 @@ function replaceYamlHostedPaymentBridgeBlocks(content) {
786
805
  * @name replaceOpenClawYamlHostedPaymentBridgeBlocks
787
806
  * @description Replaces or appends hosted SAP MCP plus local x402 bridge blocks under OpenClaw `mcp.servers`.
788
807
  */
789
- function replaceOpenClawYamlHostedPaymentBridgeBlocks(content) {
808
+ function replaceOpenClawYamlHostedPaymentBridgeBlocks(content, platform) {
790
809
  const lines = content.split(/\r?\n/);
791
- const paymentBridge = createNpxPaymentBridgeServerConfig();
810
+ const paymentBridge = createNpxPaymentBridgeServerConfigForPlatform(platform);
792
811
  const replacement = [
793
812
  ...yamlHostedServerBlock(SAP_SERVER_NAME, 4),
794
813
  ...yamlCommandServerBlock(SAP_PAYMENT_BRIDGE_SERVER_NAME, paymentBridge, 4),
@@ -869,12 +888,11 @@ function hostedTomlServerBlock(hosted) {
869
888
  */
870
889
  function codexPaymentBridgeTomlBlock(canonical) {
871
890
  const args = `[${canonical.args.map((arg) => JSON.stringify(arg)).join(', ')}]`;
872
- const enabledTools = `[${X402_PAYMENT_BRIDGE_TOOLS.map((tool) => JSON.stringify(tool)).join(', ')}]`;
873
891
  const lines = [
874
892
  `[mcp_servers.${SAP_PAYMENT_BRIDGE_SERVER_NAME}]`,
875
893
  `command = ${JSON.stringify(canonical.command)}`,
876
894
  `args = ${args}`,
877
- `enabled_tools = ${enabledTools}`,
895
+ 'startup_timeout_sec = 300',
878
896
  'tool_timeout_sec = 300',
879
897
  ];
880
898
  lines.push('');
@@ -884,6 +902,108 @@ function codexPaymentBridgeTomlBlock(canonical) {
884
902
  }
885
903
  return lines.join('\n');
886
904
  }
905
+ /**
906
+ * @name getCodexMcpServerSection
907
+ * @description Extracts a Codex MCP server section and nested env subsection for targeted validation.
908
+ */
909
+ function getCodexMcpServerSection(content, serverName) {
910
+ const lines = content.split(/\r?\n/);
911
+ const start = lines.findIndex((line) => line.trim() === `[mcp_servers.${serverName}]`);
912
+ if (start === -1) {
913
+ return '';
914
+ }
915
+ let end = start + 1;
916
+ while (end < lines.length) {
917
+ const line = lines[end]?.trim() ?? '';
918
+ if (line.startsWith('[mcp_servers.') && !line.startsWith(`[mcp_servers.${serverName}.`)) {
919
+ break;
920
+ }
921
+ if (line.startsWith('[') && !line.startsWith(`[mcp_servers.${serverName}.`)) {
922
+ break;
923
+ }
924
+ end += 1;
925
+ }
926
+ return lines.slice(start, end).join('\n');
927
+ }
928
+ /**
929
+ * @name validateHostedPaymentBridgeContent
930
+ * @description Verifies that a runtime config contains both hosted SAP MCP and the local sap_payments bridge.
931
+ */
932
+ export function validateHostedPaymentBridgeContent(target, content, platform = process.platform) {
933
+ const issues = [];
934
+ const expectedNpx = getNpxCommand(platform);
935
+ if (!content.includes(SAP_PAYMENT_BRIDGE_SERVER_NAME)) {
936
+ issues.push('Missing local sap_payments MCP bridge.');
937
+ }
938
+ if (!content.includes(HOSTED_SAP_MCP_URL)) {
939
+ issues.push(`Missing hosted SAP MCP URL ${HOSTED_SAP_MCP_URL}.`);
940
+ }
941
+ if (!content.includes('SAP_MCP_ALLOW_ENV_CONFIG_OVERRIDE')) {
942
+ issues.push('Missing SAP_MCP_ALLOW_ENV_CONFIG_OVERRIDE=false in local bridge env.');
943
+ }
944
+ const bridgeOnlyEnabled = content.includes('SAP_MCP_PAYMENTS_BRIDGE_ONLY = "true"')
945
+ || content.includes('"SAP_MCP_PAYMENTS_BRIDGE_ONLY": "true"')
946
+ || content.includes('SAP_MCP_PAYMENTS_BRIDGE_ONLY: "true"')
947
+ || content.includes('SAP_MCP_PAYMENTS_BRIDGE_ONLY: true');
948
+ if (!bridgeOnlyEnabled) {
949
+ issues.push('Missing SAP_MCP_PAYMENTS_BRIDGE_ONLY=true for the local payment bridge process.');
950
+ }
951
+ if (!content.includes('SAP_ALLOWED_TOOLS')) {
952
+ issues.push('Missing SAP_ALLOWED_TOOLS allow-list for the local payment bridge.');
953
+ }
954
+ if (!content.includes(SAP_MCP_NPM_PACKAGE)) {
955
+ issues.push(`Local sap_payments bridge must pin ${SAP_MCP_NPM_PACKAGE}; unpinned npx can download an older npm latest.`);
956
+ }
957
+ const allowsAllTools = content.includes('SAP_ALLOWED_TOOLS = "all"')
958
+ || content.includes('"SAP_ALLOWED_TOOLS": "all"')
959
+ || content.includes('SAP_ALLOWED_TOOLS: all')
960
+ || content.includes('SAP_ALLOWED_TOOLS: "all"');
961
+ if (!allowsAllTools) {
962
+ issues.push('SAP_ALLOWED_TOOLS must be all because the bridge process is already payments-only.');
963
+ }
964
+ if (target.id === 'codex') {
965
+ if (!content.includes(`[mcp_servers.${SAP_SERVER_NAME}]`)) {
966
+ issues.push('Missing Codex [mcp_servers.sap] hosted server block.');
967
+ }
968
+ if (!content.includes(`[mcp_servers.${SAP_PAYMENT_BRIDGE_SERVER_NAME}]`)) {
969
+ issues.push('Missing Codex [mcp_servers.sap_payments] local bridge block.');
970
+ }
971
+ if (!content.includes(`command = ${JSON.stringify(expectedNpx)}`)) {
972
+ issues.push(`Codex local bridge must use ${expectedNpx} on ${platform}.`);
973
+ }
974
+ if (!content.includes('startup_timeout_sec = 300')) {
975
+ issues.push('Codex local bridge must set startup_timeout_sec = 300 so first-run npx installs do not hide sap_payments.');
976
+ }
977
+ if (!content.includes('tool_timeout_sec = 300')) {
978
+ issues.push('Codex local bridge must set tool_timeout_sec = 300 for paid settlement retries.');
979
+ }
980
+ const codexSapSection = getCodexMcpServerSection(content, SAP_SERVER_NAME);
981
+ const codexPaymentBridgeSection = getCodexMcpServerSection(content, SAP_PAYMENT_BRIDGE_SERVER_NAME);
982
+ if (codexSapSection.includes('mcp-remote') || codexPaymentBridgeSection.includes('mcp-remote')) {
983
+ issues.push('Legacy mcp-remote wrapper remains; Codex should use native Streamable HTTP plus sap_payments.');
984
+ }
985
+ }
986
+ return Array.from(new Set(issues));
987
+ }
988
+ /**
989
+ * @name resolveHostedPaymentBridgeContent
990
+ * @description Builds hosted SAP MCP plus local sap_payments config and auto-repairs stale runtime config.
991
+ */
992
+ export function resolveHostedPaymentBridgeContent(target, content, platform = process.platform) {
993
+ const preExistingIssues = content.trim()
994
+ ? validateHostedPaymentBridgeContent(target, content, platform)
995
+ : [];
996
+ const built = buildHostedPaymentBridgeContent(target, content, platform);
997
+ const builtIssues = validateHostedPaymentBridgeContent(target, built.nextContent, platform);
998
+ if (builtIssues.length === 0) {
999
+ return {
1000
+ nextContent: built.nextContent,
1001
+ hadSapConfig: built.hadSapConfig,
1002
+ resolvedIssues: preExistingIssues,
1003
+ };
1004
+ }
1005
+ throw new Error(`${target.label} hosted payment bridge auto-resolver failed without writing changes: ${builtIssues.join(' ')}`);
1006
+ }
887
1007
  /**
888
1008
  * @name removeTomlSapSections
889
1009
  * @description Removes existing Codex SAP MCP TOML sections before appending the canonical one.
@@ -955,7 +1075,7 @@ function buildTomlContent(content, canonical) {
955
1075
  * @name buildCodexHostedPaymentBridgeContent
956
1076
  * @description Builds Codex TOML with hosted SAP MCP plus a local sap_payments x402 bridge.
957
1077
  */
958
- export function buildCodexHostedPaymentBridgeContent(content, hostedUrl = HOSTED_SAP_MCP_URL) {
1078
+ export function buildCodexHostedPaymentBridgeContent(content, hostedUrl = HOSTED_SAP_MCP_URL, platform = process.platform) {
959
1079
  const stripped = removeTomlMcpServerSections(content, [SAP_SERVER_NAME, SAP_PAYMENT_BRIDGE_SERVER_NAME]);
960
1080
  const hosted = {
961
1081
  url: hostedUrl,
@@ -965,7 +1085,7 @@ export function buildCodexHostedPaymentBridgeContent(content, hostedUrl = HOSTED
965
1085
  const nextContent = [
966
1086
  prefix,
967
1087
  hostedTomlServerBlock(hosted).trimEnd(),
968
- codexPaymentBridgeTomlBlock(createNpxPaymentBridgeServerConfig()).trimEnd(),
1088
+ codexPaymentBridgeTomlBlock(createNpxPaymentBridgeServerConfigForPlatform(platform)).trimEnd(),
969
1089
  ].filter(Boolean).join('\n\n');
970
1090
  return {
971
1091
  nextContent: `${nextContent}\n`,
@@ -976,7 +1096,7 @@ export function buildCodexHostedPaymentBridgeContent(content, hostedUrl = HOSTED
976
1096
  * @name installCodexHostedPaymentBridgeConfig
977
1097
  * @description Writes Codex config.toml with hosted SAP MCP and the local x402 payment bridge.
978
1098
  */
979
- export function installCodexHostedPaymentBridgeConfig(homeDir = homedir()) {
1099
+ export function installCodexHostedPaymentBridgeConfig(homeDir = homedir(), platform = process.platform) {
980
1100
  const target = {
981
1101
  id: 'codex',
982
1102
  label: 'Codex',
@@ -985,67 +1105,71 @@ export function installCodexHostedPaymentBridgeConfig(homeDir = homedir()) {
985
1105
  exists: existsSync(join(homeDir, '.codex', 'config.toml')),
986
1106
  };
987
1107
  const before = readTargetContent(target);
988
- const built = buildCodexHostedPaymentBridgeContent(before);
1108
+ const resolved = resolveHostedPaymentBridgeContent(target, before, platform);
989
1109
  const backupPath = target.exists ? `${target.path}.bak-${Date.now()}` : undefined;
990
1110
  mkdirSync(dirname(target.path), { recursive: true });
991
1111
  if (backupPath) {
992
1112
  writeFileSync(backupPath, before, 'utf-8');
993
1113
  }
994
- writeFileSync(target.path, built.nextContent, 'utf-8');
1114
+ writeFileSync(target.path, resolved.nextContent, 'utf-8');
995
1115
  return {
996
1116
  target,
997
- mode: built.hadSapConfig ? 'override' : 'merge',
1117
+ mode: resolved.hadSapConfig ? 'override' : 'merge',
998
1118
  written: true,
999
1119
  backupPath,
1000
- message: built.hadSapConfig
1001
- ? 'Updated Codex hosted SAP MCP and local x402 payment bridge config'
1002
- : 'Created Codex hosted SAP MCP and local x402 payment bridge config',
1120
+ message: resolved.resolvedIssues.length > 0
1121
+ ? `Auto-repaired Codex hosted SAP MCP and local x402 payment bridge config (${resolved.resolvedIssues.length} issue${resolved.resolvedIssues.length === 1 ? '' : 's'} fixed)`
1122
+ : resolved.hadSapConfig
1123
+ ? 'Updated Codex hosted SAP MCP and local x402 payment bridge config'
1124
+ : 'Created Codex hosted SAP MCP and local x402 payment bridge config',
1003
1125
  };
1004
1126
  }
1005
1127
  /**
1006
1128
  * @name buildHostedPaymentBridgeContent
1007
1129
  * @description Builds runtime-specific config with hosted SAP MCP and local x402 bridge.
1008
1130
  */
1009
- export function buildHostedPaymentBridgeContent(target, content) {
1131
+ export function buildHostedPaymentBridgeContent(target, content, platform = process.platform) {
1010
1132
  if (target.format === 'toml') {
1011
- return buildCodexHostedPaymentBridgeContent(content);
1133
+ return buildCodexHostedPaymentBridgeContent(content, HOSTED_SAP_MCP_URL, platform);
1012
1134
  }
1013
1135
  if (target.format === 'json') {
1014
- return buildHostedPaymentBridgeJsonContent(content, target);
1136
+ return buildHostedPaymentBridgeJsonContent(content, target, platform);
1015
1137
  }
1016
1138
  if (target.id === 'openclaw') {
1017
- return replaceOpenClawYamlHostedPaymentBridgeBlocks(content);
1139
+ return replaceOpenClawYamlHostedPaymentBridgeBlocks(content, platform);
1018
1140
  }
1019
- return replaceYamlHostedPaymentBridgeBlocks(content);
1141
+ return replaceYamlHostedPaymentBridgeBlocks(content, platform);
1020
1142
  }
1021
1143
  /**
1022
1144
  * @name installHostedPaymentBridgeConfig
1023
1145
  * @description Installs or repairs hosted SAP MCP plus local x402 bridge config for a concrete runtime target.
1024
1146
  */
1025
- export function installHostedPaymentBridgeConfig(target) {
1147
+ export function installHostedPaymentBridgeConfig(target, platform = process.platform) {
1026
1148
  if (target.id === 'codex') {
1027
- return installCodexHostedPaymentBridgeConfig(dirname(dirname(target.path)));
1149
+ return installCodexHostedPaymentBridgeConfig(dirname(dirname(target.path)), platform);
1028
1150
  }
1029
1151
  const currentTarget = {
1030
1152
  ...target,
1031
1153
  exists: existsSync(target.path),
1032
1154
  };
1033
1155
  const before = readTargetContent(currentTarget);
1034
- const built = buildHostedPaymentBridgeContent(currentTarget, before);
1156
+ const resolved = resolveHostedPaymentBridgeContent(currentTarget, before, platform);
1035
1157
  const backupPath = currentTarget.exists ? `${currentTarget.path}.bak-${Date.now()}` : undefined;
1036
1158
  mkdirSync(dirname(currentTarget.path), { recursive: true, mode: 0o700 });
1037
1159
  if (backupPath) {
1038
1160
  writeFileSync(backupPath, before, 'utf-8');
1039
1161
  }
1040
- writeFileSync(currentTarget.path, built.nextContent, { encoding: 'utf-8', mode: 0o600 });
1162
+ writeFileSync(currentTarget.path, resolved.nextContent, { encoding: 'utf-8', mode: 0o600 });
1041
1163
  return {
1042
1164
  target: currentTarget,
1043
- mode: built.hadSapConfig ? 'override' : 'merge',
1165
+ mode: resolved.hadSapConfig ? 'override' : 'merge',
1044
1166
  written: true,
1045
1167
  backupPath,
1046
- message: built.hadSapConfig
1047
- ? `Repaired hosted SAP MCP and local x402 payment bridge config in ${currentTarget.label}`
1048
- : `Installed hosted SAP MCP and local x402 payment bridge config in ${currentTarget.label}`,
1168
+ message: resolved.resolvedIssues.length > 0
1169
+ ? `Auto-repaired hosted SAP MCP and local x402 payment bridge config in ${currentTarget.label} (${resolved.resolvedIssues.length} issue${resolved.resolvedIssues.length === 1 ? '' : 's'} fixed)`
1170
+ : resolved.hadSapConfig
1171
+ ? `Repaired hosted SAP MCP and local x402 payment bridge config in ${currentTarget.label}`
1172
+ : `Installed hosted SAP MCP and local x402 payment bridge config in ${currentTarget.label}`,
1049
1173
  };
1050
1174
  }
1051
1175
  /**
@@ -1056,7 +1180,7 @@ export function installHostedPaymentBridgeConfigs(runtimeIds, homeDir = homedir(
1056
1180
  const selected = new Set(runtimeIds);
1057
1181
  const targets = discoverMcpClientTargets(homeDir, platform)
1058
1182
  .filter((target) => selected.has(target.id));
1059
- return targets.map((target) => installHostedPaymentBridgeConfig(target));
1183
+ return targets.map((target) => installHostedPaymentBridgeConfig(target, platform));
1060
1184
  }
1061
1185
  /**
1062
1186
  * @name summarizeContent