Skip to main content
Glama
pskill9

Hacker News MCP

by pskill9

get_stories

Fetch structured Hacker News stories by type (top, new, ask, show, jobs) and limit results to a specified number. Designed to provide parsed HTML content from news.ycombinator.com.

Instructions

Get stories from Hacker News

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
limitNoNumber of stories to return (max 30)
typeNoType of stories to fetch (top, new, ask, show, jobs)top

Implementation Reference

  • Implements the execution logic for the 'get_stories' tool by handling CallToolRequest, validating parameters, fetching stories, and returning JSON response.
    this.server.setRequestHandler(CallToolRequestSchema, async (request) => { if (request.params.name !== 'get_stories') { throw new McpError( ErrorCode.MethodNotFound, `Unknown tool: ${request.params.name}` ); } const args = request.params.arguments as { type?: string; limit?: number }; const type = args.type || 'top'; const limit = Math.min(args.limit || 10, 30); if (!isValidStoryType(type)) { throw new McpError( ErrorCode.InvalidParams, `Invalid story type: ${type}. Must be one of: top, new, ask, show, jobs` ); } try { const stories = await this.fetchStories(type); return { content: [ { type: 'text', text: JSON.stringify(stories.slice(0, limit), null, 2) } ] }; } catch (error) { if (error instanceof McpError) { throw error; } throw new McpError( ErrorCode.InternalError, `Failed to fetch stories: ${error}` ); } });
  • Fetches and parses Hacker News stories using axios and cheerio, extracting title, url, points, author, time, comments, and rank.
    private async fetchStories(type: string = 'top'): Promise<Story[]> { try { const url = type === 'top' ? this.baseUrl : `${this.baseUrl}/${type}`; const response = await axios.get(url); const $ = cheerio.load(response.data); const stories: Story[] = []; $('.athing').each((i, elem) => { const titleRow = $(elem); const metadataRow = titleRow.next(); const rank = parseInt(titleRow.find('.rank').text(), 10); const titleElement = titleRow.find('.titleline > a').first(); const title = titleElement.text(); const url = titleElement.attr('href'); const sitebit = titleRow.find('.sitebit'); const points = parseInt(metadataRow.find('.score').text(), 10) || 0; const author = metadataRow.find('.hnuser').text(); const time = metadataRow.find('.age').attr('title') || ''; const commentText = metadataRow.find('a').last().text(); const commentCount = parseInt(commentText.split('&nbsp;')[0]) || 0; stories.push({ title, url: url?.startsWith('item?id=') ? `${this.baseUrl}/${url}` : url, points, author, time, commentCount, rank }); }); return stories; } catch (error) { if (axios.isAxiosError(error)) { throw new McpError( ErrorCode.InternalError, `Failed to fetch stories: ${error.message}` ); } throw error; } }
  • src/index.ts:101-127 (registration)
    Registers the 'get_stories' tool in the ListToolsRequest handler with name, description, and input schema.
    this.server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: [ { name: 'get_stories', description: 'Get stories from Hacker News', inputSchema: { type: 'object', properties: { type: { type: 'string', description: 'Type of stories to fetch (top, new, ask, show, jobs)', enum: ['top', 'new', 'ask', 'show', 'jobs'], default: 'top' }, limit: { type: 'number', description: 'Number of stories to return (max 30)', minimum: 1, maximum: 30, default: 10 } } } } ] }));
  • Input schema definition for the 'get_stories' tool parameters: type (enum) and limit (number).
    inputSchema: { type: 'object', properties: { type: { type: 'string', description: 'Type of stories to fetch (top, new, ask, show, jobs)', enum: ['top', 'new', 'ask', 'show', 'jobs'], default: 'top' }, limit: { type: 'number', description: 'Number of stories to return (max 30)', minimum: 1, maximum: 30, default: 10 } } }
  • TypeScript interface defining the structure of a Story object returned by the tool.
    interface Story { title: string; url?: string; points: number; author: string; time: string; commentCount: number; rank: number; }

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/pskill9/hn-server'

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