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_user
and 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-auth
if auth loops:rm -rf ~/.mcp-auth