Skip to content

About

v3 of my personal development portfolio. the first version was react, html, and css, with assets i made in adobe. the second was similar, but served a cleaner ui. this one is another full redesign — react, typescript, vite, tailwind — and the skill logos are still from react-icons. same pages for people and agents. also an MCP server.

Topics

Resources

Stars

0 stars

Watchers

1 watching

Forks

Repository files navigation

My First Site Using Vite + React, HTML, and CSS.

One Vite + React terminal. Path routes (/about, /work, /developers, …) are the same URLs for humans and agents. Bio, projects, skills, and contact live in src/lib; React stages render them, and MCP / REST / /ask / generated markdown are adapters over that same data. There is no parallel HTML site.

Installation

npm i

Development

npm run dev

Terminal

The human UI is a prompt over path routes, not a PTY. ? or :help opens the same reference in the app.

Modes (chrome prefix; type the payload only):

  • / — live filter. Unfocused / focuses the line. Query stays on the stage while you run a command.
  • : — command. Unfocused : focuses and switches to command mode.
  • ~ — navigate by section path (work, about, …).

g then w|a|t|i|r|m|h jumps sections without the prompt. * wipes the filter.

Line editor (bash analogs on the single-line input):

  • ↑ / ↓ — history (localStorage key ain_hist, consecutive-deduped)
  • Tab / Shift+Tab — complete commands, themes, paths
  • Ctrl+R — reverse incremental search
  • Ctrl+A / E / U / K / W — start, end, kill-to-start, kill-to-end, kill-word
  • Ctrl+L or :clear — clear the line and wipe the activity log

Commands include :resume, :theme <name>, :crt, :github, :share, :mcp, :log. Full list is in the overlay.

Agent discovery

Public, read-only surfaces for AI agents (no API key):

  • GET /llms.txt — when-to-use index
  • GET /openapi.json — REST spec (/api/v1)
  • GET /developers — developer portal
  • MCP product: https://dev.actuallyitsnathaniel.com/api/mcp and /.well-known/mcp
  • MCP docs: https://dev.actuallyitsnathaniel.com/api/mcp-docs
  • Auth skill: /auth.md

MCP Server

api/mcp.ts exposes a Model Context Protocol server at https://dev.actuallyitsnathaniel.com/api/mcp (Node runtime, Streamable HTTP transport) with 6 tools: search_projects, get_toolbelt, get_about, get_resume, get_contact, get_github_activity. No auth — every tool reads data that's already public on the site.

To test it:

  • npm run test:mcp — automated check: spins up a real Node HTTP server wrapping the handler and exercises every tool (init → list → call each tool → unknown-tool error path)
  • npx vercel dev, then point MCP Inspector (npx @modelcontextprotocol/inspector) at http://localhost:3000/api/mcp for an interactive UI
  • npx vercel build — reproduces Vercel's real bundler/runtime locally; catches deploy-only failures (e.g. edge vs. node runtime bundling issues) before pushing

Gotcha: package.json has "type": "module", so Node's real ESM loader requires explicit .js extensions on every relative import reachable from api/mcp.ts (e.g. ../src/lib/portfolio.js, not ../src/lib/portfolio) — TypeScript's bundler resolution accepts either, and tsx/vercel dev silently tolerate a missing extension, so this only breaks in the actual deployed function (ERR_MODULE_NOT_FOUND, ready but 500ing on every request). npm run test:mcp and vercel dev cannot catch this class of bug. To verify for real: npx vercel build, then load the compiled output directly under plain Node —

cd .vercel/output/functions/api/mcp.func && node --input-type=module -e "await import('./api/mcp.js')"

If that throws ERR_MODULE_NOT_FOUND, an extension is missing somewhere in the import chain. This is also why api/mcp.ts reads from src/lib/skills.ts (plain data) instead of src/Components/skills/skills-data.ts — the latter pulls in JSX icon components with their own relative imports, widening the surface area for this exact bug.

Connecting from Claude

Claude's custom-connector UI (claude.ai and Claude Desktop) currently forces an OAuth Dynamic Client Registration attempt on any custom remote MCP connector, even ones — like this one — that advertise no auth at all. That produces a "Couldn't register with … sign-in service" error and is a known, Anthropic-acknowledged, currently-unfixed limitation of the connector UI (closed "not planned": anthropics/claude-ai-mcp#457, #402) — not a bug in this server.

Workaround for Claude Desktop: bypass the web connector flow with a local mcp-remote stdio bridge instead. Add to claude_desktop_config.json:

{
  "mcpServers": {
    "nathaniel-portfolio": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://dev.actuallyitsnathaniel.com/api/mcp"]
    }
  }
}

Restart Claude Desktop after editing. Other MCP clients that don't go through the web custom-connector flow (Claude Code CLI, MCP Inspector, etc.) connect directly with no workaround needed.

About

v3 of my personal development portfolio. the first version was react, html, and css, with assets i made in adobe. the second was similar, but served a cleaner ui. this one is another full redesign — react, typescript, vite, tailwind — and the skill logos are still from react-icons. same pages for people and agents. also an MCP server.

Topics

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages