Hacker News Explorer MCP
While exploring ways to remotely deploy an MCP (Model Context Protocol) server, I found existing frameworks overly complex. I prefer to understand the fundamentals and ask: What’s the bare minimum needed to make this work?
I was already a fan of Cloudflare Workers and was warming up to Server-Sent Events (SSE). However, I hit a snag: the serverless nature of Cloudflare Workers doesn’t naturally align with SSE’s requirement for persistent connections to push data to clients. This seemed like a fundamental mismatch.
Then it struck me—Durable Objects could bridge this gap. They offer stateful, single-threaded instances with persistent storage, making them ideal for managing SSE connections in a serverless environment. Excited by this realization, I dove into building the solution, navigating the challenges of working with cutting-edge libraries.
This landing page (README) is my way of guiding others toward building correct, scalable, and secure MCP servers. It also showcases how authentication can prevent DNS rebinding attacks.
| Tool | Args (JSON) | What you get |
|---|---|---|
top_stories |
{ "limit?": integer ≤ 500 } |
Array of top‑story IDs |
get_story |
{ "id": integer } |
Full item object (title, url, score, kids …) |
get_user |
{ "username": string } |
User profile (karma, created, submissions) |
Why an autonomous agent cares
- Feed curation – poll
top_stories, pull each title viaget_story, filter by keywords, post a daily digest. - Reputation gating – fetch OP’s profile with
get_userand refuse low‑karma links. - Thread summariser – grab 10 story IDs, stream each comment tree, summarise into a newsletter section.
Because the agent calls the tools over MCP, all heavy lifting happens server‑side; the planner stays stateless.
🌩️ Why Cloudflare Durable Objects?
A Developer’s Perspective
When I set out to build an MCP server, I was driven by a desire to understand the fundamentals and minimize complexity. I was already a fan of Cloudflare Workers for their serverless capabilities, and I was exploring Server-Sent Events (SSE) to enable real-time interactions. However, I encountered a challenge: the stateless nature of Workers didn’t mesh well with SSE’s need for persistent connections.
This led me to Durable Objects. Unlike traditional Workers, Durable Objects provide a unique combination of compute and storage, allowing for stateful applications in a serverless environment. Each Durable Object is a globally unique, single-threaded instance that can maintain state across sessions .
Why Durable Objects Fit the MCP Model
Durable Objects align well with the requirements of an MCP server:
- Session Affinity: Each MCP client session can be mapped to a specific Durable Object, ensuring consistent state management without the need for external databases or sticky sessions .
- Stateful Interactions: Durable Objects can maintain in-memory and persistent state, which is crucial for handling long-lived connections and real-time data streams.
- Scalability: The architecture allows for the creation of numerous Durable Objects, each handling a specific session or task, facilitating horizontal scaling without complex coordination.
- Edge Deployment: Being part of Cloudflare’s global network, Durable Objects run close to the end-users, reducing latency and improving performance.
Real-World Applications
In practice, Durable Objects have proven effective for:
- OAuth Management: Handling authentication flows and token refreshes within a single Durable Object per user or session simplifies the logic and avoids race conditions .
- Per-Session Data Handling: Storing session-specific data within the corresponding Durable Object eliminates the need for external storage solutions and simplifies data access patterns.
- Real-Time Communication: Managing WebSocket or SSE connections within Durable Objects allows for efficient, stateful communication channels.
Considerations
While Durable Objects offer many advantages, it’s important to be mindful of their limitations:
- Throughput: Each Durable Object has its own performance characteristics, and high-throughput applications may require careful design to distribute load effectively.
- Storage Limits: There are storage quotas per Durable Object, so applications with large data requirements need to plan accordingly.
- Pricing Model: Understanding Cloudflare’s pricing for Durable Objects is essential to avoid unexpected costs, especially for applications with long-lived connections or high request volumes.
Develop locally
# clone the repository
git clone git@github.com:fintkz/hn-explore-mcp.git
# install dependencies
cd hn-explore-mcp
bun install
# run locally
wrangler dev
Open http://localhost:8787/ in your browser.
Connect the MCP inspector to your server
To explore your new MCP API, use the MCP Inspector.
npx @modelcontextprotocol/inspector- Switch Transport to SSE and enter
http://localhost:8787/sse. - The mock login page appears; use any creds, then you can list and call the Hacker‑News tools.
Connect Claude Desktop to your local MCP server
Follow Anthropic's Quickstart. In Claude’s config:
{
"mcpServers": {
"hn": {
"command": "npx",
"args": ["mcp-remote", "http://localhost:8787/sse"]
}
}
}
Once logged in Claude will show top_stories / get_story / get_user in the hammer menu.
Deploy to Cloudflare
npx wrangler kv namespace create OAUTH_KV- Add that ID to
wrangler.jsonc. npm run deploy
Call your deployed MCP server
npx @modelcontextprotocol/inspector https://hn-explore-mcp.fintkz.workers.dev/sse
Connect Claude Desktop to production
{
"mcpServers": {
"hn": {
"command": "npx",
"args": ["mcp-remote", "https://hn-explore-mcp.fintkz.workers.dev/sse"]
}
}
}
Debugging tips
- Restart Claude if it caches an old token.
- Test straight from the terminal:
npx mcp-remote http://localhost:8787/sse - Clear
~/.mcp-authif auth loops:rm -rf ~/.mcp-auth