Felipe Tavares — brain glyph brand mark Felipe Tavares

Engineering

How this site is actually built

This site itself is a proof point: the decisions behind it, the stack it runs on, and a changelog distilled from its real commit history. Not marketing copy about engineering discipline. The discipline itself.

Decisions

Decisions

Six calls that shaped the build

Context, the call made, and what it cost or bought. Rewritten from this repo's own ADRs and design specs.

  • Astro over Next.js

    The site is mostly static, SEO-critical content read by recruiters and peers on commutes, not an app that needs client-side routing state.

    Astro 5 with React islands only where interactivity is real (chat, forms, theme toggle), instead of Next.js.

  • Git-based CMS over a hosted one

    No evidence yet that a plain git-plus-editor workflow can't keep up with actual publishing cadence, before paying for a hosted CMS to solve a problem that might not exist.

    Content lives as git-versioned MDX/JSON, read through one ContentRepository port, edited three equivalent ways — direct file, Claude Code, or a local Keystatic UI.

  • Workers AI first, Anthropic as fallback

    The chatbot needs a model provider, and a paid API as the default breaks the $0/month budget the moment the site gets any real traffic.

    A provider router tries Cloudflare Workers AI first, free and colocated with the rest of the stack, and falls back to Anthropic only if that call errors — never the other way around.

  • Cloudflare's free tier as the ceiling, not a starting point

    Domain already owned; every other cost (hosting, embeddings, rate-limit storage, email) had to fit inside a tier that won't get bumped by a personal site's real traffic, not just look cheap on a demo.

    Pages/Workers for hosting, KV for rate limiting, Vectorize for embeddings, Workers AI for the chatbot — one provider, one free tier, for everything that isn't the domain itself.

  • The hero moved from decorative to data-true

    An early hero concept was a generic animated gradient mesh with an optional pointer-parallax dot grid: motion for its own sake, no connection to what the site is actually about.

    Replaced it with a living-blueprint diagram generated at build time from the real competency matrix — nodes are skill domains weighted by real depth, edges are roles that touched them. Not decorative randomness.

  • A hand-written fetch transport over the MCP SDK's own

    The MCP server's Cloudflare Worker transport needed to implement the protocol's Transport interface, and the SDK ships one, StreamableHTTPServerTransport, for exactly this.

    Traced that class into node_modules and found it's typed and implemented directly against Node's IncomingMessage/ServerResponse, which don't exist in the Workers runtime. Wrote FetchTransport instead: the same interface, implemented directly over the standard Fetch API.

Why this stack

Why this stack

Every piece, one honest reason

No component here is the default choice. Each earned its place against the $0/month constraint.

  • Astro 5

    Islands architecture ships near-zero client JS on static content by default.

  • React (islands only)

    Used only where a component genuinely needs client-side state — chat, forms, toggles.

  • TypeScript, hexagonal ports & adapters

    core stays framework-free; swapping an adapter never touches a page.

  • Tailwind CSS v4

    Token-driven styling; every color and spacing value traces to one CSS custom-property file.

  • Cloudflare Pages + Workers

    Hybrid output: pages prerender to the CDN, /api/* runs as Workers functions.

  • Cloudflare Workers AI + Vectorize

    Free-tier chatbot provider and embedding index, with Anthropic as a config-swappable fallback.

  • Cloudflare KV

    Rate-limit storage for /api/contact and /api/chat, free tier, no separate database.

  • Resend

    Contact form email delivery via the REST API; the RESEND_API_KEY env binding keeps it out of the bundle.

  • Cloudflare Turnstile

    Server-side bot verification on /api/contact; sitekey is public, secret stays in the Worker env binding.

  • Astro content collections (git-based CMS)

    content/ is the CMS — MDX/JSON, versioned in git, edited three equivalent ways.

  • Keystatic

    Local content-editing UI mirroring the same zod schemas Astro's collections already validate.

  • GSAP, Lenis, OGL (motion stack)

    MIT-licensed; loaded lazily per page so content pages never pay for motion they don't use.

  • Model Context Protocol (packages/mcp)

    Publishes the same content and chatbot to AI agents as typed tools, not scraped HTML.

  • Vitest + Playwright

    Vitest for unit and architecture boundary tests; Playwright for cross-engine E2E across Chromium, WebKit, and mobile-WebKit.

Changelog

Changelog

Milestones, not commit noise

Distilled from real git history: dated, narrative, no hashes to chase.

Last updated 2026-07-11

  1. 2026-07-11 feature

    Agent-discovery endpoints added

    A well-known API catalog, an MCP server card, and HTTP Link headers on the homepage let AI agents find the site's machine-readable surfaces without guessing paths.

  2. 2026-07-11 content

    Structured data and SEO pass

    Person, WebSite, ProfilePage, and Article JSON-LD added across all main pages. Desktop Lighthouse scores after the pass: 100/100/100/100.

  3. 2026-07-10 feature

    Site deployed to Cloudflare Pages at $0/month

    The full stack (Pages, Workers, KV, Vectorize, Workers AI) runs inside Cloudflare's free tier. Total recurring cost after the domain: $0/month.

  4. 2026-07-09 feature

    /reading section opens

    A public log of books, articles, and papers, each with a verdict and rationale. Filterable by type and domain, with four verdict levels.

  5. 2026-07-09 feature

    Brand identity and galaxy backdrop ship

    The owner's brand glyph replaces placeholder marks across favicon, OG image, and chat launcher. A WebGL galaxy layer sits behind all page content, tuned for light and dark themes.

Earlier milestones (5)
  1. 2026-07-06 feature

    MCP server live at mcp.felipetavares.dev

    Career data and the chatbot are exposed as typed Model Context Protocol tools. Any MCP-capable agent can query roles, search articles, or start a grounded chat.

  2. 2026-07-05 content

    AI-readable surfaces ship

    Markdown twins for every page, an llms.txt file, and a JSON Resume endpoint go live. An AI agent can read this site cleanly without scraping HTML.

  3. 2026-07-05 feature

    Accessibility controls added

    A floating panel ships with reduce-motion, high-contrast, and larger-text toggles, backed by a published accessibility statement.

  4. 2026-07-05 feature

    Projects, writing engine, and chatbot launch

    Project deep-dives, an RSS-backed writing engine with per-article publish kits, and a RAG chatbot built on Cloudflare Workers AI ship in one push.

  5. 2026-07-04 feature

    Experience and career narrative published

    Scroll-driven career timeline and printable executive dossier go live, covering seven roles.