gemini-design-mcp 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +101 -0
- package/build/index.d.ts +2 -0
- package/build/index.js +32 -0
- package/build/lib/gemini.d.ts +4 -0
- package/build/lib/gemini.js +27 -0
- package/build/prompts/system.d.ts +3 -0
- package/build/prompts/system.js +36 -0
- package/build/tools/generate-frontend.d.ts +18 -0
- package/build/tools/generate-frontend.js +32 -0
- package/build/tools/improve-frontend.d.ts +16 -0
- package/build/tools/improve-frontend.js +21 -0
- package/build/tools/suggest-design.d.ts +14 -0
- package/build/tools/suggest-design.js +17 -0
- package/package.json +48 -0
package/README.md
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# gemini-design-mcp
|
|
2
|
+
|
|
3
|
+
MCP server that uses **Google Gemini 3 Pro** for frontend/design code generation.
|
|
4
|
+
|
|
5
|
+
## Why?
|
|
6
|
+
|
|
7
|
+
Gemini excels at UI/UX design and frontend code generation. This MCP lets any AI agent (Claude Code, Codex, etc.) delegate frontend tasks to Gemini.
|
|
8
|
+
|
|
9
|
+
**Key principle:** The calling agent manages context. No config files needed.
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
Add to your Claude Desktop config (`~/.claude/claude_desktop_config.json`):
|
|
14
|
+
|
|
15
|
+
```json
|
|
16
|
+
{
|
|
17
|
+
"mcpServers": {
|
|
18
|
+
"gemini-design": {
|
|
19
|
+
"command": "npx",
|
|
20
|
+
"args": ["-y", "gemini-design-mcp"],
|
|
21
|
+
"env": {
|
|
22
|
+
"GEMINI_API_KEY": "your-api-key-here"
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Get your Gemini API key at: https://aistudio.google.com/app/apikey
|
|
30
|
+
|
|
31
|
+
## Tools
|
|
32
|
+
|
|
33
|
+
### generate_frontend
|
|
34
|
+
|
|
35
|
+
Main tool for creating frontend code.
|
|
36
|
+
|
|
37
|
+
**Parameters:**
|
|
38
|
+
- `request` (required): What to create (e.g., "A hero section with gradient background")
|
|
39
|
+
- `context` (nullable): Existing code for style reference. Pass `null` for new projects.
|
|
40
|
+
- `techStack` (optional): Tech stack (e.g., "React + Tailwind", "Vue + CSS", "Next.js + shadcn")
|
|
41
|
+
- `preferences` (optional): Style preferences (e.g., "dark mode", "glassmorphism", "minimal")
|
|
42
|
+
|
|
43
|
+
### improve_frontend
|
|
44
|
+
|
|
45
|
+
Improve existing frontend code.
|
|
46
|
+
|
|
47
|
+
**Parameters:**
|
|
48
|
+
- `code` (required): Current code to improve
|
|
49
|
+
- `feedback` (required): What to improve (e.g., "Make it more modern", "Add hover effects")
|
|
50
|
+
- `context` (optional): Additional context for consistency
|
|
51
|
+
|
|
52
|
+
### suggest_design
|
|
53
|
+
|
|
54
|
+
Get design suggestions without generating code. Saves tokens.
|
|
55
|
+
|
|
56
|
+
**Parameters:**
|
|
57
|
+
- `description` (required): What you're designing
|
|
58
|
+
- `currentApproach` (optional): Current approach or constraints
|
|
59
|
+
|
|
60
|
+
## How Context Works
|
|
61
|
+
|
|
62
|
+
The calling agent (Claude, Codex) is responsible for passing relevant context:
|
|
63
|
+
|
|
64
|
+
- **New project**: Pass `context: null`, Gemini creates from scratch
|
|
65
|
+
- **Existing project**: Agent reads relevant components and passes them as context
|
|
66
|
+
|
|
67
|
+
This ensures design consistency without requiring any user configuration.
|
|
68
|
+
|
|
69
|
+
## Example Usage
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
Agent: "Create a pricing card component"
|
|
73
|
+
|
|
74
|
+
→ Calls generate_frontend({
|
|
75
|
+
request: "A pricing card with 3 tiers, toggle for monthly/yearly",
|
|
76
|
+
context: "<existing Button and Card components>",
|
|
77
|
+
techStack: "React + Tailwind",
|
|
78
|
+
preferences: "glassmorphism, dark mode"
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
← Returns complete, production-ready component code
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Development
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
# Clone and install
|
|
88
|
+
git clone <repo>
|
|
89
|
+
cd gemini-design-mcp
|
|
90
|
+
npm install
|
|
91
|
+
|
|
92
|
+
# Build
|
|
93
|
+
npm run build
|
|
94
|
+
|
|
95
|
+
# Test locally
|
|
96
|
+
GEMINI_API_KEY=your-key node build/index.js
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## License
|
|
100
|
+
|
|
101
|
+
MIT
|
package/build/index.d.ts
ADDED
package/build/index.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
|
+
import { generateFrontendSchema, generateFrontend } from "./tools/generate-frontend.js";
|
|
5
|
+
import { improveFrontendSchema, improveFrontend } from "./tools/improve-frontend.js";
|
|
6
|
+
import { suggestDesignSchema, suggestDesign } from "./tools/suggest-design.js";
|
|
7
|
+
// Create MCP server
|
|
8
|
+
const server = new McpServer({
|
|
9
|
+
name: "gemini-design-mcp",
|
|
10
|
+
version: "1.0.0",
|
|
11
|
+
});
|
|
12
|
+
// Tool 1: generate_frontend
|
|
13
|
+
server.tool("generate_frontend", `Generate frontend code (components, pages, sections) with Gemini 3 Pro.
|
|
14
|
+
The calling agent MUST provide project context to ensure design consistency.
|
|
15
|
+
If new project, pass context=null and Gemini will create a new design system.
|
|
16
|
+
Gemini has 1M tokens of context - feel free to send multiple files.`, generateFrontendSchema, generateFrontend);
|
|
17
|
+
// Tool 2: improve_frontend
|
|
18
|
+
server.tool("improve_frontend", `Improve existing frontend code based on provided feedback.
|
|
19
|
+
Use for design modifications, UX improvements, or visual refactoring.`, improveFrontendSchema, improveFrontend);
|
|
20
|
+
// Tool 3: suggest_design
|
|
21
|
+
server.tool("suggest_design", `Returns design suggestions without generating code.
|
|
22
|
+
Useful for exploring directions before coding, saves tokens.`, suggestDesignSchema, suggestDesign);
|
|
23
|
+
// Start server
|
|
24
|
+
async function main() {
|
|
25
|
+
const transport = new StdioServerTransport();
|
|
26
|
+
await server.connect(transport);
|
|
27
|
+
console.error("gemini-design-mcp v1.0.0 running on stdio");
|
|
28
|
+
}
|
|
29
|
+
main().catch((error) => {
|
|
30
|
+
console.error("Fatal error:", error);
|
|
31
|
+
process.exit(1);
|
|
32
|
+
});
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { GoogleGenAI } from "@google/genai";
|
|
2
|
+
const apiKey = process.env.GEMINI_API_KEY;
|
|
3
|
+
if (!apiKey) {
|
|
4
|
+
console.error("ERROR: GEMINI_API_KEY environment variable is required");
|
|
5
|
+
console.error("Get your API key at: https://aistudio.google.com/app/apikey");
|
|
6
|
+
process.exit(1);
|
|
7
|
+
}
|
|
8
|
+
export const ai = new GoogleGenAI({ apiKey });
|
|
9
|
+
// Default model - Gemini 3 Pro (best for design)
|
|
10
|
+
export const DEFAULT_MODEL = "gemini-3-pro";
|
|
11
|
+
export async function generateWithGemini(systemPrompt, userPrompt, model = DEFAULT_MODEL) {
|
|
12
|
+
try {
|
|
13
|
+
const response = await ai.models.generateContent({
|
|
14
|
+
model,
|
|
15
|
+
contents: userPrompt,
|
|
16
|
+
config: {
|
|
17
|
+
systemInstruction: systemPrompt,
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
return response.text ?? "";
|
|
21
|
+
}
|
|
22
|
+
catch (error) {
|
|
23
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
24
|
+
console.error("Gemini API error:", errorMessage);
|
|
25
|
+
throw new Error(`Gemini API error: ${errorMessage}`);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export declare const GENERATE_FRONTEND_PROMPT = "You are an expert UI/UX designer and frontend developer.\nYou generate production-quality frontend code.\n\nSTRICT RULES:\n1. COMPLETE and functional code - never use placeholders like \"// TODO\" or \"...\"\n2. Modern, aesthetic, and professional design\n3. Responsive by default (mobile-first)\n4. Accessibility (aria-labels, semantic HTML, proper contrast)\n5. If CONTEXT is provided, you MUST match the existing style exactly\n6. If no context, create a coherent design system\n7. Use best practices for the requested framework/tech stack\n8. Return ONLY the code, no explanations\n\nDEFAULT STYLE (if not specified):\n- Colors: neutral tones with one accent color\n- Typography: clean and readable\n- Spacing: generous, airy\n- Effects: subtle (soft shadows, light transitions)";
|
|
2
|
+
export declare const IMPROVE_FRONTEND_PROMPT = "You are an expert UI/UX designer and frontend developer.\nYou improve existing frontend code based on the feedback provided.\n\nRULES:\n1. Keep the general structure unless asked otherwise\n2. Only improve the aspects mentioned in the feedback\n3. Maintain consistency with the rest of the code\n4. Return the COMPLETE improved code, not just the changes\n5. No explanations, just the code";
|
|
3
|
+
export declare const SUGGEST_DESIGN_PROMPT = "You are an expert UI/UX designer.\nYou provide concise and actionable design suggestions.\n\nRULES:\n1. Short and precise suggestions\n2. Focus on visual impact and UX\n3. Propose 3-5 ideas maximum\n4. Format: bullet points\n5. No code, just ideas";
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export const GENERATE_FRONTEND_PROMPT = `You are an expert UI/UX designer and frontend developer.
|
|
2
|
+
You generate production-quality frontend code.
|
|
3
|
+
|
|
4
|
+
STRICT RULES:
|
|
5
|
+
1. COMPLETE and functional code - never use placeholders like "// TODO" or "..."
|
|
6
|
+
2. Modern, aesthetic, and professional design
|
|
7
|
+
3. Responsive by default (mobile-first)
|
|
8
|
+
4. Accessibility (aria-labels, semantic HTML, proper contrast)
|
|
9
|
+
5. If CONTEXT is provided, you MUST match the existing style exactly
|
|
10
|
+
6. If no context, create a coherent design system
|
|
11
|
+
7. Use best practices for the requested framework/tech stack
|
|
12
|
+
8. Return ONLY the code, no explanations
|
|
13
|
+
|
|
14
|
+
DEFAULT STYLE (if not specified):
|
|
15
|
+
- Colors: neutral tones with one accent color
|
|
16
|
+
- Typography: clean and readable
|
|
17
|
+
- Spacing: generous, airy
|
|
18
|
+
- Effects: subtle (soft shadows, light transitions)`;
|
|
19
|
+
export const IMPROVE_FRONTEND_PROMPT = `You are an expert UI/UX designer and frontend developer.
|
|
20
|
+
You improve existing frontend code based on the feedback provided.
|
|
21
|
+
|
|
22
|
+
RULES:
|
|
23
|
+
1. Keep the general structure unless asked otherwise
|
|
24
|
+
2. Only improve the aspects mentioned in the feedback
|
|
25
|
+
3. Maintain consistency with the rest of the code
|
|
26
|
+
4. Return the COMPLETE improved code, not just the changes
|
|
27
|
+
5. No explanations, just the code`;
|
|
28
|
+
export const SUGGEST_DESIGN_PROMPT = `You are an expert UI/UX designer.
|
|
29
|
+
You provide concise and actionable design suggestions.
|
|
30
|
+
|
|
31
|
+
RULES:
|
|
32
|
+
1. Short and precise suggestions
|
|
33
|
+
2. Focus on visual impact and UX
|
|
34
|
+
3. Propose 3-5 ideas maximum
|
|
35
|
+
4. Format: bullet points
|
|
36
|
+
5. No code, just ideas`;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const generateFrontendSchema: {
|
|
3
|
+
request: z.ZodString;
|
|
4
|
+
context: z.ZodNullable<z.ZodString>;
|
|
5
|
+
techStack: z.ZodOptional<z.ZodString>;
|
|
6
|
+
preferences: z.ZodOptional<z.ZodString>;
|
|
7
|
+
};
|
|
8
|
+
export declare function generateFrontend(params: {
|
|
9
|
+
request: string;
|
|
10
|
+
context: string | null;
|
|
11
|
+
techStack?: string;
|
|
12
|
+
preferences?: string;
|
|
13
|
+
}): Promise<{
|
|
14
|
+
content: {
|
|
15
|
+
type: "text";
|
|
16
|
+
text: string;
|
|
17
|
+
}[];
|
|
18
|
+
}>;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { generateWithGemini } from "../lib/gemini.js";
|
|
3
|
+
import { GENERATE_FRONTEND_PROMPT } from "../prompts/system.js";
|
|
4
|
+
export const generateFrontendSchema = {
|
|
5
|
+
request: z.string().describe("Description of what to create (component, page, section, etc.)"),
|
|
6
|
+
context: z.string().nullable().describe("Existing project code for reference (components, styles, config). " +
|
|
7
|
+
"Send relevant files to ensure design consistency. " +
|
|
8
|
+
"Null if new project."),
|
|
9
|
+
techStack: z.string().optional().describe("Tech stack (e.g., 'React + Tailwind', 'Vue + CSS', 'HTML/CSS vanilla', 'Next.js + shadcn'). " +
|
|
10
|
+
"If not specified, Gemini will choose based on context."),
|
|
11
|
+
preferences: z.string().optional().describe("Style preferences (e.g., 'glassmorphism', 'dark mode', 'minimal', 'brutalist')"),
|
|
12
|
+
};
|
|
13
|
+
export async function generateFrontend(params) {
|
|
14
|
+
const { request, context, techStack, preferences } = params;
|
|
15
|
+
const systemPrompt = `${GENERATE_FRONTEND_PROMPT}
|
|
16
|
+
|
|
17
|
+
${techStack ? `TECH STACK: ${techStack}` : ""}
|
|
18
|
+
${preferences ? `STYLE PREFERENCES: ${preferences}` : ""}`.trim();
|
|
19
|
+
const userPrompt = context
|
|
20
|
+
? `PROJECT CONTEXT (match this style):
|
|
21
|
+
${context}
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
REQUEST:
|
|
26
|
+
${request}`
|
|
27
|
+
: request;
|
|
28
|
+
const result = await generateWithGemini(systemPrompt, userPrompt);
|
|
29
|
+
return {
|
|
30
|
+
content: [{ type: "text", text: result }],
|
|
31
|
+
};
|
|
32
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const improveFrontendSchema: {
|
|
3
|
+
code: z.ZodString;
|
|
4
|
+
feedback: z.ZodString;
|
|
5
|
+
context: z.ZodOptional<z.ZodString>;
|
|
6
|
+
};
|
|
7
|
+
export declare function improveFrontend(params: {
|
|
8
|
+
code: string;
|
|
9
|
+
feedback: string;
|
|
10
|
+
context?: string;
|
|
11
|
+
}): Promise<{
|
|
12
|
+
content: {
|
|
13
|
+
type: "text";
|
|
14
|
+
text: string;
|
|
15
|
+
}[];
|
|
16
|
+
}>;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { generateWithGemini } from "../lib/gemini.js";
|
|
3
|
+
import { IMPROVE_FRONTEND_PROMPT } from "../prompts/system.js";
|
|
4
|
+
export const improveFrontendSchema = {
|
|
5
|
+
code: z.string().describe("Current frontend code to improve"),
|
|
6
|
+
feedback: z.string().describe("What to improve or change"),
|
|
7
|
+
context: z.string().optional().describe("Additional context (other components for consistency)"),
|
|
8
|
+
};
|
|
9
|
+
export async function improveFrontend(params) {
|
|
10
|
+
const { code, feedback, context } = params;
|
|
11
|
+
const userPrompt = `CURRENT CODE:
|
|
12
|
+
${code}
|
|
13
|
+
|
|
14
|
+
${context ? `CONTEXT:\n${context}\n` : ""}
|
|
15
|
+
FEEDBACK / REQUESTED IMPROVEMENTS:
|
|
16
|
+
${feedback}`;
|
|
17
|
+
const result = await generateWithGemini(IMPROVE_FRONTEND_PROMPT, userPrompt);
|
|
18
|
+
return {
|
|
19
|
+
content: [{ type: "text", text: result }],
|
|
20
|
+
};
|
|
21
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const suggestDesignSchema: {
|
|
3
|
+
description: z.ZodString;
|
|
4
|
+
currentApproach: z.ZodOptional<z.ZodString>;
|
|
5
|
+
};
|
|
6
|
+
export declare function suggestDesign(params: {
|
|
7
|
+
description: string;
|
|
8
|
+
currentApproach?: string;
|
|
9
|
+
}): Promise<{
|
|
10
|
+
content: {
|
|
11
|
+
type: "text";
|
|
12
|
+
text: string;
|
|
13
|
+
}[];
|
|
14
|
+
}>;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { generateWithGemini } from "../lib/gemini.js";
|
|
3
|
+
import { SUGGEST_DESIGN_PROMPT } from "../prompts/system.js";
|
|
4
|
+
export const suggestDesignSchema = {
|
|
5
|
+
description: z.string().describe("Description of the component/page you want suggestions for"),
|
|
6
|
+
currentApproach: z.string().optional().describe("Current approach or constraints to consider"),
|
|
7
|
+
};
|
|
8
|
+
export async function suggestDesign(params) {
|
|
9
|
+
const { description, currentApproach } = params;
|
|
10
|
+
const userPrompt = currentApproach
|
|
11
|
+
? `DESCRIPTION: ${description}\n\nCURRENT APPROACH: ${currentApproach}`
|
|
12
|
+
: description;
|
|
13
|
+
const result = await generateWithGemini(SUGGEST_DESIGN_PROMPT, userPrompt);
|
|
14
|
+
return {
|
|
15
|
+
content: [{ type: "text", text: result }],
|
|
16
|
+
};
|
|
17
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "gemini-design-mcp",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "MCP server that uses Gemini 3 Pro for frontend/design code generation",
|
|
5
|
+
"main": "build/index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"gemini-design-mcp": "./build/index.js"
|
|
8
|
+
},
|
|
9
|
+
"type": "module",
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"dev": "tsc --watch",
|
|
13
|
+
"start": "node build/index.js",
|
|
14
|
+
"prepublishOnly": "npm run build"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"mcp",
|
|
18
|
+
"gemini",
|
|
19
|
+
"design",
|
|
20
|
+
"frontend",
|
|
21
|
+
"ai",
|
|
22
|
+
"model-context-protocol",
|
|
23
|
+
"claude",
|
|
24
|
+
"codex"
|
|
25
|
+
],
|
|
26
|
+
"author": "",
|
|
27
|
+
"license": "MIT",
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
30
|
+
"@google/genai": "^1.33.0",
|
|
31
|
+
"zod": "^3.23.0"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@types/node": "^20.0.0",
|
|
35
|
+
"typescript": "^5.0.0"
|
|
36
|
+
},
|
|
37
|
+
"engines": {
|
|
38
|
+
"node": ">=18.0.0"
|
|
39
|
+
},
|
|
40
|
+
"repository": {
|
|
41
|
+
"type": "git",
|
|
42
|
+
"url": ""
|
|
43
|
+
},
|
|
44
|
+
"files": [
|
|
45
|
+
"build",
|
|
46
|
+
"README.md"
|
|
47
|
+
]
|
|
48
|
+
}
|