A modern, serverless portfolio with conversational AI assistant powered by MCP
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 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?"
This project was built to explore and demonstrate:
Conversational interface powered by Claude AI with direct database access through MCP
Sub-100ms response times globally thanks to Cloudflare's edge network
Admin endpoints protected by Cloudflare Access, rate limiting on public APIs
Dynamic portfolio statistics and analytics accessible via AI or API
Responsive design with glassmorphism effects and smooth animations
Simple CRUD operations for projects, skills, and categories
┌─────────────────┐
│ User Browser │
└────────┬────────┘
│
├──────────────┐
▼ ▼
┌─────────────┐ ┌─────────────┐
│ Frontend │ │ AI Chat │
│ (CF Pages) │ │ Interface │
└──────┬──────┘ └──────┬──────┘
│ │
▼ ▼
┌──────────────────────────┐
│ Backend API │
│ (Cloudflare Workers) │
└─────┬──────────────┬─────┘
│ │
▼ ▼
┌──────────┐ ┌─────────────┐
│ D1 DB │ │ Claude API │
│ (SQLite) │ │ with MCP │
└──────────┘ └──────┬──────┘
│
▼
┌──────────────┐
│ MCP Server │
│ (Workers) │
└──────────────┘
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)
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
The AI assistant has access to these tools for querying portfolio data:
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.
All admin write operations (/api/admin/*) are protected by Cloudflare Access:
AI chat endpoint is rate limited to prevent abuse:
Proper CORS headers ensure frontend can access the API while maintaining security
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)
});
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)
}]
};
}
);
npm install -g wrangler
wrangler login
cd backend
wrangler deploy
echo 'your-claude-api-key' | wrangler secret put CLAUDE_API_KEY
cd frontend
wrangler pages deploy . --project-name=portfolio-frontend
cd portfolio-mcp-server
npm run deploy
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