@vybit/mcp-server 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,981 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Vybit MCP Server
4
+ *
5
+ * Model Context Protocol server for the Vybit Developer API.
6
+ * Provides tools for managing vybits, sounds, and monitoring usage.
7
+ */
8
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
9
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
10
+ import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
11
+ import { VybitAPIClient } from '@vybit/api-sdk';
12
+ // Get API key and optional base URL from environment
13
+ const API_KEY = process.env.VYBIT_API_KEY;
14
+ const API_URL = process.env.VYBIT_API_URL;
15
+ if (!API_KEY) {
16
+ console.error('Error: VYBIT_API_KEY environment variable is required');
17
+ process.exit(1);
18
+ }
19
+ // Initialize Vybit API client
20
+ const vybitClient = new VybitAPIClient({
21
+ apiKey: API_KEY,
22
+ ...(API_URL && { baseUrl: API_URL })
23
+ });
24
+ // Define available tools
25
+ const TOOLS = [
26
+ {
27
+ name: 'vybit_list',
28
+ description: 'List vybits with optional search and pagination. Returns a list of vybits owned by the authenticated user.',
29
+ inputSchema: {
30
+ type: 'object',
31
+ properties: {
32
+ search: {
33
+ type: 'string',
34
+ description: 'Search term to filter vybits by name',
35
+ },
36
+ limit: {
37
+ type: 'number',
38
+ description: 'Maximum number of vybits to return (default: 50)',
39
+ default: 50,
40
+ },
41
+ offset: {
42
+ type: 'number',
43
+ description: 'Number of vybits to skip for pagination (default: 0)',
44
+ default: 0,
45
+ },
46
+ },
47
+ },
48
+ },
49
+ {
50
+ name: 'vybit_get',
51
+ description: 'Get detailed information about a specific vybit by ID',
52
+ inputSchema: {
53
+ type: 'object',
54
+ properties: {
55
+ vybitId: {
56
+ type: 'string',
57
+ description: 'The unique identifier of the vybit',
58
+ },
59
+ },
60
+ required: ['vybitId'],
61
+ },
62
+ },
63
+ {
64
+ name: 'vybit_create',
65
+ description: 'Create a new vybit notification',
66
+ inputSchema: {
67
+ type: 'object',
68
+ properties: {
69
+ name: {
70
+ type: 'string',
71
+ description: 'Name of the vybit',
72
+ },
73
+ soundKey: {
74
+ type: 'string',
75
+ description: 'Sound key to use for the notification (defaults to a system sound if not provided)',
76
+ },
77
+ status: {
78
+ type: 'string',
79
+ description: 'Vybit status (on = active, off = disabled, defaults to "on")',
80
+ enum: ['on', 'off'],
81
+ },
82
+ triggerType: {
83
+ type: 'string',
84
+ description: 'Type of trigger (defaults to "webhook" if not provided)',
85
+ enum: ['webhook', 'schedule', 'geofence', 'integration'],
86
+ },
87
+ description: {
88
+ type: 'string',
89
+ description: 'Detailed description of the vybit',
90
+ },
91
+ access: {
92
+ type: 'string',
93
+ description: 'Vybit visibility (defaults to "private")',
94
+ enum: ['public', 'private', 'unlisted'],
95
+ },
96
+ message: {
97
+ type: 'string',
98
+ description: 'Default message displayed with notifications',
99
+ },
100
+ imageUrl: {
101
+ type: 'string',
102
+ description: 'Default image URL for notifications',
103
+ },
104
+ linkUrl: {
105
+ type: 'string',
106
+ description: 'Default URL to open when notification is tapped',
107
+ },
108
+ },
109
+ required: ['name'],
110
+ },
111
+ },
112
+ {
113
+ name: 'vybit_update',
114
+ description: 'Update an existing vybit',
115
+ inputSchema: {
116
+ type: 'object',
117
+ properties: {
118
+ vybitId: {
119
+ type: 'string',
120
+ description: 'The unique identifier of the vybit to update',
121
+ },
122
+ name: {
123
+ type: 'string',
124
+ description: 'New name for the vybit',
125
+ },
126
+ description: {
127
+ type: 'string',
128
+ description: 'New description for the vybit',
129
+ },
130
+ soundKey: {
131
+ type: 'string',
132
+ description: 'New sound key for the vybit',
133
+ },
134
+ status: {
135
+ type: 'string',
136
+ description: 'Vybit status (on = active, off = disabled)',
137
+ enum: ['on', 'off'],
138
+ },
139
+ access: {
140
+ type: 'string',
141
+ description: 'Vybit visibility and access control',
142
+ enum: ['public', 'private', 'unlisted'],
143
+ },
144
+ message: {
145
+ type: 'string',
146
+ description: 'Default message displayed with notifications',
147
+ },
148
+ },
149
+ required: ['vybitId'],
150
+ },
151
+ },
152
+ {
153
+ name: 'vybit_delete',
154
+ description: 'Delete a vybit',
155
+ inputSchema: {
156
+ type: 'object',
157
+ properties: {
158
+ vybitId: {
159
+ type: 'string',
160
+ description: 'The unique identifier of the vybit to delete',
161
+ },
162
+ },
163
+ required: ['vybitId'],
164
+ },
165
+ },
166
+ {
167
+ name: 'vybit_trigger',
168
+ description: 'Trigger a vybit notification using its vybit key',
169
+ inputSchema: {
170
+ type: 'object',
171
+ properties: {
172
+ triggerKey: {
173
+ type: 'string',
174
+ description: 'The vybit key (not the trigger key)',
175
+ },
176
+ message: {
177
+ type: 'string',
178
+ description: 'Optional message to include with the notification',
179
+ },
180
+ imageUrl: {
181
+ type: 'string',
182
+ description: 'Optional image URL to attach to the notification',
183
+ },
184
+ linkUrl: {
185
+ type: 'string',
186
+ description: 'Optional URL to open when notification is tapped',
187
+ },
188
+ log: {
189
+ type: 'string',
190
+ description: 'Optional log entry to append to the vybit log',
191
+ },
192
+ },
193
+ required: ['triggerKey'],
194
+ },
195
+ },
196
+ {
197
+ name: 'sounds_list',
198
+ description: 'List available sounds with optional search and pagination',
199
+ inputSchema: {
200
+ type: 'object',
201
+ properties: {
202
+ search: {
203
+ type: 'string',
204
+ description: 'Search term to filter sounds',
205
+ },
206
+ limit: {
207
+ type: 'number',
208
+ description: 'Maximum number of sounds to return (default: 50)',
209
+ default: 50,
210
+ },
211
+ offset: {
212
+ type: 'number',
213
+ description: 'Number of sounds to skip for pagination (default: 0)',
214
+ default: 0,
215
+ },
216
+ },
217
+ },
218
+ },
219
+ {
220
+ name: 'sound_get',
221
+ description: 'Get detailed information about a specific sound',
222
+ inputSchema: {
223
+ type: 'object',
224
+ properties: {
225
+ soundKey: {
226
+ type: 'string',
227
+ description: 'The unique key of the sound',
228
+ },
229
+ },
230
+ required: ['soundKey'],
231
+ },
232
+ },
233
+ {
234
+ name: 'meter_get',
235
+ description: 'Get current API usage and limits. Shows daily and monthly usage counts, caps, and tier information.',
236
+ inputSchema: {
237
+ type: 'object',
238
+ properties: {},
239
+ },
240
+ },
241
+ // Public Vybit Discovery
242
+ {
243
+ name: 'vybits_browse_public',
244
+ description: 'Browse public vybits available for subscription. Returns simplified PublicVybit objects.',
245
+ inputSchema: {
246
+ type: 'object',
247
+ properties: {
248
+ search: {
249
+ type: 'string',
250
+ description: 'Search term to filter public vybits',
251
+ },
252
+ limit: {
253
+ type: 'number',
254
+ description: 'Maximum number of vybits to return (default: 50)',
255
+ default: 50,
256
+ },
257
+ offset: {
258
+ type: 'number',
259
+ description: 'Number of vybits to skip for pagination (default: 0)',
260
+ default: 0,
261
+ },
262
+ },
263
+ },
264
+ },
265
+ {
266
+ name: 'vybit_get_public',
267
+ description: 'Get details about a public vybit by subscription key before subscribing',
268
+ inputSchema: {
269
+ type: 'object',
270
+ properties: {
271
+ subscriptionKey: {
272
+ type: 'string',
273
+ description: 'The subscription key of the public vybit',
274
+ },
275
+ },
276
+ required: ['subscriptionKey'],
277
+ },
278
+ },
279
+ // Subscription Management
280
+ {
281
+ name: 'subscription_create',
282
+ description: 'Subscribe to a public vybit using its subscription key',
283
+ inputSchema: {
284
+ type: 'object',
285
+ properties: {
286
+ subscriptionKey: {
287
+ type: 'string',
288
+ description: 'The subscription key of the vybit to subscribe to',
289
+ },
290
+ },
291
+ required: ['subscriptionKey'],
292
+ },
293
+ },
294
+ {
295
+ name: 'subscriptions_list',
296
+ description: 'List all vybits you are subscribed to (following)',
297
+ inputSchema: {
298
+ type: 'object',
299
+ properties: {
300
+ search: {
301
+ type: 'string',
302
+ description: 'Search term to filter subscriptions',
303
+ },
304
+ limit: {
305
+ type: 'number',
306
+ description: 'Maximum number of subscriptions to return (default: 50)',
307
+ default: 50,
308
+ },
309
+ offset: {
310
+ type: 'number',
311
+ description: 'Number of subscriptions to skip for pagination (default: 0)',
312
+ default: 0,
313
+ },
314
+ },
315
+ },
316
+ },
317
+ {
318
+ name: 'subscription_get',
319
+ description: 'Get details about a specific subscription',
320
+ inputSchema: {
321
+ type: 'object',
322
+ properties: {
323
+ followingKey: {
324
+ type: 'string',
325
+ description: 'The unique followingKey of the subscription',
326
+ },
327
+ },
328
+ required: ['followingKey'],
329
+ },
330
+ },
331
+ {
332
+ name: 'subscription_update',
333
+ description: 'Update a subscription (enable/disable, update permissions)',
334
+ inputSchema: {
335
+ type: 'object',
336
+ properties: {
337
+ followingKey: {
338
+ type: 'string',
339
+ description: 'The unique followingKey of the subscription',
340
+ },
341
+ status: {
342
+ type: 'string',
343
+ description: 'Enable or disable notifications for this subscription',
344
+ enum: ['on', 'off'],
345
+ },
346
+ accessStatus: {
347
+ type: 'string',
348
+ description: 'Accept or decline invitation (only when current status is invited)',
349
+ enum: ['granted', 'declined'],
350
+ },
351
+ message: {
352
+ type: 'string',
353
+ description: 'Custom notification message (only if subscribers can send)',
354
+ },
355
+ imageUrl: {
356
+ type: 'string',
357
+ description: 'Custom image URL (only if subscribers can send)',
358
+ },
359
+ linkUrl: {
360
+ type: 'string',
361
+ description: 'Custom link URL (only if subscribers can send)',
362
+ },
363
+ },
364
+ required: ['followingKey'],
365
+ },
366
+ },
367
+ {
368
+ name: 'subscription_delete',
369
+ description: 'Unsubscribe from a vybit',
370
+ inputSchema: {
371
+ type: 'object',
372
+ properties: {
373
+ followingKey: {
374
+ type: 'string',
375
+ description: 'The unique followingKey of the subscription to delete',
376
+ },
377
+ },
378
+ required: ['followingKey'],
379
+ },
380
+ },
381
+ // Logs
382
+ {
383
+ name: 'logs_list',
384
+ description: 'List all notification logs with optional search and pagination',
385
+ inputSchema: {
386
+ type: 'object',
387
+ properties: {
388
+ search: {
389
+ type: 'string',
390
+ description: 'Search term to filter logs',
391
+ },
392
+ limit: {
393
+ type: 'number',
394
+ description: 'Maximum number of logs to return (default: 50)',
395
+ default: 50,
396
+ },
397
+ offset: {
398
+ type: 'number',
399
+ description: 'Number of logs to skip for pagination (default: 0)',
400
+ default: 0,
401
+ },
402
+ },
403
+ },
404
+ },
405
+ {
406
+ name: 'log_get',
407
+ description: 'Get details about a specific log entry',
408
+ inputSchema: {
409
+ type: 'object',
410
+ properties: {
411
+ logKey: {
412
+ type: 'string',
413
+ description: 'The unique key of the log entry',
414
+ },
415
+ },
416
+ required: ['logKey'],
417
+ },
418
+ },
419
+ {
420
+ name: 'vybit_logs',
421
+ description: 'List logs for a specific vybit you own',
422
+ inputSchema: {
423
+ type: 'object',
424
+ properties: {
425
+ vybitKey: {
426
+ type: 'string',
427
+ description: 'The key of the vybit',
428
+ },
429
+ search: {
430
+ type: 'string',
431
+ description: 'Search term to filter logs',
432
+ },
433
+ limit: {
434
+ type: 'number',
435
+ description: 'Maximum number of logs to return (default: 50)',
436
+ default: 50,
437
+ },
438
+ offset: {
439
+ type: 'number',
440
+ description: 'Number of logs to skip for pagination (default: 0)',
441
+ default: 0,
442
+ },
443
+ },
444
+ required: ['vybitKey'],
445
+ },
446
+ },
447
+ {
448
+ name: 'subscription_logs',
449
+ description: 'List logs for a specific subscription',
450
+ inputSchema: {
451
+ type: 'object',
452
+ properties: {
453
+ followingKey: {
454
+ type: 'string',
455
+ description: 'The followingKey of the subscription',
456
+ },
457
+ search: {
458
+ type: 'string',
459
+ description: 'Search term to filter logs',
460
+ },
461
+ limit: {
462
+ type: 'number',
463
+ description: 'Maximum number of logs to return (default: 50)',
464
+ default: 50,
465
+ },
466
+ offset: {
467
+ type: 'number',
468
+ description: 'Number of logs to skip for pagination (default: 0)',
469
+ default: 0,
470
+ },
471
+ },
472
+ required: ['followingKey'],
473
+ },
474
+ },
475
+ // Peeps (Access Control)
476
+ {
477
+ name: 'peeps_list',
478
+ description: 'List all peeps (people you have shared vybits with)',
479
+ inputSchema: {
480
+ type: 'object',
481
+ properties: {
482
+ search: {
483
+ type: 'string',
484
+ description: 'Search term to filter peeps',
485
+ },
486
+ limit: {
487
+ type: 'number',
488
+ description: 'Maximum number of peeps to return (default: 50)',
489
+ default: 50,
490
+ },
491
+ offset: {
492
+ type: 'number',
493
+ description: 'Number of peeps to skip for pagination (default: 0)',
494
+ default: 0,
495
+ },
496
+ },
497
+ },
498
+ },
499
+ {
500
+ name: 'peep_get',
501
+ description: 'Get details about a specific peep',
502
+ inputSchema: {
503
+ type: 'object',
504
+ properties: {
505
+ peepKey: {
506
+ type: 'string',
507
+ description: 'The unique key of the peep',
508
+ },
509
+ },
510
+ required: ['peepKey'],
511
+ },
512
+ },
513
+ {
514
+ name: 'peep_create',
515
+ description: 'Invite someone to a private vybit by email',
516
+ inputSchema: {
517
+ type: 'object',
518
+ properties: {
519
+ vybitKey: {
520
+ type: 'string',
521
+ description: 'The key of the vybit to share',
522
+ },
523
+ email: {
524
+ type: 'string',
525
+ description: 'Email address of the person to invite',
526
+ },
527
+ },
528
+ required: ['vybitKey', 'email'],
529
+ },
530
+ },
531
+ {
532
+ name: 'peep_delete',
533
+ description: 'Remove a peep (revoke access)',
534
+ inputSchema: {
535
+ type: 'object',
536
+ properties: {
537
+ peepKey: {
538
+ type: 'string',
539
+ description: 'The unique key of the peep to delete',
540
+ },
541
+ },
542
+ required: ['peepKey'],
543
+ },
544
+ },
545
+ {
546
+ name: 'vybit_peeps_list',
547
+ description: 'List all peeps for a specific vybit',
548
+ inputSchema: {
549
+ type: 'object',
550
+ properties: {
551
+ vybitKey: {
552
+ type: 'string',
553
+ description: 'The key of the vybit',
554
+ },
555
+ },
556
+ required: ['vybitKey'],
557
+ },
558
+ },
559
+ ];
560
+ // Create MCP server
561
+ const server = new Server({
562
+ name: 'vybit-mcp-server',
563
+ version: '1.0.0',
564
+ }, {
565
+ capabilities: {
566
+ tools: {},
567
+ },
568
+ });
569
+ // Handle list_tools request
570
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
571
+ return {
572
+ tools: TOOLS,
573
+ };
574
+ });
575
+ // Handle call_tool request
576
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
577
+ const { name, arguments: args } = request.params;
578
+ if (!args) {
579
+ return {
580
+ content: [
581
+ {
582
+ type: 'text',
583
+ text: 'Error: Missing arguments',
584
+ },
585
+ ],
586
+ isError: true,
587
+ };
588
+ }
589
+ try {
590
+ switch (name) {
591
+ case 'vybit_list': {
592
+ const result = await vybitClient.listVybits({
593
+ search: args.search,
594
+ limit: args.limit,
595
+ offset: args.offset,
596
+ });
597
+ return {
598
+ content: [
599
+ {
600
+ type: 'text',
601
+ text: JSON.stringify(result, null, 2),
602
+ },
603
+ ],
604
+ };
605
+ }
606
+ case 'vybit_get': {
607
+ const result = await vybitClient.getVybit(args.vybitId);
608
+ return {
609
+ content: [
610
+ {
611
+ type: 'text',
612
+ text: JSON.stringify(result, null, 2),
613
+ },
614
+ ],
615
+ };
616
+ }
617
+ case 'vybit_create': {
618
+ const createData = {
619
+ name: args.name,
620
+ };
621
+ if (args.description)
622
+ createData.description = args.description;
623
+ if (args.soundKey)
624
+ createData.soundKey = args.soundKey;
625
+ if (args.status)
626
+ createData.status = args.status;
627
+ if (args.triggerType)
628
+ createData.triggerType = args.triggerType;
629
+ if (args.access)
630
+ createData.access = args.access;
631
+ if (args.message !== undefined)
632
+ createData.message = args.message;
633
+ if (args.imageUrl)
634
+ createData.imageUrl = args.imageUrl;
635
+ if (args.linkUrl)
636
+ createData.linkUrl = args.linkUrl;
637
+ const result = await vybitClient.createVybit(createData);
638
+ return {
639
+ content: [
640
+ {
641
+ type: 'text',
642
+ text: JSON.stringify(result, null, 2),
643
+ },
644
+ ],
645
+ };
646
+ }
647
+ case 'vybit_update': {
648
+ const updateData = {};
649
+ if (args.name)
650
+ updateData.name = args.name;
651
+ if (args.description)
652
+ updateData.description = args.description;
653
+ if (args.soundKey)
654
+ updateData.soundKey = args.soundKey;
655
+ if (args.status)
656
+ updateData.status = args.status;
657
+ if (args.access)
658
+ updateData.access = args.access;
659
+ if (args.message !== undefined)
660
+ updateData.message = args.message;
661
+ const result = await vybitClient.patchVybit(args.vybitId, updateData);
662
+ return {
663
+ content: [
664
+ {
665
+ type: 'text',
666
+ text: JSON.stringify(result, null, 2),
667
+ },
668
+ ],
669
+ };
670
+ }
671
+ case 'vybit_delete': {
672
+ await vybitClient.deleteVybit(args.vybitId);
673
+ return {
674
+ content: [
675
+ {
676
+ type: 'text',
677
+ text: JSON.stringify({ success: true, message: 'Vybit deleted successfully' }, null, 2),
678
+ },
679
+ ],
680
+ };
681
+ }
682
+ case 'vybit_trigger': {
683
+ const options = {};
684
+ if (args.message)
685
+ options.message = args.message;
686
+ if (args.imageUrl)
687
+ options.imageUrl = args.imageUrl;
688
+ if (args.linkUrl)
689
+ options.linkUrl = args.linkUrl;
690
+ if (args.log)
691
+ options.log = args.log;
692
+ const result = await vybitClient.triggerVybit(args.triggerKey, Object.keys(options).length > 0 ? options : undefined);
693
+ return {
694
+ content: [
695
+ {
696
+ type: 'text',
697
+ text: JSON.stringify(result, null, 2),
698
+ },
699
+ ],
700
+ };
701
+ }
702
+ case 'sounds_list': {
703
+ const result = await vybitClient.searchSounds({
704
+ search: args.search,
705
+ limit: args.limit,
706
+ offset: args.offset,
707
+ });
708
+ return {
709
+ content: [
710
+ {
711
+ type: 'text',
712
+ text: JSON.stringify(result, null, 2),
713
+ },
714
+ ],
715
+ };
716
+ }
717
+ case 'sound_get': {
718
+ const result = await vybitClient.getSound(args.soundKey);
719
+ return {
720
+ content: [
721
+ {
722
+ type: 'text',
723
+ text: JSON.stringify(result, null, 2),
724
+ },
725
+ ],
726
+ };
727
+ }
728
+ case 'meter_get': {
729
+ const result = await vybitClient.getMeter();
730
+ return {
731
+ content: [
732
+ {
733
+ type: 'text',
734
+ text: JSON.stringify(result, null, 2),
735
+ },
736
+ ],
737
+ };
738
+ }
739
+ // Public Vybit Discovery
740
+ case 'vybits_browse_public': {
741
+ const result = await vybitClient.listPublicVybits({
742
+ search: args.search,
743
+ limit: args.limit,
744
+ offset: args.offset,
745
+ });
746
+ return {
747
+ content: [
748
+ {
749
+ type: 'text',
750
+ text: JSON.stringify(result, null, 2),
751
+ },
752
+ ],
753
+ };
754
+ }
755
+ case 'vybit_get_public': {
756
+ const result = await vybitClient.getPublicVybit(args.subscriptionKey);
757
+ return {
758
+ content: [
759
+ {
760
+ type: 'text',
761
+ text: JSON.stringify(result, null, 2),
762
+ },
763
+ ],
764
+ };
765
+ }
766
+ // Subscription Management
767
+ case 'subscription_create': {
768
+ const result = await vybitClient.createVybitFollow(args.subscriptionKey);
769
+ return {
770
+ content: [
771
+ {
772
+ type: 'text',
773
+ text: JSON.stringify(result, null, 2),
774
+ },
775
+ ],
776
+ };
777
+ }
778
+ case 'subscriptions_list': {
779
+ const result = await vybitClient.listVybitFollows({
780
+ search: args.search,
781
+ limit: args.limit,
782
+ offset: args.offset,
783
+ });
784
+ return {
785
+ content: [
786
+ {
787
+ type: 'text',
788
+ text: JSON.stringify(result, null, 2),
789
+ },
790
+ ],
791
+ };
792
+ }
793
+ case 'subscription_get': {
794
+ const result = await vybitClient.getVybitFollow(args.followingKey);
795
+ return {
796
+ content: [
797
+ {
798
+ type: 'text',
799
+ text: JSON.stringify(result, null, 2),
800
+ },
801
+ ],
802
+ };
803
+ }
804
+ case 'subscription_update': {
805
+ const updateData = {};
806
+ if (args.status)
807
+ updateData.status = args.status;
808
+ if (args.accessStatus)
809
+ updateData.accessStatus = args.accessStatus;
810
+ if (args.message !== undefined)
811
+ updateData.message = args.message;
812
+ if (args.imageUrl)
813
+ updateData.imageUrl = args.imageUrl;
814
+ if (args.linkUrl)
815
+ updateData.linkUrl = args.linkUrl;
816
+ const result = await vybitClient.updateVybitFollow(args.followingKey, updateData);
817
+ return {
818
+ content: [
819
+ {
820
+ type: 'text',
821
+ text: JSON.stringify(result, null, 2),
822
+ },
823
+ ],
824
+ };
825
+ }
826
+ case 'subscription_delete': {
827
+ await vybitClient.deleteVybitFollow(args.followingKey);
828
+ return {
829
+ content: [
830
+ {
831
+ type: 'text',
832
+ text: JSON.stringify({ success: true, message: 'Unsubscribed successfully' }, null, 2),
833
+ },
834
+ ],
835
+ };
836
+ }
837
+ // Logs
838
+ case 'logs_list': {
839
+ const result = await vybitClient.listLogs({
840
+ search: args.search,
841
+ limit: args.limit,
842
+ offset: args.offset,
843
+ });
844
+ return {
845
+ content: [
846
+ {
847
+ type: 'text',
848
+ text: JSON.stringify(result, null, 2),
849
+ },
850
+ ],
851
+ };
852
+ }
853
+ case 'log_get': {
854
+ const result = await vybitClient.getLog(args.logKey);
855
+ return {
856
+ content: [
857
+ {
858
+ type: 'text',
859
+ text: JSON.stringify(result, null, 2),
860
+ },
861
+ ],
862
+ };
863
+ }
864
+ case 'vybit_logs': {
865
+ const result = await vybitClient.listVybitLogs(args.vybitKey, {
866
+ search: args.search,
867
+ limit: args.limit,
868
+ offset: args.offset,
869
+ });
870
+ return {
871
+ content: [
872
+ {
873
+ type: 'text',
874
+ text: JSON.stringify(result, null, 2),
875
+ },
876
+ ],
877
+ };
878
+ }
879
+ case 'subscription_logs': {
880
+ const result = await vybitClient.listVybitFollowLogs(args.followingKey, {
881
+ search: args.search,
882
+ limit: args.limit,
883
+ offset: args.offset,
884
+ });
885
+ return {
886
+ content: [
887
+ {
888
+ type: 'text',
889
+ text: JSON.stringify(result, null, 2),
890
+ },
891
+ ],
892
+ };
893
+ }
894
+ // Peeps
895
+ case 'peeps_list': {
896
+ const result = await vybitClient.listPeeps({
897
+ limit: args.limit,
898
+ offset: args.offset,
899
+ });
900
+ return {
901
+ content: [
902
+ {
903
+ type: 'text',
904
+ text: JSON.stringify(result, null, 2),
905
+ },
906
+ ],
907
+ };
908
+ }
909
+ case 'peep_get': {
910
+ const result = await vybitClient.getPeep(args.peepKey);
911
+ return {
912
+ content: [
913
+ {
914
+ type: 'text',
915
+ text: JSON.stringify(result, null, 2),
916
+ },
917
+ ],
918
+ };
919
+ }
920
+ case 'peep_create': {
921
+ const result = await vybitClient.createPeep(args.vybitKey, args.email);
922
+ return {
923
+ content: [
924
+ {
925
+ type: 'text',
926
+ text: JSON.stringify(result, null, 2),
927
+ },
928
+ ],
929
+ };
930
+ }
931
+ case 'peep_delete': {
932
+ await vybitClient.deletePeep(args.peepKey);
933
+ return {
934
+ content: [
935
+ {
936
+ type: 'text',
937
+ text: JSON.stringify({ success: true, message: 'Peep removed successfully' }, null, 2),
938
+ },
939
+ ],
940
+ };
941
+ }
942
+ case 'vybit_peeps_list': {
943
+ const result = await vybitClient.listVybitPeeps(args.vybitKey);
944
+ return {
945
+ content: [
946
+ {
947
+ type: 'text',
948
+ text: JSON.stringify(result, null, 2),
949
+ },
950
+ ],
951
+ };
952
+ }
953
+ default:
954
+ throw new Error(`Unknown tool: ${name}`);
955
+ }
956
+ }
957
+ catch (error) {
958
+ const errorMessage = error.message || 'Unknown error';
959
+ const statusCode = error.statusCode ? ` (Status: ${error.statusCode})` : '';
960
+ return {
961
+ content: [
962
+ {
963
+ type: 'text',
964
+ text: `Error: ${errorMessage}${statusCode}`,
965
+ },
966
+ ],
967
+ isError: true,
968
+ };
969
+ }
970
+ });
971
+ // Start the server
972
+ async function main() {
973
+ const transport = new StdioServerTransport();
974
+ await server.connect(transport);
975
+ console.error('Vybit MCP server running on stdio');
976
+ }
977
+ main().catch((error) => {
978
+ console.error('Server error:', error);
979
+ process.exit(1);
980
+ });
981
+ //# sourceMappingURL=index.js.map