reddit-mcp-server 1.1.1 → 1.2.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/bin.js CHANGED
@@ -1,1249 +1,22 @@
1
1
  #!/usr/bin/env node
2
- "use strict";
3
- var __create = Object.create;
4
- var __defProp = Object.defineProperty;
5
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
- var __getOwnPropNames = Object.getOwnPropertyNames;
7
- var __getProtoOf = Object.getPrototypeOf;
8
- var __hasOwnProp = Object.prototype.hasOwnProperty;
9
- var __esm = (fn, res) => function __init() {
10
- return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
11
- };
12
- var __copyProps = (to, from, except, desc) => {
13
- if (from && typeof from === "object" || typeof from === "function") {
14
- for (let key of __getOwnPropNames(from))
15
- if (!__hasOwnProp.call(to, key) && key !== except)
16
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
- }
18
- return to;
19
- };
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
- mod
27
- ));
28
-
29
- // node_modules/.pnpm/tsup@8.5.0_postcss@8.5.6_tsx@4.20.5_typescript@5.9.2/node_modules/tsup/assets/cjs_shims.js
30
- var init_cjs_shims = __esm({
31
- "node_modules/.pnpm/tsup@8.5.0_postcss@8.5.6_tsx@4.20.5_typescript@5.9.2/node_modules/tsup/assets/cjs_shims.js"() {
32
- "use strict";
33
- }
34
- });
35
-
36
- // src/client/reddit-client.ts
37
- function initializeRedditClient(config) {
38
- redditClient = new RedditClient(config);
39
- return redditClient;
40
- }
41
- function getRedditClient() {
42
- return redditClient;
43
- }
44
- var RedditClient, redditClient;
45
- var init_reddit_client = __esm({
46
- "src/client/reddit-client.ts"() {
47
- "use strict";
48
- init_cjs_shims();
49
- RedditClient = class {
50
- clientId;
51
- clientSecret;
52
- userAgent;
53
- username;
54
- password;
55
- accessToken;
56
- tokenExpiry = 0;
57
- baseUrl = "https://oauth.reddit.com";
58
- authenticated = false;
59
- constructor(config) {
60
- this.clientId = config.clientId;
61
- this.clientSecret = config.clientSecret;
62
- this.userAgent = config.userAgent;
63
- this.username = config.username;
64
- this.password = config.password;
65
- }
66
- async makeRequest(path2, options = {}) {
67
- if (Date.now() >= this.tokenExpiry || !this.authenticated) {
68
- await this.authenticate();
69
- }
70
- const url = `${this.baseUrl}${path2}`;
71
- const headers = {
72
- "User-Agent": this.userAgent,
73
- Authorization: `Bearer ${this.accessToken}`,
74
- ...options.headers
75
- };
76
- const response = await fetch(url, {
77
- ...options,
78
- headers
79
- });
80
- if (response.status === 401 && this.authenticated) {
81
- await this.authenticate();
82
- const retryHeaders = {
83
- ...headers,
84
- Authorization: `Bearer ${this.accessToken}`
85
- };
86
- return fetch(url, {
87
- ...options,
88
- headers: retryHeaders
89
- });
90
- }
91
- return response;
92
- }
93
- async authenticate() {
94
- try {
95
- const now = Date.now();
96
- if (this.accessToken && now < this.tokenExpiry) {
97
- return;
98
- }
99
- const authUrl = "https://www.reddit.com/api/v1/access_token";
100
- const authData = new URLSearchParams();
101
- if (this.username && this.password) {
102
- authData.append("grant_type", "password");
103
- authData.append("username", this.username);
104
- authData.append("password", this.password);
105
- } else {
106
- authData.append("grant_type", "client_credentials");
107
- }
108
- const credentials = Buffer.from(`${this.clientId}:${this.clientSecret}`).toString("base64");
109
- const response = await fetch(authUrl, {
110
- method: "POST",
111
- headers: {
112
- "User-Agent": this.userAgent,
113
- "Content-Type": "application/x-www-form-urlencoded",
114
- Authorization: `Basic ${credentials}`
115
- },
116
- body: authData.toString()
117
- });
118
- if (!response.ok) {
119
- throw new Error(`Authentication failed: ${response.status}`);
120
- }
121
- const data = await response.json();
122
- this.accessToken = data.access_token;
123
- this.tokenExpiry = now + data.expires_in * 1e3;
124
- this.authenticated = true;
125
- } catch {
126
- throw new Error("Failed to authenticate with Reddit API");
127
- }
128
- }
129
- async checkAuthentication() {
130
- if (!this.authenticated) {
131
- try {
132
- await this.authenticate();
133
- return true;
134
- } catch {
135
- return false;
136
- }
137
- }
138
- return true;
139
- }
140
- async getUser(username) {
141
- await this.authenticate();
142
- try {
143
- const response = await this.makeRequest(`/user/${username}/about.json`);
144
- if (!response.ok) {
145
- throw new Error(`HTTP ${response.status}`);
146
- }
147
- const json = await response.json();
148
- const data = json.data;
149
- return {
150
- name: data.name,
151
- id: data.id,
152
- commentKarma: data.comment_karma,
153
- linkKarma: data.link_karma,
154
- totalKarma: data.total_karma || data.comment_karma + data.link_karma,
155
- isMod: data.is_mod,
156
- isGold: data.is_gold,
157
- isEmployee: data.is_employee,
158
- createdUtc: data.created_utc,
159
- profileUrl: `https://reddit.com/user/${data.name}`
160
- };
161
- } catch {
162
- throw new Error(`Failed to get user info for ${username}`);
163
- }
164
- }
165
- async getSubredditInfo(subredditName) {
166
- await this.authenticate();
167
- try {
168
- const response = await this.makeRequest(`/r/${subredditName}/about.json`);
169
- if (!response.ok) {
170
- throw new Error(`HTTP ${response.status}`);
171
- }
172
- const json = await response.json();
173
- const data = json.data;
174
- return {
175
- displayName: data.display_name,
176
- title: data.title,
177
- description: data.description || "",
178
- publicDescription: data.public_description || "",
179
- subscribers: data.subscribers,
180
- activeUserCount: data.active_user_count ?? void 0,
181
- createdUtc: data.created_utc,
182
- over18: data.over18,
183
- subredditType: data.subreddit_type,
184
- url: data.url
185
- };
186
- } catch {
187
- throw new Error(`Failed to get subreddit info for ${subredditName}`);
188
- }
189
- }
190
- async getTopPosts(subreddit, timeFilter = "week", limit = 10) {
191
- await this.authenticate();
192
- try {
193
- const endpoint = subreddit ? `/r/${subreddit}/top.json` : "/top.json";
194
- const params = new URLSearchParams({
195
- t: timeFilter,
196
- limit: limit.toString()
197
- });
198
- const response = await this.makeRequest(`${endpoint}?${params}`);
199
- if (!response.ok) {
200
- throw new Error(`HTTP ${response.status}`);
201
- }
202
- const json = await response.json();
203
- return json.data.children.map((child) => {
204
- const post = child.data;
205
- return {
206
- id: post.id,
207
- title: post.title,
208
- author: post.author,
209
- subreddit: post.subreddit,
210
- selftext: post.selftext,
211
- url: post.url,
212
- score: post.score,
213
- upvoteRatio: post.upvote_ratio,
214
- numComments: post.num_comments,
215
- createdUtc: post.created_utc,
216
- over18: post.over_18,
217
- spoiler: post.spoiler,
218
- edited: !!post.edited,
219
- isSelf: post.is_self,
220
- linkFlairText: post.link_flair_text ?? void 0,
221
- permalink: post.permalink
222
- };
223
- });
224
- } catch {
225
- throw new Error(`Failed to get top posts for ${subreddit || "home"}`);
226
- }
227
- }
228
- async getPost(postId, subreddit) {
229
- await this.authenticate();
230
- try {
231
- const endpoint = subreddit ? `/r/${subreddit}/comments/${postId}.json` : `/api/info.json?id=t3_${postId}`;
232
- const response = await this.makeRequest(endpoint);
233
- if (!response.ok) {
234
- throw new Error(`HTTP ${response.status}`);
235
- }
236
- const json = await response.json();
237
- let post;
238
- if (subreddit) {
239
- post = json[0].data.children[0].data;
240
- } else {
241
- if (!json.data.children.length) {
242
- throw new Error(`Post with ID ${postId} not found`);
243
- }
244
- post = json.data.children[0].data;
245
- }
246
- return {
247
- id: post.id,
248
- title: post.title,
249
- author: post.author,
250
- subreddit: post.subreddit,
251
- selftext: post.selftext,
252
- url: post.url,
253
- score: post.score,
254
- upvoteRatio: post.upvote_ratio,
255
- numComments: post.num_comments,
256
- createdUtc: post.created_utc,
257
- over18: post.over_18,
258
- spoiler: post.spoiler,
259
- edited: !!post.edited,
260
- isSelf: post.is_self,
261
- linkFlairText: post.link_flair_text,
262
- permalink: post.permalink
263
- };
264
- } catch {
265
- throw new Error(`Failed to get post with ID ${postId}`);
266
- }
267
- }
268
- async getTrendingSubreddits(limit = 5) {
269
- await this.authenticate();
270
- try {
271
- const params = new URLSearchParams({ limit: limit.toString() });
272
- const response = await this.makeRequest(`/subreddits/popular.json?${params}`);
273
- if (!response.ok) {
274
- throw new Error(`HTTP ${response.status}`);
275
- }
276
- const json = await response.json();
277
- return json.data.children.map((child) => child.data.display_name);
278
- } catch {
279
- throw new Error("Failed to get trending subreddits");
280
- }
281
- }
282
- async createPost(subreddit, title, content, isSelf = true) {
283
- await this.authenticate();
284
- if (!this.username || !this.password) {
285
- throw new Error("User authentication required for posting");
286
- }
287
- try {
288
- const kind = isSelf ? "self" : "link";
289
- const params = new URLSearchParams();
290
- params.append("sr", subreddit);
291
- params.append("kind", kind);
292
- params.append("title", title);
293
- params.append(isSelf ? "text" : "url", content);
294
- const response = await this.makeRequest("/api/submit", {
295
- method: "POST",
296
- headers: {
297
- "Content-Type": "application/x-www-form-urlencoded"
298
- },
299
- body: params.toString()
300
- });
301
- if (!response.ok) {
302
- throw new Error(`HTTP ${response.status}`);
303
- }
304
- const json = await response.json();
305
- if (json.success) {
306
- const postId = json.data.id;
307
- return await this.getPost(postId);
308
- } else {
309
- throw new Error("Failed to create post");
310
- }
311
- } catch {
312
- throw new Error(`Failed to create post in ${subreddit}`);
313
- }
314
- }
315
- async checkPostExists(postId) {
316
- await this.authenticate();
317
- try {
318
- const response = await this.makeRequest(`/api/info.json?id=t3_${postId}`);
319
- if (!response.ok) {
320
- return false;
321
- }
322
- const json = await response.json();
323
- return json.data.children.length > 0;
324
- } catch {
325
- return false;
326
- }
327
- }
328
- async replyToPost(postId, content) {
329
- await this.authenticate();
330
- if (!this.username || !this.password) {
331
- throw new Error("User authentication required for posting replies");
332
- }
333
- try {
334
- if (!await this.checkPostExists(postId)) {
335
- throw new Error(`Post with ID ${postId} does not exist or is not accessible`);
336
- }
337
- const params = new URLSearchParams();
338
- params.append("thing_id", `t3_${postId}`);
339
- params.append("text", content);
340
- const response = await this.makeRequest("/api/comment", {
341
- method: "POST",
342
- headers: {
343
- "Content-Type": "application/x-www-form-urlencoded"
344
- },
345
- body: params.toString()
346
- });
347
- if (!response.ok) {
348
- throw new Error(`HTTP ${response.status}`);
349
- }
350
- const commentData = await response.json();
351
- return {
352
- id: commentData.id,
353
- author: this.username,
354
- body: content,
355
- score: 1,
356
- controversiality: 0,
357
- subreddit: commentData.subreddit,
358
- submissionTitle: commentData.link_title,
359
- createdUtc: Date.now() / 1e3,
360
- edited: false,
361
- isSubmitter: false,
362
- permalink: commentData.permalink
363
- };
364
- } catch {
365
- throw new Error(`Failed to reply to post ${postId}`);
366
- }
367
- }
368
- async searchReddit(query, options = {}) {
369
- await this.authenticate();
370
- try {
371
- const { subreddit, sort = "relevance", timeFilter = "all", limit = 25, type = "link" } = options;
372
- const endpoint = subreddit ? `/r/${subreddit}/search.json` : "/search.json";
373
- const params = new URLSearchParams({
374
- q: query,
375
- sort,
376
- t: timeFilter,
377
- limit: limit.toString(),
378
- type,
379
- ...subreddit && { restrict_sr: "true" }
380
- });
381
- const response = await this.makeRequest(`${endpoint}?${params}`);
382
- if (!response.ok) {
383
- throw new Error(`HTTP ${response.status}`);
384
- }
385
- const json = await response.json();
386
- return json.data.children.filter((child) => child.kind === "t3").map((child) => {
387
- const post = child.data;
388
- return {
389
- id: post.id,
390
- title: post.title,
391
- author: post.author,
392
- subreddit: post.subreddit,
393
- selftext: post.selftext || "",
394
- url: post.url,
395
- score: post.score,
396
- upvoteRatio: post.upvote_ratio,
397
- numComments: post.num_comments,
398
- createdUtc: post.created_utc,
399
- over18: post.over_18,
400
- spoiler: post.spoiler,
401
- edited: !!post.edited,
402
- isSelf: post.is_self,
403
- linkFlairText: post.link_flair_text ?? void 0,
404
- permalink: post.permalink
405
- };
406
- });
407
- } catch {
408
- throw new Error(`Failed to search Reddit for: ${query}`);
409
- }
410
- }
411
- async getPostComments(postId, subreddit, options = {}) {
412
- await this.authenticate();
413
- try {
414
- const { sort = "best", limit = 100 } = options;
415
- const params = new URLSearchParams({
416
- sort,
417
- limit: limit.toString()
418
- });
419
- const response = await this.makeRequest(`/r/${subreddit}/comments/${postId}.json?${params}`);
420
- if (!response.ok) {
421
- throw new Error(`HTTP ${response.status}`);
422
- }
423
- const json = await response.json();
424
- const postData = json[0].data.children[0].data;
425
- const post = {
426
- id: postData.id,
427
- title: postData.title,
428
- author: postData.author,
429
- subreddit: postData.subreddit,
430
- selftext: postData.selftext || "",
431
- url: postData.url,
432
- score: postData.score,
433
- upvoteRatio: postData.upvote_ratio,
434
- numComments: postData.num_comments,
435
- createdUtc: postData.created_utc,
436
- over18: postData.over_18,
437
- spoiler: postData.spoiler,
438
- edited: !!postData.edited,
439
- isSelf: postData.is_self,
440
- linkFlairText: postData.link_flair_text,
441
- permalink: postData.permalink
442
- };
443
- const comments = [];
444
- const parseComments = (commentData, depth = 0) => {
445
- for (const item of commentData) {
446
- if (item.kind === "t1" && item.data.body) {
447
- comments.push({
448
- id: item.data.id,
449
- author: item.data.author,
450
- body: item.data.body,
451
- score: item.data.score,
452
- controversiality: item.data.controversiality,
453
- subreddit: item.data.subreddit,
454
- submissionTitle: post.title,
455
- createdUtc: item.data.created_utc,
456
- edited: !!item.data.edited,
457
- isSubmitter: item.data.is_submitter,
458
- permalink: item.data.permalink,
459
- depth,
460
- parentId: item.data.parent_id
461
- });
462
- if (item.data.replies && item.data.replies.data && item.data.replies.data.children) {
463
- parseComments(item.data.replies.data.children, depth + 1);
464
- }
465
- }
466
- }
467
- };
468
- if (json[1] && json[1].data && json[1].data.children) {
469
- parseComments(json[1].data.children);
470
- }
471
- return { post, comments };
472
- } catch {
473
- throw new Error(`Failed to get comments for post ${postId}`);
474
- }
475
- }
476
- async getUserPosts(username, options = {}) {
477
- await this.authenticate();
478
- try {
479
- const { sort = "new", timeFilter = "all", limit = 25 } = options;
480
- const params = new URLSearchParams({
481
- sort,
482
- t: timeFilter,
483
- limit: limit.toString()
484
- });
485
- const response = await this.makeRequest(`/user/${username}/submitted.json?${params}`);
486
- if (!response.ok) {
487
- throw new Error(`HTTP ${response.status}`);
488
- }
489
- const json = await response.json();
490
- return json.data.children.filter((child) => child.kind === "t3").map((child) => {
491
- const post = child.data;
492
- return {
493
- id: post.id,
494
- title: post.title,
495
- author: post.author,
496
- subreddit: post.subreddit,
497
- selftext: post.selftext || "",
498
- url: post.url,
499
- score: post.score,
500
- upvoteRatio: post.upvote_ratio,
501
- numComments: post.num_comments,
502
- createdUtc: post.created_utc,
503
- over18: post.over_18,
504
- spoiler: post.spoiler,
505
- edited: !!post.edited,
506
- isSelf: post.is_self,
507
- linkFlairText: post.link_flair_text ?? void 0,
508
- permalink: post.permalink
509
- };
510
- });
511
- } catch {
512
- throw new Error(`Failed to get posts for user ${username}`);
513
- }
514
- }
515
- async getUserComments(username, options = {}) {
516
- await this.authenticate();
517
- try {
518
- const { sort = "new", timeFilter = "all", limit = 25 } = options;
519
- const params = new URLSearchParams({
520
- sort,
521
- t: timeFilter,
522
- limit: limit.toString()
523
- });
524
- const response = await this.makeRequest(`/user/${username}/comments.json?${params}`);
525
- if (!response.ok) {
526
- throw new Error(`HTTP ${response.status}`);
527
- }
528
- const json = await response.json();
529
- return json.data.children.filter((child) => child.kind === "t1").map((child) => {
530
- const comment = child.data;
531
- return {
532
- id: comment.id,
533
- author: comment.author,
534
- body: comment.body,
535
- score: comment.score,
536
- controversiality: comment.controversiality,
537
- subreddit: comment.subreddit,
538
- submissionTitle: comment.link_title || "",
539
- createdUtc: comment.created_utc,
540
- edited: !!comment.edited,
541
- isSubmitter: comment.is_submitter,
542
- permalink: comment.permalink
543
- };
544
- });
545
- } catch {
546
- throw new Error(`Failed to get comments for user ${username}`);
547
- }
548
- }
549
- };
550
- redditClient = null;
551
- }
552
- });
553
-
554
- // src/utils/formatters.ts
555
- function formatTimestamp(timestamp) {
556
- try {
557
- const date = new Date(timestamp * 1e3);
558
- return date.toISOString().replace("T", " ").replace(/\.\d+Z$/, " UTC");
559
- } catch {
560
- return String(timestamp);
561
- }
562
- }
563
- function analyzeUserActivity(karmaRatio, isMod, accountAgeDays) {
564
- const insights = [];
565
- if (karmaRatio > 5) {
566
- insights.push("Primarily a commenter, highly engaged in discussions");
567
- } else if (karmaRatio < 0.2) {
568
- insights.push("Content creator, focuses on sharing posts");
569
- } else {
570
- insights.push("Balanced participation in both posting and commenting");
571
- }
572
- if (accountAgeDays < 30) {
573
- insights.push("New user, still exploring Reddit");
574
- } else if (accountAgeDays > 365 * 5) {
575
- insights.push("Long-time Redditor with extensive platform experience");
576
- }
577
- if (isMod) {
578
- insights.push("Community leader who helps maintain subreddit quality");
579
- }
580
- return insights.join("\n - ");
581
- }
582
- function analyzePostEngagement(score, ratio, numComments) {
583
- const insights = [];
584
- if (score > 1e3 && ratio > 0.95) {
585
- insights.push("Highly successful post with strong community approval");
586
- } else if (score > 100 && ratio > 0.8) {
587
- insights.push("Well-received post with good engagement");
588
- } else if (ratio < 0.5) {
589
- insights.push("Controversial post that sparked debate");
590
- }
591
- if (numComments > 100) {
592
- insights.push("Generated significant discussion");
593
- } else if (numComments > score * 0.5) {
594
- insights.push("Highly discussable content with active comment section");
595
- } else if (numComments === 0) {
596
- insights.push("Yet to receive community interaction");
597
- }
598
- return insights.join("\n - ");
599
- }
600
- function analyzeSubredditHealth(subscribers, activeUsers, ageDays) {
601
- const insights = [];
602
- if (subscribers > 1e6) {
603
- insights.push("Major subreddit with massive following");
604
- } else if (subscribers > 1e5) {
605
- insights.push("Well-established community");
606
- } else if (subscribers < 1e3) {
607
- insights.push("Niche community, potential for growth");
608
- }
609
- if (activeUsers) {
610
- const activityRatio = activeUsers / subscribers;
611
- if (activityRatio > 0.1) {
612
- insights.push("Highly active community with strong engagement");
613
- } else if (activityRatio < 0.01) {
614
- insights.push("Could benefit from more community engagement initiatives");
615
- }
616
- }
617
- if (ageDays > 365 * 5) {
618
- insights.push("Mature subreddit with established culture");
619
- } else if (ageDays < 90) {
620
- insights.push("New subreddit still forming its community");
621
- }
622
- return insights.join("\n - ");
623
- }
624
- function getUserRecommendations(karmaRatio, isMod, accountAgeDays) {
625
- const recommendations = [];
626
- if (karmaRatio > 5) {
627
- recommendations.push("Consider creating more posts to share your expertise");
628
- } else if (karmaRatio < 0.2) {
629
- recommendations.push("Engage more in discussions to build community connections");
630
- }
631
- if (accountAgeDays < 30) {
632
- recommendations.push("Explore popular subreddits in your areas of interest");
633
- recommendations.push("Read community guidelines before posting");
634
- }
635
- if (isMod) {
636
- recommendations.push("Share moderation insights with other community leaders");
637
- }
638
- if (!recommendations.length) {
639
- recommendations.push("Maintain your balanced engagement across Reddit");
640
- }
641
- return recommendations.join("\n - ");
642
- }
643
- function getBestEngagementTime(createdUtc) {
644
- const postHour = new Date(createdUtc * 1e3).getHours();
645
- if (14 <= postHour && postHour <= 18) {
646
- return "Posted during peak engagement hours (2 PM - 6 PM), good timing!";
647
- } else if (23 <= postHour || postHour <= 5) {
648
- return "Consider posting during more active hours (morning to evening)";
649
- } else {
650
- return "Posted during moderate activity hours, timing could be optimized";
651
- }
652
- }
653
- function getSubredditEngagementTips(subreddit) {
654
- const tips = [];
655
- if (subreddit.subscribers > 1e6) {
656
- tips.push("Post during peak hours for maximum visibility");
657
- tips.push("Ensure content is highly polished due to high competition");
658
- } else if (subreddit.subscribers < 1e3) {
659
- tips.push("Engage actively to help grow the community");
660
- tips.push("Consider cross-posting to related larger subreddits");
661
- }
662
- if (subreddit.activeUserCount) {
663
- const activityRatio = subreddit.activeUserCount / subreddit.subscribers;
664
- if (activityRatio > 0.1) {
665
- tips.push("Quick responses recommended due to high activity");
666
- }
667
- }
668
- return tips.length ? tips.join("\n - ") : "Regular engagement recommended to maintain community presence";
669
- }
670
- function formatUserInfo(user) {
671
- const status = [];
672
- if (user.isMod) status.push("Moderator");
673
- if (user.isGold) status.push("Reddit Gold Member");
674
- if (user.isEmployee) status.push("Reddit Employee");
675
- const accountAgeDays = (Date.now() / 1e3 - user.createdUtc) / (24 * 3600);
676
- const karmaRatio = user.commentKarma / (user.linkKarma || 1);
677
- return {
678
- username: user.name,
679
- karma: {
680
- commentKarma: user.commentKarma,
681
- postKarma: user.linkKarma,
682
- totalKarma: user.totalKarma
683
- },
684
- accountStatus: status.length ? status : ["Regular User"],
685
- accountCreated: formatTimestamp(user.createdUtc),
686
- profileUrl: user.profileUrl,
687
- activityAnalysis: analyzeUserActivity(karmaRatio, user.isMod, accountAgeDays),
688
- recommendations: getUserRecommendations(karmaRatio, user.isMod, accountAgeDays)
689
- };
690
- }
691
- function formatPostInfo(post) {
692
- const contentType = post.isSelf ? "Text Post" : "Link Post";
693
- const content = post.isSelf ? post.selftext || "" : post.url || "";
694
- const flags = [];
695
- if (post.over18) flags.push("NSFW");
696
- if (post.spoiler) flags.push("Spoiler");
697
- if (post.edited) flags.push("Edited");
698
- return {
699
- title: post.title,
700
- type: contentType,
701
- content: content.length > 300 ? content.substring(0, 297) + "..." : content,
702
- author: post.author,
703
- subreddit: post.subreddit,
704
- stats: {
705
- score: post.score,
706
- upvoteRatio: post.upvoteRatio,
707
- comments: post.numComments
708
- },
709
- metadata: {
710
- posted: formatTimestamp(post.createdUtc),
711
- flags,
712
- flair: post.linkFlairText || "None"
713
- },
714
- links: {
715
- fullPost: `https://reddit.com${post.permalink}`,
716
- shortLink: `https://redd.it/${post.id}`
717
- },
718
- engagementAnalysis: analyzePostEngagement(post.score, post.upvoteRatio, post.numComments),
719
- bestTimeToEngage: getBestEngagementTime(post.createdUtc)
720
- };
721
- }
722
- function formatSubredditInfo(subreddit) {
723
- const flags = [];
724
- if (subreddit.over18) flags.push("NSFW");
725
- if (subreddit.subredditType) flags.push(`Type: ${subreddit.subredditType}`);
726
- const ageDays = (Date.now() / 1e3 - subreddit.createdUtc) / (24 * 3600);
727
- return {
728
- name: subreddit.displayName,
729
- title: subreddit.title,
730
- stats: {
731
- subscribers: subreddit.subscribers,
732
- activeUsers: subreddit.activeUserCount !== void 0 ? subreddit.activeUserCount : "Unknown"
733
- },
734
- description: {
735
- short: subreddit.publicDescription,
736
- full: subreddit.description.length > 300 ? subreddit.description.substring(0, 297) + "..." : subreddit.description
737
- },
738
- metadata: {
739
- created: formatTimestamp(subreddit.createdUtc),
740
- flags: flags.length ? flags : ["None"]
741
- },
742
- links: {
743
- subreddit: `https://reddit.com${subreddit.url}`,
744
- wiki: `https://reddit.com/r/${subreddit.displayName}/wiki`
745
- },
746
- communityAnalysis: analyzeSubredditHealth(subreddit.subscribers, subreddit.activeUserCount, ageDays),
747
- engagementTips: getSubredditEngagementTips(subreddit)
748
- };
749
- }
750
- var init_formatters = __esm({
751
- "src/utils/formatters.ts"() {
752
- "use strict";
753
- init_cjs_shims();
754
- }
755
- });
756
-
757
- // src/index.ts
758
- var src_exports = {};
759
- async function setupRedditClient() {
760
- const clientId = process.env.REDDIT_CLIENT_ID;
761
- const clientSecret = process.env.REDDIT_CLIENT_SECRET;
762
- const userAgent = process.env.REDDIT_USER_AGENT || "RedditMCPServer/1.1.0";
763
- const username = process.env.REDDIT_USERNAME;
764
- const password = process.env.REDDIT_PASSWORD;
765
- if (!clientId || !clientSecret) {
766
- console.error(
767
- "[Error] Missing required Reddit API credentials. Please set REDDIT_CLIENT_ID and REDDIT_CLIENT_SECRET environment variables."
768
- );
769
- process.exit(1);
770
- }
771
- try {
772
- initializeRedditClient({
773
- clientId,
774
- clientSecret,
775
- userAgent,
776
- username,
777
- password
778
- });
779
- console.error("[Setup] Reddit client initialized");
780
- if (username && password) {
781
- console.error(`[Setup] Authenticated as user: ${username}`);
782
- } else {
783
- console.error("[Setup] Running in read-only mode (no user authentication)");
784
- }
785
- } catch (error) {
786
- console.error("[Error] Failed to initialize Reddit client:", error);
787
- process.exit(1);
788
- }
789
- }
790
- async function main() {
791
- try {
792
- await setupRedditClient();
793
- await server.start({
794
- transportType: "stdio"
795
- });
796
- } catch (error) {
797
- console.error("[Error] Failed to start server:", error);
798
- process.exit(1);
799
- }
800
- }
801
- var import_fastmcp, import_zod, import_dotenv, server;
802
- var init_src = __esm({
803
- "src/index.ts"() {
804
- "use strict";
805
- init_cjs_shims();
806
- import_fastmcp = require("fastmcp");
807
- import_zod = require("zod");
808
- init_reddit_client();
809
- init_formatters();
810
- import_dotenv = __toESM(require("dotenv"));
811
- import_dotenv.default.config();
812
- server = new import_fastmcp.FastMCP({
813
- name: "reddit-mcp-server",
814
- version: "1.1.0",
815
- instructions: `A comprehensive Reddit MCP server that provides tools for interacting with Reddit API.
816
-
817
- Available capabilities:
818
- - Fetch Reddit posts, comments, and user information
819
- - Get subreddit details and statistics
820
- - Search Reddit content across posts and subreddits
821
- - Create posts and reply to posts/comments (with authentication)
822
- - Analyze engagement metrics and community insights
823
-
824
- For write operations (posting, replying), ensure REDDIT_USERNAME and REDDIT_PASSWORD are configured.`,
825
- // Optional OAuth configuration for HTTP transport
826
- ...process.env.OAUTH_ENABLED === "true" && {
827
- authenticate: async (request) => {
828
- const authHeader = request.headers.authorization;
829
- const expectedToken = process.env.OAUTH_TOKEN;
830
- if (!expectedToken) {
831
- const token2 = Array.from(
832
- { length: 32 },
833
- () => "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".charAt(Math.floor(Math.random() * 62))
834
- ).join("");
835
- console.log(`[Auth] Generated OAuth token: ${token2}`);
836
- throw new Response(
837
- JSON.stringify({
838
- error: "No OAuth token configured",
839
- generatedToken: token2
840
- }),
841
- {
842
- status: 401,
843
- headers: { "Content-Type": "application/json" }
844
- }
845
- );
846
- }
847
- if (!(authHeader == null ? void 0 : authHeader.startsWith("Bearer "))) {
848
- throw new Response(null, {
849
- status: 401,
850
- statusText: "Missing or invalid Authorization header"
851
- });
852
- }
853
- const token = authHeader.slice(7);
854
- if (token !== expectedToken) {
855
- throw new Response(null, {
856
- status: 403,
857
- statusText: "Invalid token"
858
- });
859
- }
860
- return { authenticated: true };
861
- }
862
- }
863
- });
864
- server.addTool({
865
- name: "test_reddit_mcp_server",
866
- description: "Test the Reddit MCP Server connection and configuration",
867
- parameters: import_zod.z.object({}),
868
- execute: async () => {
869
- const client = getRedditClient();
870
- const hasAuth = client ? "\u2713" : "\u2717";
871
- const hasWriteAccess = process.env.REDDIT_USERNAME && process.env.REDDIT_PASSWORD ? "\u2713" : "\u2717";
872
- return `Reddit MCP Server Status:
873
- - Server: \u2713 Running
874
- - Reddit Client: ${hasAuth} ${client ? "Initialized" : "Not initialized"}
875
- - Write Access: ${hasWriteAccess} ${hasWriteAccess === "\u2713" ? "Available" : "Read-only mode"}
876
- - Version: 1.1.0
877
-
878
- Ready to handle Reddit API requests!`;
879
- }
880
- });
881
- server.addTool({
882
- name: "get_user_info",
883
- description: "Get detailed information about a Reddit user including karma, account status, and activity analysis",
884
- parameters: import_zod.z.object({
885
- username: import_zod.z.string().describe("The Reddit username (without u/ prefix)")
886
- }),
887
- execute: async (args2) => {
888
- const client = getRedditClient();
889
- if (!client) {
890
- throw new Error("Reddit client not initialized");
891
- }
892
- const user = await client.getUser(args2.username);
893
- const formattedUser = formatUserInfo(user);
894
- return `# User Information: u/${formattedUser.username}
895
-
896
- ## Profile Overview
897
- - Username: u/${formattedUser.username}
898
- - Karma:
899
- - Comment Karma: ${formattedUser.karma.commentKarma.toLocaleString()}
900
- - Post Karma: ${formattedUser.karma.postKarma.toLocaleString()}
901
- - Total Karma: ${formattedUser.karma.totalKarma.toLocaleString()}
902
- - Account Status: ${formattedUser.accountStatus.join(", ")}
903
- - Account Created: ${formattedUser.accountCreated}
904
- - Profile URL: ${formattedUser.profileUrl}
905
-
906
- ## Activity Analysis
907
- - ${formattedUser.activityAnalysis.replace(/\n - /g, "\n- ")}
908
-
909
- ## Recommendations
910
- - ${formattedUser.recommendations.replace(/\n {2}- /g, "\n- ")}`;
911
- }
912
- });
913
- server.addTool({
914
- name: "get_user_posts",
915
- description: "Get recent posts by a Reddit user with sorting and filtering options",
916
- parameters: import_zod.z.object({
917
- username: import_zod.z.string().describe("The Reddit username (without u/ prefix)"),
918
- sort: import_zod.z.enum(["new", "hot", "top"]).default("new").describe("Sort order for posts"),
919
- time_filter: import_zod.z.enum(["hour", "day", "week", "month", "year", "all"]).default("all").describe("Time filter for top posts"),
920
- limit: import_zod.z.number().min(1).max(100).default(10).describe("Number of posts to retrieve")
921
- }),
922
- execute: async (args2) => {
923
- const client = getRedditClient();
924
- if (!client) {
925
- throw new Error("Reddit client not initialized");
926
- }
927
- const posts = await client.getUserPosts(args2.username, {
928
- sort: args2.sort,
929
- timeFilter: args2.time_filter,
930
- limit: args2.limit
931
- });
932
- if (posts.length === 0) {
933
- return `No posts found for u/${args2.username} with the specified filters.`;
934
- }
935
- const postSummaries = posts.map((post, index) => {
936
- const flags = [...post.over18 ? ["**NSFW**"] : [], ...post.spoiler ? ["**Spoiler**"] : []];
937
- return `### ${index + 1}. ${post.title} ${flags.join(" ")}
938
- - Subreddit: r/${post.subreddit}
939
- - Score: ${post.score.toLocaleString()} (${(post.upvoteRatio * 100).toFixed(1)}% upvoted)
940
- - Comments: ${post.numComments.toLocaleString()}
941
- - Posted: ${new Date(post.createdUtc * 1e3).toLocaleString()}
942
- - Link: https://reddit.com${post.permalink}`;
943
- }).join("\n\n");
944
- return `# Posts by u/${args2.username} (${args2.sort} - ${args2.time_filter})
945
-
946
- ${postSummaries}`;
947
- }
948
- });
949
- server.addTool({
950
- name: "get_user_comments",
951
- description: "Get recent comments by a Reddit user with sorting and filtering options",
952
- parameters: import_zod.z.object({
953
- username: import_zod.z.string().describe("The Reddit username (without u/ prefix)"),
954
- sort: import_zod.z.enum(["new", "hot", "top"]).default("new").describe("Sort order for comments"),
955
- time_filter: import_zod.z.enum(["hour", "day", "week", "month", "year", "all"]).default("all").describe("Time filter for top comments"),
956
- limit: import_zod.z.number().min(1).max(100).default(10).describe("Number of comments to retrieve")
957
- }),
958
- execute: async (args2) => {
959
- const client = getRedditClient();
960
- if (!client) {
961
- throw new Error("Reddit client not initialized");
962
- }
963
- const comments = await client.getUserComments(args2.username, {
964
- sort: args2.sort,
965
- timeFilter: args2.time_filter,
966
- limit: args2.limit
967
- });
968
- if (comments.length === 0) {
969
- return `No comments found for u/${args2.username} with the specified filters.`;
970
- }
971
- const commentSummaries = comments.map((comment, index) => {
972
- const truncatedBody = comment.body.length > 300 ? comment.body.substring(0, 300) + "..." : comment.body;
973
- const flags = [...comment.edited ? ["*(edited)*"] : [], ...comment.isSubmitter ? ["**OP**"] : []];
974
- return `### ${index + 1}. Comment ${flags.join(" ")}
975
- In r/${comment.subreddit} on "${comment.submissionTitle}"
976
-
977
- > ${truncatedBody}
978
-
979
- - Score: ${comment.score.toLocaleString()}
980
- - Posted: ${new Date(comment.createdUtc * 1e3).toLocaleString()}
981
- - Link: https://reddit.com${comment.permalink}`;
982
- }).join("\n\n");
983
- return `# Comments by u/${args2.username} (${args2.sort} - ${args2.time_filter})
984
-
985
- ${commentSummaries}`;
986
- }
987
- });
988
- server.addTool({
989
- name: "get_reddit_post",
990
- description: "Get detailed information about a specific Reddit post including content, stats, and engagement analysis",
991
- parameters: import_zod.z.object({
992
- subreddit: import_zod.z.string().describe("The subreddit name (without r/ prefix)"),
993
- post_id: import_zod.z.string().describe("The Reddit post ID")
994
- }),
995
- execute: async (args2) => {
996
- const client = getRedditClient();
997
- if (!client) {
998
- throw new Error("Reddit client not initialized");
999
- }
1000
- const post = await client.getPost(args2.post_id, args2.subreddit);
1001
- const formattedPost = formatPostInfo(post);
1002
- return `# Post from r/${formattedPost.subreddit}
1003
-
1004
- ## Post Details
1005
- - Title: ${formattedPost.title}
1006
- - Type: ${formattedPost.type}
1007
- - Author: u/${formattedPost.author}
1008
-
1009
- ## Content
1010
- ${formattedPost.content}
1011
-
1012
- ## Stats
1013
- - Score: ${formattedPost.stats.score.toLocaleString()}
1014
- - Upvote Ratio: ${(formattedPost.stats.upvoteRatio * 100).toFixed(1)}%
1015
- - Comments: ${formattedPost.stats.comments.toLocaleString()}
1016
-
1017
- ## Metadata
1018
- - Posted: ${formattedPost.metadata.posted}
1019
- - Flags: ${formattedPost.metadata.flags.length ? formattedPost.metadata.flags.join(", ") : "None"}
1020
- - Flair: ${formattedPost.metadata.flair}
1021
-
1022
- ## Links
1023
- - Full Post: ${formattedPost.links.fullPost}
1024
- - Short Link: ${formattedPost.links.shortLink}
1025
-
1026
- ## Engagement Analysis
1027
- - ${formattedPost.engagementAnalysis.replace(/\n - /g, "\n- ")}
1028
-
1029
- ## Best Time to Engage
1030
- ${formattedPost.bestTimeToEngage}`;
1031
- }
1032
- });
1033
- server.addTool({
1034
- name: "get_top_posts",
1035
- description: "Get top posts from a subreddit or from the Reddit home feed",
1036
- parameters: import_zod.z.object({
1037
- subreddit: import_zod.z.string().optional().describe("The subreddit name (without r/ prefix). Leave empty for home feed"),
1038
- time_filter: import_zod.z.enum(["hour", "day", "week", "month", "year", "all"]).default("week").describe("Time period for top posts"),
1039
- limit: import_zod.z.number().min(1).max(100).default(10).describe("Number of posts to retrieve")
1040
- }),
1041
- execute: async (args2) => {
1042
- const client = getRedditClient();
1043
- if (!client) {
1044
- throw new Error("Reddit client not initialized");
1045
- }
1046
- const posts = await client.getTopPosts(args2.subreddit || "", args2.time_filter, args2.limit);
1047
- if (posts.length === 0) {
1048
- const location2 = args2.subreddit ? `r/${args2.subreddit}` : "home feed";
1049
- return `No posts found in ${location2} for the specified time period.`;
1050
- }
1051
- const formattedPosts = posts.map(formatPostInfo);
1052
- const postSummaries = formattedPosts.map(
1053
- (post, index) => `### ${index + 1}. ${post.title}
1054
- - Author: u/${post.author}
1055
- - Score: ${post.stats.score.toLocaleString()} (${(post.stats.upvoteRatio * 100).toFixed(1)}% upvoted)
1056
- - Comments: ${post.stats.comments.toLocaleString()}
1057
- - Posted: ${post.metadata.posted}
1058
- - Link: ${post.links.shortLink}`
1059
- ).join("\n\n");
1060
- const location = args2.subreddit ? `r/${args2.subreddit}` : "Home Feed";
1061
- return `# Top Posts from ${location} (${args2.time_filter})
1062
-
1063
- ${postSummaries}`;
1064
- }
1065
- });
1066
- server.addTool({
1067
- name: "get_subreddit_info",
1068
- description: "Get detailed information about a subreddit including description, stats, and community analysis",
1069
- parameters: import_zod.z.object({
1070
- subreddit_name: import_zod.z.string().describe("The subreddit name (without r/ prefix)")
1071
- }),
1072
- execute: async (args2) => {
1073
- const client = getRedditClient();
1074
- if (!client) {
1075
- throw new Error("Reddit client not initialized");
1076
- }
1077
- const subreddit = await client.getSubredditInfo(args2.subreddit_name);
1078
- const formattedSubreddit = formatSubredditInfo(subreddit);
1079
- return `# Subreddit Information: r/${formattedSubreddit.name}
1080
-
1081
- ## Overview
1082
- - Name: r/${formattedSubreddit.name}
1083
- - Title: ${formattedSubreddit.title}
1084
- - Subscribers: ${formattedSubreddit.stats.subscribers.toLocaleString()}
1085
- - Active Users: ${typeof formattedSubreddit.stats.activeUsers === "number" ? formattedSubreddit.stats.activeUsers.toLocaleString() : formattedSubreddit.stats.activeUsers}
1086
-
1087
- ## Description
1088
- ${formattedSubreddit.description.short}
1089
-
1090
- ## Detailed Description
1091
- ${formattedSubreddit.description.full}
1092
-
1093
- ## Metadata
1094
- - Created: ${formattedSubreddit.metadata.created}
1095
- - Flags: ${formattedSubreddit.metadata.flags.join(", ")}
1096
-
1097
- ## Links
1098
- - Subreddit: ${formattedSubreddit.links.subreddit}
1099
- - Wiki: ${formattedSubreddit.links.wiki}
1100
-
1101
- ## Community Analysis
1102
- - ${formattedSubreddit.communityAnalysis.replace(/\n - /g, "\n- ")}
1103
-
1104
- ## Engagement Tips
1105
- - ${formattedSubreddit.engagementTips.replace(/\n - /g, "\n- ")}`;
1106
- }
1107
- });
1108
- server.addTool({
1109
- name: "get_trending_subreddits",
1110
- description: "Get a list of currently trending subreddits",
1111
- parameters: import_zod.z.object({}),
1112
- execute: async () => {
1113
- const client = getRedditClient();
1114
- if (!client) {
1115
- throw new Error("Reddit client not initialized");
1116
- }
1117
- const trendingSubreddits = await client.getTrendingSubreddits();
1118
- return `# Trending Subreddits
1119
-
1120
- ${trendingSubreddits.map((subreddit, index) => `${index + 1}. r/${subreddit}`).join("\n")}`;
1121
- }
1122
- });
1123
- server.addTool({
1124
- name: "search_reddit",
1125
- description: "Search Reddit for posts and content across subreddits",
1126
- parameters: import_zod.z.object({
1127
- query: import_zod.z.string().describe("Search query"),
1128
- subreddit: import_zod.z.string().optional().describe("Limit search to specific subreddit (without r/ prefix)"),
1129
- sort: import_zod.z.enum(["relevance", "hot", "top", "new", "comments"]).default("relevance").describe("Sort order"),
1130
- time_filter: import_zod.z.enum(["hour", "day", "week", "month", "year", "all"]).default("all").describe("Time filter"),
1131
- limit: import_zod.z.number().min(1).max(100).default(10).describe("Number of results"),
1132
- type: import_zod.z.enum(["link", "sr", "user"]).default("link").describe("Type of content to search")
1133
- }),
1134
- execute: async (args2) => {
1135
- const client = getRedditClient();
1136
- if (!client) {
1137
- throw new Error("Reddit client not initialized");
1138
- }
1139
- if (!args2.query || args2.query.trim() === "") {
1140
- throw new Error("Search query cannot be empty");
1141
- }
1142
- const posts = await client.searchReddit(args2.query, {
1143
- subreddit: args2.subreddit,
1144
- sort: args2.sort,
1145
- timeFilter: args2.time_filter,
1146
- limit: args2.limit,
1147
- type: args2.type
1148
- });
1149
- if (posts.length === 0) {
1150
- const searchLocation2 = args2.subreddit ? ` in r/${args2.subreddit}` : "";
1151
- return `No results found for "${args2.query}"${searchLocation2}.`;
1152
- }
1153
- const searchResults = posts.map((post, index) => {
1154
- const flags = [...post.over18 ? ["**NSFW**"] : [], ...post.spoiler ? ["**Spoiler**"] : []];
1155
- return `### ${index + 1}. ${post.title} ${flags.join(" ")}
1156
- - Subreddit: r/${post.subreddit}
1157
- - Author: u/${post.author}
1158
- - Score: ${post.score.toLocaleString()} (${(post.upvoteRatio * 100).toFixed(1)}% upvoted)
1159
- - Comments: ${post.numComments.toLocaleString()}
1160
- - Posted: ${new Date(post.createdUtc * 1e3).toLocaleString()}
1161
- - Link: https://reddit.com${post.permalink}`;
1162
- }).join("\n\n");
1163
- const searchLocation = args2.subreddit ? ` in r/${args2.subreddit}` : "";
1164
- return `# Reddit Search Results for: "${args2.query}"${searchLocation}
1165
-
1166
- Sorted by: ${args2.sort} | Time: ${args2.time_filter} | Type: ${args2.type}
1167
-
1168
- ${searchResults}`;
1169
- }
1170
- });
1171
- server.addTool({
1172
- name: "get_post_comments",
1173
- description: "Get comments from a specific Reddit post",
1174
- parameters: import_zod.z.object({
1175
- post_id: import_zod.z.string().describe("The Reddit post ID"),
1176
- subreddit: import_zod.z.string().describe("The subreddit name (without r/ prefix)"),
1177
- sort: import_zod.z.enum(["best", "top", "new", "controversial", "old", "qa"]).default("best").describe("Comment sort order"),
1178
- limit: import_zod.z.number().min(1).max(500).default(100).describe("Maximum number of comments to retrieve")
1179
- }),
1180
- execute: async (args2) => {
1181
- const client = getRedditClient();
1182
- if (!client) {
1183
- throw new Error("Reddit client not initialized");
1184
- }
1185
- if (!args2.post_id || !args2.subreddit) {
1186
- throw new Error("post_id and subreddit are required");
1187
- }
1188
- const data = await client.getPostComments(args2.post_id, args2.subreddit, {
1189
- sort: args2.sort,
1190
- limit: args2.limit
1191
- });
1192
- const post = data.post;
1193
- const comments = data.comments;
1194
- let response = `# Comments for: ${post.title}
1195
-
1196
- **Post by u/${post.author} in r/${post.subreddit}**
1197
- - Score: ${post.score.toLocaleString()} | Comments: ${post.numComments.toLocaleString()}
1198
- - Posted: ${new Date(post.createdUtc * 1e3).toLocaleString()}
1199
-
1200
- ---
1201
-
1202
- `;
1203
- if (comments.length === 0) {
1204
- response += "No comments found for this post.";
1205
- return response;
1206
- }
1207
- const commentSummaries = comments.map((comment) => {
1208
- const indent = "\u2514\u2500".repeat(Math.min(comment.depth || 0, 3));
1209
- const authorBadge = comment.isSubmitter ? " **[OP]**" : "";
1210
- const editedBadge = comment.edited ? " *(edited)*" : "";
1211
- return `${indent} **u/${comment.author}**${authorBadge}${editedBadge} (${comment.score.toLocaleString()} points)
1212
-
1213
- ${comment.body}
1214
-
1215
- ---`;
1216
- }).join("\n\n");
1217
- response += commentSummaries;
1218
- return response;
1219
- }
1220
- });
1221
- process.on("SIGINT", async () => {
1222
- console.error("[Shutdown] Shutting down Reddit MCP Server...");
1223
- process.exit(0);
1224
- });
1225
- process.on("SIGTERM", async () => {
1226
- console.error("[Shutdown] Shutting down Reddit MCP Server...");
1227
- process.exit(0);
1228
- });
1229
- main().catch(console.error);
1230
- }
1231
- });
1232
-
1233
- // src/bin.ts
1234
- init_cjs_shims();
1235
- var import_fs = __toESM(require("fs"));
1236
- var import_path = __toESM(require("path"));
1237
- var packageJsonPath = import_path.default.join(__dirname, "..", "package.json");
1238
- var packageJson = JSON.parse(import_fs.default.readFileSync(packageJsonPath, "utf-8"));
1239
- var args = process.argv.slice(2);
2
+ const require_chunk = require('./chunk-kSYXY2_d.js');
3
+ let fs = require("fs");
4
+ fs = require_chunk.__toESM(fs);
5
+ let path = require("path");
6
+ path = require_chunk.__toESM(path);
7
+
8
+ //#region src/bin.ts
9
+ const packageJsonPath = path.default.join(__dirname, "..", "package.json");
10
+ const packageJson = JSON.parse(fs.default.readFileSync(packageJsonPath, "utf-8"));
11
+ if (!process.env.TRANSPORT_TYPE) process.env.TRANSPORT_TYPE = "stdio";
12
+ const args = process.argv.slice(2);
1240
13
  if (args.includes("--version") || args.includes("-v")) {
1241
- console.log(packageJson.version);
1242
- process.exit(0);
14
+ console.log(packageJson.version);
15
+ process.exit(0);
1243
16
  }
1244
- main2().then();
17
+ main().then();
1245
18
  if (args.includes("--help") || args.includes("-h")) {
1246
- console.log(`
19
+ console.log(`
1247
20
  Reddit MCP Server v${packageJson.version}
1248
21
 
1249
22
  Usage: reddit-mcp-server [options]
@@ -1261,8 +34,11 @@ Environment Variables:
1261
34
 
1262
35
  For more information, visit: https://github.com/jordanburke/reddit-mcp-server
1263
36
  `);
1264
- process.exit(0);
37
+ process.exit(0);
1265
38
  }
1266
- async function main2() {
1267
- await Promise.resolve().then(() => (init_src(), src_exports));
39
+ async function main() {
40
+ await Promise.resolve().then(() => require("./index.js"));
1268
41
  }
42
+
43
+ //#endregion
44
+ //# sourceMappingURL=bin.js.map