Skip to content

vibegui/vibegui.com

Repository files navigation

vibegui.com

Personal blog, experiments sandbox, and AI-curated bookmarks by Guilherme Rodrigues (@vibegui)

A minimal, high-performance static site with SQLite-powered content and bookmarks, all managed through MCP (Model Context Protocol). This project serves as both a personal platform and an educational reference for building MCP-first applications.

Live at vibegui.com


Recent Updates 🚀

January 1, 2026 — The Great SSG Simplification

Complete architecture overhaul focused on zero-fetch page loads:

  • Unified Build Script — One entrypoint (scripts/build.ts) with three modes: dev, prod, pages
  • Embedded Content — All articles, context pages, and the homepage manifest are now embedded directly in static HTML. Zero runtime fetches.
  • Context Page SEO — Full meta tags (Open Graph, Twitter Cards) with auto-extracted descriptions from content
  • ~15 Second Deploys — Cloudflare Pages builds with no npm install, just Node.js scripts

See DEPLOY.md for deployment details.

Read the full writeup: SEO-First SSG: From Social Embeds to Zero-Fetch Pages


What's Been Built ✅

  • Zero-Fetch SSG — All pages (articles, context, homepage) have content embedded directly in HTML. No runtime fetches.
  • SQLite-First Architecture — All content stored in SQLite databases, version-controlled in git
  • Zero-Dependency Build — Uses Node 22's native node:sqlite for exports (no npm install needed on Cloudflare)
  • AI-Powered Bookmark Enrichment — Perplexity research + Exa content + Claude Sonnet classification
  • Full SEO — Every page has title, description, Open Graph, Twitter Cards, and canonical URLs
  • Context Library — LLM-generated summaries from leadership papers with proper SEO and embedded content
  • Comprehensive Testing — E2E tests (Playwright), constraint tests, accessibility verification

Tech Stack

Layer Technology
Frontend React 19, Vite, Tailwind CSS v4
Database SQLite (Node 22 native node:sqlite)
MCP Server @decocms/runtime + custom tools
AI Enrichment Perplexity + Exa + Claude Sonnet via MCP Mesh
Testing Playwright (E2E), Bun test (unit/constraints)
Deployment Cloudflare Pages (edge, zero-install build)
Quality Biome (format), oxlint (lint), TypeScript strict

Quick Start

# Install dependencies
bun install

# Start development server (generate + vite dev)
bun run dev

# Build for production (generate + vite build + finalize)
bun run build

# Preview production build locally
bun run preview:build

# Run all checks (pre-commit)
bun run precommit

Build Modes

The unified scripts/build.ts supports three modes:

Command Mode What It Does
bun run dev dev Generate content + Vite dev server
bun run build prod Generate + Vite build + Finalize
npm run pages:build pages Generate + Finalize (for Cloudflare)

MCP Server (for AI-assisted content management)

# HTTP transport (for MCP Mesh web connections)
bun run mcp:dev          # Development with hot reload
bun run mcp:serve        # Production mode

# STDIO transport (for MCP Mesh command connections)
bun run mcp:stdio        # Production mode
bun run mcp:stdio:dev    # Development with hot reload

For Mesh integration (add as custom STDIO command):

  • Command: bun
  • Args: --watch /path/to/vibegui.com/server/stdio.ts

Architecture Overview

┌─────────────────────────────────────────────────────────────────┐
│                      SQLite DATABASES                           │
│                   (version-controlled in git)                   │
│                                                                 │
│   data/content.db          data/bookmarks.db                   │
│   ├── articles             ├── 400+ curated links              │
│   ├── drafts               ├── AI enrichment data              │
│   └── tags                 └── tags, ratings, insights         │
└───────────────────────────┬─────────────────────────────────────┘
                            │
                            ▼
┌─────────────────────────────────────────────────────────────────┐
│              scripts/build.ts --mode=X                          │
│                                                                 │
│   One unified entrypoint with three modes:                      │
│                                                                 │
│   --mode=dev   → generate + vite dev server                     │
│   --mode=prod  → generate + vite build + finalize               │
│   --mode=pages → generate + finalize (for Cloudflare)           │
└───────────────────────────┬─────────────────────────────────────┘
                            │
                            ▼
┌─────────────────────────────────────────────────────────────────┐
│            GENERATE (scripts/generate.ts)                       │
│                                                                 │
│   Reads SQLite → writes:                                        │
│   • public/content/manifest.json   (article list)               │
│   • .build/article/{slug}/index.html (SSG pages)                │
│   • .build/context/{path}/index.html (SSG context)              │
│                                                                 │
│   Content embedded as JSON. Zero runtime fetches!               │
└───────────────────────────┬─────────────────────────────────────┘
                            │
                            ▼
┌─────────────────────────────────────────────────────────────────┐
│            FINALIZE (scripts/finalize.ts)                       │
│                                                                 │
│   Post-processing (no SQLite needed):                           │
│   • Copy manifest, bookmarks to dist/                           │
│   • Process SSG HTML (inject prod assets)                       │
│   • Embed manifest directly into index.html                     │
└───────────────────────────┬─────────────────────────────────────┘
                            │
                            ▼
┌─────────────────────────────────────────────────────────────────┐
│                   CLOUDFLARE PAGES                              │
│                                                                 │
│   pages:build runs --mode=pages (no Vite, no npm install!)      │
│   • SKIP_DEPENDENCY_INSTALL=true in Cloudflare settings         │
│   • dist/assets/* pre-built and committed to git                │
│   • index.html: 30s cache + stale-while-revalidate              │
│   • Assets: 1 year immutable cache                              │
└─────────────────────────────────────────────────────────────────┘

SQLite-First Content Management

Why SQLite?

Instead of managing markdown files in folders, all content lives in SQLite databases:

Database Purpose
data/content.db Articles (with status: draft/published)
data/bookmarks.db 400+ curated links with AI enrichment

Benefits:

  • Version-controlled — Database files committed to git
  • Zero-dependency export — Node 22's native node:sqlite (no npm install)
  • Structured data — Tags, ratings, timestamps in proper columns
  • Fast builds — Cloudflare build completes in seconds

Generate Script

At dev/build time, the generate script reads SQLite and creates static files:

# Runs automatically with dev/build, but can run manually:
bun scripts/generate.ts

This creates:

  • public/content/manifest.json — Article metadata for the homepage
  • .build/article/{slug}/index.html — SSG pages with embedded article content

WAL Checkpoint on Commit

SQLite uses WAL mode for better concurrency, but WAL files are gitignored. The pre-commit hook automatically checkpoints:

# lefthook.yml
5_checkpoint_db:
  run: |
    sqlite3 data/bookmarks.db "PRAGMA wal_checkpoint(TRUNCATE);" 2>/dev/null || true
    sqlite3 data/content.db "PRAGMA wal_checkpoint(TRUNCATE);" 2>/dev/null || true

This ensures all writes are in the main .db file before committing.


Bookmarks System

AI-Powered Enrichment

Each bookmark goes through a 3-step enrichment pipeline:

1. Research (Perplexity)     → What is this resource about?
2. Content (Exa)             → Fetch and parse page content
3. Classification (Claude)   → Stars, tags, insights for 3 personas

Enrichment Output

Field Source
title, description AI-generated (improved)
stars (1-5) Claude rating
icon Emoji representing the resource
language Detected content language
research_raw Full Perplexity research
exa_content Scraped page content
insight_dev Key insight for developers
insight_founder Key insight for founders
insight_investor Key insight for investors
tags tech:*, type:*, persona:*

Filtering & Sorting

The /bookmarks page supports:

  • Persona filter — Developer, Founder, Investor
  • Tech filter — TypeScript, React, AI, etc.
  • Type filter — Tool, Article, Video, etc.
  • Platform filter — GitHub, LinkedIn, Twitter, YouTube, etc.
  • Rating filter — Minimum stars (1-5)
  • Sort — Default (enriched first) or by rating

Static Site Generation (SSG)

All content pages are pre-rendered with data embedded directly in the HTML — zero fetches needed:

Page Embedded Data
Homepage manifest-data (article list)
Article pages article-data (full markdown)
Context pages context-data (leadership summaries)
<!-- Example: dist/article/my-article/index.html -->
<div id="root"></div>
<script id="article-data" type="application/json">
  {"slug":"my-article","title":"My Article","content":"# Full markdown..."}
</script>

Cache Headers (_headers)

/*.html, /article/*, /context/*
  Cache-Control: public, max-age=30, stale-while-revalidate=3600

/assets/*
  Cache-Control: public, max-age=31536000, immutable

Testing

E2E Tests (Playwright)

bun run test:e2e

Tests run against production build to exercise the full pipeline:

Test Suite What It Verifies
content.spec.ts All context/leadership pages load, articles render
accessibility.spec.ts Semantic HTML, keyboard navigation, focus indicators
responsive.spec.ts No horizontal scroll, touch targets ≥44px
performance.spec.ts HTML < 100KB, DOM load < 3s

Constraint Tests (Bun)

bun run test:constraints
Test Constraint
build-size.test.ts Total JS < 300KB, HTML < 100KB
image-size.test.ts Each image < 250KB
cache-efficiency.test.ts Content-hash URLs, immutable cache headers

Project Structure

vibegui.com/
├── server/                    # MCP Server (STDIO transport)
│   ├── cli.ts                 # CLI entry point (--http flag support)
│   ├── stdio.ts               # STDIO transport entry point
│   └── tools.ts               # Shared tool definitions (McpServer)
│
├── mcp-server.ts              # MCP server (HTTP transport, @decocms/runtime)
├── main.ts                    # HTTP server entry point (with WhatsApp bridge)
├── CONSTRAINTS.md             # Project axioms (read this first!)
│
├── data/                      # SQLite databases (version-controlled)
│   ├── content.db             # Articles and drafts
│   ├── learnings.db           # Daily learnings (local only, gitignored)
│   └── bookmarks.db           # Curated links with AI enrichment
│
├── lib/
│   ├── db/                    # Database modules (Node 22 native sqlite)
│   │   ├── content.ts         # Content database
│   │   └── learnings.ts       # Learnings database
│   └── bookmarks/             # Browser bookmark readers
│
├── scripts/
│   ├── generate.ts            # SQLite → manifest.json + article HTML (Step 1)
│   ├── finalize.ts            # Post-build: embed manifest, hash context (Step 2)
│   ├── preview-server.ts      # Static server for production preview
│   └── optimize-images.ts     # Image optimization
│
├── context/                   # Reference material for AI writing
│   ├── leadership/*.md        # 11 leadership summaries
│   └── LINKEDIN_PROFILE.md    # Author context
│
├── src/                       # Frontend source
│   ├── main.tsx               # Entry point
│   ├── app.tsx                # Router and layout
│   ├── pages/                 # Home, Article, Bookmarks, etc.
│   └── lib/                   # Utilities (manifest, markdown)
│
├── tests/
│   ├── e2e/                   # Playwright E2E tests
│   └── constraints/           # Build constraint verification
│
├── public/                    # Static assets (gitignored: content/, bookmarks/)
│   └── _headers               # Cloudflare cache headers
│
├── dist/                      # Build output (assets versioned in git)
│
├── vite.config.ts             # Vite + dev API endpoints
├── lefthook.yml               # Git hooks (checkpoint DB, stage dist)
└── package.json

Commands Reference

Core Commands

Command Description
bun run dev Generate content + start Vite dev server
bun run build Generate + Vite build + finalize (full production build)
bun run preview Build + serve locally (test production)
bun run pages:build Cloudflare Pages build (no Vite, no npm deps)

Quality & Testing

Command Description
bun run precommit All checks (format, lint, type, build, test)
bun run test:e2e Playwright E2E tests
bun run test:constraints Verify build constraints
bun run check TypeScript type checking
bun run lint oxlint linting
bun run fmt Biome formatting

MCP Server

Command Description
bun run mcp:dev HTTP server with hot reload (includes WhatsApp bridge)
bun run mcp:serve HTTP server production mode
bun run mcp:stdio STDIO server for Mesh command connections
bun run mcp:stdio:dev STDIO server with hot reload

MCP Tools

The MCP server exposes 50+ tools for AI-assisted content management. Both HTTP and STDIO transports share the same tools (except WhatsApp which requires HTTP).

Content Management

Tool Description
COLLECTION_ARTICLES_* CRUD for articles (LIST, GET, CREATE, UPDATE, DELETE)
CONTENT_SEARCH_REPLACE Precise text replacement in content
CONTENT_APPEND/PREPEND Add text to start/end of content
CONTENT_INSERT_AFTER/BEFORE Insert text relative to a marker

Search

Tool Description
SEARCH_CONTEXT Search reference materials (uses ripgrep)
SEARCH_CONTENT Search articles and drafts

Development

Tool Description
DEV_SERVER_START/STOP Control Vite dev server
GIT_STATUS Show changed files
COMMIT Stage and commit changes
PUSH Push to remote
SCRIPT_* Auto-generated from package.json (11 scripts)

Bookmarks

Tool Description
BOOKMARKS_DISCOVER_BROWSERS Find browser profiles on system
BOOKMARKS_READ Read bookmarks from a browser
BOOKMARKS_SEARCH Search across all browsers
BOOKMARKS_EXPORT_CSV Export to CSV format

Learnings (Local Memory)

Tool Description
LEARNINGS_RECORD Record insights, bug fixes, accomplishments
LEARNINGS_TODAY Get today's learnings
LEARNINGS_BY_PROJECT Filter by project
LEARNINGS_SEARCH Search learnings
LEARNINGS_PUBLISHABLE Find content for blog posts
LEARNINGS_STATS Get statistics

Projects (Roadmap)

Tool Description
COLLECTION_PROJECTS_* CRUD for roadmap projects (LIST, GET, CREATE, UPDATE, DELETE)
PROJECT_MARK_COMPLETE Mark project as completed

WhatsApp Bridge (HTTP only)

Tool Description
WHATSAPP_STATUS Check extension connection
WHATSAPP_LIST_CHATS List visible chats
WHATSAPP_OPEN_CHAT Open a specific chat
WHATSAPP_READ_MESSAGES Read visible messages
WHATSAPP_SCRAPE Full chat history scrape

Deployment

Cloudflare Pages (Zero-Install Build)

# Build command (in Cloudflare dashboard)
npm run pages:build

# Environment variables
SKIP_DEPENDENCY_INSTALL=true   # Skip npm install
CI=true                        # Skip drafts in production

The pages:build script runs:

# Step 1: Generate content from SQLite (requires node:sqlite)
node --experimental-strip-types --experimental-sqlite scripts/generate.ts

# Step 2: Finalize build (copy assets, embed manifest, hash context)
node --experimental-strip-types scripts/finalize.ts

Note: Vite build does NOT run on Cloudflare. The dist/assets/* are committed to git, so only content generation and post-processing is needed.

Why Zero Dependencies?

  • Faster builds — No npm install (saves 30+ seconds)
  • Simpler deploys — Just Node 22 built-ins
  • No native modules — No better-sqlite3 compilation issues
  • No Vite on CI — Assets committed, only content changes trigger rebuild

About the Author

Guilherme Rodrigues is a software engineer and entrepreneur from Rio de Janeiro. After 9 years at VTEX leading high-performance e-commerce projects (including their NYSE IPO), he founded deco CMS — a platform democratizing the creation of governable AI agents.

He's also a co-founder of Movimento Tech, a coalition that has impacted over 3 million young Brazilians in technology.

Contact


License

Content (articles, bookmarks) © Guilherme Rodrigues. All rights reserved.

Code (everything else) is MIT licensed.


Built with MCP + SQLite · Made in Brazil 🇧🇷

About

My blog

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •  

Languages