The easiest way to bring real-time Hacker News data and discussion into your LLM, agent, or app workflows.
Instantly turn Hacker News into a programmable, conversational knowledge base for your AI agents and apps!
- Plug-and-play: Instantly connect LLMs, agents, or chatbots to live Hacker News data and discussions.
- Flexible: Use as a local tool, cloud API, or containerized microservice.
- Natural Language Friendly: Users can reference stories by title, keywords, or natural language ("What are people saying about quantum computing?").
- Rich Prompts: Built-in prompt templates for summaries, trending topics, user analysis, and more.
- Production Ready: Robust error handling, health checks, and cloud deployment support out of the box.
- ⚡ Multiple Transport Modes: STDIO/MCP and SSE/MCP for flexible LLM/agent integration
- 🌐 REST/OpenAPI Endpoints: Direct HTTP access with auto-generated docs
- 📰 Full Hacker News Coverage: Access stories, comments, users, trending topics, and more
- 🛡️ Robust Error Handling: Clear response models and status codes
- 🧩 Easy Configuration: Environment variables for API keys, host, and logging
- 🐳 Container Ready: Docker & Docker Compose for painless deployment
- ❤️ Health Monitoring: Built-in health check endpoint
- 🔒 CORS Support: Secure and configurable origins for web integration
All endpoints are available by default at http://localhost:8000
(or your configured host/port).
GET /api/stories/top?limit=30
— Get top storiesGET /api/stories/best?limit=30
— Get best storiesGET /api/stories/new?limit=30
— Get newest storiesGET /api/stories/ask?limit=30
— Get Ask HN storiesGET /api/stories/show?limit=30
— Get Show HN storiesGET /api/stories/search?query=YOUR_QUERY&limit=5
— Search for stories by title or keywordsGET /api/stories/by-date?days_ago=1&limit=30
— Get stories from N days ago
GET /api/item/{item_id}
— Get a Hacker News item by IDGET /api/story/by-title?title=YOUR_TITLE
— Get a story (and comments) by title/keywordsGET /api/story/{story_id}/comments?comment_limit=10
— Get a story and its top comments
GET /api/story/{story_id}/content?format=markdown
— Get the actual content from a story's URLGET /api/story/content-by-title?title=YOUR_TITLE&format=markdown
— Get content by story titleformat
parameter acceptsmarkdown
(default) orjson
GET /api/user/{username}
— Get a Hacker News user by username
GET /api/maxitem
— Get the current largest item IDGET /api/updates
— Get latest item and profile changesGET /health
— Health check endpointGET /sse-info
— Info about the SSE endpoint
GET /sse
— Server-Sent Events (SSE) endpoint for MCP protocol
GET /docs
— Swagger UI (interactive API docs)GET /openapi.json
— OpenAPI schema (for tool integration)
You can search and retrieve stories using natural language or keywords, not just numeric IDs!
-
Example:
GET /api/stories/search?query=quantum computing
— Find stories about quantum computingGET /api/story/by-title?title=React framework
— Get the latest story and comments about React framework
-
Natural Language-Friendly:
- "Tell me about that story on quantum computing from yesterday"
- "What's the discussion about the new React framework like?"
These queries are handled via /api/stories/search
and /api/story/by-title
endpoints.
Search for stories by title/keywords:
curl "http://localhost:8000/api/stories/search?query=AI+ethics&limit=3"
Get a story and its comments by title:
curl "http://localhost:8000/api/story/by-title?title=OpenAI+GPT-4"
Get the actual content from a story URL (as Markdown):
curl "http://localhost:8000/api/story/12345/content?format=markdown"
Get content by story title:
curl "http://localhost:8000/api/story/content-by-title?title=quantum+computing&format=markdown"
Health check:
curl "http://localhost:8000/health"
Get top stories:
curl "http://localhost:8000/api/stories/top?limit=5"
See /docs
for full interactive documentation and try endpoints live.
- LLM/AI Agent Developers: Add real-world, up-to-date news and discussion to your agents.
- Chatbot Builders: Power your bots with trending stories and community insights.
- Researchers & Data Scientists: Analyze Hacker News trends, user activity, and topic sentiment.
- Productivity Hackers: Build custom dashboards, notification bots, or research tools.
- Anyone who wants to make Hacker News programmable!
ℹ️ Tip: You don't need to know story IDs—just ask for stories by title, topic, or keywords!
🛠️ Install in seconds, run anywhere!
# Clone the repository
git clone https://github.com/yourusername/hacker-news-mcp.git
cd hacker-news-mcp
# Install dependencies
pip install -r requirements.txt
# Run with SSE transport (default, good for web/remote)
python run.py --transport sse --host 127.0.0.1 --port 8000
# Run with STDIO transport (for direct LLM/agent integration)
python run.py --transport stdio
# Optional: Run with custom log level
env LOG_LEVEL=debug python run.py --transport sse
# Build and run with Docker
docker build -t hacker-news-mcp .
docker run -p 8000:8000 hacker-news-mcp
# Or use Docker Compose
docker-compose up -d
💡 Tip: Works with Claude Desktop, Windsurf, Cursor IDE, and any LLM/agent supporting MCP!
STDIO (Local):
{
"mcpServers": {
"hackerNews": {
"command": "python",
"args": ["/path/to/hacker-news-mcp/run.py", "--transport", "stdio"],
"env": { "LOG_LEVEL": "info" }
}
}
}
STDIO (Local):
{
"mcpServers": {
"hackerNews": {
"command": "python",
"args": ["/path/to/hacker-news-mcp/run.py", "--transport", "stdio"],
"env": { "LOG_LEVEL": "info" }
}
}
}
SSE (Remote):
{
"mcpServers": {
"hackerNews": {
"url": "https://your-deployed-server.com/sse",
"transport": "sse"
}
}
}
- 🔎 Basic Data Retrieval
get_item(id)
: Get a Hacker News item by IDget_user(id)
: Get a Hacker News user by IDget_max_item_id()
: Get the current largest item ID
- 🏆 Story Listings
get_top_stories(limit)
: Get top storiesget_best_stories(limit)
: Get best storiesget_new_stories(limit)
: Get newest storiesget_ask_stories(limit)
: Get Ask HN storiesget_show_stories(limit)
: Get Show HN storiesget_job_stories(limit)
: Get job stories
- 📝 Content Retrieval
get_story_content(story_id, format)
: Get the actual content from a story's URLget_story_content_by_title(title, format)
: Get content by story title- Format options:
"markdown"
(default) or"json"
- 💬 Advanced Story Retrieval
get_story_with_comments(story_id, comment_limit)
: Get a story with its commentsfind_stories_by_title(query, limit)
: Find stories by title or keywordsget_story_by_title(title)
: Find and retrieve a story by its title or keywords with comments
- 🔄 Other Tools
get_updates()
: Get latest item and profile changessearch_by_date(days_ago, limit)
: Search for stories from approximately N days ago
- 🧑💻 Item Resources
hn://item/{id}
: Get item by IDhn://user/{id}
: Get user by ID
- 📋 Story Listing Resources
hn://top/{limit}
: Get top storieshn://best/{limit}
: Get best storieshn://new/{limit}
: Get newest storieshn://ask/{limit}
: Get Ask HN storieshn://show/{limit}
: Get Show HN storieshn://jobs/{limit}
: Get job stories
💡 Natural Language Friendly: Users can reference stories by title, keywords, or just ask questions in plain English!
-
🧠 Smart Router
hn_router(query)
: Analyzes any HN-related query and routes to the best tools and approach
-
📝 Story Analysis
hn_story_summary_by_id(story_id)
: Summarize a Hacker News story by IDhn_story_summary_by_title(title)
: Summarize a story by title/keywordshn_story_comment_analysis(title|id)
: Analyze comments for a story
-
📰 Content Retrieval & Analysis
hn_story_content_by_id(story_id)
: Get and analyze the full article content from a story's URLhn_story_content_by_title(title)
: Get and analyze content by searching for a story by title/keywordshn_content_filter(story_id, filter_type)
: Extract specific types of content (technical, code, opinions, etc.)
-
🔎 Advanced Search & Comparison
hn_advanced_search(query, days, min_score, min_comments)
: Find stories matching specific criteriahn_compare_stories(story_ids)
: Compare multiple stories to identify similarities and differenceshn_multi_source_analysis(query, sources_count)
: Analyze multiple sources on the same topic
-
📈 Trend Analysis
hn_trending_topics()
: List current trending topicshn_trend_analysis(days, story_type, topic)
: Analyze trends over time, optionally focused on a specific topic
-
👤 User Analysis
hn_user_profile_analysis(username)
: Analyze a user's activity and interests
- "Summarize that HN story about quantum computing"
- "What's trending on Hacker News today?"
- "Tell me about HN user 'dang'"
- "Give me a detailed analysis of the discussion on AI regulation"
⚡ No need for IDs! Just ask naturally—this server matches your request to the right prompt and tools.
"What can you tell me about quantum computing discussions on Hacker News?"
The router analyzes your query, identifies the intent, and recommends the best approach using available tools (e.g., search for quantum computing stories, analyze content, compare perspectives).
"Compare different perspectives on blockchain from Hacker News"
"What are the various opinions about the new MacBook Pro?"
Retrieves multiple sources on the same topic, extracts their content, and provides a comprehensive analysis of different viewpoints, areas of agreement/disagreement, and synthesizes insights.
"Show me just the technical parts of HN story 12345"
"Extract the code examples from that article about Rust"
Retrieves a story's content and filters it according to specific needs (technical details, code examples, opinions, beginner-friendly explanations, etc.).
"Find popular stories about quantum computing with lots of discussion"
"What are the highest-rated AI stories from the past month?"
Performs advanced search with filtering by score, comment count, and timeframe, then analyzes the results.
"How has discussion about AI changed on HN over the last month?"
"What topics are gaining traction compared to last week?"
Compares current stories with historical data to identify emerging topics, changing interests, and community engagement patterns.
"Compare HN stories 12345 and 67890"
"What's the difference between those two quantum computing articles?"
Compares multiple stories to identify similarities, differences, and relationships between them.
When running with SSE transport, OpenAPI documentation is available at:
- Swagger UI:
http://localhost:8000/docs
- ReDoc:
http://localhost:8000/redoc
- OpenAPI JSON:
http://localhost:8000/openapi.json
HN_API_KEY
: API key for Hacker News (if required in the future)LOG_LEVEL
: Logging level (debug, info, warning, error, critical)FASTMCP_TOOL_ATTEMPT_PARSE_JSON_ARGS
: Set to 1 to enable JSON parsing for tool arguments
- Build and Push Docker Image
# Build the Docker image
docker build -t gcr.io/your-project-id/hacker-news-mcp .
# Push to Google Container Registry
docker push gcr.io/your-project-id/hacker-news-mcp
- Deploy to Cloud Run
gcloud run deploy hacker-news-mcp \
--image gcr.io/your-project-id/hacker-news-mcp \
--platform managed \
--region us-central1 \
--allow-unauthenticated \
--memory 512Mi \
--set-env-vars="LOG_LEVEL=info"
- Configure MCP Consumers with Cloud Run URL
After deployment, Cloud Run will provide a URL like https://hacker-news-mcp-abcdef123-uc.a.run.app
. Use this URL in your MCP configuration:
{
"name": "Hacker News",
"url": "https://hacker-news-mcp-abcdef123-uc.a.run.app/sse",
"transport": "sse"
}
- Package the Application
# Create a deployment package
zip -r deployment.zip . -x "*.git*" -x "*.pytest_cache*" -x "__pycache__/*"
- Create Lambda Function with API Gateway
- Create a Lambda function in the AWS Console
- Upload the deployment.zip package
- Configure an API Gateway trigger
- Set environment variables as needed
- Configure MCP Consumers with API Gateway URL
Use the API Gateway URL in your MCP configuration:
{
"name": "Hacker News",
"url": "https://abcdef123.execute-api.us-east-1.amazonaws.com/prod/sse",
"transport": "sse"
}
import asyncio
from fastmcp import Client
from fastmcp.client.transports import SSETransport
import json
async def main():
# Connect to the server
client = Client(SSETransport("http://localhost:8000/sse"))
async with client:
# List available tools
tools = await client.list_tools()
print(f"Available tools: {len(tools)}")
# Get top stories
top_stories = await client.call_tool("get_top_stories", {"limit": 5})
story_ids = json.loads(top_stories[0].text)
print(f"Top stories: {story_ids}")
# Get a specific story
if story_ids:
story_result = await client.call_tool("get_item", {"id": story_ids[0]})
story_data = json.loads(story_result[0].text)
print(f"Story: {story_data.get('title')}")
if __name__ == "__main__":
asyncio.run(main())
For LLM agents that support STDIO-based MCP servers:
# Run the server in STDIO mode
python run.py --transport stdio
# Run all tests
python -m pytest tests/
# Run specific test file
python -m pytest tests/test_server.py
# Start the server in one terminal
python run.py --transport sse
# Run the test client in another terminal
python test_client.py
-
Connection Refused
- Ensure the server is running and the port is correct
- Check firewall settings
-
Transport Not Supported
- Verify you're using a supported transport ("stdio" or "sse")
-
JSON Parsing Errors
- For older LLMs, set
FASTMCP_TOOL_ATTEMPT_PARSE_JSON_ARGS=1
- For older LLMs, set
-
Missing Dependencies
- Run
pip install -r requirements.txt
to ensure all dependencies are installed
- Run
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature
) - Commit your changes (
git commit -m 'Add some amazing feature'
) - Push to the branch (
git push origin feature/amazing-feature
) - Open a Pull Request
This project is licensed under the GNU Affero General Public License v3.0 (AGPLv3) - see the LICENSE file for details.
The AGPLv3 is a copyleft license that requires anyone who distributes your code or a derivative work to make the source available under the same terms, and also extends this requirement to users who interact with the software over a network.
COMMERCIAL USE WARNING
If you want to use or deploy this code in any form as part of a monetised service to others, even if you don't specifically require payment for the code, you need to contact me for permission (this means YOU Smithery/Glama or ANY similar services) - which will only be granted following payment of the appropriate licensing fee. No, you might not be charging for the use of the code itself, and you might be providing the infrastructure, but you'd be using MY code to facilitate YOUR service. That's an intrinsic dependency that MUST be licensed. PAYWALLING the use of Open Source Software is not democratising software it is gating it only for those who can afford to pay which is counter to the ethos of OpenSource Licensing.
For anyone else, whether you're a business or individual, I hope it's of use to you. Enjoy.