Skip to main content
Glama
xiaobenyang-com

HackerNews-Search

search-posts

search-posts

Search HackerNews content by keyword with filters for tags, points, comments, and dates to find relevant stories and discussions.

Instructions

Search HackerNews for stories, comments, and other content by keyword.

Supports:

  • Keyword search across titles, text, and authors

  • Tag filtering (story, comment, poll, show_hn, ask_hn, front_page, author_USERNAME)

  • Numeric filters for points, comments, and dates

  • Pagination with customizable results per page

  • Advanced filtering with OR logic and multiple conditions

Basic Examples:

  • Search for AI stories: { "query": "AI", "tags": ["story"] }

  • Find popular posts: { "query": "Python", "numericFilters": ["points>=100"] }

  • Filter by author: { "query": "startup", "tags": ["author_pg"] }

  • Date range: { "query": "startup", "numericFilters": ["created_at_i>1640000000"] }

Advanced Filtering Examples:

  • High engagement posts: { "query": "programming", "numericFilters": ["points>=100", "num_comments>=50"] }

  • OR logic for tags: { "query": "web", "tags": ["(story,poll)"] } - returns stories OR polls

  • Author with filters: { "query": "", "tags": ["author_pg", "story"], "numericFilters": ["points>=50"] }

  • Multiple conditions: { "query": "AI", "tags": ["story"], "numericFilters": ["points>=200", "num_comments>=100"] }

Numeric Filter Operators: < (less than), <= (less than or equal), = (equal), >= (greater than or equal), > (greater than) Numeric Filter Fields: points, num_comments, created_at_i (Unix timestamp)

Tag Syntax:

  • Single tag: ["story"] - only stories

  • Multiple tags (AND): ["story", "show_hn"] - stories that are also show_hn

  • OR logic: ["(story,poll)"] - stories OR polls

  • Author filter: ["author_USERNAME"] - posts by specific author

Returns paginated results with hits, total count, and page information.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
queryYes
tagsNo
numericFiltersNo
pageNo
hitsPerPageNo

