🚀 AI-Powered Portfolio Site

A modern, serverless portfolio with conversational AI assistant powered by MCP

📖Project Overview

This is a next-generation portfolio site that combines modern serverless architecture with AI capabilities. Instead of just displaying static project information, visitors can interact with an AI assistant that understands and can query the entire portfolio database in real-time.

💡 The Innovation

The project uses MCP (Model Context Protocol) - Anthropic's new standard for connecting AI to external data sources. This creates a bridge between Claude AI and the portfolio database, enabling natural language queries like "Show me React projects" or "What are your top technologies?"

🎯Purpose

This project was built to explore and demonstrate:

Key Features

🤖 AI Chat Assistant

Conversational interface powered by Claude AI with direct database access through MCP

⚡ Lightning Fast

Sub-100ms response times globally thanks to Cloudflare's edge network

🔒 Secure by Default

Admin endpoints protected by Cloudflare Access, rate limiting on public APIs

📊 Real-time Stats

Dynamic portfolio statistics and analytics accessible via AI or API

🎨 Modern UI

Responsive design with glassmorphism effects and smooth animations

🔧 Easy Management

Simple CRUD operations for projects, skills, and categories

🏗️Architecture

┌─────────────────┐
│   User Browser  │
└────────┬────────┘
         │
         ├──────────────┐
         ▼              ▼
┌─────────────┐  ┌─────────────┐
│  Frontend   │  │  AI Chat    │
│ (CF Pages)  │  │  Interface  │
└──────┬──────┘  └──────┬──────┘
       │                │
       ▼                ▼
┌──────────────────────────┐
│   Backend API            │
│   (Cloudflare Workers)   │
└─────┬──────────────┬─────┘
      │              │
      ▼              ▼
┌──────────┐  ┌─────────────┐
│ D1 DB    │  │ Claude API  │
│ (SQLite) │  │  with MCP   │
└──────────┘  └──────┬──────┘
                     │
                     ▼
              ┌──────────────┐
              │  MCP Server  │
              │  (Workers)   │
              └──────────────┘
            

Components Breakdown:

1. Frontend (Cloudflare Pages)

2. Backend API (Cloudflare Workers)

3. MCP Server (Cloudflare Workers)

💻Tech Stack

Cloudflare Workers Cloudflare Pages D1 Database Claude AI MCP Protocol TypeScript JavaScript itty-router SSE Cloudflare Access

🔌API Endpoints

Public Endpoints (No Auth)

GET  /api/projects           # List all projects
GET  /api/projects/:id       # Get project details
GET  /api/categories         # List categories
GET  /api/skills             # List skills
GET  /api/stats              # Portfolio statistics
POST /api/chat               # AI chat (rate limited: 3/min)

Admin Endpoints (Cloudflare Access)

POST   /api/admin/projects/add
PUT    /api/admin/projects/:id/update
DELETE /api/admin/projects/:id/delete
POST   /api/admin/categories/add
PUT    /api/admin/categories/:id/update
DELETE /api/admin/categories/:id/delete
POST   /api/admin/skills/add
PUT    /api/admin/skills/:id/update
DELETE /api/admin/skills/:id/delete

🤖MCP Tools

The AI assistant has access to these tools for querying portfolio data:

  1. list_projects: List projects with optional filters (category, difficulty, technology, limit)
  2. get_project: Get detailed information about a specific project
  3. search_projects: Search projects by keyword
  4. list_skills: List all skills with optional category filter
  5. get_portfolio_stats: Get aggregated statistics (total projects, completion rate, top technologies)

🔒 Security Note

The MCP server is read-only by design. The AI assistant can query and retrieve portfolio data but cannot create, update, or delete anything. This ensures data integrity while providing helpful information to visitors.

🔐Security Features

1. Cloudflare Access

All admin write operations (/api/admin/*) are protected by Cloudflare Access:

2. Rate Limiting

AI chat endpoint is rate limited to prevent abuse:

3. CORS Configuration

Proper CORS headers ensure frontend can access the API while maintaining security

📚Code Highlights

Claude AI with MCP Integration

const claudeRequest = {
  model: 'claude-3-5-sonnet-20241022',
  max_tokens: 2000,
  messages: [{ role: 'user', content: userMessage }],
  mcp_servers: [{
    type: 'url',
    url: 'https://portfolio-mcp-server.oskarmansanqu.workers.dev/sse',
    name: 'portfolio-mcp'
  }],
  system: "You are a helpful AI assistant with READ-ONLY access to portfolio data through MCP tools."
};

const response = await fetch('https://api.anthropic.com/v1/messages', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'x-api-key': env.CLAUDE_API_KEY,
    'anthropic-version': '2023-06-01',
    'anthropic-beta': 'mcp-client-2025-04-04'
  },
  body: JSON.stringify(claudeRequest)
});

MCP Tool Implementation

this.server.tool(
  "list_projects",
  {
    category: z.string().optional(),
    difficulty: z.enum(["Beginner", "Intermediate", "Advanced"]).optional(),
    technology: z.string().optional(),
    limit: z.number().optional()
  },
  async (params) => {
    const result = await callPortfolioAPI("/api/projects");
    let projects = result.projects;

    // Apply filters
    if (params.category) {
      projects = projects.filter(p => p.category === params.category);
    }
    // ... more filtering logic

    return {
      content: [{
        type: "text",
        text: formatProjectList(projects)
      }]
    };
  }
);

📊Project Statistics

🎓Learning Outcomes

Technical Skills Gained:

Architectural Insights:

🚀Deployment

Prerequisites:

npm install -g wrangler
wrangler login

Deploy Backend:

cd backend
wrangler deploy
echo 'your-claude-api-key' | wrangler secret put CLAUDE_API_KEY

Deploy Frontend:

cd frontend
wrangler pages deploy . --project-name=portfolio-frontend

Deploy MCP Server:

cd portfolio-mcp-server
npm run deploy

🔮Future Enhancements

📖Additional Resources

🎯 Try It Out!

Visit the live demo and chat with the AI assistant. Ask it questions like:


Built with 💜 by Oskar
Powered by Cloudflare Workers, Claude AI, and MCP