Skip to main content
Tom Børvan

2026-06-28 · 6 min

Why my portfolio runs an MCP server

A page built for human eyes is close to invisible to an agent. So my portfolio ships a real MCP server, in-page tools, and plain-text profiles — and turns the smallest site I own into a lab for the agentic web.

Point an assistant like Claude at my website and it does not read the page. It calls a function. It asks for a resource named profile://full, receives clean markdown, and answers whatever you wanted to know — my role, my projects, how to reach me — without parsing a single heading or guessing at my layout. My portfolio runs a small Model Context Protocol server, and that is deliberate.

The web is picking up a second kind of reader. Alongside people with browsers, there are now agents with tools: assistants that act on someone's behalf, call APIs, and assemble an answer from whatever they can reach. A site that only renders HTML speaks fluently to the first reader and barely at all to the second. I wanted mine to speak to both. So I built the machine-facing half on the smallest surface I own — this site.

What an agent actually sees

An agent does not have eyes. It has a network request and a budget of tokens. Point it at an ordinary page and it gets a document built for a human: navigation it has to skip, markup it has to strip, content welded to presentation. It can cope. Models are good at reading messy HTML now. But every token spent untangling a layout is a token not spent on the question, and every guess about structure is a chance to get me wrong.

MCP removes the guessing. Instead of a page to scrape, the agent gets a contract: a list of resources it can read and tools it can call, each with a name, a description, and a typed schema. It does not infer what is available. It asks, and the server tells it. When the answer comes from a tool, there is no ambiguity about where my email ends and my job title begins — the shape is declared, not implied. That move, from parsing to calling, is the whole idea.

A page is content an agent must decode. A tool is a capability it can simply call.

What this site ships

There are three layers, aimed at three kinds of reader. The first is a real MCP endpoint at https://www.tomborvan.com/api/mcp. It is built with the mcp-handler package, runs as a Next.js route on the same deployment as the rest of the site, and speaks streamable HTTP. No separate service, no extra host to keep alive.

The endpoint exposes two resources and a handful of tools. The resources are profile://brief and profile://full — the short and long versions of who I am, as markdown. The tools do the active work:

The second layer is for agents that live inside the browser rather than calling a server. A small script registers in-page WebMCP tools through navigator.modelContext — the same get_contact_info, plus a navigate tool that scrolls the page to a section and a view_profile tool that fetches the full markdown. If an in-browser assistant is driving the tab, it can act on the page instead of squinting at it.

The third layer is the humble one: an llms.txt file and its longer companion, plain-markdown summaries a crawler can grab in a single request. It is the least clever part of the stack and probably the most widely useful, because it needs no protocol at all.

Pointing a client at it

None of this is hypothetical. If you run an MCP client — Claude Desktop, an editor, your own script — you can add the endpoint to its config and the tools show up in the session. Most desktop clients speak stdio, so a small bridge connects them to a remote HTTP server:

{
  "mcpServers": {
    "tomborvan": {
      "command": "npx",
      "args": ["mcp-remote", "https://www.tomborvan.com/api/mcp"]
    }
  }
}

Restart the client and get_profile, list_projects and the rest are available. Ask who I am or what I have shipped, and the answer comes from the tools rather than from a scrape of the homepage or, worse, the model's stale memory of me.

SEO for agents

It is tempting to call this SEO for agents, and the comparison holds up further than you would expect. Classic SEO is the craft of making a page legible to a machine that decides what humans see — titles, structured data, sitemaps, clean semantics. The agentic version keeps the goal and swaps the machine. The reader is no longer a crawler building an index for later; it is an assistant answering a question right now, on someone's behalf, and it would rather make a typed call than interpret a paragraph.

Doing this on a personal site is the cheapest possible lab. The domain is mine. The content is me, so I am both the subject-matter expert and the person checking the output. Nothing breaks a customer's checkout if I get a schema wrong. I can add a tool, point a client at it, watch how an agent uses it, and change it the same afternoon. That loop — build, expose, observe — is hard to come by at work and free to run here. The lessons transfer directly: how to describe a tool so a model picks the right one, how much to return before you drown the context window, what a graceful fallback looks like when the data source is down.

Fluency, not scale

I want to be honest about the size of this. It is a small server. A few tools, two resources, traffic you could count on one hand. Measured in requests it does almost nothing, and I am not pretending an army of agents queries my profile every night.

That was never the point. The point is fluency — knowing, from having built one end to end, what a resource is, where a tool boundary belongs, and how an agent behaves when the CMS goes down and the fallback takes over. When a client asks me to make their platform legible to the agentic web, I would rather answer from a server I have run than a diagram I have drawn. The portfolio is the site. The MCP server is the proof.

← All writing