I didn’t just want a portfolio that looks good, I wanted one that thinks. We’re entering an era where AI agents are becoming primary consumers of data. Yet most portfolios are still stuck in Web 2.0:

  • static text

  • markdown files

  • manual navigation

I wanted to change that.

▶️ Live demo (Claude Desktop + MCP)

Claude Desktop querying my portfolio live via Model Context Protocol.

🎯 The goal

I wanted my portfolio (aniketppatil.com) to have a brain. Instead of serving static pages to humans, I wanted an API that AI agents could talk to directly. So an agent could ask:

  • “List the projects he worked on”

  • “Explain the technical architecture of RagBot”

  • “what are his skills?”

…and get structured answers.

The technology that enables this is Model Context Protocol (MCP).

🚧 The constraints

This sounded simple on paper. In reality, my setup made it tricky:

  • Framework: Next.js (App Router)

  • Hosting: Vercel (serverless, free tier)

  • Budget: $0 (no VPS, no long-running socket servers)

I assumed I could install a library and be done. I was wrong.

Failure: the “official” MCP approach

I started with the official MCP SDK (@modelcontextprotocol/sdk) and tried to run a server.

The problem

The SDK assumes a stateful environment:

  • persistent processes

  • long-lived connections

  • stdio or WebSockets

Vercel is stateless. Functions spin up, handle a request, and die milliseconds later.

The symptoms

  • 📉 Connection timeouts

  • 🚫 Hanging requests

  • Claude disconnecting mid-handshake

Official MCP support for serverless was effectively non-existent. I needed a way to fake persistence.

🔄 The pivot: mcp-handler

I found a community library called mcp-handler, and everything changed.

Why it worked:

  • Designed for Next.js App Router

  • HTTP-first tool calls (POST requests)

  • Server-Sent Events (SSE) for streaming

  • Redis-backed state across stateless executions

This finally matched Vercel’s execution model.

🐛 The debugging sprint

Even with the right library, it took a full weekend to make it work.

The 404 / slug nightmare

Claude kept failing with:

Connection failed: 404 Not Found

What was happening:

  • Client requested: /api/mcp/sse

  • My route handled only: /api/mcp

MCP clients automatically append /sse and /message.

The fix

Use a catch-all route:

app/api/mcp/[[...slug]]/route.ts

Now one handler correctly processes:

  • /api/mcp

  • /api/mcp/sse

  • /api/mcp/message

Sometimes the hardest bugs are just mismatched assumptions.

🏗️ Modular refactor (sanity restored)

By Sunday morning, my route.ts was ~500 lines of spaghetti.

I refactored the “brain” into a clean structure:

  • types.ts — TypeScript interfaces

  • data.ts — read-only JSON loaders

  • utils.ts — semantic search logic

  • index.ts — clean exports

Now the route handler is just a registry:

server.registerTool("list_projects", {...}, async () => { ... })

Bonus: I migrated to the new server.registerTool() API to future-proof the code.

🛡️ Security: the “NASA hack” test

I’m exposing parts of my filesystem to the internet.
That’s dangerous — unless you’re strict.

The strategy

  • No writes — no fs.writeFile anywhere

  • Allow-lists only — strict Zod enums for inputs

The test

I asked Claude:

“Tell me about the project secret-nasa-hack”

Result:
🛑 Blocked. Input validation error.
The system never touched the disk.

Security held.

🚀 The result

This wasn’t just “installing a library”.

It was:

  • adapting a stateful protocol to stateless infrastructure

  • fixing routing edge cases

  • designing a secure, read-only architecture

Now my portfolio is no longer a brochure.
It’s a personal AI API.

Any MCP-compatible client can query it.

🧪 Try it yourself

If you use Claude Desktop, add this config:

"aniket-portfolio": {
  "command": "npx",
  "args": ["-y", "mcp-remote", "https://aniketppatil.com/api/mcp"]
}

It works. And it’s built to last.

Why this matters

This isn’t really about portfolios. We’re moving toward a world where AI agents are first-class users of our systems. Most software today isn’t built for that. This was my experiment in changing that — starting with my own site.

If you’re building with MCP, serverless infra, or AI-first interfaces, hit reply — I’d love to hear what you’re making.

Recommended for you