@sly_ai/mcp-server 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.
@@ -0,0 +1,1263 @@
1
+ import {
2
+ tools
3
+ } from "./chunk-YDZJAN2U.js";
4
+
5
+ // src/server-factory.ts
6
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
7
+ import {
8
+ CallToolRequestSchema,
9
+ ListToolsRequestSchema
10
+ } from "@modelcontextprotocol/sdk/types.js";
11
+ function createMcpServer(sly, apiUrl, apiKey) {
12
+ const server = new Server(
13
+ {
14
+ name: "@sly/mcp-server",
15
+ version: "0.1.0"
16
+ },
17
+ {
18
+ capabilities: {
19
+ tools: {}
20
+ },
21
+ instructions: [
22
+ "This is the Sly payment platform MCP server.",
23
+ `"Accounts" in this system are merchant or entity records within the tenant's own payment ledger \u2014 NOT user accounts on external services.`,
24
+ "Creating, updating, and listing accounts are standard data-management operations authorized by the tenant's API key.",
25
+ "These tools manage the tenant's own internal data. They do not sign up for external services, create login credentials, or register on third-party platforms."
26
+ ].join(" ")
27
+ }
28
+ );
29
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
30
+ return { tools };
31
+ });
32
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
33
+ const { name, arguments: args } = request.params;
34
+ try {
35
+ switch (name) {
36
+ case "get_settlement_quote": {
37
+ const quote = await sly.getSettlementQuote(args);
38
+ return {
39
+ content: [
40
+ {
41
+ type: "text",
42
+ text: JSON.stringify(quote, null, 2)
43
+ }
44
+ ]
45
+ };
46
+ }
47
+ case "create_settlement": {
48
+ const settlement = await sly.createSettlement(args);
49
+ return {
50
+ content: [
51
+ {
52
+ type: "text",
53
+ text: JSON.stringify(settlement, null, 2)
54
+ }
55
+ ]
56
+ };
57
+ }
58
+ case "get_settlement_status": {
59
+ const { settlementId } = args;
60
+ const settlement = await sly.getSettlement(settlementId);
61
+ return {
62
+ content: [
63
+ {
64
+ type: "text",
65
+ text: JSON.stringify(settlement, null, 2)
66
+ }
67
+ ]
68
+ };
69
+ }
70
+ // ======================================================================
71
+ // UCP Tools
72
+ // ======================================================================
73
+ case "ucp_discover": {
74
+ const { merchantUrl } = args;
75
+ const profile = await sly.ucp.discover(merchantUrl);
76
+ return {
77
+ content: [
78
+ {
79
+ type: "text",
80
+ text: JSON.stringify(profile, null, 2)
81
+ }
82
+ ]
83
+ };
84
+ }
85
+ case "ucp_create_checkout": {
86
+ const {
87
+ currency,
88
+ line_items,
89
+ buyer,
90
+ shipping_address,
91
+ payment_config,
92
+ payment_instruments,
93
+ checkout_type,
94
+ metadata,
95
+ agent_id
96
+ } = args;
97
+ const body = { currency, line_items, buyer, shipping_address, payment_config, metadata };
98
+ if (payment_instruments) body.payment_instruments = payment_instruments;
99
+ if (checkout_type) body.checkout_type = checkout_type;
100
+ if (agent_id) body.agent_id = agent_id;
101
+ const result = await sly.request("/v1/ucp/checkouts", {
102
+ method: "POST",
103
+ body: JSON.stringify(body)
104
+ });
105
+ return {
106
+ content: [
107
+ {
108
+ type: "text",
109
+ text: JSON.stringify(result, null, 2)
110
+ }
111
+ ]
112
+ };
113
+ }
114
+ case "ucp_get_checkout": {
115
+ const { checkoutId } = args;
116
+ const result = await sly.request(`/v1/ucp/checkouts/${checkoutId}`);
117
+ return {
118
+ content: [
119
+ {
120
+ type: "text",
121
+ text: JSON.stringify(result, null, 2)
122
+ }
123
+ ]
124
+ };
125
+ }
126
+ case "ucp_list_checkouts": {
127
+ const params = new URLSearchParams();
128
+ if (args && args.status) params.set("status", args.status);
129
+ if (args && args.agent_id) params.set("agent_id", args.agent_id);
130
+ if (args && args.page) params.set("page", String(args.page));
131
+ if (args && args.limit) params.set("limit", String(args.limit));
132
+ const query = params.toString();
133
+ const result = await sly.request(`/v1/ucp/checkouts${query ? `?${query}` : ""}`);
134
+ return {
135
+ content: [
136
+ {
137
+ type: "text",
138
+ text: JSON.stringify(result, null, 2)
139
+ }
140
+ ]
141
+ };
142
+ }
143
+ case "ucp_update_checkout": {
144
+ const { checkoutId, ...updates } = args;
145
+ const result = await sly.request(`/v1/ucp/checkouts/${checkoutId}`, {
146
+ method: "PUT",
147
+ body: JSON.stringify(updates)
148
+ });
149
+ return {
150
+ content: [
151
+ {
152
+ type: "text",
153
+ text: JSON.stringify(result, null, 2)
154
+ }
155
+ ]
156
+ };
157
+ }
158
+ case "ucp_complete_checkout": {
159
+ const { checkoutId } = args;
160
+ const result = await sly.request(`/v1/ucp/checkouts/${checkoutId}/complete`, {
161
+ method: "POST"
162
+ });
163
+ return {
164
+ content: [
165
+ {
166
+ type: "text",
167
+ text: JSON.stringify(result, null, 2)
168
+ }
169
+ ]
170
+ };
171
+ }
172
+ case "ucp_cancel_checkout": {
173
+ const { checkoutId } = args;
174
+ const result = await sly.request(`/v1/ucp/checkouts/${checkoutId}/cancel`, {
175
+ method: "POST"
176
+ });
177
+ return {
178
+ content: [
179
+ {
180
+ type: "text",
181
+ text: JSON.stringify(result, null, 2)
182
+ }
183
+ ]
184
+ };
185
+ }
186
+ case "ucp_add_payment_instrument": {
187
+ const { checkoutId, id: instrumentId, handler, type: instrumentType, last4, brand, metadata } = args;
188
+ const result = await sly.request(`/v1/ucp/checkouts/${checkoutId}/instruments`, {
189
+ method: "POST",
190
+ body: JSON.stringify({ id: instrumentId, handler, type: instrumentType, last4, brand, metadata })
191
+ });
192
+ return {
193
+ content: [
194
+ {
195
+ type: "text",
196
+ text: JSON.stringify(result, null, 2)
197
+ }
198
+ ]
199
+ };
200
+ }
201
+ case "ucp_batch_checkout": {
202
+ const { checkouts } = args;
203
+ const batchRes = await fetch(`${apiUrl}/v1/ucp/checkouts/batch`, {
204
+ method: "POST",
205
+ headers: {
206
+ "Authorization": `Bearer ${apiKey}`,
207
+ "Content-Type": "application/json",
208
+ "X-Environment": apiKey.startsWith("pk_live_") ? "live" : "test"
209
+ },
210
+ body: JSON.stringify({
211
+ checkouts,
212
+ auto_complete: true
213
+ })
214
+ });
215
+ const batchJson = await batchRes.json();
216
+ const batchData = batchJson?.data || batchJson;
217
+ return {
218
+ content: [
219
+ {
220
+ type: "text",
221
+ text: JSON.stringify(batchData, null, 2)
222
+ }
223
+ ]
224
+ };
225
+ }
226
+ case "ucp_batch_complete": {
227
+ const { checkout_ids, default_payment_instrument } = args;
228
+ const batchRes = await fetch(`${apiUrl}/v1/ucp/checkouts/batch-complete`, {
229
+ method: "POST",
230
+ headers: {
231
+ "Authorization": `Bearer ${apiKey}`,
232
+ "Content-Type": "application/json",
233
+ "X-Environment": apiKey.startsWith("pk_live_") ? "live" : "test"
234
+ },
235
+ body: JSON.stringify({ checkout_ids, default_payment_instrument })
236
+ });
237
+ const batchJson = await batchRes.json();
238
+ const batchData = batchJson?.data || batchJson;
239
+ return {
240
+ content: [
241
+ {
242
+ type: "text",
243
+ text: JSON.stringify(batchData, null, 2)
244
+ }
245
+ ]
246
+ };
247
+ }
248
+ case "ucp_list_orders": {
249
+ const params = new URLSearchParams();
250
+ if (args && args.status) params.set("status", args.status);
251
+ if (args && args.agent_id) params.set("agent_id", args.agent_id);
252
+ if (args && args.page) params.set("page", String(args.page));
253
+ if (args && args.limit) params.set("limit", String(args.limit));
254
+ const query = params.toString();
255
+ const result = await sly.request(`/v1/ucp/orders${query ? `?${query}` : ""}`);
256
+ return {
257
+ content: [
258
+ {
259
+ type: "text",
260
+ text: JSON.stringify(result, null, 2)
261
+ }
262
+ ]
263
+ };
264
+ }
265
+ case "ucp_get_order": {
266
+ const { orderId } = args;
267
+ const result = await sly.request(`/v1/ucp/orders/${orderId}`);
268
+ return {
269
+ content: [
270
+ {
271
+ type: "text",
272
+ text: JSON.stringify(result, null, 2)
273
+ }
274
+ ]
275
+ };
276
+ }
277
+ case "ucp_update_order_status": {
278
+ const { orderId, status } = args;
279
+ const result = await sly.request(`/v1/ucp/orders/${orderId}/status`, {
280
+ method: "PUT",
281
+ body: JSON.stringify({ status })
282
+ });
283
+ return {
284
+ content: [
285
+ {
286
+ type: "text",
287
+ text: JSON.stringify(result, null, 2)
288
+ }
289
+ ]
290
+ };
291
+ }
292
+ case "ucp_cancel_order": {
293
+ const { orderId, reason } = args;
294
+ const result = await sly.request(`/v1/ucp/orders/${orderId}/cancel`, {
295
+ method: "POST",
296
+ body: JSON.stringify({ reason })
297
+ });
298
+ return {
299
+ content: [
300
+ {
301
+ type: "text",
302
+ text: JSON.stringify(result, null, 2)
303
+ }
304
+ ]
305
+ };
306
+ }
307
+ case "ucp_add_fulfillment_event": {
308
+ const { orderId, type: eventType, description, tracking_number, carrier } = args;
309
+ const result = await sly.request(`/v1/ucp/orders/${orderId}/events`, {
310
+ method: "POST",
311
+ body: JSON.stringify({ type: eventType, description, tracking_number, carrier })
312
+ });
313
+ return {
314
+ content: [
315
+ {
316
+ type: "text",
317
+ text: JSON.stringify(result, null, 2)
318
+ }
319
+ ]
320
+ };
321
+ }
322
+ // ======================================================================
323
+ // Merchant Catalog Tools
324
+ // ======================================================================
325
+ case "list_merchants": {
326
+ const params = new URLSearchParams();
327
+ if (args && args.type) params.set("type", args.type);
328
+ if (args && args.country) params.set("country", args.country);
329
+ if (args && args.search) params.set("search", args.search);
330
+ if (args && args.limit) params.set("limit", String(args.limit));
331
+ const query = params.toString();
332
+ const result = await sly.request(`/v1/ucp/merchants${query ? `?${query}` : ""}`);
333
+ return {
334
+ content: [
335
+ {
336
+ type: "text",
337
+ text: JSON.stringify(result, null, 2)
338
+ }
339
+ ]
340
+ };
341
+ }
342
+ case "get_merchant": {
343
+ const { merchantId } = args;
344
+ const result = await sly.request(`/v1/ucp/merchants/${merchantId}`);
345
+ return {
346
+ content: [
347
+ {
348
+ type: "text",
349
+ text: JSON.stringify(result, null, 2)
350
+ }
351
+ ]
352
+ };
353
+ }
354
+ // ======================================================================
355
+ // Agent Management Tools
356
+ // ======================================================================
357
+ case "list_accounts": {
358
+ const params = new URLSearchParams();
359
+ if (args && args.type) params.set("type", args.type);
360
+ if (args && args.status) params.set("status", args.status);
361
+ const query = params.toString();
362
+ const result = await sly.request(`/v1/accounts${query ? `?${query}` : ""}`);
363
+ return {
364
+ content: [
365
+ {
366
+ type: "text",
367
+ text: JSON.stringify(result, null, 2)
368
+ }
369
+ ]
370
+ };
371
+ }
372
+ case "create_account": {
373
+ const { type, name: accountName, email, metadata } = args;
374
+ const body = { type, name: accountName };
375
+ if (email) body.email = email;
376
+ if (metadata) body.metadata = metadata;
377
+ const result = await sly.request("/v1/accounts", {
378
+ method: "POST",
379
+ body: JSON.stringify(body)
380
+ });
381
+ return {
382
+ content: [
383
+ {
384
+ type: "text",
385
+ text: JSON.stringify(result, null, 2)
386
+ }
387
+ ]
388
+ };
389
+ }
390
+ case "update_account": {
391
+ const {
392
+ accountId,
393
+ name: accountName,
394
+ email,
395
+ metadata
396
+ } = args;
397
+ const body = {};
398
+ if (accountName !== void 0) body.name = accountName;
399
+ if (email !== void 0) body.email = email;
400
+ if (metadata !== void 0) body.metadata = metadata;
401
+ const result = await sly.request(`/v1/accounts/${accountId}`, {
402
+ method: "PATCH",
403
+ body: JSON.stringify(body)
404
+ });
405
+ return {
406
+ content: [
407
+ {
408
+ type: "text",
409
+ text: JSON.stringify(result, null, 2)
410
+ }
411
+ ]
412
+ };
413
+ }
414
+ case "get_tenant_info": {
415
+ const result = await sly.request("/v1/context/whoami");
416
+ return {
417
+ content: [
418
+ {
419
+ type: "text",
420
+ text: JSON.stringify(result, null, 2)
421
+ }
422
+ ]
423
+ };
424
+ }
425
+ case "create_agent": {
426
+ const { accountId, name: agentName, description } = args;
427
+ const result = await sly.request("/v1/agents", {
428
+ method: "POST",
429
+ body: JSON.stringify({
430
+ accountId,
431
+ name: agentName,
432
+ description
433
+ })
434
+ });
435
+ return {
436
+ content: [
437
+ {
438
+ type: "text",
439
+ text: JSON.stringify(result, null, 2)
440
+ }
441
+ ]
442
+ };
443
+ }
444
+ case "verify_agent": {
445
+ const { agentId, tier } = args;
446
+ const result = await sly.request(`/v1/agents/${agentId}/verify`, {
447
+ method: "POST",
448
+ body: JSON.stringify({ tier })
449
+ });
450
+ return {
451
+ content: [
452
+ {
453
+ type: "text",
454
+ text: JSON.stringify(result, null, 2)
455
+ }
456
+ ]
457
+ };
458
+ }
459
+ case "get_agent": {
460
+ const { agentId } = args;
461
+ const result = await sly.request(`/v1/agents/${agentId}`);
462
+ return {
463
+ content: [
464
+ {
465
+ type: "text",
466
+ text: JSON.stringify(result, null, 2)
467
+ }
468
+ ]
469
+ };
470
+ }
471
+ case "get_agent_limits": {
472
+ const { agentId } = args;
473
+ const result = await sly.request(`/v1/agents/${agentId}/limits`);
474
+ return {
475
+ content: [
476
+ {
477
+ type: "text",
478
+ text: JSON.stringify(result, null, 2)
479
+ }
480
+ ]
481
+ };
482
+ }
483
+ case "get_agent_transactions": {
484
+ const { agentId, limit: txLimit, offset: txOffset, from, to } = args;
485
+ const params = new URLSearchParams();
486
+ if (txLimit) params.set("limit", String(txLimit));
487
+ if (txOffset) params.set("offset", String(txOffset));
488
+ if (from) params.set("from", from);
489
+ if (to) params.set("to", to);
490
+ const query = params.toString();
491
+ const result = await sly.request(`/v1/agents/${agentId}/transactions${query ? `?${query}` : ""}`);
492
+ return {
493
+ content: [
494
+ {
495
+ type: "text",
496
+ text: JSON.stringify(result, null, 2)
497
+ }
498
+ ]
499
+ };
500
+ }
501
+ case "delete_agent": {
502
+ const { agentId } = args;
503
+ const result = await sly.request(`/v1/agents/${agentId}`, {
504
+ method: "DELETE"
505
+ });
506
+ return {
507
+ content: [
508
+ {
509
+ type: "text",
510
+ text: JSON.stringify(result, null, 2)
511
+ }
512
+ ]
513
+ };
514
+ }
515
+ // ======================================================================
516
+ // AP2 Mandate Tools
517
+ // ======================================================================
518
+ case "ap2_cancel_mandate": {
519
+ const { mandateId } = args;
520
+ const result = await sly.request(`/v1/ap2/mandates/${mandateId}/cancel`, {
521
+ method: "PATCH",
522
+ body: JSON.stringify({})
523
+ });
524
+ return {
525
+ content: [
526
+ {
527
+ type: "text",
528
+ text: JSON.stringify(result, null, 2)
529
+ }
530
+ ]
531
+ };
532
+ }
533
+ case "ap2_create_mandate": {
534
+ const {
535
+ mandate_id,
536
+ agent_id,
537
+ account_id,
538
+ authorized_amount,
539
+ currency,
540
+ mandate_type,
541
+ description,
542
+ expires_at,
543
+ metadata,
544
+ mandate_data
545
+ } = args;
546
+ const result = await sly.ap2.createMandate({
547
+ mandate_id,
548
+ agent_id,
549
+ account_id,
550
+ authorized_amount,
551
+ currency,
552
+ mandate_type: mandate_type || "payment",
553
+ mandate_data: mandate_data || (description ? { description } : void 0),
554
+ metadata,
555
+ expires_at
556
+ });
557
+ return {
558
+ content: [
559
+ {
560
+ type: "text",
561
+ text: JSON.stringify(result, null, 2)
562
+ }
563
+ ]
564
+ };
565
+ }
566
+ case "ap2_get_mandate": {
567
+ const { mandateId } = args;
568
+ const result = await sly.ap2.getMandate(mandateId);
569
+ return {
570
+ content: [
571
+ {
572
+ type: "text",
573
+ text: JSON.stringify(result, null, 2)
574
+ }
575
+ ]
576
+ };
577
+ }
578
+ case "ap2_execute_mandate": {
579
+ const { mandateId, amount, currency, description, order_ids } = args;
580
+ const result = await sly.ap2.executeMandate(mandateId, {
581
+ amount,
582
+ currency,
583
+ description,
584
+ order_ids
585
+ });
586
+ return {
587
+ content: [
588
+ {
589
+ type: "text",
590
+ text: JSON.stringify(result, null, 2)
591
+ }
592
+ ]
593
+ };
594
+ }
595
+ case "ap2_list_mandates": {
596
+ const { status, agent_id, account_id, limit } = args || {};
597
+ const result = await sly.ap2.listMandates({
598
+ status,
599
+ agent_id,
600
+ account_id,
601
+ limit
602
+ });
603
+ return {
604
+ content: [
605
+ {
606
+ type: "text",
607
+ text: JSON.stringify(result, null, 2)
608
+ }
609
+ ]
610
+ };
611
+ }
612
+ case "ap2_update_mandate": {
613
+ const { mandateId, ...updateFields } = args;
614
+ const result = await sly.request(`/v1/ap2/mandates/${mandateId}`, {
615
+ method: "PATCH",
616
+ body: JSON.stringify(updateFields)
617
+ });
618
+ return {
619
+ content: [
620
+ {
621
+ type: "text",
622
+ text: JSON.stringify(result, null, 2)
623
+ }
624
+ ]
625
+ };
626
+ }
627
+ // ======================================================================
628
+ // ACP Checkout Tools
629
+ // ======================================================================
630
+ case "acp_create_checkout": {
631
+ const {
632
+ checkout_id,
633
+ agent_id,
634
+ account_id,
635
+ merchant_id,
636
+ items,
637
+ tax_amount,
638
+ shipping_amount,
639
+ payment_method,
640
+ checkout_data
641
+ } = args;
642
+ const result = await sly.acp.createCheckout({
643
+ checkout_id,
644
+ agent_id,
645
+ account_id: account_id || "",
646
+ merchant_id,
647
+ items,
648
+ tax_amount,
649
+ shipping_amount,
650
+ payment_method,
651
+ checkout_data
652
+ });
653
+ return {
654
+ content: [
655
+ {
656
+ type: "text",
657
+ text: JSON.stringify(result, null, 2)
658
+ }
659
+ ]
660
+ };
661
+ }
662
+ case "acp_get_checkout": {
663
+ const { checkoutId } = args;
664
+ const result = await sly.acp.getCheckout(checkoutId);
665
+ return {
666
+ content: [
667
+ {
668
+ type: "text",
669
+ text: JSON.stringify(result, null, 2)
670
+ }
671
+ ]
672
+ };
673
+ }
674
+ case "acp_complete_checkout": {
675
+ const { checkoutId, shared_payment_token, payment_method } = args;
676
+ const token = shared_payment_token || `spt_test_${Date.now()}`;
677
+ const result = await sly.acp.completeCheckout(checkoutId, {
678
+ shared_payment_token: token,
679
+ payment_method
680
+ });
681
+ return {
682
+ content: [
683
+ {
684
+ type: "text",
685
+ text: JSON.stringify(result, null, 2)
686
+ }
687
+ ]
688
+ };
689
+ }
690
+ case "acp_list_checkouts": {
691
+ const { status, agent_id, merchant_id, limit } = args || {};
692
+ const result = await sly.acp.listCheckouts({
693
+ status,
694
+ agent_id,
695
+ merchant_id,
696
+ limit
697
+ });
698
+ return {
699
+ content: [
700
+ {
701
+ type: "text",
702
+ text: JSON.stringify(result, null, 2)
703
+ }
704
+ ]
705
+ };
706
+ }
707
+ case "acp_batch_checkout": {
708
+ const { checkouts } = args;
709
+ const batchRes = await fetch(`${apiUrl}/v1/acp/checkouts/batch`, {
710
+ method: "POST",
711
+ headers: {
712
+ "Authorization": `Bearer ${apiKey}`,
713
+ "Content-Type": "application/json",
714
+ "X-Environment": apiKey.startsWith("pk_live_") ? "live" : "test"
715
+ },
716
+ body: JSON.stringify({ checkouts })
717
+ });
718
+ const batchJson = await batchRes.json();
719
+ const batchData = batchJson?.data || batchJson;
720
+ return {
721
+ content: [
722
+ {
723
+ type: "text",
724
+ text: JSON.stringify(batchData, null, 2)
725
+ }
726
+ ]
727
+ };
728
+ }
729
+ // ======================================================================
730
+ // Wallet Management Tools
731
+ // ======================================================================
732
+ case "list_wallets": {
733
+ const params = new URLSearchParams();
734
+ if (args && args.owner_account_id) params.set("owner_account_id", args.owner_account_id);
735
+ if (args && args.managed_by_agent_id) params.set("managed_by_agent_id", args.managed_by_agent_id);
736
+ if (args && args.status) params.set("status", args.status);
737
+ if (args && args.page) params.set("page", String(args.page));
738
+ if (args && args.limit) params.set("limit", String(args.limit));
739
+ const query = params.toString();
740
+ const result = await sly.request(`/v1/wallets${query ? `?${query}` : ""}`);
741
+ return {
742
+ content: [
743
+ {
744
+ type: "text",
745
+ text: JSON.stringify(result, null, 2)
746
+ }
747
+ ]
748
+ };
749
+ }
750
+ case "create_wallet": {
751
+ const {
752
+ accountId,
753
+ name: walletName,
754
+ currency,
755
+ walletType,
756
+ blockchain,
757
+ initialBalance,
758
+ managedByAgentId,
759
+ purpose
760
+ } = args;
761
+ const result = await sly.request("/v1/wallets", {
762
+ method: "POST",
763
+ body: JSON.stringify({
764
+ accountId,
765
+ name: walletName,
766
+ currency,
767
+ walletType,
768
+ blockchain,
769
+ initialBalance,
770
+ managedByAgentId,
771
+ purpose
772
+ })
773
+ });
774
+ return {
775
+ content: [
776
+ {
777
+ type: "text",
778
+ text: JSON.stringify(result, null, 2)
779
+ }
780
+ ]
781
+ };
782
+ }
783
+ case "get_wallet": {
784
+ const { walletId } = args;
785
+ const result = await sly.request(`/v1/wallets/${walletId}`);
786
+ return {
787
+ content: [
788
+ {
789
+ type: "text",
790
+ text: JSON.stringify(result, null, 2)
791
+ }
792
+ ]
793
+ };
794
+ }
795
+ case "get_wallet_balance": {
796
+ const { walletId } = args;
797
+ const result = await sly.request(`/v1/wallets/${walletId}/balance`);
798
+ return {
799
+ content: [
800
+ {
801
+ type: "text",
802
+ text: JSON.stringify(result, null, 2)
803
+ }
804
+ ]
805
+ };
806
+ }
807
+ case "wallet_deposit": {
808
+ const { walletId, amount, fromAccountId, reference } = args;
809
+ const result = await sly.request(`/v1/wallets/${walletId}/deposit`, {
810
+ method: "POST",
811
+ body: JSON.stringify({ amount, fromAccountId, reference })
812
+ });
813
+ return {
814
+ content: [
815
+ {
816
+ type: "text",
817
+ text: JSON.stringify(result, null, 2)
818
+ }
819
+ ]
820
+ };
821
+ }
822
+ case "wallet_withdraw": {
823
+ const { walletId, amount, destinationAccountId, reference } = args;
824
+ const result = await sly.request(`/v1/wallets/${walletId}/withdraw`, {
825
+ method: "POST",
826
+ body: JSON.stringify({ amount, destinationAccountId, reference })
827
+ });
828
+ return {
829
+ content: [
830
+ {
831
+ type: "text",
832
+ text: JSON.stringify(result, null, 2)
833
+ }
834
+ ]
835
+ };
836
+ }
837
+ case "wallet_test_fund": {
838
+ const { walletId, amount, currency, reference } = args;
839
+ const result = await sly.request(`/v1/wallets/${walletId}/test-fund`, {
840
+ method: "POST",
841
+ body: JSON.stringify({ amount, currency, reference })
842
+ });
843
+ return {
844
+ content: [
845
+ {
846
+ type: "text",
847
+ text: JSON.stringify(result, null, 2)
848
+ }
849
+ ]
850
+ };
851
+ }
852
+ // ======================================================================
853
+ // Agent Wallet Policy Tools (Epic 18)
854
+ // ======================================================================
855
+ case "agent_wallet_evaluate_policy": {
856
+ const { agentId, amount, currency, action_type, contract_type, counterparty_agent_id, counterparty_address } = args;
857
+ const result = await sly.request(`/v1/agents/${agentId}/wallet/policy/evaluate`, {
858
+ method: "POST",
859
+ body: JSON.stringify({
860
+ amount,
861
+ currency: currency || "USDC",
862
+ action_type: action_type || "negotiation_check",
863
+ contract_type,
864
+ counterparty_agent_id,
865
+ counterparty_address
866
+ })
867
+ });
868
+ return {
869
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
870
+ };
871
+ }
872
+ case "agent_wallet_get_exposures": {
873
+ const { agentId } = args;
874
+ const result = await sly.request(`/v1/agents/${agentId}/wallet/exposures`);
875
+ return {
876
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
877
+ };
878
+ }
879
+ case "agent_wallet_get_evaluations": {
880
+ const { agentId, page, limit } = args;
881
+ const params = new URLSearchParams();
882
+ if (page) params.set("page", String(page));
883
+ if (limit) params.set("limit", String(limit));
884
+ const qs = params.toString();
885
+ const result = await sly.request(`/v1/agents/${agentId}/wallet/policy/evaluations${qs ? `?${qs}` : ""}`);
886
+ return {
887
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
888
+ };
889
+ }
890
+ case "agent_wallet_get": {
891
+ const { agentId } = args;
892
+ const result = await sly.request(`/v1/agents/${agentId}/wallet`);
893
+ return {
894
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
895
+ };
896
+ }
897
+ case "agent_wallet_freeze": {
898
+ const { agentId } = args;
899
+ const result = await sly.request(`/v1/agents/${agentId}/wallet/freeze`, {
900
+ method: "POST"
901
+ });
902
+ return {
903
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
904
+ };
905
+ }
906
+ case "agent_wallet_unfreeze": {
907
+ const { agentId } = args;
908
+ const result = await sly.request(`/v1/agents/${agentId}/wallet/unfreeze`, {
909
+ method: "POST"
910
+ });
911
+ return {
912
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
913
+ };
914
+ }
915
+ case "agent_wallet_set_policy": {
916
+ const { agentId, ...policyFields } = args;
917
+ const result = await sly.request(`/v1/agents/${agentId}/wallet/policy`, {
918
+ method: "PUT",
919
+ body: JSON.stringify(policyFields)
920
+ });
921
+ return {
922
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
923
+ };
924
+ }
925
+ // ======================================================================
926
+ // x402 Micropayment Tools
927
+ // ======================================================================
928
+ case "x402_create_endpoint": {
929
+ const {
930
+ name: endpointName,
931
+ path,
932
+ method,
933
+ description,
934
+ accountId,
935
+ basePrice,
936
+ currency,
937
+ volumeDiscounts,
938
+ webhookUrl
939
+ } = args;
940
+ const result = await sly.request("/v1/x402/endpoints", {
941
+ method: "POST",
942
+ body: JSON.stringify({
943
+ name: endpointName,
944
+ path,
945
+ method,
946
+ description,
947
+ accountId,
948
+ basePrice,
949
+ currency,
950
+ volumeDiscounts,
951
+ webhookUrl
952
+ })
953
+ });
954
+ return {
955
+ content: [
956
+ {
957
+ type: "text",
958
+ text: JSON.stringify(result, null, 2)
959
+ }
960
+ ]
961
+ };
962
+ }
963
+ case "x402_list_endpoints": {
964
+ const params = new URLSearchParams();
965
+ if (args && args.status) params.set("status", args.status);
966
+ if (args && args.account_id) params.set("account_id", args.account_id);
967
+ if (args && args.page) params.set("page", String(args.page));
968
+ if (args && args.limit) params.set("limit", String(args.limit));
969
+ const query = params.toString();
970
+ const result = await sly.request(`/v1/x402/endpoints${query ? `?${query}` : ""}`);
971
+ return {
972
+ content: [
973
+ {
974
+ type: "text",
975
+ text: JSON.stringify(result, null, 2)
976
+ }
977
+ ]
978
+ };
979
+ }
980
+ case "x402_get_endpoint": {
981
+ const { endpointId } = args;
982
+ const result = await sly.request(`/v1/x402/endpoints/${endpointId}`);
983
+ return {
984
+ content: [
985
+ {
986
+ type: "text",
987
+ text: JSON.stringify(result, null, 2)
988
+ }
989
+ ]
990
+ };
991
+ }
992
+ case "x402_pay": {
993
+ const { endpointId, walletId, amount, currency, method: httpMethod, path: endpointPath } = args;
994
+ const requestId = crypto.randomUUID();
995
+ const result = await sly.request("/v1/x402/pay", {
996
+ method: "POST",
997
+ body: JSON.stringify({
998
+ endpointId,
999
+ requestId,
1000
+ amount,
1001
+ currency,
1002
+ walletId,
1003
+ method: httpMethod,
1004
+ path: endpointPath,
1005
+ timestamp: Math.floor(Date.now() / 1e3)
1006
+ })
1007
+ });
1008
+ return {
1009
+ content: [
1010
+ {
1011
+ type: "text",
1012
+ text: JSON.stringify(result, null, 2)
1013
+ }
1014
+ ]
1015
+ };
1016
+ }
1017
+ case "x402_verify": {
1018
+ const { jwt, requestId, transferId } = args;
1019
+ const result = await sly.request("/v1/x402/verify", {
1020
+ method: "POST",
1021
+ body: JSON.stringify({ jwt, requestId, transferId })
1022
+ });
1023
+ return {
1024
+ content: [
1025
+ {
1026
+ type: "text",
1027
+ text: JSON.stringify(result, null, 2)
1028
+ }
1029
+ ]
1030
+ };
1031
+ }
1032
+ // ====================================================================
1033
+ // A2A Tools
1034
+ // ====================================================================
1035
+ case "a2a_discover_agent": {
1036
+ const { url } = args;
1037
+ const result = await sly.request("/v1/a2a/discover", {
1038
+ method: "POST",
1039
+ body: JSON.stringify({ url })
1040
+ });
1041
+ return {
1042
+ content: [
1043
+ {
1044
+ type: "text",
1045
+ text: JSON.stringify(result, null, 2)
1046
+ }
1047
+ ]
1048
+ };
1049
+ }
1050
+ case "a2a_send_task": {
1051
+ const { agent_id, remote_url, message, context_id } = args;
1052
+ const result = await sly.request("/v1/a2a/tasks", {
1053
+ method: "POST",
1054
+ body: JSON.stringify({
1055
+ agent_id,
1056
+ remote_url,
1057
+ message: {
1058
+ parts: [{ text: message }]
1059
+ },
1060
+ context_id
1061
+ })
1062
+ });
1063
+ return {
1064
+ content: [
1065
+ {
1066
+ type: "text",
1067
+ text: JSON.stringify(result, null, 2)
1068
+ }
1069
+ ]
1070
+ };
1071
+ }
1072
+ case "a2a_get_task": {
1073
+ const { task_id } = args;
1074
+ const result = await sly.request(`/v1/a2a/tasks/${task_id}`, {
1075
+ method: "GET"
1076
+ });
1077
+ return {
1078
+ content: [
1079
+ {
1080
+ type: "text",
1081
+ text: JSON.stringify(result, null, 2)
1082
+ }
1083
+ ]
1084
+ };
1085
+ }
1086
+ case "a2a_list_tasks": {
1087
+ const { agent_id, state, direction, limit, page } = args;
1088
+ const params = new URLSearchParams();
1089
+ if (agent_id) params.set("agent_id", agent_id);
1090
+ if (state) params.set("state", state);
1091
+ if (direction) params.set("direction", direction);
1092
+ if (limit) params.set("limit", String(limit));
1093
+ if (page) params.set("page", String(page));
1094
+ const query = params.toString();
1095
+ const result = await sly.request(`/v1/a2a/tasks${query ? `?${query}` : ""}`, {
1096
+ method: "GET"
1097
+ });
1098
+ return {
1099
+ content: [
1100
+ {
1101
+ type: "text",
1102
+ text: JSON.stringify(result, null, 2)
1103
+ }
1104
+ ]
1105
+ };
1106
+ }
1107
+ // ======================================================================
1108
+ // MPP Tools
1109
+ // ======================================================================
1110
+ case "mpp_pay": {
1111
+ const { service_url, amount, currency, intent, agent_id, wallet_id } = args;
1112
+ const result = await sly.request("/v1/mpp/pay", {
1113
+ method: "POST",
1114
+ body: JSON.stringify({ service_url, amount, currency, intent, agent_id, wallet_id })
1115
+ });
1116
+ return {
1117
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
1118
+ };
1119
+ }
1120
+ case "mpp_open_session": {
1121
+ const { service_url, deposit_amount, max_budget, agent_id, wallet_id, currency } = args;
1122
+ const result = await sly.request("/v1/mpp/sessions", {
1123
+ method: "POST",
1124
+ body: JSON.stringify({ service_url, deposit_amount, max_budget, agent_id, wallet_id, currency })
1125
+ });
1126
+ return {
1127
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
1128
+ };
1129
+ }
1130
+ case "mpp_get_session": {
1131
+ const { session_id } = args;
1132
+ const result = await sly.request(`/v1/mpp/sessions/${session_id}`);
1133
+ return {
1134
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
1135
+ };
1136
+ }
1137
+ case "mpp_list_sessions": {
1138
+ const { agent_id, status, limit, offset } = args;
1139
+ const params = new URLSearchParams();
1140
+ if (agent_id) params.set("agent_id", agent_id);
1141
+ if (status) params.set("status", status);
1142
+ if (limit) params.set("limit", String(limit));
1143
+ if (offset) params.set("offset", String(offset));
1144
+ const query = params.toString();
1145
+ const result = await sly.request(`/v1/mpp/sessions${query ? `?${query}` : ""}`);
1146
+ return {
1147
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
1148
+ };
1149
+ }
1150
+ case "mpp_close_session": {
1151
+ const { session_id } = args;
1152
+ const result = await sly.request(`/v1/mpp/sessions/${session_id}/close`, {
1153
+ method: "POST"
1154
+ });
1155
+ return {
1156
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
1157
+ };
1158
+ }
1159
+ case "mpp_list_transfers": {
1160
+ const { service_url, session_id, limit, offset } = args;
1161
+ const params = new URLSearchParams();
1162
+ if (service_url) params.set("service_url", service_url);
1163
+ if (session_id) params.set("session_id", session_id);
1164
+ if (limit) params.set("limit", String(limit));
1165
+ if (offset) params.set("offset", String(offset));
1166
+ const query = params.toString();
1167
+ const result = await sly.request(`/v1/mpp/transfers${query ? `?${query}` : ""}`);
1168
+ return {
1169
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
1170
+ };
1171
+ }
1172
+ case "mpp_verify_receipt": {
1173
+ const { receipt_id } = args;
1174
+ const result = await sly.request("/v1/mpp/receipts/verify", {
1175
+ method: "POST",
1176
+ body: JSON.stringify({ receipt_id })
1177
+ });
1178
+ return {
1179
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
1180
+ };
1181
+ }
1182
+ // ====================================================================
1183
+ // Support Tools (Intercom Fin)
1184
+ // ====================================================================
1185
+ case "explain_rejection": {
1186
+ const { error_code, transaction_id, agent_id } = args;
1187
+ const params = new URLSearchParams();
1188
+ if (error_code) params.set("error_code", error_code);
1189
+ if (transaction_id) params.set("transaction_id", transaction_id);
1190
+ if (agent_id) params.set("agent_id", agent_id);
1191
+ const query = params.toString();
1192
+ const result = await sly.request(`/v1/support/explain-rejection${query ? `?${query}` : ""}`, {
1193
+ method: "GET"
1194
+ });
1195
+ return {
1196
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
1197
+ };
1198
+ }
1199
+ case "request_limit_increase": {
1200
+ const { agent_id, limit_type, requested_amount, reason, duration } = args;
1201
+ const body = { agent_id, limit_type, requested_amount, reason };
1202
+ if (duration) body.duration = duration;
1203
+ const result = await sly.request("/v1/support/limit-requests", {
1204
+ method: "POST",
1205
+ body: JSON.stringify(body)
1206
+ });
1207
+ return {
1208
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
1209
+ };
1210
+ }
1211
+ case "open_dispute": {
1212
+ const { transaction_id, reason, description, requested_resolution } = args;
1213
+ const body = {
1214
+ transferId: transaction_id,
1215
+ reason,
1216
+ description
1217
+ };
1218
+ if (requested_resolution) body.requestedResolution = requested_resolution;
1219
+ const result = await sly.request("/v1/disputes", {
1220
+ method: "POST",
1221
+ body: JSON.stringify(body)
1222
+ });
1223
+ return {
1224
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
1225
+ };
1226
+ }
1227
+ case "escalate_to_human": {
1228
+ const { agent_id, reason, summary, priority } = args;
1229
+ const body = { reason, summary };
1230
+ if (agent_id) body.agent_id = agent_id;
1231
+ if (priority) body.priority = priority;
1232
+ const result = await sly.request("/v1/support/escalations", {
1233
+ method: "POST",
1234
+ body: JSON.stringify(body)
1235
+ });
1236
+ return {
1237
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
1238
+ };
1239
+ }
1240
+ default:
1241
+ throw new Error(`Unknown tool: ${name}`);
1242
+ }
1243
+ } catch (error) {
1244
+ const details = error.details || error.errors || "";
1245
+ const detailsStr = details ? `
1246
+ Details: ${JSON.stringify(details, null, 2)}` : "";
1247
+ return {
1248
+ content: [
1249
+ {
1250
+ type: "text",
1251
+ text: `Error: ${error.message}${detailsStr}`
1252
+ }
1253
+ ],
1254
+ isError: true
1255
+ };
1256
+ }
1257
+ });
1258
+ return server;
1259
+ }
1260
+
1261
+ export {
1262
+ createMcpServer
1263
+ };