/**
* get-latest-posts MCP Tool
*
* Retrieves most recent HackerNews posts sorted by date.
* Uses the search_by_date API endpoint.
*/
import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
import { z } from "zod";
import { HNAPIClient } from "../services/hn-api.js";
import { createSuccessResult, handleAPIError } from "../utils/error-handlers.js";
/**
* Input schema for get-latest-posts tool
*/
export const GetLatestPostsInputSchema = z.object({
tags: z.array(z.string()).optional().describe("Optional filter tags (story, comment, etc.)"),
page: z.number().int().nonnegative().default(0).describe("Page number (0-indexed)"),
hitsPerPage: z.number().int().min(1).max(1000).default(20).describe("Results per page (1-1000)"),
});
/**
* Output schema for get-latest-posts tool (SearchResult)
*/
export const GetLatestPostsOutputSchema = z.object({
hits: z.array(z.any()),
nbHits: z.number().int().nonnegative(),
page: z.number().int().nonnegative(),
nbPages: z.number().int().positive(),
hitsPerPage: z.number().int().positive(),
processingTimeMS: z.number().nonnegative(),
query: z.string(),
params: z.string().min(1),
});
/**
* Type for validated input
*/
export type GetLatestPostsInput = z.infer<typeof GetLatestPostsInputSchema>;
/**
* Get latest posts handler
*
* @param input - Input parameters (tags, page, hitsPerPage)
* @returns Tool result with latest posts sorted by date
*/
export async function getLatestPostsHandler(input: unknown): Promise<CallToolResult> {
try {
// Validate input
const validatedParams = GetLatestPostsInputSchema.parse(input);
// Create API client
const client = new HNAPIClient();
// Call search_by_date API with empty query to get all latest posts
const result = await client.searchByDate({
query: "",
tags: validatedParams.tags,
page: validatedParams.page,
hitsPerPage: validatedParams.hitsPerPage,
});
// Validate output
const validatedResult = GetLatestPostsOutputSchema.parse(result);
return createSuccessResult(validatedResult);
} catch (error) {
return handleAPIError(error, "get-latest-posts");
}
}
/**
* Tool metadata for MCP registration
*/
export const getLatestPostsTool = {
name: "get-latest-posts",
description: `Retrieve the most recent HackerNews posts sorted by date.
Returns posts in chronological order (newest first), including all types of content unless filtered.
Supports:
- Filter by content type using tags (story, comment, poll, show_hn, ask_hn, etc.)
- Pagination to view older posts
- Customizable results per page (default: 20)
- Empty query to get all recent posts
Examples:
- Get latest stories: { "tags": ["story"] }
- Get latest comments: { "tags": ["comment"] }
- Get all recent activity: { }
- Get with custom page size: { "hitsPerPage": 50 }
Use this to monitor real-time HackerNews activity or find the newest content.`,
inputSchema: {
type: "object",
properties: {
tags: {
type: "array",
items: { type: "string" },
description: "Optional filter tags (e.g., ['story'], ['comment'])",
},
page: {
type: "number",
description: "Page number (0-indexed, default: 0)",
default: 0,
},
hitsPerPage: {
type: "number",
description: "Results per page (1-1000, default: 20)",
default: 20,
minimum: 1,
maximum: 1000,
},
},
},
};