@prmichaelsen/reddit-mcp 0.1.0 → 0.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 (58) hide show
  1. package/.claude/settings.local.json +4 -1
  2. package/README.md +253 -27
  3. package/agent/progress.yaml +29 -30
  4. package/dist/factory.js +1206 -0
  5. package/dist/factory.js.map +4 -4
  6. package/dist/index.js +1206 -0
  7. package/dist/index.js.map +4 -4
  8. package/dist/server.d.ts.map +1 -1
  9. package/dist/server.js +1206 -0
  10. package/dist/server.js.map +4 -4
  11. package/dist/tools/account.d.ts +4 -0
  12. package/dist/tools/account.d.ts.map +1 -0
  13. package/dist/tools/comments.d.ts +4 -0
  14. package/dist/tools/comments.d.ts.map +1 -0
  15. package/dist/tools/flair.d.ts +4 -0
  16. package/dist/tools/flair.d.ts.map +1 -0
  17. package/dist/tools/messages.d.ts +4 -0
  18. package/dist/tools/messages.d.ts.map +1 -0
  19. package/dist/tools/moderation.d.ts +4 -0
  20. package/dist/tools/moderation.d.ts.map +1 -0
  21. package/dist/tools/multireddits.d.ts +4 -0
  22. package/dist/tools/multireddits.d.ts.map +1 -0
  23. package/dist/tools/posts.d.ts +4 -0
  24. package/dist/tools/posts.d.ts.map +1 -0
  25. package/dist/tools/subreddits.d.ts +4 -0
  26. package/dist/tools/subreddits.d.ts.map +1 -0
  27. package/dist/tools/users.d.ts +4 -0
  28. package/dist/tools/users.d.ts.map +1 -0
  29. package/dist/tools/voting.d.ts +4 -0
  30. package/dist/tools/voting.d.ts.map +1 -0
  31. package/dist/tools/wiki.d.ts +4 -0
  32. package/dist/tools/wiki.d.ts.map +1 -0
  33. package/package.json +1 -1
  34. package/src/server.ts +22 -0
  35. package/src/tools/account.ts +84 -0
  36. package/src/tools/comments.ts +73 -0
  37. package/src/tools/flair.ts +79 -0
  38. package/src/tools/messages.ts +126 -0
  39. package/src/tools/moderation.ts +292 -0
  40. package/src/tools/multireddits.ts +152 -0
  41. package/src/tools/posts.ts +177 -0
  42. package/src/tools/subreddits.ts +137 -0
  43. package/src/tools/users.ts +181 -0
  44. package/src/tools/voting.ts +90 -0
  45. package/src/tools/wiki.ts +118 -0
  46. package/tests/fixtures/reddit-responses.ts +159 -0
  47. package/tests/unit/account.test.ts +95 -0
  48. package/tests/unit/comments.test.ts +92 -0
  49. package/tests/unit/flair.test.ts +101 -0
  50. package/tests/unit/messages.test.ts +106 -0
  51. package/tests/unit/moderation.test.ts +243 -0
  52. package/tests/unit/multireddits.test.ts +136 -0
  53. package/tests/unit/posts.test.ts +155 -0
  54. package/tests/unit/subreddits.test.ts +125 -0
  55. package/tests/unit/transport.test.ts +13 -0
  56. package/tests/unit/users.test.ts +124 -0
  57. package/tests/unit/voting.test.ts +110 -0
  58. package/tests/unit/wiki.test.ts +116 -0
package/dist/factory.js CHANGED
@@ -30369,6 +30369,1201 @@ function registerSearchTools(server, client) {
30369
30369
  );
30370
30370
  }
30371
30371
 
