{"slug": "i-turned-my-portfolio-into-an-mcp-server-and-i-m-not-a-programmer", "title": "I turned my portfolio into an MCP server (and I'm not a programmer)", "summary": "Mikhail, a civil engineer who does not write code, built a portfolio website that functions as an MCP (Model Context Protocol) server, allowing AI agents like Claude and GPT to query his experience and projects directly. The portfolio includes a live architecture simulator and tools such as analyze_stack and get_antipatterns, all powered by a single source of truth. He deployed it on Cloudflare Workers and shared lessons learned, including a pitfall with Cloudflare Workers' execution model.", "body_md": "My background is civil engineering. I don't write code — I direct AI agents to write it while I handle architecture, decisions, and QA.\n\nSo when I built my portfolio, I didn't want it to look like everyone else's. I wanted it to *do* something no one else's does.\n\nHere's what I built: a portfolio that answers questions from AI agents directly. Not a chatbot. Not a demo. A real server that any AI — Claude, GPT, anything — can connect to and interrogate.\n\n```\nclaude mcp add --transport http msp-portfolio \\\n  https://msp-portfolio.mansio-dev.workers.dev/mcp\n```\n\nAsk it *\"what has Mikhail built?\"* or *\"does his stack match this job description?\"* and it answers with live data — not a frozen PDF from six months ago.\n\nEvery portfolio makes the same silent promise: \"trust that this is still true.\"\n\nIt's a snapshot. The moment you close the editor, it starts going stale. And there's no way for anyone — human or AI recruiter — to verify what's actually there.\n\nI wanted the opposite. A portfolio that doesn't just display claims, but answers questions about them. If the evidence for a skill isn't there, it says so instead of bluffing.\n\nThe site has three parts that share the same brain:\n\n**1. The website** — what you see when you open it in a browser. Interactive, dark-themed, with a simulator you can break.\n\n**2. A server for AI agents** — the same data, but in a format any AI can query directly. This is the MCP part.\n\n**3. A local version** — for development and testing from the command line.\n\nThe unusual thing: all three read from exactly the same source. No copy-pasting, no \"API version\" vs \"website version.\" One place, three doors.\n\nThink of these as questions the AI can ask my portfolio:\n\n| Question | Tool |\n|---|---|\n| Who is Mikhail? | `get_profile` |\n| What has he built? | `get_projects` |\n| What has he been working on lately? | `get_commit_history` |\n| What are his engineering principles? | `get_engineering_principles` |\n| What has he written recently? | `get_articles` |\n| What mistakes has he made? | `get_antipatterns` |\n| How does his stack match this job? | `analyze_stack` |\n| What decisions did he make and when? | `get_timeline` |\n| What happens to his architecture under load? | `simulate_architecture` |\n\nThe one recruiters use most: `analyze_stack`\n\n. You paste a job description, it returns a per-skill breakdown with actual evidence — not \"I know Kubernetes\" but \"used in project X, decision log here.\"\n\nThe one I'm most proud of: `get_antipatterns`\n\n. It's a museum of real mistakes I made while building this — a forked repo I accidentally claimed as mine, a feature that worked in local tests and silently broke in production, a counter that looked like it was writing data and wasn't. Honest lessons, not a polished highlight reel.\n\nThe portfolio has a live architecture simulator. You pick one of my real projects, pick a failure scenario — kill a node, freeze the cache, overload the AI — and watch the performance numbers change in real time.\n\nIt's not a video. It's not a screenshot. It runs the actual model.\n\nAt 20× load on the search architecture: p95 latency goes from ~10ms to 239ms under a load spike, 401ms if a node dies. When it crosses a threshold, a chip appears: `circuit_open`\n\n, `fallback_engaged`\n\n, `degraded_mode`\n\n. This is what I mean when I say \"I understand distributed systems\" — you can verify it yourself.\n\n**The package that doesn't exist.** I spent time trying to install `@fastify/mcp`\n\n. It doesn't exist. The real name is `@modelcontextprotocol/fastify`\n\n. Simple mistake, cost an hour.\n\n**The function that worked locally and did nothing in production.** I had a counter that tracked how many times the MCP server was queried. It passed all tests. In production, the counter never wrote anything. Reason: in Cloudflare Workers, code that runs after you send a response gets cancelled immediately. My counter was running after the response. Fix: one line — `ctx.waitUntil(task)`\n\n. The lesson is that local Node.js and Cloudflare Workers have different rules about what happens after a request ends.\n\n**The rate limiter that reported success but did nothing.** I set up a rate limit on the free plan. Every call returned `success: true`\n\n. Enforcement simply wasn't active at that tier. I only caught it by deliberately triggering it with a burst test. Configuration saying \"yes\" and the system actually enforcing it are two different things.\n\n**The hourly commit that silently moved the code forward without me.** The CI runs every hour to refresh metrics. Each run makes a commit. If I pushed without fetching first, I'd be pushing on top of a diverged history. Now I always `git fetch`\n\nfirst. Not a disaster, just a thing you learn once.\n\nThe agent loop — where you can type a question and watch the AI call tools step by step, live, in the browser — turned out to be the most interesting part to watch.\n\nYou see it think. It calls `get_profile`\n\n, reads the result, decides it needs more, calls `analyze_stack`\n\n, compares, then answers. The whole chain is visible. It's not a black box with an answer at the end. It's a process you can audit.\n\nI didn't plan that as a feature. It came from trying to debug the demo and realizing the debug view was more interesting than the final answer.\n\n```\n  claude mcp add --transport http msp-portfolio \\\n    https://msp-portfolio.mansio-dev.workers.dev/mcp\n```\n\nThen ask it: *\"what did your mistakes teach you?\"*\n\nIf you build something like this, drop a comment. I'd genuinely like to see it.", "url": "https://wpnews.pro/news/i-turned-my-portfolio-into-an-mcp-server-and-i-m-not-a-programmer", "canonical_source": "https://dev.to/mansio/i-turned-my-portfolio-into-an-mcp-server-and-im-not-a-programmer-4h0a", "published_at": "2026-08-14 13:14:02+00:00", "updated_at": "2026-08-14 13:35:54.680227+00:00", "lang": "en", "topics": ["ai-agents", "developer-tools", "ai-infrastructure"], "entities": ["Mikhail", "Claude", "GPT", "Cloudflare Workers", "MCP", "Fastify"], "alternates": {"html": "https://wpnews.pro/news/i-turned-my-portfolio-into-an-mcp-server-and-i-m-not-a-programmer", "markdown": "https://wpnews.pro/news/i-turned-my-portfolio-into-an-mcp-server-and-i-m-not-a-programmer.md", "text": "https://wpnews.pro/news/i-turned-my-portfolio-into-an-mcp-server-and-i-m-not-a-programmer.txt", "jsonld": "https://wpnews.pro/news/i-turned-my-portfolio-into-an-mcp-server-and-i-m-not-a-programmer.jsonld"}}