index.ts•2.86 kB
#!/usr/bin/env node
/**
* HackerNews MCP Server
*
* Main entry point for the Model Context Protocol server.
* Initializes the server and registers all tools.
*
* @see https://modelcontextprotocol.io
*/
import { createRequire } from "node:module";
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 { getFrontPageHandler, getFrontPageTool } from "./tools/get-front-page.js";
import { getItemHandler, getItemTool } from "./tools/get-item.js";
import { getLatestPostsHandler, getLatestPostsTool } from "./tools/get-latest-posts.js";
import { getUserHandler, getUserTool } from "./tools/get-user.js";
import { searchPostsTool, searchPostsToolMetadata } from "./tools/search-posts.js";
const require = createRequire(import.meta.url);
const packageJson = require("../package.json");
/**
* Server configuration
*/
const SERVER_CONFIG = {
name: packageJson.name,
version: packageJson.version,
} as const;
/**
* Create and configure the MCP server
*/
const server = new Server(SERVER_CONFIG, {
capabilities: {
tools: {},
},
});
/**
* Handle tool listing requests
*/
server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
tools: [
searchPostsToolMetadata,
getFrontPageTool,
getLatestPostsTool,
getItemTool,
getUserTool,
],
};
});
/**
* Handle tool execution requests
*/
server.setRequestHandler(CallToolRequestSchema, async (request) => {
const { name } = request.params;
const args = request.params.arguments;
try {
switch (name) {
case "search-posts":
return await searchPostsTool(args);
case "get-front-page":
return await getFrontPageHandler(args);
case "get-latest-posts":
return await getLatestPostsHandler(args);
case "get-item":
return await getItemHandler(args);
case "get-user":
return await getUserHandler(args);
default:
return {
content: [
{
type: "text",
text: JSON.stringify({
type: "error",
message: `Unknown tool: ${name}`,
}),
},
],
isError: true,
};
}
} catch (error) {
return {
content: [
{
type: "text",
text: JSON.stringify({
type: "error",
message: error instanceof Error ? error.message : String(error),
}),
},
],
isError: true,
};
}
});
/**
* Start the server with stdio transport
*/
async function main() {
const transport = new StdioServerTransport();
await server.connect(transport);
// Log to stderr (stdout is used for MCP communication)
console.error("HackerNews MCP Server running on stdio");
}
main().catch((error) => {
console.error("Fatal error:", error);
process.exit(1);
});