Browse Subreddit
browse_subredditBrowse posts from any subreddit using sort options like hot, new, top, rising, or controversial. Filter by time range for top and controversial results.
Instructions
Browse posts from a subreddit with sort options (hot, new, top, rising, controversial). For top and controversial, you can specify a time range.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| subreddit | Yes | Subreddit name without r/ prefix | |
| sort | No | Sort order for posts | hot |
| time | No | Time range filter (only for top and controversial) | |
| limit | No | Number of posts to return |
Implementation Reference
- src/tools/browse.ts:72-107 (handler)The handler function that executes the 'browse_subreddit' tool logic. It takes subreddit, sort, time, and limit parameters, calls the Reddit API client to fetch posts from /r/{subreddit}/{sort}.json, formats the posts using formatPost(), and returns the result as JSON text. Includes error handling.
async ({ subreddit, sort, time, limit }) => { try { const params = new URLSearchParams({ limit: String(limit) }); if (time && (sort === "top" || sort === "controversial")) { params.set("t", time); } const data = await client.getJson( `/r/${subreddit}/${sort}.json?${params}` ); const posts = (data?.data?.children || []).map((c: any) => formatPost(c.data) ); return { content: [ { type: "text" as const, text: JSON.stringify( { subreddit, sort, time: time ?? null, posts }, null, 2 ), }, ], }; } catch (error) { return { content: [ { type: "text" as const, text: `Error browsing r/${subreddit}: ${error instanceof Error ? error.message : String(error)}`, }, ], isError: true, }; } } - src/tools/browse.ts:49-70 (schema)The input schema (Zod validation) for browse_subreddit. Defines: subreddit (string), sort (enum: hot/new/top/rising/controversial, default hot), time (enum: hour/day/week/month/year/all, optional, only for top/controversial), limit (int 1-100, default 25).
{ title: "Browse Subreddit", description: "Browse posts from a subreddit with sort options (hot, new, top, rising, controversial). For top and controversial, you can specify a time range.", inputSchema: z.object({ subreddit: z.string().describe("Subreddit name without r/ prefix"), sort: z .enum(["hot", "new", "top", "rising", "controversial"]) .default("hot") .describe("Sort order for posts"), time: z .enum(["hour", "day", "week", "month", "year", "all"]) .optional() .describe("Time range filter (only for top and controversial)"), limit: z .number() .int() .min(1) .max(100) .default(25) .describe("Number of posts to return"), }), - src/tools/browse.ts:46-108 (registration)Registration call: server.registerTool('browse_subreddit', ...) inside the exported register() function of src/tools/browse.ts. The register function itself is invoked in src/index.ts (line 27) as registerBrowseTools(server, client).
export function register(server: McpServer, client: RedditClient): void { server.registerTool( "browse_subreddit", { title: "Browse Subreddit", description: "Browse posts from a subreddit with sort options (hot, new, top, rising, controversial). For top and controversial, you can specify a time range.", inputSchema: z.object({ subreddit: z.string().describe("Subreddit name without r/ prefix"), sort: z .enum(["hot", "new", "top", "rising", "controversial"]) .default("hot") .describe("Sort order for posts"), time: z .enum(["hour", "day", "week", "month", "year", "all"]) .optional() .describe("Time range filter (only for top and controversial)"), limit: z .number() .int() .min(1) .max(100) .default(25) .describe("Number of posts to return"), }), }, async ({ subreddit, sort, time, limit }) => { try { const params = new URLSearchParams({ limit: String(limit) }); if (time && (sort === "top" || sort === "controversial")) { params.set("t", time); } const data = await client.getJson( `/r/${subreddit}/${sort}.json?${params}` ); const posts = (data?.data?.children || []).map((c: any) => formatPost(c.data) ); return { content: [ { type: "text" as const, text: JSON.stringify( { subreddit, sort, time: time ?? null, posts }, null, 2 ), }, ], }; } catch (error) { return { content: [ { type: "text" as const, text: `Error browsing r/${subreddit}: ${error instanceof Error ? error.message : String(error)}`, }, ], isError: true, }; } } ); - src/tools/browse.ts:6-21 (helper)formatPost helper function used by browse_subreddit to transform raw Reddit API post data into a structured object with fields: id, title, author, subreddit, score, numComments, url, permalink, createdUtc, isSelf, flair, selfText.
function formatPost(p: any) { return { id: p.name || `t3_${p.id}`, title: p.title, author: p.author, subreddit: p.subreddit, score: p.score, numComments: p.num_comments, url: p.url, permalink: `${BASE_URL}${p.permalink}`, createdUtc: p.created_utc, isSelf: p.is_self, flair: p.link_flair_text || null, selfText: p.selftext || undefined, }; }