Skip to main content
Glama

getStories

Fetch Hacker News stories by type (top, new, best, ask, show, job) with customizable limits to streamline content discovery and integration into LLM workflows.

Instructions

Get multiple stories by type (top, new, best, ask, show, job)

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
limitNoThe maximum number of stories to fetch
typeYesThe type of stories to fetch

Implementation Reference

  • Main execution logic for the getStories tool: fetches story IDs by type from HN API, retrieves items, formats them, and returns a numbered list.
    case "getStories": { const { type, limit = 30 } = args as { type: "top" | "new" | "best" | "ask" | "show" | "job"; limit?: number; }; try { let storyIds: number[] = []; switch (type) { case "top": storyIds = await hnApi.getTopStories(limit); break; case "new": storyIds = await hnApi.getNewStories(limit); break; case "best": storyIds = await hnApi.getBestStories(limit); break; case "ask": storyIds = await hnApi.getAskStories(limit); break; case "show": storyIds = await hnApi.getShowStories(limit); break; case "job": storyIds = await hnApi.getJobStories(limit); break; } const items = await hnApi.getItems(storyIds); const stories = items .filter((item) => item && item.type === "story") .map(formatStory); if (stories.length === 0) { return { content: [{ type: "text", text: "No stories found." }], }; } const text = stories .map( (story, index) => `${index + 1}. ${story.title}\n` + ` ID: ${story.id}\n` + ` URL: ${story.url || "(text post)"}\n` + ` Points: ${story.score} | Author: ${story.by} | Comments: ${story.descendants}\n\n` ) .join(""); return { content: [{ type: "text", text: text.trim() }], }; } catch (err) { const error = err as Error; throw new McpError( ErrorCode.InternalError, `Failed to fetch stories: ${error.message}` ); } }
  • src/index.ts:92-111 (registration)
    Registration of the getStories tool in the ListTools handler, defining name, description, and input schema.
    name: "getStories", description: "Get multiple stories by type (top, new, best, ask, show, job)", inputSchema: { type: "object", properties: { type: { type: "string", enum: ["top", "new", "best", "ask", "show", "job"], description: "The type of stories to fetch", }, limit: { type: "number", description: "The maximum number of stories to fetch", default: 30, }, }, required: ["type"], }, },
  • HackerNewsAPI class with methods like getTopStories, getNewStories, etc., used to fetch story IDs by category for the getStories tool.
    export class HackerNewsAPI { /** * Fetch an item by ID */ async getItem(id: number): Promise<any> { const response = await fetch(`${API_BASE_URL}/item/${id}.json`); return response.json(); } /** * Fetch multiple items by ID */ async getItems(ids: number[]): Promise<any[]> { return Promise.all(ids.map((id) => this.getItem(id))); } /** * Fetch top stories */ async getTopStories(limit: number = 30): Promise<number[]> { const response = await fetch(`${API_BASE_URL}/topstories.json`); const ids = (await response.json()) as number[]; return ids.slice(0, limit); } /** * Fetch new stories */ async getNewStories(limit: number = 30): Promise<number[]> { const response = await fetch(`${API_BASE_URL}/newstories.json`); const ids = (await response.json()) as number[]; return ids.slice(0, limit); } /** * Fetch best stories */ async getBestStories(limit: number = 30): Promise<number[]> { const response = await fetch(`${API_BASE_URL}/beststories.json`); const ids = (await response.json()) as number[]; return ids.slice(0, limit); } /** * Fetch ask stories */ async getAskStories(limit: number = 30): Promise<number[]> { const response = await fetch(`${API_BASE_URL}/askstories.json`); const ids = (await response.json()) as number[]; return ids.slice(0, limit); } /** * Fetch show stories */ async getShowStories(limit: number = 30): Promise<number[]> { const response = await fetch(`${API_BASE_URL}/showstories.json`); const ids = (await response.json()) as number[]; return ids.slice(0, limit); } /** * Fetch job stories */ async getJobStories(limit: number = 30): Promise<number[]> { const response = await fetch(`${API_BASE_URL}/jobstories.json`); const ids = (await response.json()) as number[]; return ids.slice(0, limit); } /** * Fetch a user by ID */ async getUser(id: string): Promise<any> { const response = await fetch(`${API_BASE_URL}/user/${id}.json`); return response.json(); } /** * Fetch the maximum item ID */ async getMaxItemId(): Promise<number> { const response = await fetch(`${API_BASE_URL}/maxitem.json`); const result = (await response.json()) as number; return result; } } // Export a singleton instance export const hnApi = new HackerNewsAPI();
  • formatStory helper function used in getStories handler to format raw HN story data.
    export function formatStory(item: any): Story { return { id: item.id, title: item.title, url: item.url, text: item.text, by: item.by, score: item.score || 0, time: item.time, descendants: item.descendants || 0, kids: item.kids || [], type: "story", }; }

Other Tools

Related Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/devabdultech/hn-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server