#!/usr/bin/env node
/**
* HackerNews MCP Server
* Main entry point
*/
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
import { tools } from "./tools/index.js";
import { formatErrorResponse } from "./utils/index.js";
import { handleGetFrontPage } from "./tools/get-front-page.js";
import { handleGetPost } from "./tools/get-post.js";
import { handleGetUser } from "./tools/get-user.js";
// Tool handlers
import { handleSearchPosts } from "./tools/search-posts.js";
/**
* Create and configure MCP server
*/
const server = new Server(
{
name: "hn-mcp-server",
version: "1.0.0",
},
{
capabilities: {
tools: {},
},
},
);
/**
* Handle tool list requests
*/
server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
tools,
};
});
/**
* Handle tool call requests
*/
server.setRequestHandler(CallToolRequestSchema, async (request) => {
const { name, arguments: args } = request.params;
try {
switch (name) {
case "search_posts":
return await handleSearchPosts(args);
case "get_front_page":
return await handleGetFrontPage(args);
case "get_post":
return await handleGetPost(args);
case "get_user":
return await handleGetUser(args);
default:
throw new Error(`Unknown tool: ${name}`);
}
} catch (error) {
return formatErrorResponse(error instanceof Error ? error : new Error("Unknown error"));
}
});
/**
* Start server with stdio transport
*/
async function main() {
const transport = new StdioServerTransport();
await server.connect(transport);
// Log to stderr (stdout is used for MCP protocol)
console.error("HackerNews MCP Server running on stdio");
}
main().catch((error) => {
console.error("Fatal error:", error);
process.exit(1);
});