Implementation Reference

  • Core handler logic for all tools including 'search-posts': forwards arguments to remote API https://mcp.xiaobenyang.com/api using toolName='search-posts' in headers, returns text response as MCP content.
    const calcXiaoBenYangApi = async function (fullArgs: Record<string, any>) {
        // 发起 POST 请求
        let response = await fetch('https://mcp.xiaobenyang.com/api', {
            method: 'POST',
            headers: {
                'XBY-APIKEY': apiKey,
                'func': fullArgs.toolName,
                'mcpid': mcpID
            },
            body: new URLSearchParams(fullArgs)
        });
        const apiResult = await response.text();
    
        return {
            content: [
                {
                    type: "text",
                    text: apiResult // 将字符串结果放入 content 中
                }
            ]
        } as { [x: string]: unknown; content: [{ type: "text"; text: string }] };
    };
  • Intermediate handler called by registered tool handler: adds toolName to args and invokes the API proxy.
    const handleXiaoBenYangApi = async (args: Record<string, any>, toolName: string) => {
        // 校验aid是否存在
        if (toolName === undefined || toolName === null) {
            throw new Error("缺少必要参数 'aid'");
        }
        // 合并参数
        const fullArgs = {...args, toolName: toolName};
        // 调用API
        return calcXiaoBenYangApi(fullArgs);
    };
  • src/mcp.ts:50-65 (registration)
    Helper function that registers each tool (including 'search-posts') with dynamic schema, description, and shared handler.
    const addToolXiaoBenYangApi = function (
        name: string,
        desc: string,
        params: Record<string, ZodType>
    ) {
        server.registerTool(
            name,
            {
                title: name,
                description: desc,
                inputSchema: params,
            }
            ,
            async (args: Record<string, any>) => handleXiaoBenYangApi(args, name)
        )
    };
  • src/mcp.ts:88-132 (registration)
    Dynamically fetches tool definitions from remote (https://mcp.xiaobenyang.com/getMcpDesc?mcpId=1777316659382275) and registers them, including 'search-posts', with generated Zod schemas.
    const apiDescList = data.tools;
    
    for (const apiDesc of apiDescList) {
        let inputSchema = JSON.parse(apiDesc.inputSchema);
        const zodDict: Record<string, z.ZodTypeAny> = {};
    
        Object.entries(inputSchema.properties).forEach(([name, propConfig]) => {
            let zodType;
            let pt = (propConfig as { type: string }).type;
            switch (pt) {
                case 'string':
                    zodType = z.string();
                    break;
                case 'number':
                    zodType = z.number();
                    break;
                case 'boolean':
                    zodType = z.boolean();
                    break;
                case 'integer':
                    zodType = z.int32();
                    break;
                case 'array':
                    zodType = z.array(z.any());
                    break;
                case 'object':
                    zodType = z.object(z.any());
                    break;
                default:
                    zodType = z.any();
            }
    
            if (inputSchema.required?.includes(name)) {
                zodDict[name] = zodType;
            } else {
                zodDict[name] = zodType.optional();
            }
        });
    
    
        addToolXiaoBenYangApi(
            apiDesc.name,
            apiDesc.description ? apiDesc.description : apiDesc.name,
            zodDict);
    }
  • Generates Zod input schema for each tool based on remote JSON schema description, mapping types to Zod types and handling required/optional.
    let inputSchema = JSON.parse(apiDesc.inputSchema);
    const zodDict: Record<string, z.ZodTypeAny> = {};
    
    Object.entries(inputSchema.properties).forEach(([name, propConfig]) => {
        let zodType;
        let pt = (propConfig as { type: string }).type;
        switch (pt) {
            case 'string':
                zodType = z.string();
                break;
            case 'number':
                zodType = z.number();
                break;
            case 'boolean':
                zodType = z.boolean();
                break;
            case 'integer':
                zodType = z.int32();
                break;
            case 'array':
                zodType = z.array(z.any());
                break;
            case 'object':
                zodType = z.object(z.any());
                break;
            default:
                zodType = z.any();
        }
    
        if (inputSchema.required?.includes(name)) {
            zodDict[name] = zodType;
        } else {
            zodDict[name] = zodType.optional();
        }
    });
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries full burden and does well: it discloses the tool returns paginated results with hits, total count, and page info, and details advanced filtering capabilities like OR logic. However, it doesn't mention rate limits, authentication needs, or error behaviors, leaving some gaps for a search tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is appropriately sized and front-loaded with the core purpose, followed by organized sections (Supports, Basic Examples, Advanced Filtering Examples, syntax details). While comprehensive, some redundancy in examples could be trimmed for tighter structure, but overall it's efficient and well-organized.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given 5 parameters with 0% schema coverage and no output schema, the description is largely complete: it explains parameters thoroughly, provides return format (paginated results with hits, total count, page info), and includes examples. Minor gaps include lack of error handling or rate limit info, but it's sufficient for effective use.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must fully compensate, which it does excellently. It explains all 5 parameters: query (keyword search), tags (with syntax examples), numericFilters (with operators and fields), page (pagination), and hitsPerPage (customizable results). Examples and detailed syntax rules provide comprehensive parameter meaning beyond the bare schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool searches HackerNews for stories, comments, and other content by keyword, specifying the resource (HackerNews content) and action (search). It distinguishes from siblings like get-front-page (front page only), get-item (single item), get-latest-posts (latest posts without search), and get-user (user info).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly provides when to use this tool through examples and capabilities: keyword search across titles/text/authors, tag filtering, numeric filtering, pagination, and advanced filtering. It implicitly distinguishes from siblings by offering comprehensive search vs. their specific retrieval functions, though no explicit 'when-not' statements are given.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other 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/xiaobenyang-com/HackerNews-Search'

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