hn-mcp-server
Version:
Model Context Protocol server for HackerNews API access
98 lines (94 loc) • 3.33 kB
JavaScript
/**
* get-item MCP Tool
*
* Retrieves a single HackerNews item by ID with complete nested comment tree.
* Uses the items/:id API endpoint.
*/
import { z } from "zod";
import { HNAPIClient } from "../services/hn-api.js";
import { checkItemExists, createSuccessResult, handleAPIError } from "../utils/error-handlers.js";
/**
* Input schema for get-item tool
*/
export const GetItemInputSchema = z.object({
itemId: z.string().min(1, "itemId must not be empty").describe("HackerNews item ID"),
});
/**
* Output schema for get-item tool (ItemResult with nested children)
*/
export const GetItemOutputSchema = z.object({
id: z.string(),
created_at: z.string().datetime(),
created_at_i: z.number().int().positive(),
type: z.enum(["story", "comment", "poll", "pollopt"]),
author: z.string(),
title: z.string().nullable(),
url: z.string().url().nullable(),
text: z.string().nullable(),
points: z.number().int().nonnegative().nullable(),
parent_id: z.number().int().positive().nullable(),
story_id: z.number().int().positive(),
options: z.array(z.number().int()),
children: z.array(z.any()), // Recursive type, validated at runtime
});
/**
* Get item handler
*
* @param input - Input parameters (itemId)
* @returns Tool result with complete item including nested comments
*/
export async function getItemHandler(input) {
try {
// Validate input
const validatedParams = GetItemInputSchema.parse(input);
// Create API client
const client = new HNAPIClient();
// Call items API to get item with nested children
const result = await client.getItem(validatedParams.itemId);
// Check if item exists
const notFoundError = checkItemExists(result, "Item", validatedParams.itemId);
if (notFoundError) {
return notFoundError;
}
// Validate output
const validatedResult = GetItemOutputSchema.parse(result);
return createSuccessResult(validatedResult);
}
catch (error) {
return handleAPIError(error, "get-item");
}
}
/**
* Tool metadata for MCP registration
*/
export const getItemTool = {
name: "get-item",
description: `Retrieve detailed information about a specific HackerNews item by ID.
Returns complete item details including the full nested comment tree. Use this to:
- View a story with all comments
- Read a specific comment with its replies
- Explore discussion threads in depth
- Get complete metadata for any item
Features:
- Full nested comment tree (all levels)
- Complete item metadata (title, url, text, points, author, etc.)
- Works for stories, comments, polls, and poll options
- Includes creation time and item type
Examples:
- Get story with comments: { "itemId": "38456789" }
- Get specific comment: { "itemId": "38456790" }
- Get poll: { "itemId": "126809" }
Note: Large comment threads (>500 comments) may take 2-3 seconds to load due to nested fetching.
Returns error if item doesn't exist or has been deleted.`,
inputSchema: {
type: "object",
properties: {
itemId: {
type: "string",
description: "HackerNews item ID (e.g., '38456789')",
},
},
required: ["itemId"],
},
};
//# sourceMappingURL=get-item.js.map