@serpstat/serpstat-mcp-server 1.0.5 → 1.0.6

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 (36) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/README.md +30 -21
  3. package/dist/handlers/backlinks_tools.d.ts +48 -0
  4. package/dist/handlers/backlinks_tools.d.ts.map +1 -1
  5. package/dist/handlers/backlinks_tools.js +652 -2
  6. package/dist/handlers/backlinks_tools.js.map +1 -1
  7. package/dist/server.d.ts.map +1 -1
  8. package/dist/server.js +7 -1
  9. package/dist/server.js.map +1 -1
  10. package/dist/services/backlinks_tools.d.ts +8 -2
  11. package/dist/services/backlinks_tools.d.ts.map +1 -1
  12. package/dist/services/backlinks_tools.js +141 -0
  13. package/dist/services/backlinks_tools.js.map +1 -1
  14. package/dist/transports/base.d.ts +18 -0
  15. package/dist/transports/base.d.ts.map +1 -0
  16. package/dist/transports/base.js +11 -0
  17. package/dist/transports/base.js.map +1 -0
  18. package/dist/transports/http.d.ts +21 -0
  19. package/dist/transports/http.d.ts.map +1 -0
  20. package/dist/transports/http.js +283 -0
  21. package/dist/transports/http.js.map +1 -0
  22. package/dist/transports/stdio.d.ts +8 -0
  23. package/dist/transports/stdio.d.ts.map +1 -0
  24. package/dist/transports/stdio.js +25 -0
  25. package/dist/transports/stdio.js.map +1 -0
  26. package/dist/types/serpstat.d.ts +72 -0
  27. package/dist/types/serpstat.d.ts.map +1 -1
  28. package/dist/utils/constants.d.ts +13 -0
  29. package/dist/utils/constants.d.ts.map +1 -1
  30. package/dist/utils/constants.js +48 -2
  31. package/dist/utils/constants.js.map +1 -1
  32. package/dist/utils/validation.d.ts +301 -4
  33. package/dist/utils/validation.d.ts.map +1 -1
  34. package/dist/utils/validation.js +70 -1
  35. package/dist/utils/validation.js.map +1 -1
  36. package/package.json +1 -1
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.GetLostBacklinksHandler = exports.GetReferringDomainsHandler = exports.GetActiveBacklinksHandler = exports.GetAnchorsHandler = exports.BacklinksSummaryHandler = void 0;
3
+ exports.GetThreatBacklinksHandler = exports.GetActiveOutlinkDomainsHandler = exports.GetActiveOutlinksHandler = exports.GetBacklinksIntersectionHandler = exports.GetTopPagesByBacklinksHandler = exports.GetTopAnchorsHandler = exports.GetLostBacklinksHandler = exports.GetReferringDomainsHandler = exports.GetActiveBacklinksHandler = exports.GetAnchorsHandler = exports.BacklinksSummaryHandler = void 0;
4
4
  const base_js_1 = require("./base.js");
5
5
  const backlinks_tools_js_1 = require("../services/backlinks_tools.js");
6
6
  const validation_js_1 = require("../utils/validation.js");
@@ -306,7 +306,7 @@ class GetLostBacklinksHandler extends base_js_1.BaseHandler {
306
306
  return 'get_lost_backlinks';
307
307
  }
308
308
  getDescription() {
309
- return 'Get a list of lost backlinks showing linking pages, target pages, link attributes, and deletion dates for domain or URL analysis';
309
+ return 'Get a list of lost backlinks showing linking pages, target pages, link attributes, and deletion dates for domain or URL analysis, **use sort by check desc** to get recently lost backlinks';
310
310
  }
311
311
  getInputSchema() {
312
312
  return {
@@ -405,4 +405,654 @@ class GetLostBacklinksHandler extends base_js_1.BaseHandler {
405
405
  }
406
406
  }
407
407
  exports.GetLostBacklinksHandler = GetLostBacklinksHandler;
408
+ class GetTopAnchorsHandler extends base_js_1.BaseHandler {
409
+ backlinksService;
410
+ constructor() {
411
+ super();
412
+ const config = (0, config_js_1.loadConfig)();
413
+ this.backlinksService = new backlinks_tools_js_1.BacklinksService(config);
414
+ }
415
+ getName() {
416
+ return 'get_top10_anchors';
417
+ }
418
+ getDescription() {
419
+ return 'Get TOP-10 anchors with the number of backlinks and referring domains for domain analysis, use this method is you need a fast brief way to get info about top 10 anchors';
420
+ }
421
+ getInputSchema() {
422
+ return {
423
+ type: "object",
424
+ properties: {
425
+ query: {
426
+ type: "string",
427
+ minLength: constants_js_1.MIN_DOMAIN_LENGTH,
428
+ maxLength: constants_js_1.MAX_DOMAIN_LENGTH,
429
+ description: "Domain name to analyze"
430
+ },
431
+ searchType: {
432
+ type: "string",
433
+ enum: constants_js_1.SEARCH_TYPES,
434
+ default: "domain",
435
+ description: "Type of search: domain or domain_with_subdomains"
436
+ }
437
+ },
438
+ required: ["query"],
439
+ additionalProperties: false
440
+ };
441
+ }
442
+ async handle(call) {
443
+ try {
444
+ const params = validation_js_1.getTopAnchorsSchema.parse(call.arguments);
445
+ const result = await this.backlinksService.getTopAnchors(params);
446
+ return this.createSuccessResponse(result);
447
+ }
448
+ catch (error) {
449
+ if (error instanceof zod_1.z.ZodError) {
450
+ return this.createErrorResponse(new Error('Invalid parameters: ' + error.errors.map(e => e.path.join('.') + ': ' + e.message).join(', ')));
451
+ }
452
+ return this.createErrorResponse(error);
453
+ }
454
+ }
455
+ }
456
+ exports.GetTopAnchorsHandler = GetTopAnchorsHandler;
457
+ class GetTopPagesByBacklinksHandler extends base_js_1.BaseHandler {
458
+ backlinksService;
459
+ constructor() {
460
+ super();
461
+ const config = (0, config_js_1.loadConfig)();
462
+ this.backlinksService = new backlinks_tools_js_1.BacklinksService(config);
463
+ }
464
+ getName() {
465
+ return 'get_top_pages_by_backlinks';
466
+ }
467
+ getDescription() {
468
+ return 'Get leading pages by backlinks using Serpstat API. Returns pages with the highest number of referring pages, domains, and IP addresses for comprehensive backlink analysis.';
469
+ }
470
+ getInputSchema() {
471
+ return {
472
+ type: "object",
473
+ properties: {
474
+ query: {
475
+ type: "string",
476
+ minLength: constants_js_1.MIN_DOMAIN_LENGTH,
477
+ maxLength: constants_js_1.MAX_DOMAIN_LENGTH,
478
+ description: "Domain name to analyze"
479
+ },
480
+ searchType: {
481
+ type: "string",
482
+ enum: constants_js_1.SEARCH_TYPES,
483
+ default: "domain",
484
+ description: "Type of search: domain or domain_with_subdomains"
485
+ },
486
+ sort: {
487
+ type: "string",
488
+ enum: constants_js_1.TOP_PAGES_SORT_FIELDS,
489
+ default: "lastupdate",
490
+ description: "Field to sort results by"
491
+ },
492
+ order: {
493
+ type: "string",
494
+ enum: constants_js_1.SORT_ORDER,
495
+ description: "Sort order: asc or desc"
496
+ },
497
+ complexFilter: {
498
+ type: "array",
499
+ items: {
500
+ type: "array",
501
+ items: {
502
+ oneOf: [
503
+ {
504
+ type: "object",
505
+ properties: {
506
+ field: {
507
+ type: "string",
508
+ enum: constants_js_1.TOP_PAGES_COMPLEX_FILTER_FIELDS
509
+ },
510
+ compareType: {
511
+ type: "string",
512
+ enum: constants_js_1.COMPLEX_FILTER_COMPARE_TYPES
513
+ },
514
+ value: {
515
+ type: "array",
516
+ items: {
517
+ oneOf: [
518
+ { type: "string" },
519
+ { type: "number" }
520
+ ]
521
+ }
522
+ }
523
+ },
524
+ required: ["field", "compareType", "value"],
525
+ additionalProperties: false
526
+ },
527
+ {
528
+ type: "object",
529
+ properties: {
530
+ additional_filters: {
531
+ type: "string",
532
+ enum: constants_js_1.ADDITIONAL_FILTERS
533
+ }
534
+ },
535
+ required: ["additional_filters"],
536
+ additionalProperties: false
537
+ }
538
+ ]
539
+ }
540
+ },
541
+ description: "Complex filters for advanced filtering"
542
+ },
543
+ page: {
544
+ type: "integer",
545
+ minimum: constants_js_1.MIN_PAGE,
546
+ default: 1,
547
+ description: "Page number for pagination"
548
+ },
549
+ size: {
550
+ type: "integer",
551
+ minimum: 1,
552
+ maximum: constants_js_1.MAX_PAGE_SIZE,
553
+ default: constants_js_1.DEFAULT_PAGE_SIZE,
554
+ description: "Number of results per page"
555
+ }
556
+ },
557
+ required: ["query"],
558
+ additionalProperties: false
559
+ };
560
+ }
561
+ async handle(call) {
562
+ try {
563
+ const params = validation_js_1.getTopPagesByBacklinksSchema.parse(call.arguments);
564
+ const result = await this.backlinksService.getTopPagesByBacklinks(params);
565
+ return this.createSuccessResponse(result);
566
+ }
567
+ catch (error) {
568
+ if (error instanceof zod_1.z.ZodError) {
569
+ return this.createErrorResponse(new Error('Invalid parameters: ' + error.errors.map(e => e.path.join('.') + ': ' + e.message).join(', ')));
570
+ }
571
+ return this.createErrorResponse(error);
572
+ }
573
+ }
574
+ }
575
+ exports.GetTopPagesByBacklinksHandler = GetTopPagesByBacklinksHandler;
576
+ class GetBacklinksIntersectionHandler extends base_js_1.BaseHandler {
577
+ backlinksService;
578
+ constructor() {
579
+ super();
580
+ const config = (0, config_js_1.loadConfig)();
581
+ this.backlinksService = new backlinks_tools_js_1.BacklinksService(config);
582
+ }
583
+ getName() {
584
+ return 'get_backlinks_intersection';
585
+ }
586
+ getDescription() {
587
+ return 'Get backlinks from domains that link to multiple analyzed sites simultaneously. This method reveals shared referring domains between your target domain and competitors, useful for competitive backlink analysis and identifying potential link sources. Returns intersection data showing which donors link to multiple domains in your analysis set, including link metrics, anchor texts, and domain authority scores.';
588
+ }
589
+ getInputSchema() {
590
+ return {
591
+ type: "object",
592
+ properties: {
593
+ query: {
594
+ type: "string",
595
+ minLength: constants_js_1.MIN_DOMAIN_LENGTH,
596
+ maxLength: constants_js_1.MAX_DOMAIN_LENGTH,
597
+ description: "Main domain to analyze for backlinks intersection"
598
+ },
599
+ intersect: {
600
+ type: "array",
601
+ items: {
602
+ type: "string",
603
+ minLength: constants_js_1.MIN_DOMAIN_LENGTH,
604
+ maxLength: constants_js_1.MAX_DOMAIN_LENGTH
605
+ },
606
+ minItems: 1,
607
+ maxItems: constants_js_1.MAX_INTERSECT_DOMAINS,
608
+ description: "Array of competitor domains for intersection analysis"
609
+ },
610
+ sort: {
611
+ type: "string",
612
+ enum: constants_js_1.BACKLINKS_INTERSECTION_SORT_FIELDS,
613
+ default: "domain_rank",
614
+ description: "Field to sort results by (domain_rank, links_count1, links_count2, links_count3)"
615
+ },
616
+ order: {
617
+ type: "string",
618
+ enum: constants_js_1.SORT_ORDER,
619
+ default: "desc",
620
+ description: "Sort order: asc or desc"
621
+ },
622
+ complexFilter: {
623
+ type: "array",
624
+ items: {
625
+ type: "array",
626
+ items: {
627
+ oneOf: [
628
+ {
629
+ type: "object",
630
+ properties: {
631
+ field: {
632
+ type: "string",
633
+ enum: constants_js_1.BACKLINKS_INTERSECTION_COMPLEX_FILTER_FIELDS
634
+ },
635
+ compareType: {
636
+ type: "string",
637
+ enum: constants_js_1.COMPLEX_FILTER_COMPARE_TYPES
638
+ },
639
+ value: {
640
+ type: "array",
641
+ items: {
642
+ oneOf: [
643
+ { type: "string" },
644
+ { type: "number" }
645
+ ]
646
+ }
647
+ }
648
+ },
649
+ required: ["field", "compareType", "value"],
650
+ additionalProperties: false
651
+ },
652
+ {
653
+ type: "object",
654
+ properties: {
655
+ additional_filters: {
656
+ type: "string",
657
+ enum: constants_js_1.ADDITIONAL_FILTERS
658
+ }
659
+ },
660
+ required: ["additional_filters"],
661
+ additionalProperties: false
662
+ }
663
+ ]
664
+ }
665
+ },
666
+ description: "Complex filters for advanced filtering"
667
+ },
668
+ page: {
669
+ type: "integer",
670
+ minimum: constants_js_1.MIN_PAGE,
671
+ default: 1,
672
+ description: "Page number for pagination"
673
+ },
674
+ size: {
675
+ type: "integer",
676
+ minimum: 1,
677
+ maximum: constants_js_1.MAX_PAGE_SIZE,
678
+ default: constants_js_1.DEFAULT_PAGE_SIZE,
679
+ description: "Number of results per page"
680
+ }
681
+ },
682
+ required: ["query", "intersect"],
683
+ additionalProperties: false
684
+ };
685
+ }
686
+ async handle(call) {
687
+ try {
688
+ const params = validation_js_1.getBacklinksIntersectionSchema.parse(call.arguments);
689
+ const result = await this.backlinksService.getBacklinksIntersection(params);
690
+ return this.createSuccessResponse(result);
691
+ }
692
+ catch (error) {
693
+ if (error instanceof zod_1.z.ZodError) {
694
+ return this.createErrorResponse(new Error('Invalid parameters: ' + error.errors.map(e => e.path.join('.') + ': ' + e.message).join(', ')));
695
+ }
696
+ return this.createErrorResponse(error);
697
+ }
698
+ }
699
+ }
700
+ exports.GetBacklinksIntersectionHandler = GetBacklinksIntersectionHandler;
701
+ class GetActiveOutlinksHandler extends base_js_1.BaseHandler {
702
+ backlinksService;
703
+ constructor() {
704
+ super();
705
+ const config = (0, config_js_1.loadConfig)();
706
+ this.backlinksService = new backlinks_tools_js_1.BacklinksService(config);
707
+ }
708
+ getName() {
709
+ return 'get_active_outlinks';
710
+ }
711
+ getDescription() {
712
+ return 'Get active outbound links from a domain or URL. Returns external links the site points to, including target URLs, anchor text, link attributes (nofollow/dofollow), link types, and discovery dates. Useful for analyzing linking strategies, finding partnership opportunities, and auditing outbound link profiles.';
713
+ }
714
+ getInputSchema() {
715
+ return {
716
+ type: "object",
717
+ properties: {
718
+ query: {
719
+ type: "string",
720
+ minLength: constants_js_1.MIN_DOMAIN_LENGTH,
721
+ maxLength: constants_js_1.MAX_DOMAIN_LENGTH,
722
+ description: "Domain name or URL to analyze for outbound links"
723
+ },
724
+ searchType: {
725
+ type: "string",
726
+ enum: constants_js_1.SEARCH_TYPES_URL,
727
+ default: "domain",
728
+ description: "Type of search: domain, domain_with_subdomains, url, or part_url"
729
+ },
730
+ sort: {
731
+ type: "string",
732
+ enum: constants_js_1.ACTIVE_OUTLINKS_SORT_FIELDS,
733
+ default: "check",
734
+ description: "Field to sort results by"
735
+ },
736
+ order: {
737
+ type: "string",
738
+ enum: constants_js_1.SORT_ORDER,
739
+ default: "desc",
740
+ description: "Sort order: asc or desc"
741
+ },
742
+ linkPerDomain: {
743
+ type: "integer",
744
+ minimum: 1,
745
+ description: "Maximum number of links to return per domain"
746
+ },
747
+ complexFilter: {
748
+ type: "array",
749
+ items: {
750
+ type: "array",
751
+ items: {
752
+ oneOf: [
753
+ {
754
+ type: "object",
755
+ properties: {
756
+ field: {
757
+ type: "string",
758
+ enum: constants_js_1.ACTIVE_OUTLINKS_COMPLEX_FILTER_FIELDS
759
+ },
760
+ compareType: {
761
+ type: "string",
762
+ enum: constants_js_1.COMPLEX_FILTER_COMPARE_TYPES
763
+ },
764
+ value: {
765
+ type: "array",
766
+ items: {
767
+ oneOf: [
768
+ { type: "string" },
769
+ { type: "number" }
770
+ ]
771
+ }
772
+ }
773
+ },
774
+ required: ["field", "compareType", "value"],
775
+ additionalProperties: false
776
+ },
777
+ {
778
+ type: "object",
779
+ properties: {
780
+ additional_filters: {
781
+ type: "string",
782
+ enum: constants_js_1.ADDITIONAL_FILTERS
783
+ }
784
+ },
785
+ required: ["additional_filters"],
786
+ additionalProperties: false
787
+ }
788
+ ]
789
+ }
790
+ },
791
+ description: "Complex filters for advanced filtering"
792
+ },
793
+ page: {
794
+ type: "integer",
795
+ minimum: constants_js_1.MIN_PAGE,
796
+ default: 1,
797
+ description: "Page number for pagination"
798
+ },
799
+ size: {
800
+ type: "integer",
801
+ minimum: 1,
802
+ maximum: constants_js_1.MAX_PAGE_SIZE,
803
+ default: constants_js_1.DEFAULT_PAGE_SIZE,
804
+ description: "Number of results per page"
805
+ }
806
+ },
807
+ required: ["query", "searchType"],
808
+ additionalProperties: false
809
+ };
810
+ }
811
+ async handle(call) {
812
+ try {
813
+ const params = validation_js_1.getActiveOutlinksSchema.parse(call.arguments);
814
+ const result = await this.backlinksService.getActiveOutlinks(params);
815
+ return this.createSuccessResponse(result);
816
+ }
817
+ catch (error) {
818
+ if (error instanceof zod_1.z.ZodError) {
819
+ return this.createErrorResponse(new Error('Invalid parameters: ' + error.errors.map(e => e.path.join('.') + ': ' + e.message).join(', ')));
820
+ }
821
+ return this.createErrorResponse(error);
822
+ }
823
+ }
824
+ }
825
+ exports.GetActiveOutlinksHandler = GetActiveOutlinksHandler;
826
+ class GetActiveOutlinkDomainsHandler extends base_js_1.BaseHandler {
827
+ backlinksService;
828
+ constructor() {
829
+ super();
830
+ const config = (0, config_js_1.loadConfig)();
831
+ this.backlinksService = new backlinks_tools_js_1.BacklinksService(config);
832
+ }
833
+ getName() {
834
+ return 'get_active_outlink_domains';
835
+ }
836
+ getDescription() {
837
+ return 'Get external domains that receive outbound links from the analyzed domain. Returns target domains with total link counts, revealing partnership networks, referenced sources, and linking patterns. Helps identify collaboration opportunities by analyzing which domains competitors link to.';
838
+ }
839
+ getInputSchema() {
840
+ return {
841
+ type: "object",
842
+ properties: {
843
+ query: {
844
+ type: "string",
845
+ description: "Domain name to analyze outbound link destinations",
846
+ minLength: constants_js_1.MIN_DOMAIN_LENGTH,
847
+ maxLength: constants_js_1.MAX_DOMAIN_LENGTH
848
+ },
849
+ searchType: {
850
+ type: "string",
851
+ enum: constants_js_1.SEARCH_TYPES_URL,
852
+ description: "Search type for analysis",
853
+ default: "domain"
854
+ },
855
+ sort: {
856
+ type: "string",
857
+ enum: constants_js_1.ACTIVE_OUTLINK_DOMAINS_SORT_FIELDS,
858
+ description: "Field to sort results by",
859
+ default: "domain_rank"
860
+ },
861
+ order: {
862
+ type: "string",
863
+ enum: constants_js_1.SORT_ORDER,
864
+ description: "Sort order",
865
+ default: "desc"
866
+ },
867
+ complexFilter: {
868
+ type: "array",
869
+ description: "Complex filtering conditions",
870
+ items: {
871
+ type: "array",
872
+ items: {
873
+ anyOf: [
874
+ {
875
+ type: "object",
876
+ properties: {
877
+ field: {
878
+ type: "string",
879
+ enum: constants_js_1.ACTIVE_OUTLINK_DOMAINS_COMPLEX_FILTER_FIELDS
880
+ },
881
+ compareType: {
882
+ type: "string",
883
+ enum: constants_js_1.COMPLEX_FILTER_COMPARE_TYPES
884
+ },
885
+ value: {
886
+ type: "array",
887
+ items: {
888
+ oneOf: [
889
+ { type: "integer" },
890
+ { type: "string" }
891
+ ]
892
+ }
893
+ }
894
+ },
895
+ required: ["field", "compareType", "value"]
896
+ },
897
+ {
898
+ type: "object",
899
+ properties: {
900
+ additional_filters: {
901
+ type: "string",
902
+ enum: ["only_subdomains", "only_hosts", "last_week"]
903
+ }
904
+ },
905
+ required: ["additional_filters"]
906
+ }
907
+ ]
908
+ }
909
+ }
910
+ },
911
+ page: {
912
+ type: "integer",
913
+ description: "Page number for pagination",
914
+ minimum: constants_js_1.MIN_PAGE,
915
+ default: 1
916
+ },
917
+ size: {
918
+ type: "integer",
919
+ description: "Number of results per page",
920
+ minimum: 1,
921
+ maximum: constants_js_1.MAX_PAGE_SIZE,
922
+ default: constants_js_1.DEFAULT_PAGE_SIZE
923
+ }
924
+ },
925
+ required: ["query", "searchType"],
926
+ additionalProperties: false
927
+ };
928
+ }
929
+ async handle(call) {
930
+ try {
931
+ const params = validation_js_1.getActiveOutlinkDomainsSchema.parse(call.arguments);
932
+ const result = await this.backlinksService.getActiveOutlinkDomains(params);
933
+ return this.createSuccessResponse(result);
934
+ }
935
+ catch (error) {
936
+ if (error instanceof zod_1.z.ZodError) {
937
+ return this.createErrorResponse(new Error('Invalid parameters: ' + error.errors.map(e => e.path.join('.') + ': ' + e.message).join(', ')));
938
+ }
939
+ return this.createErrorResponse(error);
940
+ }
941
+ }
942
+ }
943
+ exports.GetActiveOutlinkDomainsHandler = GetActiveOutlinkDomainsHandler;
944
+ class GetThreatBacklinksHandler extends base_js_1.BaseHandler {
945
+ backlinksService;
946
+ constructor() {
947
+ super();
948
+ const config = (0, config_js_1.loadConfig)();
949
+ this.backlinksService = new backlinks_tools_js_1.BacklinksService(config);
950
+ }
951
+ getName() {
952
+ return 'get_threat_backlinks';
953
+ }
954
+ getDescription() {
955
+ return 'Get malicious backlinks pointing to the analyzed domain. Returns links from sites flagged for threats like social engineering, malware, or unwanted software. Shows referring domain, source URL, target URL, platform type, threat type, and last update date. Essential for identifying and removing harmful backlinks that could damage domain reputation and SEO rankings.';
956
+ }
957
+ getInputSchema() {
958
+ return {
959
+ type: "object",
960
+ properties: {
961
+ query: {
962
+ type: "string",
963
+ pattern: constants_js_1.DOMAIN_NAME_REGEX,
964
+ minLength: constants_js_1.MIN_DOMAIN_LENGTH,
965
+ maxLength: constants_js_1.MAX_DOMAIN_LENGTH,
966
+ description: "Domain to analyze for threat backlinks"
967
+ },
968
+ searchType: {
969
+ type: "string",
970
+ enum: constants_js_1.SEARCH_TYPES,
971
+ default: "domain",
972
+ description: "Search type: 'domain' (exact domain) or 'domain_with_subdomains' (includes subdomains)"
973
+ },
974
+ sort: {
975
+ type: "string",
976
+ enum: constants_js_1.BACKLINKS_THREAT_SORT_FIELDS,
977
+ default: "lastupdate",
978
+ description: "Field to sort by: lastupdate, url_from, url_to, platform_type, threat_type"
979
+ },
980
+ order: {
981
+ type: "string",
982
+ enum: constants_js_1.SORT_ORDER,
983
+ default: "desc",
984
+ description: "Sort order: asc or desc"
985
+ },
986
+ linkPerDomain: {
987
+ type: "integer",
988
+ minimum: 1,
989
+ description: "Maximum number of links per domain to return"
990
+ },
991
+ complexFilter: {
992
+ type: "array",
993
+ description: "Complex filtering conditions using field-value pairs with comparison operators",
994
+ items: {
995
+ type: "array",
996
+ items: {
997
+ type: "object",
998
+ properties: {
999
+ field: {
1000
+ type: "string",
1001
+ enum: constants_js_1.BACKLINKS_THREAT_COMPLEX_FILTER_FIELDS,
1002
+ description: "Field to filter by"
1003
+ },
1004
+ compareType: {
1005
+ type: "string",
1006
+ enum: constants_js_1.COMPLEX_FILTER_COMPARE_TYPES,
1007
+ description: "Comparison operator for filtering"
1008
+ },
1009
+ value: {
1010
+ type: "array",
1011
+ description: "Values to compare against",
1012
+ items: {
1013
+ oneOf: [
1014
+ { type: "integer" },
1015
+ { type: "string" }
1016
+ ]
1017
+ }
1018
+ }
1019
+ },
1020
+ required: ["field", "compareType", "value"],
1021
+ additionalProperties: false
1022
+ }
1023
+ }
1024
+ },
1025
+ page: {
1026
+ type: "integer",
1027
+ description: "Page number for pagination",
1028
+ minimum: constants_js_1.MIN_PAGE,
1029
+ default: 1
1030
+ },
1031
+ size: {
1032
+ type: "integer",
1033
+ description: "Number of results per page",
1034
+ minimum: 1,
1035
+ maximum: constants_js_1.MAX_PAGE_SIZE,
1036
+ default: constants_js_1.DEFAULT_PAGE_SIZE
1037
+ }
1038
+ },
1039
+ required: ["query"],
1040
+ additionalProperties: false
1041
+ };
1042
+ }
1043
+ async handle(call) {
1044
+ try {
1045
+ const params = validation_js_1.getThreatBacklinksSchema.parse(call.arguments);
1046
+ const result = await this.backlinksService.getThreatBacklinks(params);
1047
+ return this.createSuccessResponse(result);
1048
+ }
1049
+ catch (error) {
1050
+ if (error instanceof zod_1.z.ZodError) {
1051
+ return this.createErrorResponse(new Error('Invalid parameters: ' + error.errors.map(e => e.path.join('.') + ': ' + e.message).join(', ')));
1052
+ }
1053
+ return this.createErrorResponse(error);
1054
+ }
1055
+ }
1056
+ }
1057
+ exports.GetThreatBacklinksHandler = GetThreatBacklinksHandler;
408
1058
  //# sourceMappingURL=backlinks_tools.js.map