@scriptmasterlabs/mcp-x402 2.0.2 → 2.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (323) hide show
  1. package/.well-known/x402.json +37 -0
  2. package/LICENSE +57 -21
  3. package/README.md +262 -304
  4. package/dist/index.d.ts +12 -0
  5. package/dist/index.d.ts.map +1 -0
  6. package/dist/index.js +9 -0
  7. package/dist/index.js.map +1 -0
  8. package/dist/mcp-wrapper.d.ts +71 -0
  9. package/dist/mcp-wrapper.d.ts.map +1 -0
  10. package/dist/mcp-wrapper.js +104 -0
  11. package/dist/mcp-wrapper.js.map +1 -0
  12. package/dist/x402-middleware.d.ts +76 -0
  13. package/dist/x402-middleware.d.ts.map +1 -0
  14. package/dist/x402-middleware.js +113 -0
  15. package/dist/x402-middleware.js.map +1 -0
  16. package/dist/xrpl-facilitator.d.ts +77 -0
  17. package/dist/xrpl-facilitator.d.ts.map +1 -0
  18. package/dist/xrpl-facilitator.js +156 -0
  19. package/dist/xrpl-facilitator.js.map +1 -0
  20. package/llms.txt +108 -70
  21. package/package.json +65 -78
  22. package/schema.jsonld +97 -0
  23. package/.env.example +0 -35
  24. package/.github/workflows/ci.yml +0 -59
  25. package/.github/workflows/keepalive.yml +0 -31
  26. package/.well-known/agentcard.json +0 -34
  27. package/CONTRIBUTING.md +0 -76
  28. package/Dockerfile +0 -19
  29. package/agents.json +0 -67
  30. package/dist/lib/chains/base.d.ts +0 -10
  31. package/dist/lib/chains/base.d.ts.map +0 -1
  32. package/dist/lib/chains/base.js +0 -73
  33. package/dist/lib/chains/base.js.map +0 -1
  34. package/dist/lib/chains/solana.d.ts +0 -10
  35. package/dist/lib/chains/solana.d.ts.map +0 -1
  36. package/dist/lib/chains/solana.js +0 -49
  37. package/dist/lib/chains/solana.js.map +0 -1
  38. package/dist/lib/chains/xrpl.d.ts +0 -10
  39. package/dist/lib/chains/xrpl.d.ts.map +0 -1
  40. package/dist/lib/chains/xrpl.js +0 -55
  41. package/dist/lib/chains/xrpl.js.map +0 -1
  42. package/dist/lib/credit/bureau.d.ts +0 -10
  43. package/dist/lib/credit/bureau.d.ts.map +0 -1
  44. package/dist/lib/credit/bureau.js +0 -58
  45. package/dist/lib/credit/bureau.js.map +0 -1
  46. package/dist/lib/sml-api/agentcard.d.ts +0 -17
  47. package/dist/lib/sml-api/agentcard.d.ts.map +0 -1
  48. package/dist/lib/sml-api/agentcard.js +0 -30
  49. package/dist/lib/sml-api/agentcard.js.map +0 -1
  50. package/dist/lib/sml-api/backtest.d.ts +0 -22
  51. package/dist/lib/sml-api/backtest.d.ts.map +0 -1
  52. package/dist/lib/sml-api/backtest.js +0 -28
  53. package/dist/lib/sml-api/backtest.js.map +0 -1
  54. package/dist/lib/sml-api/brokers.d.ts +0 -40
  55. package/dist/lib/sml-api/brokers.d.ts.map +0 -1
  56. package/dist/lib/sml-api/brokers.js +0 -128
  57. package/dist/lib/sml-api/brokers.js.map +0 -1
  58. package/dist/lib/sml-api/copytrader.d.ts +0 -11
  59. package/dist/lib/sml-api/copytrader.d.ts.map +0 -1
  60. package/dist/lib/sml-api/copytrader.js +0 -30
  61. package/dist/lib/sml-api/copytrader.js.map +0 -1
  62. package/dist/lib/sml-api/crawl.d.ts +0 -20
  63. package/dist/lib/sml-api/crawl.d.ts.map +0 -1
  64. package/dist/lib/sml-api/crawl.js +0 -32
  65. package/dist/lib/sml-api/crawl.js.map +0 -1
  66. package/dist/lib/sml-api/echo.d.ts +0 -10
  67. package/dist/lib/sml-api/echo.d.ts.map +0 -1
  68. package/dist/lib/sml-api/echo.js +0 -23
  69. package/dist/lib/sml-api/echo.js.map +0 -1
  70. package/dist/lib/sml-api/forge.d.ts +0 -11
  71. package/dist/lib/sml-api/forge.d.ts.map +0 -1
  72. package/dist/lib/sml-api/forge.js +0 -29
  73. package/dist/lib/sml-api/forge.js.map +0 -1
  74. package/dist/lib/sml-api/ftd.d.ts +0 -18
  75. package/dist/lib/sml-api/ftd.d.ts.map +0 -1
  76. package/dist/lib/sml-api/ftd.js +0 -43
  77. package/dist/lib/sml-api/ftd.js.map +0 -1
  78. package/dist/lib/sml-api/ghost.d.ts +0 -13
  79. package/dist/lib/sml-api/ghost.d.ts.map +0 -1
  80. package/dist/lib/sml-api/ghost.js +0 -29
  81. package/dist/lib/sml-api/ghost.js.map +0 -1
  82. package/dist/lib/sml-api/launchpad.d.ts +0 -20
  83. package/dist/lib/sml-api/launchpad.d.ts.map +0 -1
  84. package/dist/lib/sml-api/launchpad.js +0 -31
  85. package/dist/lib/sml-api/launchpad.js.map +0 -1
  86. package/dist/lib/sml-api/leviathan.d.ts +0 -22
  87. package/dist/lib/sml-api/leviathan.d.ts.map +0 -1
  88. package/dist/lib/sml-api/leviathan.js +0 -33
  89. package/dist/lib/sml-api/leviathan.js.map +0 -1
  90. package/dist/lib/sml-api/nexus.d.ts +0 -18
  91. package/dist/lib/sml-api/nexus.d.ts.map +0 -1
  92. package/dist/lib/sml-api/nexus.js +0 -40
  93. package/dist/lib/sml-api/nexus.js.map +0 -1
  94. package/dist/lib/sml-api/proof402.d.ts +0 -6
  95. package/dist/lib/sml-api/proof402.d.ts.map +0 -1
  96. package/dist/lib/sml-api/proof402.js +0 -30
  97. package/dist/lib/sml-api/proof402.js.map +0 -1
  98. package/dist/lib/sml-api/rails.d.ts +0 -12
  99. package/dist/lib/sml-api/rails.d.ts.map +0 -1
  100. package/dist/lib/sml-api/rails.js +0 -29
  101. package/dist/lib/sml-api/rails.js.map +0 -1
  102. package/dist/lib/sml-api/shadow.d.ts +0 -15
  103. package/dist/lib/sml-api/shadow.d.ts.map +0 -1
  104. package/dist/lib/sml-api/shadow.js +0 -27
  105. package/dist/lib/sml-api/shadow.js.map +0 -1
  106. package/dist/lib/sml-api/squeezeos.d.ts +0 -21
  107. package/dist/lib/sml-api/squeezeos.d.ts.map +0 -1
  108. package/dist/lib/sml-api/squeezeos.js +0 -97
  109. package/dist/lib/sml-api/squeezeos.js.map +0 -1
  110. package/dist/lib/sml-api/xdeo.d.ts +0 -13
  111. package/dist/lib/sml-api/xdeo.d.ts.map +0 -1
  112. package/dist/lib/sml-api/xdeo.js +0 -34
  113. package/dist/lib/sml-api/xdeo.js.map +0 -1
  114. package/dist/lib/sml-api/xmit.d.ts +0 -13
  115. package/dist/lib/sml-api/xmit.d.ts.map +0 -1
  116. package/dist/lib/sml-api/xmit.js +0 -34
  117. package/dist/lib/sml-api/xmit.js.map +0 -1
  118. package/dist/server/health.d.ts +0 -16
  119. package/dist/server/health.d.ts.map +0 -1
  120. package/dist/server/health.js +0 -39
  121. package/dist/server/health.js.map +0 -1
  122. package/dist/server/index.d.ts +0 -3
  123. package/dist/server/index.d.ts.map +0 -1
  124. package/dist/server/index.js +0 -199
  125. package/dist/server/index.js.map +0 -1
  126. package/dist/server/payments/ap2.d.ts +0 -17
  127. package/dist/server/payments/ap2.d.ts.map +0 -1
  128. package/dist/server/payments/ap2.js +0 -77
  129. package/dist/server/payments/ap2.js.map +0 -1
  130. package/dist/server/payments/receipt.d.ts +0 -28
  131. package/dist/server/payments/receipt.d.ts.map +0 -1
  132. package/dist/server/payments/receipt.js +0 -60
  133. package/dist/server/payments/receipt.js.map +0 -1
  134. package/dist/server/payments/router.d.ts +0 -23
  135. package/dist/server/payments/router.d.ts.map +0 -1
  136. package/dist/server/payments/router.js +0 -69
  137. package/dist/server/payments/router.js.map +0 -1
  138. package/dist/server/payments/wallet.d.ts +0 -18
  139. package/dist/server/payments/wallet.d.ts.map +0 -1
  140. package/dist/server/payments/wallet.js +0 -107
  141. package/dist/server/payments/wallet.js.map +0 -1
  142. package/dist/server/payments/x402.d.ts +0 -29
  143. package/dist/server/payments/x402.d.ts.map +0 -1
  144. package/dist/server/payments/x402.js +0 -138
  145. package/dist/server/payments/x402.js.map +0 -1
  146. package/dist/server/registry/catalog.d.ts +0 -12
  147. package/dist/server/registry/catalog.d.ts.map +0 -1
  148. package/dist/server/registry/catalog.js +0 -55
  149. package/dist/server/registry/catalog.js.map +0 -1
  150. package/dist/server/registry/discovery.d.ts +0 -16
  151. package/dist/server/registry/discovery.d.ts.map +0 -1
  152. package/dist/server/registry/discovery.js +0 -33
  153. package/dist/server/registry/discovery.js.map +0 -1
  154. package/dist/server/registry/pricing.d.ts +0 -10
  155. package/dist/server/registry/pricing.d.ts.map +0 -1
  156. package/dist/server/registry/pricing.js +0 -123
  157. package/dist/server/registry/pricing.js.map +0 -1
  158. package/dist/server/security/acl.d.ts +0 -28
  159. package/dist/server/security/acl.d.ts.map +0 -1
  160. package/dist/server/security/acl.js +0 -36
  161. package/dist/server/security/acl.js.map +0 -1
  162. package/dist/server/security/audit.d.ts +0 -15
  163. package/dist/server/security/audit.d.ts.map +0 -1
  164. package/dist/server/security/audit.js +0 -77
  165. package/dist/server/security/audit.js.map +0 -1
  166. package/dist/server/security/rate-limit.d.ts +0 -12
  167. package/dist/server/security/rate-limit.d.ts.map +0 -1
  168. package/dist/server/security/rate-limit.js +0 -72
  169. package/dist/server/security/rate-limit.js.map +0 -1
  170. package/dist/server/security/sandbox.d.ts +0 -7
  171. package/dist/server/security/sandbox.d.ts.map +0 -1
  172. package/dist/server/security/sandbox.js +0 -42
  173. package/dist/server/security/sandbox.js.map +0 -1
  174. package/dist/server/tools/agentcard.d.ts +0 -3
  175. package/dist/server/tools/agentcard.d.ts.map +0 -1
  176. package/dist/server/tools/agentcard.js +0 -118
  177. package/dist/server/tools/agentcard.js.map +0 -1
  178. package/dist/server/tools/backtest.d.ts +0 -3
  179. package/dist/server/tools/backtest.d.ts.map +0 -1
  180. package/dist/server/tools/backtest.js +0 -112
  181. package/dist/server/tools/backtest.js.map +0 -1
  182. package/dist/server/tools/brokers.d.ts +0 -3
  183. package/dist/server/tools/brokers.d.ts.map +0 -1
  184. package/dist/server/tools/brokers.js +0 -223
  185. package/dist/server/tools/brokers.js.map +0 -1
  186. package/dist/server/tools/copytrader.d.ts +0 -3
  187. package/dist/server/tools/copytrader.d.ts.map +0 -1
  188. package/dist/server/tools/copytrader.js +0 -90
  189. package/dist/server/tools/copytrader.js.map +0 -1
  190. package/dist/server/tools/crawl.d.ts +0 -3
  191. package/dist/server/tools/crawl.d.ts.map +0 -1
  192. package/dist/server/tools/crawl.js +0 -60
  193. package/dist/server/tools/crawl.js.map +0 -1
  194. package/dist/server/tools/discovery.d.ts +0 -3
  195. package/dist/server/tools/discovery.d.ts.map +0 -1
  196. package/dist/server/tools/discovery.js +0 -188
  197. package/dist/server/tools/discovery.js.map +0 -1
  198. package/dist/server/tools/echo.d.ts +0 -3
  199. package/dist/server/tools/echo.d.ts.map +0 -1
  200. package/dist/server/tools/echo.js +0 -48
  201. package/dist/server/tools/echo.js.map +0 -1
  202. package/dist/server/tools/forge.d.ts +0 -3
  203. package/dist/server/tools/forge.d.ts.map +0 -1
  204. package/dist/server/tools/forge.js +0 -77
  205. package/dist/server/tools/forge.js.map +0 -1
  206. package/dist/server/tools/ftd.d.ts +0 -3
  207. package/dist/server/tools/ftd.d.ts.map +0 -1
  208. package/dist/server/tools/ftd.js +0 -70
  209. package/dist/server/tools/ftd.js.map +0 -1
  210. package/dist/server/tools/ghost.d.ts +0 -3
  211. package/dist/server/tools/ghost.d.ts.map +0 -1
  212. package/dist/server/tools/ghost.js +0 -83
  213. package/dist/server/tools/ghost.js.map +0 -1
  214. package/dist/server/tools/index.d.ts +0 -3
  215. package/dist/server/tools/index.d.ts.map +0 -1
  216. package/dist/server/tools/index.js +0 -44
  217. package/dist/server/tools/index.js.map +0 -1
  218. package/dist/server/tools/launchpad.d.ts +0 -3
  219. package/dist/server/tools/launchpad.d.ts.map +0 -1
  220. package/dist/server/tools/launchpad.js +0 -151
  221. package/dist/server/tools/launchpad.js.map +0 -1
  222. package/dist/server/tools/leviathan.d.ts +0 -3
  223. package/dist/server/tools/leviathan.d.ts.map +0 -1
  224. package/dist/server/tools/leviathan.js +0 -73
  225. package/dist/server/tools/leviathan.js.map +0 -1
  226. package/dist/server/tools/nexus.d.ts +0 -3
  227. package/dist/server/tools/nexus.d.ts.map +0 -1
  228. package/dist/server/tools/nexus.js +0 -65
  229. package/dist/server/tools/nexus.js.map +0 -1
  230. package/dist/server/tools/proof402.d.ts +0 -3
  231. package/dist/server/tools/proof402.d.ts.map +0 -1
  232. package/dist/server/tools/proof402.js +0 -74
  233. package/dist/server/tools/proof402.js.map +0 -1
  234. package/dist/server/tools/rails.d.ts +0 -3
  235. package/dist/server/tools/rails.d.ts.map +0 -1
  236. package/dist/server/tools/rails.js +0 -82
  237. package/dist/server/tools/rails.js.map +0 -1
  238. package/dist/server/tools/shadow.d.ts +0 -3
  239. package/dist/server/tools/shadow.d.ts.map +0 -1
  240. package/dist/server/tools/shadow.js +0 -114
  241. package/dist/server/tools/shadow.js.map +0 -1
  242. package/dist/server/tools/squeezeos.d.ts +0 -3
  243. package/dist/server/tools/squeezeos.d.ts.map +0 -1
  244. package/dist/server/tools/squeezeos.js +0 -231
  245. package/dist/server/tools/squeezeos.js.map +0 -1
  246. package/dist/server/tools/xdeo.d.ts +0 -3
  247. package/dist/server/tools/xdeo.d.ts.map +0 -1
  248. package/dist/server/tools/xdeo.js +0 -58
  249. package/dist/server/tools/xdeo.js.map +0 -1
  250. package/dist/server/tools/xmit.d.ts +0 -3
  251. package/dist/server/tools/xmit.d.ts.map +0 -1
  252. package/dist/server/tools/xmit.js +0 -59
  253. package/dist/server/tools/xmit.js.map +0 -1
  254. package/docker-compose.yml +0 -50
  255. package/mcp-publisher.exe +0 -0
  256. package/render.yaml +0 -39
  257. package/sdk/mcp-x402-sdk/package.json +0 -18
  258. package/sdk/mcp-x402-sdk/src/index.ts +0 -118
  259. package/sdk/mcp-x402-sdk/tsconfig.json +0 -14
  260. package/server.json +0 -48
  261. package/services/backtest_service.py +0 -176
  262. package/src/lib/chains/base.ts +0 -77
  263. package/src/lib/chains/solana.ts +0 -59
  264. package/src/lib/chains/xrpl.ts +0 -63
  265. package/src/lib/credit/bureau.ts +0 -65
  266. package/src/lib/sml-api/agentcard.ts +0 -40
  267. package/src/lib/sml-api/backtest.ts +0 -47
  268. package/src/lib/sml-api/brokers.ts +0 -160
  269. package/src/lib/sml-api/copytrader.ts +0 -33
  270. package/src/lib/sml-api/crawl.ts +0 -44
  271. package/src/lib/sml-api/echo.ts +0 -28
  272. package/src/lib/sml-api/forge.ts +0 -33
  273. package/src/lib/sml-api/ftd.ts +0 -53
  274. package/src/lib/sml-api/ghost.ts +0 -35
  275. package/src/lib/sml-api/launchpad.ts +0 -43
  276. package/src/lib/sml-api/leviathan.ts +0 -49
  277. package/src/lib/sml-api/nexus.ts +0 -50
  278. package/src/lib/sml-api/proof402.ts +0 -27
  279. package/src/lib/sml-api/rails.ts +0 -34
  280. package/src/lib/sml-api/shadow.ts +0 -35
  281. package/src/lib/sml-api/squeezeos.ts +0 -95
  282. package/src/lib/sml-api/xdeo.ts +0 -40
  283. package/src/lib/sml-api/xmit.ts +0 -40
  284. package/src/server/health.ts +0 -52
  285. package/src/server/index.ts +0 -213
  286. package/src/server/payments/ap2.ts +0 -101
  287. package/src/server/payments/receipt.ts +0 -85
  288. package/src/server/payments/router.ts +0 -110
  289. package/src/server/payments/wallet.ts +0 -123
  290. package/src/server/payments/x402.ts +0 -177
  291. package/src/server/registry/catalog.ts +0 -61
  292. package/src/server/registry/discovery.ts +0 -39
  293. package/src/server/registry/pricing.ts +0 -133
  294. package/src/server/security/acl.ts +0 -42
  295. package/src/server/security/audit.ts +0 -94
  296. package/src/server/security/rate-limit.ts +0 -84
  297. package/src/server/security/sandbox.ts +0 -40
  298. package/src/server/tools/agentcard.ts +0 -134
  299. package/src/server/tools/backtest.ts +0 -119
  300. package/src/server/tools/brokers.ts +0 -250
  301. package/src/server/tools/copytrader.ts +0 -104
  302. package/src/server/tools/crawl.ts +0 -70
  303. package/src/server/tools/discovery.ts +0 -202
  304. package/src/server/tools/echo.ts +0 -58
  305. package/src/server/tools/forge.ts +0 -87
  306. package/src/server/tools/ftd.ts +0 -88
  307. package/src/server/tools/ghost.ts +0 -93
  308. package/src/server/tools/index.ts +0 -42
  309. package/src/server/tools/launchpad.ts +0 -173
  310. package/src/server/tools/leviathan.ts +0 -81
  311. package/src/server/tools/nexus.ts +0 -76
  312. package/src/server/tools/proof402.ts +0 -87
  313. package/src/server/tools/rails.ts +0 -92
  314. package/src/server/tools/shadow.ts +0 -128
  315. package/src/server/tools/squeezeos.ts +0 -312
  316. package/src/server/tools/xdeo.ts +0 -67
  317. package/src/server/tools/xmit.ts +0 -68
  318. package/tests/integration/e2e.test.ts +0 -51
  319. package/tests/unit/payments.test.ts +0 -49
  320. package/tests/unit/security.test.ts +0 -92
  321. package/tests/unit/tools.test.ts +0 -42
  322. package/tsconfig.json +0 -21
  323. package/vitest.config.ts +0 -20