30372
+ // src/tools/posts.ts
30373
+ function buildParams3(input) {
30374
+ const params = {};
30375
+ for (const [key, value] of Object.entries(input)) {
30376
+ if (value !== void 0 && value !== null) {
30377
+ params[key] = String(value);
30378
+ }
30379
+ }
30380
+ return params;
30381
+ }
30382
+ function registerPostTools(server, client) {
30383
+ server.tool(
30384
+ "reddit_submit",
30385
+ "Create a new post (self-post or link). Requires 'submit' scope.",
30386
+ {
30387
+ sr: external_exports3.string().describe("Subreddit name to post in (without r/ prefix)"),
30388
+ title: external_exports3.string().describe("Post title"),
30389
+ kind: external_exports3.enum(["self", "link"]).describe("Post type: 'self' for text post, 'link' for URL post"),
30390
+ text: external_exports3.string().optional().describe("Post body text (markdown). Required for self posts."),
30391
+ url: external_exports3.string().optional().describe("URL to submit. Required for link posts."),
30392
+ nsfw: external_exports3.boolean().optional().describe("Mark as NSFW"),
30393
+ spoiler: external_exports3.boolean().optional().describe("Mark as spoiler"),
30394
+ flair_id: external_exports3.string().optional().describe("Flair template ID"),
30395
+ flair_text: external_exports3.string().optional().describe("Flair text (if flair allows custom text)"),
30396
+ resubmit: external_exports3.boolean().optional().describe("Allow resubmitting a previously submitted link"),
30397
+ sendreplies: external_exports3.boolean().optional().describe("Send replies to inbox (default true)")
30398
+ },
30399
+ async (input) => {
30400
+ const data = await client.post("/api/submit", {
30401
+ ...buildParams3(input),
30402
+ api_type: "json"
30403
+ });
30404
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
30405
+ }
30406
+ );
30407
+ server.tool(
30408
+ "reddit_edit",
30409
+ "Edit the body text of a self-post or comment. Requires 'edit' scope.",
30410
+ {
30411
+ thing_id: external_exports3.string().describe("Fullname of the post (t3_) or comment (t1_) to edit"),
30412
+ text: external_exports3.string().describe("New body text (markdown)")
30413
+ },
30414
+ async (input) => {
30415
+ const data = await client.post("/api/editusertext", {
30416
+ ...buildParams3(input),
30417
+ api_type: "json"
30418
+ });
30419
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
30420
+ }
30421
+ );
30422
+ server.tool(
30423
+ "reddit_delete",
30424
+ "Delete a post or comment. Requires 'edit' scope.",
30425
+ {
30426
+ id: external_exports3.string().describe("Fullname of the post (t3_) or comment (t1_) to delete")
30427
+ },
30428
+ async (input) => {
30429
+ const data = await client.post("/api/del", buildParams3(input));
30430
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
30431
+ }
30432
+ );
30433
+ server.tool(
30434
+ "reddit_hide",
30435
+ "Hide a post from your listings. Requires 'report' scope.",
30436
+ {
30437
+ id: external_exports3.string().describe("Fullname of the post to hide (t3_)")
30438
+ },
30439
+ async (input) => {
30440
+ const data = await client.post("/api/hide", buildParams3(input));
30441
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
30442
+ }
30443
+ );
30444
+ server.tool(
30445
+ "reddit_unhide",
30446
+ "Unhide a previously hidden post. Requires 'report' scope.",
30447
+ {
30448
+ id: external_exports3.string().describe("Fullname of the post to unhide (t3_)")
30449
+ },
30450
+ async (input) => {
30451
+ const data = await client.post("/api/unhide", buildParams3(input));
30452
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
30453
+ }
30454
+ );
30455
+ server.tool(
30456
+ "reddit_mark_nsfw",
30457
+ "Mark a post as NSFW. Requires 'modposts' scope.",
30458
+ {
30459
+ id: external_exports3.string().describe("Fullname of the post to mark NSFW (t3_)")
30460
+ },
30461
+ async (input) => {
30462
+ const data = await client.post("/api/marknsfw", buildParams3(input));
30463
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
30464
+ }
30465
+ );
30466
+ server.tool(
30467
+ "reddit_unmark_nsfw",
30468
+ "Remove NSFW mark from a post. Requires 'modposts' scope.",
30469
+ {
30470
+ id: external_exports3.string().describe("Fullname of the post to unmark NSFW (t3_)")
30471
+ },
30472
+ async (input) => {
30473
+ const data = await client.post("/api/unmarknsfw", buildParams3(input));
30474
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
30475
+ }
30476
+ );
30477
+ server.tool(
30478
+ "reddit_spoiler",
30479
+ "Mark a post as a spoiler. Requires 'modposts' scope.",
30480
+ {
30481
+ id: external_exports3.string().describe("Fullname of the post to mark as spoiler (t3_)")
30482
+ },
30483
+ async (input) => {
30484
+ const data = await client.post("/api/spoiler", buildParams3(input));
30485
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
30486
+ }
30487
+ );
30488
+ server.tool(
30489
+ "reddit_unspoiler",
30490
+ "Remove spoiler mark from a post. Requires 'modposts' scope.",
30491
+ {
30492
+ id: external_exports3.string().describe("Fullname of the post to remove spoiler mark (t3_)")
30493
+ },
30494
+ async (input) => {
30495
+ const data = await client.post("/api/unspoiler", buildParams3(input));
30496
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
30497
+ }
30498
+ );
30499
+ }
30500
+
30501
+ // src/tools/comments.ts
30502
+ function buildParams4(input) {
30503
+ const params = {};
30504
+ for (const [key, value] of Object.entries(input)) {
30505
+ if (value !== void 0 && value !== null) {
30506
+ params[key] = String(value);
30507
+ }
30508
+ }
30509
+ return params;
30510
+ }
30511
+ function registerCommentTools(server, client) {
30512
+ server.tool(
30513
+ "reddit_comment",
30514
+ "Post a comment or reply. Use a t3_ fullname as parent for a top-level comment on a post, or a t1_ fullname to reply to another comment. Requires 'submit' scope.",
30515
+ {
30516
+ parent: external_exports3.string().describe(
30517
+ "Fullname of the parent: t3_ for a post (top-level comment) or t1_ for a comment (reply)"
30518
+ ),
30519
+ text: external_exports3.string().describe("Comment body text (markdown)")
30520
+ },
30521
+ async (input) => {
30522
+ const data = await client.post("/api/comment", {
30523
+ ...buildParams4(input),
30524
+ api_type: "json"
30525
+ });
30526
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
30527
+ }
30528
+ );
30529
+ server.tool(
30530
+ "reddit_more_children",
30531
+ "Load more comments from collapsed 'load more' stubs in a comment thread. Requires 'read' scope.",
30532
+ {
30533
+ link_id: external_exports3.string().describe("Fullname of the parent post (t3_)"),
30534
+ children: external_exports3.string().describe(
30535
+ "Comma-separated list of comment IDs to expand (from the 'more' object's children array)"
30536
+ ),
30537
+ sort: external_exports3.enum(["confidence", "top", "new", "controversial", "old", "qa"]).optional().describe("Comment sort order"),
30538
+ limit_children: external_exports3.boolean().optional().describe("If true, only return the children requested (no deeper)")
30539
+ },
30540
+ async (input) => {
30541
+ const data = await client.get(
30542
+ "/api/morechildren",
30543
+ {
30544
+ ...buildParams4(input),
30545
+ api_type: "json"
30546
+ }
30547
+ );
30548
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
30549
+ }
30550
+ );
30551
+ }
30552
+
30553
+ // src/tools/voting.ts
30554
+ function registerVotingTools(server, client) {
30555
+ server.tool(
30556
+ "reddit_vote",
30557
+ "Upvote, downvote, or remove vote on a post or comment. Requires 'vote' scope.",
30558
+ {
30559
+ id: external_exports3.string().describe("Fullname of the post (t3_) or comment (t1_) to vote on"),
30560
+ dir: external_exports3.enum(["1", "0", "-1"]).describe("Vote direction: '1' = upvote, '0' = unvote, '-1' = downvote")
30561
+ },
30562
+ async (input) => {
30563
+ const data = await client.post("/api/vote", {
30564
+ id: input.id,
30565
+ dir: input.dir
30566
+ });
30567
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
30568
+ }
30569
+ );
30570
+ server.tool(
30571
+ "reddit_save",
30572
+ "Save a post or comment to your saved list. Requires 'save' scope.",
30573
+ {
30574
+ id: external_exports3.string().describe("Fullname of the post (t3_) or comment (t1_) to save"),
30575
+ category: external_exports3.string().optional().describe("Save category name (Reddit Gold feature)")
30576
+ },
30577
+ async (input) => {
30578
+ const params = {
30579
+ id: input.id,
30580
+ category: input.category
30581
+ };
30582
+ const data = await client.post("/api/save", params);
30583
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
30584
+ }
30585
+ );
30586
+ server.tool(
30587
+ "reddit_unsave",
30588
+ "Remove a post or comment from your saved list. Requires 'save' scope.",
30589
+ {
30590
+ id: external_exports3.string().describe("Fullname of the post (t3_) or comment (t1_) to unsave")
30591
+ },
30592
+ async (input) => {
30593
+ const data = await client.post("/api/unsave", { id: input.id });
30594
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
30595
+ }
30596
+ );
30597
+ server.tool(
30598
+ "reddit_report",
30599
+ "Report a post or comment to subreddit moderators. Requires 'report' scope.",
30600
+ {
30601
+ thing_id: external_exports3.string().describe("Fullname of the post (t3_) or comment (t1_) to report"),
30602
+ reason: external_exports3.string().describe("Subreddit rule violated (from subreddit rules list)"),
30603
+ other_reason: external_exports3.string().optional().describe("Additional explanation (for 'other' reason)")
30604
+ },
30605
+ async (input) => {
30606
+ const params = {
30607
+ thing_id: input.thing_id,
30608
+ reason: input.reason,
30609
+ other_reason: input.other_reason
30610
+ };
30611
+ const data = await client.post("/api/report", params);
30612
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
30613
+ }
30614
+ );
30615
+ }
30616
+
30617
+ // src/tools/account.ts
30618
+ function registerAccountTools(server, client) {
30619
+ server.tool(
30620
+ "reddit_me",
30621
+ "Get the authenticated user's account info (username, karma, etc). Requires 'identity' scope.",
30622
+ {},
30623
+ async () => {
30624
+ const data = await client.get("/api/v1/me");
30625
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
30626
+ }
30627
+ );
30628
+ server.tool(
30629
+ "reddit_me_karma",
30630
+ "Get the authenticated user's karma breakdown by subreddit. Requires 'mysubreddits' scope.",
30631
+ {},
30632
+ async () => {
30633
+ const data = await client.get("/api/v1/me/karma");
30634
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
30635
+ }
30636
+ );
30637
+ server.tool(
30638
+ "reddit_me_prefs",
30639
+ "Get the authenticated user's preferences. Requires 'identity' scope.",
30640
+ {},
30641
+ async () => {
30642
+ const data = await client.get("/api/v1/me/prefs");
30643
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
30644
+ }
30645
+ );
30646
+ server.tool(
30647
+ "reddit_me_prefs_update",
30648
+ "Update the authenticated user's preferences. Requires 'account' scope. Pass a JSON object with preference keys and values.",
30649
+ {
30650
+ prefs: external_exports3.record(external_exports3.string(), external_exports3.unknown()).describe(
30651
+ 'JSON object of preference key-value pairs to update (e.g. {"over_18": true, "hide_downs": false})'
30652
+ )
30653
+ },
30654
+ async (input) => {
30655
+ const data = await client.patch("/api/v1/me/prefs", input.prefs);
30656
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
30657
+ }
30658
+ );
30659
+ server.tool(
30660
+ "reddit_me_trophies",
30661
+ "Get the authenticated user's trophies. Requires 'identity' scope.",
30662
+ {},
30663
+ async () => {
30664
+ const data = await client.get("/api/v1/me/trophies");
30665
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
30666
+ }
30667
+ );
30668
+ server.tool(
30669
+ "reddit_me_friends",
30670
+ "Get the authenticated user's friends list. Requires 'mysubreddits' scope.",
30671
+ {},
30672
+ async () => {
30673
+ const data = await client.get("/prefs/friends");
30674
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
30675
+ }
30676
+ );
30677
+ server.tool(
30678
+ "reddit_me_blocked",
30679
+ "Get the authenticated user's blocked users list. Requires 'mysubreddits' scope.",
30680
+ {},
30681
+ async () => {
30682
+ const data = await client.get("/prefs/blocked");
30683
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
30684
+ }
30685
+ );
30686
+ }
30687
+
30688
+ // src/tools/users.ts
30689
+ var userListingParams = {
30690
+ sort: external_exports3.enum(["hot", "new", "top", "controversial"]).optional().describe("Sort order"),
30691
+ t: external_exports3.enum(["hour", "day", "week", "month", "year", "all"]).optional().describe("Time filter (for top/controversial)"),
30692
+ limit: external_exports3.number().min(1).max(100).optional().describe("Number of items to return (1-100, default 25)"),
30693
+ after: external_exports3.string().optional().describe("Fullname to paginate after"),
30694
+ before: external_exports3.string().optional().describe("Fullname to paginate before")
30695
+ };
30696
+ function buildParams5(input) {
30697
+ const params = {};
30698
+ for (const [key, value] of Object.entries(input)) {
30699
+ if (value !== void 0 && value !== null) {
30700
+ params[key] = String(value);
30701
+ }
30702
+ }
30703
+ return params;
30704
+ }
30705
+ function registerUserTools(server, client) {
30706
+ server.tool(
30707
+ "reddit_user_about",
30708
+ "Get a user's public profile info. Requires 'read' scope.",
30709
+ {
30710
+ username: external_exports3.string().describe("Username (without /u/ prefix)")
30711
+ },
30712
+ async (input) => {
30713
+ const data = await client.get(`/user/${input.username}/about`);
30714
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
30715
+ }
30716
+ );
30717
+ server.tool(
30718
+ "reddit_user_overview",
30719
+ "Get a user's recent posts and comments. Requires 'history' scope.",
30720
+ {
30721
+ username: external_exports3.string().describe("Username (without /u/ prefix)"),
30722
+ ...userListingParams
30723
+ },
30724
+ async (input) => {
30725
+ const { username, ...rest } = input;
30726
+ const data = await client.get(
30727
+ `/user/${username}/overview`,
30728
+ buildParams5(rest)
30729
+ );
30730
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
30731
+ }
30732
+ );
30733
+ server.tool(
30734
+ "reddit_user_submitted",
30735
+ "Get a user's submitted posts. Requires 'history' scope.",
30736
+ {
30737
+ username: external_exports3.string().describe("Username (without /u/ prefix)"),
30738
+ ...userListingParams
30739
+ },
30740
+ async (input) => {
30741
+ const { username, ...rest } = input;
30742
+ const data = await client.get(
30743
+ `/user/${username}/submitted`,
30744
+ buildParams5(rest)
30745
+ );
30746
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
30747
+ }
30748
+ );
30749
+ server.tool(
30750
+ "reddit_user_comments",
30751
+ "Get a user's comments. Requires 'history' scope.",
30752
+ {
30753
+ username: external_exports3.string().describe("Username (without /u/ prefix)"),
30754
+ ...userListingParams
30755
+ },
30756
+ async (input) => {
30757
+ const { username, ...rest } = input;
30758
+ const data = await client.get(
30759
+ `/user/${username}/comments`,
30760
+ buildParams5(rest)
30761
+ );
30762
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
30763
+ }
30764
+ );
30765
+ server.tool(
30766
+ "reddit_user_saved",
30767
+ "Get a user's saved posts and comments. Only works for the authenticated user. Requires 'history' scope.",
30768
+ {
30769
+ username: external_exports3.string().describe("Username (without /u/ prefix)"),
30770
+ ...userListingParams
30771
+ },
30772
+ async (input) => {
30773
+ const { username, ...rest } = input;
30774
+ const data = await client.get(
30775
+ `/user/${username}/saved`,
30776
+ buildParams5(rest)
30777
+ );
30778
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
30779
+ }
30780
+ );
30781
+ server.tool(
30782
+ "reddit_user_upvoted",
30783
+ "Get a user's upvoted posts. Only works for the authenticated user. Requires 'history' scope.",
30784
+ {
30785
+ username: external_exports3.string().describe("Username (without /u/ prefix)"),
30786
+ ...userListingParams
30787
+ },
30788
+ async (input) => {
30789
+ const { username, ...rest } = input;
30790
+ const data = await client.get(
30791
+ `/user/${username}/upvoted`,
30792
+ buildParams5(rest)
30793
+ );
30794
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
30795
+ }
30796
+ );
30797
+ server.tool(
30798
+ "reddit_user_downvoted",
30799
+ "Get a user's downvoted posts. Only works for the authenticated user. Requires 'history' scope.",
30800
+ {
30801
+ username: external_exports3.string().describe("Username (without /u/ prefix)"),
30802
+ ...userListingParams
30803
+ },
30804
+ async (input) => {
30805
+ const { username, ...rest } = input;
30806
+ const data = await client.get(
30807
+ `/user/${username}/downvoted`,
30808
+ buildParams5(rest)
30809
+ );
30810
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
30811
+ }
30812
+ );
30813
+ server.tool(
30814
+ "reddit_user_trophies",
30815
+ "Get a user's trophies. Requires 'read' scope.",
30816
+ {
30817
+ username: external_exports3.string().describe("Username (without /u/ prefix)")
30818
+ },
30819
+ async (input) => {
30820
+ const data = await client.get(
30821
+ `/api/v1/user/${input.username}/trophies`
30822
+ );
30823
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
30824
+ }
30825
+ );
30826
+ server.tool(
30827
+ "reddit_block_user",
30828
+ "Block a user. Requires 'account' scope.",
30829
+ {
30830
+ name: external_exports3.string().describe("Username to block (without /u/ prefix)")
30831
+ },
30832
+ async (input) => {
30833
+ const data = await client.post("/api/block_user", {
30834
+ name: input.name
30835
+ });
30836
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
30837
+ }
30838
+ );
30839
+ }
30840
+
30841
+ // src/tools/messages.ts
30842
+ var paginationParams2 = {
30843
+ limit: external_exports3.number().min(1).max(100).optional().describe("Number of messages to return (1-100, default 25)"),
30844
+ after: external_exports3.string().optional().describe("Fullname to paginate after"),
30845
+ before: external_exports3.string().optional().describe("Fullname to paginate before")
30846
+ };
30847
+ function buildParams6(input) {
30848
+ const params = {};
30849
+ for (const [key, value] of Object.entries(input)) {
30850
+ if (value !== void 0 && value !== null) {
30851
+ params[key] = String(value);
30852
+ }
30853
+ }
30854
+ return params;
30855
+ }
30856
+ function registerMessageTools(server, client) {
30857
+ server.tool(
30858
+ "reddit_inbox",
30859
+ "Get the authenticated user's inbox messages. Requires 'privatemessages' scope.",
30860
+ { ...paginationParams2 },
30861
+ async (input) => {
30862
+ const data = await client.get("/message/inbox", buildParams6(input));
30863
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
30864
+ }
30865
+ );
30866
+ server.tool(
30867
+ "reddit_unread",
30868
+ "Get the authenticated user's unread messages. Requires 'privatemessages' scope.",
30869
+ { ...paginationParams2 },
30870
+ async (input) => {
30871
+ const data = await client.get("/message/unread", buildParams6(input));
30872
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
30873
+ }
30874
+ );
30875
+ server.tool(
30876
+ "reddit_sent",
30877
+ "Get the authenticated user's sent messages. Requires 'privatemessages' scope.",
30878
+ { ...paginationParams2 },
30879
+ async (input) => {
30880
+ const data = await client.get("/message/sent", buildParams6(input));
30881
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
30882
+ }
30883
+ );
30884
+ server.tool(
30885
+ "reddit_compose",
30886
+ "Send a private message to a user. Requires 'privatemessages' scope.",
30887
+ {
30888
+ to: external_exports3.string().describe("Recipient username (without /u/ prefix)"),
30889
+ subject: external_exports3.string().describe("Message subject"),
30890
+ text: external_exports3.string().describe("Message body (markdown)")
30891
+ },
30892
+ async (input) => {
30893
+ const data = await client.post("/api/compose", {
30894
+ ...buildParams6(input),
30895
+ api_type: "json"
30896
+ });
30897
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
30898
+ }
30899
+ );
30900
+ server.tool(
30901
+ "reddit_read_message",
30902
+ "Mark a message as read. Requires 'privatemessages' scope.",
30903
+ {
30904
+ id: external_exports3.string().describe("Fullname of the message to mark as read (t4_)")
30905
+ },
30906
+ async (input) => {
30907
+ const data = await client.post("/api/read_message", {
30908
+ id: input.id
30909
+ });
30910
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
30911
+ }
30912
+ );
30913
+ server.tool(
30914
+ "reddit_unread_message",
30915
+ "Mark a message as unread. Requires 'privatemessages' scope.",
30916
+ {
30917
+ id: external_exports3.string().describe("Fullname of the message to mark as unread (t4_)")
30918
+ },
30919
+ async (input) => {
30920
+ const data = await client.post("/api/unread_message", {
30921
+ id: input.id
30922
+ });
30923
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
30924
+ }
30925
+ );
30926
+ server.tool(
30927
+ "reddit_del_msg",
30928
+ "Delete a message from your inbox. Requires 'privatemessages' scope.",
30929
+ {
30930
+ id: external_exports3.string().describe("Fullname of the message to delete (t4_)")
30931
+ },
30932
+ async (input) => {
30933
+ const data = await client.post("/api/del_msg", {
30934
+ id: input.id
30935
+ });
30936
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
30937
+ }
30938
+ );
30939
+ }
30940
+
30941
+ // src/tools/subreddits.ts
30942
+ var paginationParams3 = {
30943
+ limit: external_exports3.number().min(1).max(100).optional().describe("Number of items to return (1-100, default 25)"),
30944
+ after: external_exports3.string().optional().describe("Fullname to paginate after"),
30945
+ before: external_exports3.string().optional().describe("Fullname to paginate before")
30946
+ };
30947
+ function buildParams7(input) {
30948
+ const params = {};
30949
+ for (const [key, value] of Object.entries(input)) {
30950
+ if (value !== void 0 && value !== null) {
30951
+ params[key] = String(value);
30952
+ }
30953
+ }
30954
+ return params;
30955
+ }
30956
+ function registerSubredditTools(server, client) {
30957
+ server.tool(
30958
+ "reddit_subreddit_about",
30959
+ "Get a subreddit's metadata (description, subscribers, rules summary, etc). Requires 'read' scope.",
30960
+ {
30961
+ subreddit: external_exports3.string().describe("Subreddit name (without r/ prefix)")
30962
+ },
30963
+ async (input) => {
30964
+ const data = await client.get(`/r/${input.subreddit}/about`);
30965
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
30966
+ }
30967
+ );
30968
+ server.tool(
30969
+ "reddit_subreddit_rules",
30970
+ "Get a subreddit's rules list. Requires 'read' scope.",
30971
+ {
30972
+ subreddit: external_exports3.string().describe("Subreddit name (without r/ prefix)")
30973
+ },
30974
+ async (input) => {
30975
+ const data = await client.get(`/r/${input.subreddit}/about/rules`);
30976
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
30977
+ }
30978
+ );
30979
+ server.tool(
30980
+ "reddit_subscribe",
30981
+ "Subscribe to a subreddit. Requires 'subscribe' scope.",
30982
+ {
30983
+ sr_name: external_exports3.string().describe("Subreddit name to subscribe to (without r/ prefix)")
30984
+ },
30985
+ async (input) => {
30986
+ const data = await client.post("/api/subscribe", {
30987
+ sr_name: input.sr_name,
30988
+ action: "sub"
30989
+ });
30990
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
30991
+ }
30992
+ );
30993
+ server.tool(
30994
+ "reddit_unsubscribe",
30995
+ "Unsubscribe from a subreddit. Requires 'subscribe' scope.",
30996
+ {
30997
+ sr_name: external_exports3.string().describe("Subreddit name to unsubscribe from (without r/ prefix)")
30998
+ },
30999
+ async (input) => {
31000
+ const data = await client.post("/api/subscribe", {
31001
+ sr_name: input.sr_name,
31002
+ action: "unsub"
31003
+ });
31004
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
31005
+ }
31006
+ );
31007
+ server.tool(
31008
+ "reddit_subreddits_mine",
31009
+ "List subreddits the authenticated user is subscribed to. Requires 'mysubreddits' scope.",
31010
+ { ...paginationParams3 },
31011
+ async (input) => {
31012
+ const data = await client.get(
31013
+ "/subreddits/mine/subscriber",
31014
+ buildParams7(input)
31015
+ );
31016
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
31017
+ }
31018
+ );
31019
+ server.tool(
31020
+ "reddit_subreddits_popular",
31021
+ "List popular subreddits. Requires 'read' scope.",
31022
+ { ...paginationParams3 },
31023
+ async (input) => {
31024
+ const data = await client.get(
31025
+ "/subreddits/popular",
31026
+ buildParams7(input)
31027
+ );
31028
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
31029
+ }
31030
+ );
31031
+ server.tool(
31032
+ "reddit_subreddits_new",
31033
+ "List newest subreddits. Requires 'read' scope.",
31034
+ { ...paginationParams3 },
31035
+ async (input) => {
31036
+ const data = await client.get("/subreddits/new", buildParams7(input));
31037
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
31038
+ }
31039
+ );
31040
+ server.tool(
31041
+ "reddit_subreddits_search",
31042
+ "Search for subreddits by name or topic. Requires 'read' scope.",
31043
+ {
31044
+ q: external_exports3.string().describe("Search query"),
31045
+ ...paginationParams3
31046
+ },
31047
+ async (input) => {
31048
+ const data = await client.get(
31049
+ "/subreddits/search",
31050
+ buildParams7(input)
31051
+ );
31052
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
31053
+ }
31054
+ );
31055
+ }
31056
+
31057
+ // src/tools/flair.ts
31058
+ function buildParams8(input) {
31059
+ const params = {};
31060
+ for (const [key, value] of Object.entries(input)) {
31061
+ if (value !== void 0 && value !== null) {
31062
+ params[key] = String(value);
31063
+ }
31064
+ }
31065
+ return params;
31066
+ }
31067
+ function registerFlairTools(server, client) {
31068
+ server.tool(
31069
+ "reddit_link_flair",
31070
+ "Get available link (post) flair templates for a subreddit. Requires 'flair' scope.",
31071
+ {
31072
+ subreddit: external_exports3.string().describe("Subreddit name (without r/ prefix)")
31073
+ },
31074
+ async (input) => {
31075
+ const data = await client.get(
31076
+ `/r/${input.subreddit}/api/link_flair_v2`
31077
+ );
31078
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
31079
+ }
31080
+ );
31081
+ server.tool(
31082
+ "reddit_user_flair",
31083
+ "Get available user flair templates for a subreddit. Requires 'flair' scope.",
31084
+ {
31085
+ subreddit: external_exports3.string().describe("Subreddit name (without r/ prefix)")
31086
+ },
31087
+ async (input) => {
31088
+ const data = await client.get(
31089
+ `/r/${input.subreddit}/api/user_flair_v2`
31090
+ );
31091
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
31092
+ }
31093
+ );
31094
+ server.tool(
31095
+ "reddit_select_flair",
31096
+ "Set flair on a post or user in a subreddit. Provide 'link' for post flair or 'name' for user flair. Requires 'flair' scope.",
31097
+ {
31098
+ subreddit: external_exports3.string().describe("Subreddit name (without r/ prefix)"),
31099
+ flair_template_id: external_exports3.string().describe("Flair template ID (from link_flair or user_flair listing)"),
31100
+ link: external_exports3.string().optional().describe("Post fullname (t3_) to set link flair on"),
31101
+ name: external_exports3.string().optional().describe("Username to set user flair for"),
31102
+ text: external_exports3.string().optional().describe("Custom flair text (if template allows)")
31103
+ },
31104
+ async (input) => {
31105
+ const { subreddit, ...rest } = input;
31106
+ const data = await client.post(
31107
+ `/r/${subreddit}/api/selectflair`,
31108
+ buildParams8(rest)
31109
+ );
31110
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
31111
+ }
31112
+ );
31113
+ }
31114
+
31115
+ // src/tools/moderation.ts
31116
+ var paginationParams4 = {
31117
+ limit: external_exports3.number().min(1).max(100).optional().describe("Number of items to return (1-100, default 25)"),
31118
+ after: external_exports3.string().optional().describe("Fullname to paginate after"),
31119
+ before: external_exports3.string().optional().describe("Fullname to paginate before")
31120
+ };
31121
+ function buildParams9(input) {
31122
+ const params = {};
31123
+ for (const [key, value] of Object.entries(input)) {
31124
+ if (value !== void 0 && value !== null) {
31125
+ params[key] = String(value);
31126
+ }
31127
+ }
31128
+ return params;
31129
+ }
31130
+ function registerModerationTools(server, client) {
31131
+ server.tool(
31132
+ "reddit_approve",
31133
+ "Approve a post or comment in the mod queue. Requires 'modposts' scope.",
31134
+ {
31135
+ id: external_exports3.string().describe("Fullname of the post (t3_) or comment (t1_) to approve")
31136
+ },
31137
+ async (input) => {
31138
+ const data = await client.post("/api/approve", { id: input.id });
31139
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
31140
+ }
31141
+ );
31142
+ server.tool(
31143
+ "reddit_remove",
31144
+ "Remove a post or comment as a moderator. Requires 'modposts' scope.",
31145
+ {
31146
+ id: external_exports3.string().describe("Fullname of the post (t3_) or comment (t1_) to remove"),
31147
+ spam: external_exports3.boolean().optional().describe("If true, mark as spam (default false)")
31148
+ },
31149
+ async (input) => {
31150
+ const data = await client.post("/api/remove", {
31151
+ id: input.id,
31152
+ spam: input.spam !== void 0 ? String(input.spam) : void 0
31153
+ });
31154
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
31155
+ }
31156
+ );
31157
+ server.tool(
31158
+ "reddit_distinguish",
31159
+ "Distinguish a post or comment as a moderator. Requires 'modposts' scope.",
31160
+ {
31161
+ id: external_exports3.string().describe("Fullname of the post (t3_) or comment (t1_)"),
31162
+ how: external_exports3.enum(["yes", "no", "admin", "special"]).describe("'yes' = mod distinguish, 'no' = remove, 'admin' = admin, 'special' = special")
31163
+ },
31164
+ async (input) => {
31165
+ const data = await client.post("/api/distinguish", {
31166
+ id: input.id,
31167
+ how: input.how
31168
+ });
31169
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
31170
+ }
31171
+ );
31172
+ server.tool(
31173
+ "reddit_ignore_reports",
31174
+ "Ignore future reports on a post or comment. Requires 'modposts' scope.",
31175
+ {
31176
+ id: external_exports3.string().describe("Fullname of the post (t3_) or comment (t1_)")
31177
+ },
31178
+ async (input) => {
31179
+ const data = await client.post("/api/ignore_reports", { id: input.id });
31180
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
31181
+ }
31182
+ );
31183
+ server.tool(
31184
+ "reddit_unignore_reports",
31185
+ "Stop ignoring reports on a post or comment. Requires 'modposts' scope.",
31186
+ {
31187
+ id: external_exports3.string().describe("Fullname of the post (t3_) or comment (t1_)")
31188
+ },
31189
+ async (input) => {
31190
+ const data = await client.post("/api/unignore_reports", { id: input.id });
31191
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
31192
+ }
31193
+ );
31194
+ server.tool(
31195
+ "reddit_lock",
31196
+ "Lock a post or comment thread (prevent new comments). Requires 'modposts' scope.",
31197
+ {
31198
+ id: external_exports3.string().describe("Fullname of the post (t3_) or comment (t1_) to lock")
31199
+ },
31200
+ async (input) => {
31201
+ const data = await client.post("/api/lock", { id: input.id });
31202
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
31203
+ }
31204
+ );
31205
+ server.tool(
31206
+ "reddit_unlock",
31207
+ "Unlock a previously locked post or comment thread. Requires 'modposts' scope.",
31208
+ {
31209
+ id: external_exports3.string().describe("Fullname of the post (t3_) or comment (t1_) to unlock")
31210
+ },
31211
+ async (input) => {
31212
+ const data = await client.post("/api/unlock", { id: input.id });
31213
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
31214
+ }
31215
+ );
31216
+ server.tool(
31217
+ "reddit_modqueue",
31218
+ "Get items in the mod queue awaiting review. Requires 'modposts' scope.",
31219
+ {
31220
+ subreddit: external_exports3.string().describe("Subreddit name (without r/ prefix)"),
31221
+ ...paginationParams4
31222
+ },
31223
+ async (input) => {
31224
+ const { subreddit, ...rest } = input;
31225
+ const data = await client.get(
31226
+ `/r/${subreddit}/about/modqueue`,
31227
+ buildParams9(rest)
31228
+ );
31229
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
31230
+ }
31231
+ );
31232
+ server.tool(
31233
+ "reddit_reports",
31234
+ "Get reported posts and comments. Requires 'modposts' scope.",
31235
+ {
31236
+ subreddit: external_exports3.string().describe("Subreddit name (without r/ prefix)"),
31237
+ ...paginationParams4
31238
+ },
31239
+ async (input) => {
31240
+ const { subreddit, ...rest } = input;
31241
+ const data = await client.get(
31242
+ `/r/${subreddit}/about/reports`,
31243
+ buildParams9(rest)
31244
+ );
31245
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
31246
+ }
31247
+ );
31248
+ server.tool(
31249
+ "reddit_spam",
31250
+ "Get items marked as spam. Requires 'modposts' scope.",
31251
+ {
31252
+ subreddit: external_exports3.string().describe("Subreddit name (without r/ prefix)"),
31253
+ ...paginationParams4
31254
+ },
31255
+ async (input) => {
31256
+ const { subreddit, ...rest } = input;
31257
+ const data = await client.get(
31258
+ `/r/${subreddit}/about/spam`,
31259
+ buildParams9(rest)
31260
+ );
31261
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
31262
+ }
31263
+ );
31264
+ server.tool(
31265
+ "reddit_edited",
31266
+ "Get recently edited posts and comments. Requires 'modposts' scope.",
31267
+ {
31268
+ subreddit: external_exports3.string().describe("Subreddit name (without r/ prefix)"),
31269
+ ...paginationParams4
31270
+ },
31271
+ async (input) => {
31272
+ const { subreddit, ...rest } = input;
31273
+ const data = await client.get(
31274
+ `/r/${subreddit}/about/edited`,
31275
+ buildParams9(rest)
31276
+ );
31277
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
31278
+ }
31279
+ );
31280
+ server.tool(
31281
+ "reddit_modlog",
31282
+ "Get the moderation log. Requires 'modlog' scope.",
31283
+ {
31284
+ subreddit: external_exports3.string().describe("Subreddit name (without r/ prefix)"),
31285
+ type: external_exports3.string().optional().describe("Filter by action type (e.g. banuser, removelink, approvecomment)"),
31286
+ mod: external_exports3.string().optional().describe("Filter by moderator username"),
31287
+ ...paginationParams4
31288
+ },
31289
+ async (input) => {
31290
+ const { subreddit, ...rest } = input;
31291
+ const data = await client.get(
31292
+ `/r/${subreddit}/about/log`,
31293
+ buildParams9(rest)
31294
+ );
31295
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
31296
+ }
31297
+ );
31298
+ server.tool(
31299
+ "reddit_moderators",
31300
+ "List moderators of a subreddit. Requires 'read' scope.",
31301
+ {
31302
+ subreddit: external_exports3.string().describe("Subreddit name (without r/ prefix)")
31303
+ },
31304
+ async (input) => {
31305
+ const data = await client.get(
31306
+ `/r/${input.subreddit}/about/moderators`
31307
+ );
31308
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
31309
+ }
31310
+ );
31311
+ server.tool(
31312
+ "reddit_contributors",
31313
+ "List approved contributors of a subreddit. Requires 'modcontributors' scope.",
31314
+ {
31315
+ subreddit: external_exports3.string().describe("Subreddit name (without r/ prefix)"),
31316
+ ...paginationParams4
31317
+ },
31318
+ async (input) => {
31319
+ const { subreddit, ...rest } = input;
31320
+ const data = await client.get(
31321
+ `/r/${subreddit}/about/contributors`,
31322
+ buildParams9(rest)
31323
+ );
31324
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
31325
+ }
31326
+ );
31327
+ server.tool(
31328
+ "reddit_banned",
31329
+ "List banned users of a subreddit. Requires 'modcontributors' scope.",
31330
+ {
31331
+ subreddit: external_exports3.string().describe("Subreddit name (without r/ prefix)"),
31332
+ ...paginationParams4
31333
+ },
31334
+ async (input) => {
31335
+ const { subreddit, ...rest } = input;
31336
+ const data = await client.get(
31337
+ `/r/${subreddit}/about/banned`,
31338
+ buildParams9(rest)
31339
+ );
31340
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
31341
+ }
31342
+ );
31343
+ server.tool(
31344
+ "reddit_muted",
31345
+ "List muted users of a subreddit. Requires 'modcontributors' scope.",
31346
+ {
31347
+ subreddit: external_exports3.string().describe("Subreddit name (without r/ prefix)"),
31348
+ ...paginationParams4
31349
+ },
31350
+ async (input) => {
31351
+ const { subreddit, ...rest } = input;
31352
+ const data = await client.get(
31353
+ `/r/${subreddit}/about/muted`,
31354
+ buildParams9(rest)
31355
+ );
31356
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
31357
+ }
31358
+ );
31359
+ }
31360
+
31361
+ // src/tools/multireddits.ts
31362
+ function registerMultiredditTools(server, client) {
31363
+ server.tool(
31364
+ "reddit_multi_mine",
31365
+ "List the authenticated user's multireddits (custom feeds). Requires 'read' scope.",
31366
+ {},
31367
+ async () => {
31368
+ const data = await client.get("/api/multi/mine");
31369
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
31370
+ }
31371
+ );
31372
+ server.tool(
31373
+ "reddit_multi_get",
31374
+ "Get a specific multireddit by path. Requires 'read' scope.",
31375
+ {
31376
+ multipath: external_exports3.string().describe("Multireddit path (e.g. /user/username/m/multiname)")
31377
+ },
31378
+ async (input) => {
31379
+ const data = await client.get(`/api/multi${input.multipath}`);
31380
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
31381
+ }
31382
+ );
31383
+ server.tool(
31384
+ "reddit_multi_create",
31385
+ "Create a new multireddit. Requires 'subscribe' scope.",
31386
+ {
31387
+ multipath: external_exports3.string().describe("Multireddit path (e.g. /user/username/m/multiname)"),
31388
+ display_name: external_exports3.string().describe("Display name for the multireddit"),
31389
+ subreddits: external_exports3.array(external_exports3.string()).optional().describe("Array of subreddit names to include"),
31390
+ visibility: external_exports3.enum(["private", "public", "hidden"]).optional().describe("Visibility (default private)"),
31391
+ description_md: external_exports3.string().optional().describe("Description in markdown")
31392
+ },
31393
+ async (input) => {
31394
+ const { multipath, display_name, subreddits, visibility, description_md } = input;
31395
+ const model = {
31396
+ display_name,
31397
+ subreddits: subreddits?.map((name) => ({ name })) ?? [],
31398
+ visibility: visibility ?? "private",
31399
+ description_md: description_md ?? ""
31400
+ };
31401
+ const data = await client.post(`/api/multi${multipath}`, {
31402
+ model: JSON.stringify(model)
31403
+ });
31404
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
31405
+ }
31406
+ );
31407
+ server.tool(
31408
+ "reddit_multi_update",
31409
+ "Update an existing multireddit. Requires 'subscribe' scope.",
31410
+ {
31411
+ multipath: external_exports3.string().describe("Multireddit path (e.g. /user/username/m/multiname)"),
31412
+ display_name: external_exports3.string().optional().describe("New display name"),
31413
+ subreddits: external_exports3.array(external_exports3.string()).optional().describe("Updated array of subreddit names"),
31414
+ visibility: external_exports3.enum(["private", "public", "hidden"]).optional().describe("Updated visibility"),
31415
+ description_md: external_exports3.string().optional().describe("Updated description in markdown")
31416
+ },
31417
+ async (input) => {
31418
+ const { multipath, display_name, subreddits, visibility, description_md } = input;
31419
+ const model = {};
31420
+ if (display_name !== void 0) model.display_name = display_name;
31421
+ if (subreddits !== void 0) model.subreddits = subreddits.map((name) => ({ name }));
31422
+ if (visibility !== void 0) model.visibility = visibility;
31423
+ if (description_md !== void 0) model.description_md = description_md;
31424
+ const data = await client.put(`/api/multi${multipath}`, { model });
31425
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
31426
+ }
31427
+ );
31428
+ server.tool(
31429
+ "reddit_multi_delete",
31430
+ "Delete a multireddit. Requires 'subscribe' scope.",
31431
+ {
31432
+ multipath: external_exports3.string().describe("Multireddit path (e.g. /user/username/m/multiname)")
31433
+ },
31434
+ async (input) => {
31435
+ const data = await client.delete(`/api/multi${input.multipath}`);
31436
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
31437
+ }
31438
+ );
31439
+ server.tool(
31440
+ "reddit_multi_add_sub",
31441
+ "Add a subreddit to a multireddit. Requires 'subscribe' scope.",
31442
+ {
31443
+ multipath: external_exports3.string().describe("Multireddit path (e.g. /user/username/m/multiname)"),
31444
+ srname: external_exports3.string().describe("Subreddit name to add (without r/ prefix)")
31445
+ },
31446
+ async (input) => {
31447
+ const data = await client.put(
31448
+ `/api/multi${input.multipath}/r/${input.srname}`,
31449
+ { model: { name: input.srname } }
31450
+ );
31451
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
31452
+ }
31453
+ );
31454
+ server.tool(
31455
+ "reddit_multi_remove_sub",
31456
+ "Remove a subreddit from a multireddit. Requires 'subscribe' scope.",
31457
+ {
31458
+ multipath: external_exports3.string().describe("Multireddit path (e.g. /user/username/m/multiname)"),
31459
+ srname: external_exports3.string().describe("Subreddit name to remove (without r/ prefix)")
31460
+ },
31461
+ async (input) => {
31462
+ const data = await client.delete(
31463
+ `/api/multi${input.multipath}/r/${input.srname}`
31464
+ );
31465
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
31466
+ }
31467
+ );
31468
+ }
31469
+
31470
+ // src/tools/wiki.ts
31471
+ var paginationParams5 = {
31472
+ limit: external_exports3.number().min(1).max(100).optional().describe("Number of items to return (1-100, default 25)"),
31473
+ after: external_exports3.string().optional().describe("Fullname to paginate after"),
31474
+ before: external_exports3.string().optional().describe("Fullname to paginate before")
31475
+ };
31476
+ function buildParams10(input) {
31477
+ const params = {};
31478
+ for (const [key, value] of Object.entries(input)) {
31479
+ if (value !== void 0 && value !== null) {
31480
+ params[key] = String(value);
31481
+ }
31482
+ }
31483
+ return params;
31484
+ }
31485
+ function registerWikiTools(server, client) {
31486
+ server.tool(
31487
+ "reddit_wiki_page",
31488
+ "Get the content of a wiki page. Requires 'wikiread' scope.",
31489
+ {
31490
+ subreddit: external_exports3.string().describe("Subreddit name (without r/ prefix)"),
31491
+ page: external_exports3.string().describe("Wiki page name (e.g. 'index', 'faq')")
31492
+ },
31493
+ async (input) => {
31494
+ const data = await client.get(
31495
+ `/r/${input.subreddit}/wiki/${input.page}`
31496
+ );
31497
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
31498
+ }
31499
+ );
31500
+ server.tool(
31501
+ "reddit_wiki_edit",
31502
+ "Edit a wiki page. Requires 'wikiedit' scope.",
31503
+ {
31504
+ subreddit: external_exports3.string().describe("Subreddit name (without r/ prefix)"),
31505
+ page: external_exports3.string().describe("Wiki page name"),
31506
+ content: external_exports3.string().describe("Full wiki page content (markdown)"),
31507
+ reason: external_exports3.string().optional().describe("Edit reason (like a commit message)")
31508
+ },
31509
+ async (input) => {
31510
+ const data = await client.post(
31511
+ `/r/${input.subreddit}/api/wiki/edit`,
31512
+ {
31513
+ page: input.page,
31514
+ content: input.content,
31515
+ reason: input.reason
31516
+ }
31517
+ );
31518
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
31519
+ }
31520
+ );
31521
+ server.tool(
31522
+ "reddit_wiki_pages",
31523
+ "List all wiki pages in a subreddit. Requires 'wikiread' scope.",
31524
+ {
31525
+ subreddit: external_exports3.string().describe("Subreddit name (without r/ prefix)")
31526
+ },
31527
+ async (input) => {
31528
+ const data = await client.get(`/r/${input.subreddit}/wiki/pages`);
31529
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
31530
+ }
31531
+ );
31532
+ server.tool(
31533
+ "reddit_wiki_revisions",
31534
+ "Get revision history for all wiki pages in a subreddit. Requires 'wikiread' scope.",
31535
+ {
31536
+ subreddit: external_exports3.string().describe("Subreddit name (without r/ prefix)"),
31537
+ ...paginationParams5
31538
+ },
31539
+ async (input) => {
31540
+ const { subreddit, ...rest } = input;
31541
+ const data = await client.get(
31542
+ `/r/${subreddit}/wiki/revisions`,
31543
+ buildParams10(rest)
31544
+ );
31545
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
31546
+ }
31547
+ );
31548
+ server.tool(
31549
+ "reddit_wiki_page_revisions",
31550
+ "Get revision history for a specific wiki page. Requires 'wikiread' scope.",
31551
+ {
31552
+ subreddit: external_exports3.string().describe("Subreddit name (without r/ prefix)"),
31553
+ page: external_exports3.string().describe("Wiki page name"),
31554
+ ...paginationParams5
31555
+ },
31556
+ async (input) => {
31557
+ const { subreddit, page, ...rest } = input;
31558
+ const data = await client.get(
31559
+ `/r/${subreddit}/wiki/revisions/${page}`,
31560
+ buildParams10(rest)
31561
+ );
31562
+ return { content: [{ type: "text", text: JSON.stringify(data) }] };
31563
+ }
31564
+ );
31565
+ }
31566
+
30372
31567
  // src/server.ts
30373
31568
  function createServerWithToken(accessToken) {
30374
31569
  const server = new McpServer({
@@ -30382,6 +31577,17 @@ function createServerWithToken(accessToken) {
30382
31577
  function registerAllTools(server, client) {
30383
31578
  registerListingTools(server, client);
30384
31579
  registerSearchTools(server, client);
31580
+ registerPostTools(server, client);
31581
+ registerCommentTools(server, client);
31582
+ registerVotingTools(server, client);
31583
+ registerAccountTools(server, client);
31584
+ registerUserTools(server, client);
31585
+ registerMessageTools(server, client);
31586
+ registerSubredditTools(server, client);
31587
+ registerFlairTools(server, client);
31588
+ registerModerationTools(server, client);
31589
+ registerMultiredditTools(server, client);
31590
+ registerWikiTools(server, client);
30385
31591
  }
30386
31592
 
30387
31593
  // src/factory.ts