Context: I wanted a polished, “high‑tech” portfolio one‑pager in Vue 3 + TypeScript + Tailwind without spending days hand‑tweaking spacing, cards, and section layouts.
With Claude Code as the main agent and Gemini Design MCP as the “frontend designer”, I could iterate fast and keep the code in my repo.
Source code (GitHub)
The full project is available here:
To run it locally:
git clone https://github.com/VincentCapek/portfolio-gemini-design.git
cd portfolio-gemini-design
pnpm install
pnpm dev
What you’ll build
A one‑page portfolio landing that feels modern and “techy”:
- Sticky glassy navbar (scroll + section highlight)
- Hero with subtle grid background and glowing accents
- Stats/metrics row
- Services, resume/timeline, works grid, skills, testimonials slider, contact form
- Responsive + accessible by default
Prerequisites
- Node.js >= 18
- A Gemini Design MCP API key
- A Vue 3 + TypeScript + Tailwind project (Vite)
- Package manager: pnpm
1) Install Gemini Design MCP in Claude Code (local mode)
Gemini Design MCP can run locally (recommended). In your project folder, run:
claude mcp add gemini-design-mcp --env API_KEY=your_api_key_here -- npx -y gemini-design-mcp@latest
That’s it—Claude Code can now call Gemini Design tools for UI work.
Why local mode?
- Faster (no network latency)
- Simple: no remote auth headers to maintain
- Works even if your environment restricts remote connections
2) Keep secrets out of your repo (two safe approaches)
You can make the MCP config project-scoped (shareable) without committing secrets.
Option A (recommended): project .mcp.json without secrets + local key in Claude config
1) Commit a minimal .mcp.json that describes how to run the server:
{
"mcpServers": {
"gemini-design-mcp": {
"type": "stdio",
"command": "npx",
"args": ["-y", "gemini-design-mcp@latest"]
}
}
}
2) Store the API key in Claude Code local scope (not in the repo):
claude mcp add --scope local gemini-design-mcp --env API_KEY=your_api_key_here -- npx -y gemini-design-mcp@latest
This way:
-
.mcp.jsoncan be committed safely - your API key stays private in your local Claude config
Option B: environment variable expansion in .mcp.json
If you’re fine using env vars:
{
"mcpServers": {
"gemini-design-mcp": {
"type": "stdio",
"command": "npx",
"args": ["-y", "gemini-design-mcp@latest"],
"env": {
"API_KEY": "${GEMINI_DESIGN_MCP_API_KEY}"
}
}
}
}
Then set it on your machine:
export GEMINI_DESIGN_MCP_API_KEY="your_api_key_here"
Tip: If you accidentally committed your key, rotate it immediately (revoke + regenerate).
3) Add “rules” so Claude always delegates UI work to Gemini
Create a CLAUDE.md at the project root.
This file is where you teach Claude when to use Gemini Design MCP and how to structure requests.
Here’s the exact version I use for a fresh Vue 3 + TS + Tailwind repo.
# CLAUDE.md
This file guides Claude Code (claude.ai/code) when working in this repository.
This is a **fresh Vue 3 + TypeScript + Tailwind** project.
---
## General rules
- Keep changes **small and focused** (minimal diffs).
- Prefer **readability** over cleverness.
- Do not introduce new dependencies unless necessary.
- Always consider **accessibility** (labels, keyboard navigation, focus states).
- Keep UI **responsive** (mobile-first).
---
## Tech stack (baseline)
- Vue 3 + Vite + TypeScript
- Tailwind CSS
- Composition API + `<script setup lang="ts">`
- Package manager: **pnpm**
---
## Package manager: pnpm (required)
- Use **pnpm** for installs and scripts.
- Do **not** use `npm` or `yarn` (unless explicitly requested).
Common commands:
bash
pnpm install
pnpm dev
pnpm build
pnpm lint
pnpm test
pnpm add
pnpm remove
---
## Gemini Design MCP (MCP server): rules
Gemini is your frontend developer. For all UI/design work, use this MCP.
### Before writing any UI code, ask yourself:
- Is it a **NEW** visual component (popup, card, section, etc.)? → `snippet_frontend` or `create_frontend`
- Is it a **REDESIGN** of an existing element? → `modify_frontend`
- Is it just text/logic, or a trivial change? → Do it yourself
### Critical rules
1. If UI already exists and you need to redesign/restyle it → use `modify_frontend`, NOT `snippet_frontend`.
2. Tasks can be mixed (logic + UI). Mentally separate them:
- Do the logic yourself
- Delegate UI to Gemini
### Which MCP tool to call
- `create_frontend`: generate a full page/view
- `snippet_frontend`: generate a reusable UI block/snippet
- `modify_frontend`: targeted redesign of an existing component (surgical edits)
### Required brief format (always include)
When calling Gemini Design MCP, include:
1) **Target**
- File path(s) to create/modify
- Purpose of the UI
2) **Layout & content**
- Sections/blocks + hierarchy
- Copy/text placeholders
3) **States**
- Loading / empty / error / success / disabled
4) **Interactions**
- Primary/secondary actions
- Keyboard/focus expectations
5) **Constraints**
- Responsive (mobile/tablet/desktop)
- Accessibility requirements
- **Vue 3 SFC + Tailwind** output
---
## MCP configuration & secrets (important)
- **Never commit API keys or tokens** in any versioned file.
- Do **not** store keys inside committed `.mcp.json`.
- Preferred: commit `.mcp.json` without secrets, store the key in Claude’s local scope config.
---
## Output rule
When you finish a task, provide:
- A short summary of what changed
- The files touched
- Any follow-up suggestions (non-blocking)
That’s the whole “secret sauce”: Claude reliably routes anything visual to Gemini Design MCP.
4) Build the one‑page: break it into sections
Gemini Design MCP works best when you iterate in small steps, like you would with a real designer:
- Scaffold the page sections (basic layout)
- Make the hero “feel right” (spacing, grid, glow, typography)
- Add cards/grids (services, works, testimonials)
- Polish interactions (scrollspy, hover states, focus rings)
5) The prompt I used to recreate a similar template structure
I wanted a structure close to this demo layout (same “vibe” and section order, without copying text/images):
https://theme-land.com/relome/demo/index.html
Here is a copy‑paste prompt you can use in Claude Code.
Because of the rules above, Claude should automatically pick Gemini Design MCP and call create_frontend.
Use Gemini Design MCP.
Tool: create_frontend
Goal:
Create a one-page high-tech portfolio landing in Vue 3 + TypeScript + Tailwind inspired by:
https://theme-land.com/relome/demo/index.html
IMPORTANT: Do NOT copy exact text, brand names, or images. Use original copy + placeholders, but keep a very similar overall layout, spacing, and section order.
Project stack:
- Vue 3 + Vite + TypeScript
- Tailwind CSS
- pnpm
- Composition API + <script setup lang="ts">
- No extra UI libraries unless necessary (prefer inline SVG icons).
Output files:
- src/App.vue (page composition + anchors)
- src/components/layout/Navbar.vue (sticky header + mobile menu + active link)
- src/components/sections/HeroSection.vue
- src/components/sections/ServicesSection.vue
- src/components/sections/ResumeSection.vue
- src/components/sections/WorksSection.vue (filterable portfolio grid)
- src/components/sections/SkillsSection.vue
- src/components/sections/ApproachSection.vue
- src/components/sections/TestimonialsSection.vue (simple slider)
- src/components/sections/InsightsSection.vue
- src/components/sections/ContactSection.vue (form + contact info)
- src/components/layout/FooterSection.vue
- src/composables/useScrollSpy.ts (active section highlight)
- src/data/content.ts + src/data/portfolio.ts (content arrays)
Design requirements:
- Dark modern look with subtle grid background and soft glows.
- Hero: headline, subtitle, CTA, avatar placeholder, stats row (4 metrics).
- Services: 4 feature cards with icon + title + description.
- Resume: experience + education timeline blocks.
- Works: category pills + responsive project card grid.
- Skills: 6 skills with percentages (progress bars or radial).
- Approach: 3 steps (01 Define, 02 Develop, 03 Deliver).
- Testimonials: cards + prev/next + dots, keyboard accessible.
- Insights: 2–3 blog cards with date, read time, tags.
- Contact: left side info + right side form (checkboxes, budget pills, validation, loading state).
- Footer: simple.
UX:
- Smooth scrolling to anchors (respect prefers-reduced-motion).
- ScrollSpy highlights active nav link.
- Visible focus styles and accessible labels.
Tailwind:
- Utility-first. Minimal scoped CSS.
- Consistent container (max-w-6xl mx-auto px-4) and typography hierarchy.
Deliverables:
- Production-ready Vue SFC components with typed props where needed.
- Keep logic lightweight and content data-driven.
- Summarize created files and anchor IDs.
6) My iteration loop (this is what makes the result “high‑end”)
Once the scaffold is there, I iterate in tiny design requests instead of one giant prompt:
Make the hero feel more “high‑tech”
Use Gemini Design MCP.
Tool: modify_frontend
Target file: src/components/sections/HeroSection.vue
Redesign goals:
- Stronger grid background + subtle vignette
- Softer glow behind the avatar
- Better typography hierarchy (headline + name emphasis)
- CTA button with premium hover/active states
- Improve spacing on mobile
Keep the current structure and content.
Only change visuals and classes.
Upgrade the metric cards
Use Gemini Design MCP.
Tool: modify_frontend
Target file: src/components/sections/HeroSection.vue (metrics row)
Make the metric cards look more premium:
- glassmorphism, subtle borders, faint noise
- better number styling (tabular nums), label alignment
- hover effect and focus ring for accessibility
No new dependencies.
Add a new UI block without touching existing layout
Use Gemini Design MCP.
Tool: snippet_frontend
Add a "Trusted by" strip under the hero:
- 5 logo placeholders (SVG or simple text marks)
- subtle separators, matches the dark theme
- responsive (wrap on mobile)
Insert location: directly under the metrics row.
7) Common gotchas (and how to avoid them)
“Gemini generated React, but my repo is Vue”
Gemini Design MCP often defaults to React + Tailwind. If that happens:
- Treat it as a layout reference
- Ask Claude to convert it to Vue SFC
- Or explicitly remind: “Output Vue 3 SFC +
<script setup lang="ts">”
“It looks good on desktop but not on mobile”
Always ask for mobile fixes explicitly:
- “Fix mobile spacing and reduce visual clutter”
- “Make the nav menu comfortable on small screens”
- “Adjust typography scale for sm and md breakpoints”
“I’m afraid it will break my logic”
That’s exactly why modify_frontend exists: it’s a surgical restyle tool.
Use it whenever the component already exists.
8) Final checklist before shipping
-
pnpm devand verify hot reload - Keyboard navigation works (tab through buttons/links/inputs)
- Contrast is readable on the dark background
- Each section has a stable anchor ID for nav links
- No secrets are committed (
.mcp.jsonclean, API key stored locally)
Conclusion
This workflow feels like pairing with a designer who can also code:
- Claude Code orchestrates the work
- Gemini Design MCP handles the visual layer
- Your repo stays clean, typed, and maintainable
If you’re building Vue + Tailwind UIs and you want “polish” without a week of pixel pushing, this setup is a huge win.
Handy links (add as you like)
Source code (repo): https://github.com/VincentCapek/portfolio-gemini-design
Gemini Design MCP docs: https://gemini-design-mcp.com/docs
Claude Code MCP docs: https://code.claude.com/docs/en/mcp
Top comments (0)