@@ -1,94 +0,0 @@
1
- import { createHash, createHmac } from 'crypto';
2
- import { appendFileSync } from 'fs';
3
-
4
- type LogLevel = 'info' | 'warn' | 'error';
5
-
6
- interface LogEntry {
7
- seq: number;
8
- ts: number;
9
- level: LogLevel;
10
- event: string;
11
- data: Record<string, unknown>;
12
- prev_hash: string;
13
- hash: string;
14
- }
15
-
16
- // Append-only SHA-256 chained audit log (N5)
17
- // Each entry includes the hash of the previous entry — tampering breaks the chain.
18
- export class AuditLogger {
19
- private static instance: AuditLogger;
20
- private seq = 0;
21
- private prevHash = '0000000000000000000000000000000000000000000000000000000000000000';
22
- private readonly logPath: string;
23
- private readonly hmacSecret: string;
24
-
25
- private constructor() {
26
- this.logPath = process.env['AUDIT_LOG_PATH'] ?? './audit.log';
27
- this.hmacSecret = process.env['AUDIT_HMAC_SECRET'] ?? 'mcp-x402-audit-secret';
28
- }
29
-
30
- static getInstance(): AuditLogger {
31
- if (!AuditLogger.instance) {
32
- AuditLogger.instance = new AuditLogger();
33
- }
34
- return AuditLogger.instance;
35
- }
36
-
37
- private log(level: LogLevel, event: string, data: Record<string, unknown>): void {
38
- const seq = ++this.seq;
39
- const ts = Date.now();
40
-
41
- // Redact PII (N3): hash wallet addresses, never log raw filing content
42
- const safeData = this.redact(data);
43
-
44
- const payload = JSON.stringify({ seq, ts, level, event, data: safeData, prev_hash: this.prevHash });
45
- const hash = createHmac('sha256', this.hmacSecret).update(payload).digest('hex');
46
-
47
- const entry: LogEntry = {
48
- seq,
49
- ts,
50
- level,
51
- event,
52
- data: safeData,
53
- prev_hash: this.prevHash,
54
- hash,
55
- };
56
-
57
- this.prevHash = hash;
58
-
59
- try {
60
- appendFileSync(this.logPath, JSON.stringify(entry) + '\n', 'utf8');
61
- } catch {
62
- // If log write fails, emit to stderr but don't crash
63
- process.stderr.write(`[audit-fail] ${JSON.stringify(entry)}\n`);
64
- }
65
- }
66
-
67
- private redact(data: Record<string, unknown>): Record<string, unknown> {
68
- const out: Record<string, unknown> = {};
69
- for (const [k, v] of Object.entries(data)) {
70
- if (k === 'wallet' || k === 'address') {
71
- // Hash wallet addresses (N3)
72
- out[k] = createHash('sha256').update(String(v)).digest('hex').slice(0, 16) + '...';
73
- } else if (k === 'content' || k === 'raw_text' || k === 'filing') {
74
- // Never log raw filing data (N3)
75
- out[k] = '[REDACTED]';
76
- } else {
77
- out[k] = v;
78
- }
79
- }
80
- return out;
81
- }
82
-
83
- info(event: string, data: Record<string, unknown> = {}): void {
84
- this.log('info', event, data);
85
- }
86
-
87
- warn(event: string, data: Record<string, unknown> = {}): void {
88
- this.log('warn', event, data);
89
- }
90
-
91
- error(event: string, data: Record<string, unknown> = {}): void {
92
- this.log('error', event, data);
93
- }
94
- }
@@ -1,84 +0,0 @@
1
- interface BucketState {
2
- minute: { count: number; resetAt: number };
3
- day: { count: number; resetAt: number };
4
- }
5
-
6
- const PER_TOOL_MINUTE_LIMIT = 100;
7
- const PER_WALLET_DAY_LIMIT = 1000;
8
- const IP_MINUTE_LIMIT = 200;
9
-
10
- function nowMs(): number {
11
- return Date.now();
12
- }
13
-
14
- export class RateLimiter {
15
- private static instance: RateLimiter;
16
- private readonly toolBuckets = new Map<string, BucketState>();
17
- private readonly walletBuckets = new Map<string, BucketState>();
18
- private readonly ipBuckets = new Map<string, { count: number; resetAt: number }>();
19
-
20
- private constructor() {}
21
-
22
- static getInstance(): RateLimiter {
23
- if (!RateLimiter.instance) {
24
- RateLimiter.instance = new RateLimiter();
25
- }
26
- return RateLimiter.instance;
27
- }
28
-
29
- checkTool(toolName: string): boolean {
30
- const now = nowMs();
31
- let bucket = this.toolBuckets.get(toolName);
32
-
33
- if (!bucket) {
34
- bucket = {
35
- minute: { count: 0, resetAt: now + 60_000 },
36
- day: { count: 0, resetAt: now + 86_400_000 },
37
- };
38
- this.toolBuckets.set(toolName, bucket);
39
- }
40
-
41
- if (now > bucket.minute.resetAt) {
42
- bucket.minute = { count: 0, resetAt: now + 60_000 };
43
- }
44
-
45
- if (bucket.minute.count >= PER_TOOL_MINUTE_LIMIT) return false;
46
- bucket.minute.count++;
47
- return true;
48
- }
49
-
50
- checkWallet(wallet: string): boolean {
51
- const now = nowMs();
52
- let bucket = this.walletBuckets.get(wallet);
53
-
54
- if (!bucket) {
55
- bucket = {
56
- minute: { count: 0, resetAt: now + 60_000 },
57
- day: { count: 0, resetAt: now + 86_400_000 },
58
- };
59
- this.walletBuckets.set(wallet, bucket);
60
- }
61
-
62
- if (now > bucket.day.resetAt) {
63
- bucket.day = { count: 0, resetAt: now + 86_400_000 };
64
- }
65
-
66
- if (bucket.day.count >= PER_WALLET_DAY_LIMIT) return false;
67
- bucket.day.count++;
68
- return true;
69
- }
70
-
71
- checkIp(ip: string): boolean {
72
- const now = nowMs();
73
- let entry = this.ipBuckets.get(ip);
74
-
75
- if (!entry || now > entry.resetAt) {
76
- entry = { count: 0, resetAt: now + 60_000 };
77
- this.ipBuckets.set(ip, entry);
78
- }
79
-
80
- if (entry.count >= IP_MINUTE_LIMIT) return false;
81
- entry.count++;
82
- return true;
83
- }
84
- }
@@ -1,40 +0,0 @@
1
- import { z } from 'zod';
2
-
3
- // Sandboxed input validation layer — all tool inputs pass through here before execution.
4
- // No eval(), no dynamic require(), no raw SQL (N4 enforcement at schema layer).
5
- export class Sandbox {
6
- static validate<T>(schema: z.ZodType<T>, input: unknown): T {
7
- const result = schema.safeParse(input);
8
- if (!result.success) {
9
- const issues = result.error.issues
10
- .map((i) => `${i.path.join('.')}: ${i.message}`)
11
- .join('; ');
12
- throw new Error(`Input validation failed: ${issues}`);
13
- }
14
- return result.data;
15
- }
16
-
17
- // Ensure URL is http/https only — no file://, data://, javascript:
18
- static validateUrl(raw: string): URL {
19
- let url: URL;
20
- try {
21
- url = new URL(raw);
22
- } catch {
23
- throw new Error(`Invalid URL: ${raw}`);
24
- }
25
- if (url.protocol !== 'http:' && url.protocol !== 'https:') {
26
- throw new Error(`Disallowed URL protocol: ${url.protocol}`);
27
- }
28
- return url;
29
- }
30
-
31
- // Strip any response content that looks like a prompt injection attempt
32
- static sanitizeApiResponse(text: string): string {
33
- // Remove common injection markers
34
- return text
35
- .replace(/<\/?system>/gi, '')
36
- .replace(/\[INST\]/gi, '')
37
- .replace(/\[\/?INST\]/gi, '')
38
- .slice(0, 50_000); // Hard cap on returned content size
39
- }
40
- }
@@ -1,134 +0,0 @@
1
- import { z } from 'zod';
2
- import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
3
- import { executeX402Payment } from '../payments/x402.js';
4
- import { RateLimiter } from '../security/rate-limit.js';
5
- import { Sandbox } from '../security/sandbox.js';
6
- import { AuditLogger } from '../security/audit.js';
7
- import { PriceRegistry } from '../registry/pricing.js';
8
- import { AgentCardAPI } from '../../lib/sml-api/agentcard.js';
9
-
10
- const LookupSchema = z.object({
11
- identifier: z.string().min(1),
12
- });
13
-
14
- const VerifySchema = z.object({
15
- wallet_address: z.string().min(10),
16
- message: z.string().min(1),
17
- signature: z.string().min(1),
18
- });
19
-
20
- const MintSchema = z.object({
21
- wallet_address: z.string().min(10),
22
- name: z.string().min(1).max(64),
23
- did: z.string().optional(),
24
- metadata: z.record(z.unknown()).optional(),
25
- payment_wallet: z.string().optional(),
26
- });
27
-
28
- export function registerAgentCard(server: McpServer): void {
29
- const audit = AuditLogger.getInstance();
30
-
31
- // ── FREE: agentcard_lookup ─────────────────────────────────────────────────
32
- server.tool(
33
- 'agentcard_lookup',
34
- {
35
- identifier: z.string().describe('Agent wallet address or DID to look up.'),
36
- },
37
- async (rawArgs) => {
38
- const { identifier } = Sandbox.validate(LookupSchema, rawArgs);
39
- if (!RateLimiter.getInstance().checkTool('agentcard_lookup')) {
40
- return { content: [{ type: 'text', text: JSON.stringify({ error: 'rate_limit_exceeded', retry_after: 60 }) }], isError: true };
41
- }
42
- try {
43
- const data = await AgentCardAPI.lookup(identifier);
44
- audit.info('agentcard_lookup', { identifier });
45
- return { content: [{ type: 'text', text: JSON.stringify(data) }] };
46
- } catch (err) {
47
- return { content: [{ type: 'text', text: JSON.stringify({ error: 'api_error', message: String(err) }) }], isError: true };
48
- }
49
- },
50
- );
51
-
52
- // ── FREE: agentcard_verify ─────────────────────────────────────────────────
53
- server.tool(
54
- 'agentcard_verify',
55
- {
56
- wallet_address: z.string().describe('Agent wallet address that signed the message.'),
57
- message: z.string().describe('Original message that was signed.'),
58
- signature: z.string().describe('Ed25519 signature (hex or base64).'),
59
- },
60
- async (rawArgs) => {
61
- const args = Sandbox.validate(VerifySchema, rawArgs);
62
- if (!RateLimiter.getInstance().checkTool('agentcard_verify')) {
63
- return { content: [{ type: 'text', text: JSON.stringify({ error: 'rate_limit_exceeded', retry_after: 60 }) }], isError: true };
64
- }
65
- try {
66
- const data = await AgentCardAPI.verify({
67
- walletAddress: args.wallet_address,
68
- message: args.message,
69
- signature: args.signature,
70
- });
71
- audit.info('agentcard_verify', { wallet_address: args.wallet_address });
72
- return { content: [{ type: 'text', text: JSON.stringify(data) }] };
73
- } catch (err) {
74
- return { content: [{ type: 'text', text: JSON.stringify({ error: 'api_error', message: String(err) }) }], isError: true };
75
- }
76
- },
77
- );
78
-
79
- // ── PAID: agentcard_mint (0.01 USDC) ──────────────────────────────────────
80
- server.tool(
81
- 'agentcard_mint',
82
- {
83
- wallet_address: z.string().describe('XRPL wallet address for the new agent identity.'),
84
- name: z.string().describe('Human-readable agent name (max 64 chars).'),
85
- did: z.string().describe('Optional DID (decentralized identifier) for the agent.'),
86
- metadata: z.record(z.unknown()).describe('Optional metadata object (capabilities, version, etc.).'),
87
- payment_wallet: z.string().describe('Wallet to pay x402 fee from (defaults to wallet_address).'),
88
- },
89
- async (rawArgs) => {
90
- const args = Sandbox.validate(MintSchema, rawArgs);
91
- const paymentWallet = args.payment_wallet ?? args.wallet_address;
92
-
93
- if (!RateLimiter.getInstance().checkTool('agentcard_mint')) {
94
- return { content: [{ type: 'text', text: JSON.stringify({ error: 'rate_limit_exceeded', retry_after: 60 }) }], isError: true };
95
- }
96
-
97
- await PriceRegistry.getInstance().seedDefaults();
98
- const price = await PriceRegistry.getInstance().getPrice('agentcard_mint');
99
- if (!price) {
100
- return { content: [{ type: 'text', text: JSON.stringify({ error: 'price_unavailable' }) }], isError: true };
101
- }
102
-
103
- let payment;
104
- try {
105
- payment = await executeX402Payment({ price, currency: 'USDC', toolName: 'agentcard_mint', walletAddress: paymentWallet });
106
- } catch (err) {
107
- audit.warn('agentcard_mint_payment_fail', { error: String(err) });
108
- return { content: [{ type: 'text', text: JSON.stringify({ error: 'payment_failed', message: String(err) }) }], isError: true };
109
- }
110
-
111
- try {
112
- const data = await AgentCardAPI.mint({
113
- walletAddress: args.wallet_address,
114
- name: args.name,
115
- did: args.did,
116
- metadata: args.metadata,
117
- });
118
- audit.info('agentcard_mint_success', { name: args.name, receiptId: payment.receiptId });
119
- return {
120
- content: [{
121
- type: 'text',
122
- text: JSON.stringify({
123
- data,
124
- _meta: { receipt_id: payment.receiptId, tx_hash: payment.txHash, chain: payment.chain, amount_paid: `${payment.amountPaid} ${payment.currency}`, timestamp: payment.timestamp },
125
- }),
126
- }],
127
- };
128
- } catch (err) {
129
- audit.error('agentcard_mint_api_fail', { error: String(err) });
130
- return { content: [{ type: 'text', text: JSON.stringify({ error: 'api_error', message: String(err) }) }], isError: true };
131
- }
132
- },
133
- );
134
- }
@@ -1,119 +0,0 @@
1
- import { z } from 'zod';
2
- import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
3
- import { executeX402Payment } from '../payments/x402.js';
4
- import { RateLimiter } from '../security/rate-limit.js';
5
- import { Sandbox } from '../security/sandbox.js';
6
- import { AuditLogger } from '../security/audit.js';
7
- import { PriceRegistry } from '../registry/pricing.js';
8
- import { BacktestAPI } from '../../lib/sml-api/backtest.js';
9
-
10
- const BacktestSchema = z.object({
11
- ticker: z.string().min(1).max(10).toUpperCase(),
12
- lookback_days: z.number().int().min(30).max(1260).default(252),
13
- fees: z.number().min(0).max(0.05).default(0.001),
14
- slippage: z.number().min(0).max(0.05).default(0.0005),
15
- momentum_window: z.number().int().min(2).max(50).default(10),
16
- momentum_threshold: z.number().min(0).max(0.1).default(0.001),
17
- wallet_address: z.string().optional(),
18
- });
19
-
20
- const ValidateSchema = z.object({
21
- ticker: z.string().min(1).max(10).toUpperCase(),
22
- lookback_days: z.number().int().min(60).max(1260).default(504),
23
- train_ratio: z.number().min(0.5).max(0.9).default(0.7),
24
- fees: z.number().min(0).max(0.05).default(0.001),
25
- slippage: z.number().min(0).max(0.05).default(0.0005),
26
- wallet_address: z.string().optional(),
27
- });
28
-
29
- export function registerBacktest(server: McpServer): void {
30
- const audit = AuditLogger.getInstance();
31
-
32
- // ── backtest_run — full backtest on live price data (FREE) ─────────────────
33
- server.tool(
34
- 'backtest_run',
35
- {
36
- ticker: z.string().describe('Ticker symbol (e.g. NVDA, SPY, GME)'),
37
- lookback_days: z.number().describe('Days of history to backtest (30–1260, default 252)'),
38
- fees: z.number().describe('Round-trip commission rate (default 0.001 = 0.1%)'),
39
- slippage: z.number().describe('Slippage per side (default 0.0005)'),
40
- momentum_window: z.number().describe('Momentum rolling window in days (default 10)'),
41
- momentum_threshold: z.number().describe('Minimum momentum to enter long (default 0.001)'),
42
- wallet_address: z.string().describe('Agent wallet address (optional)'),
43
- },
44
- async (rawArgs) => {
45
- const args = Sandbox.validate(BacktestSchema, rawArgs);
46
- if (!RateLimiter.getInstance().checkTool('backtest_run')) {
47
- return { content: [{ type: 'text', text: JSON.stringify({ error: 'rate_limit_exceeded' }) }], isError: true };
48
- }
49
- try {
50
- const result = await BacktestAPI.backtest({
51
- ticker: args.ticker,
52
- lookback_days: args.lookback_days,
53
- fees: args.fees,
54
- slippage: args.slippage,
55
- momentum_window: args.momentum_window,
56
- momentum_threshold: args.momentum_threshold,
57
- });
58
- audit.info('backtest_run_success', { ticker: args.ticker });
59
- return { content: [{ type: 'text', text: JSON.stringify(result) }] };
60
- } catch (err) {
61
- audit.warn('backtest_run_fail', { error: String(err) });
62
- return { content: [{ type: 'text', text: JSON.stringify({ error: String(err) }) }], isError: true };
63
- }
64
- },
65
- );
66
-
67
- // ── backtest_validate — walk-forward OOS validation ($0.02) ───────────────
68
- server.tool(
69
- 'backtest_validate',
70
- {
71
- ticker: z.string().describe('Ticker symbol to validate'),
72
- lookback_days: z.number().describe('Total history window (60–1260, default 504 = 2 years)'),
73
- train_ratio: z.number().describe('Train/test split ratio (default 0.7 = 70% in-sample)'),
74
- fees: z.number().describe('Round-trip commission rate (default 0.001)'),
75
- slippage: z.number().describe('Slippage per side (default 0.0005)'),
76
- wallet_address: z.string().describe('Agent wallet for x402 payment (AP2 required)'),
77
- },
78
- async (rawArgs) => {
79
- const args = Sandbox.validate(ValidateSchema, rawArgs);
80
- if (!RateLimiter.getInstance().checkTool('backtest_validate')) {
81
- return { content: [{ type: 'text', text: JSON.stringify({ error: 'rate_limit_exceeded' }) }], isError: true };
82
- }
83
- await PriceRegistry.getInstance().seedDefaults();
84
- const price = await PriceRegistry.getInstance().getPrice('backtest_validate');
85
- if (!price) {
86
- return { content: [{ type: 'text', text: JSON.stringify({ error: 'price_unavailable' }) }], isError: true };
87
- }
88
- let payment;
89
- try {
90
- payment = await executeX402Payment({ price, currency: 'USDC', toolName: 'backtest_validate', walletAddress: args.wallet_address });
91
- } catch (err) {
92
- audit.warn('backtest_validate_payment_fail', { error: String(err) });
93
- return { content: [{ type: 'text', text: JSON.stringify({ error: 'payment_failed', message: String(err) }) }], isError: true };
94
- }
95
- try {
96
- const result = await BacktestAPI.walkForward({
97
- ticker: args.ticker,
98
- lookback_days: args.lookback_days,
99
- train_ratio: args.train_ratio,
100
- fees: args.fees,
101
- slippage: args.slippage,
102
- });
103
- audit.info('backtest_validate_success', { ticker: args.ticker });
104
- return {
105
- content: [{
106
- type: 'text',
107
- text: JSON.stringify({
108
- ...(result as object),
109
- _meta: { receipt_id: payment.receiptId, tx_hash: payment.txHash, chain: payment.chain, amount_paid: `${payment.amountPaid} ${payment.currency}` },
110
- }),
111
- }],
112
- };
113
- } catch (err) {
114
- audit.warn('backtest_validate_fail', { error: String(err) });
115
- return { content: [{ type: 'text', text: JSON.stringify({ error: String(err) }) }], isError: true };
116
- }
117
- },
118
- );
119
- }