flowbite-mcp 1.0.0 → 1.1.1
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 +73 -61
- package/build/index.js +358 -15
- package/data/overview.md +12 -0
- package/package.json +2 -3
package/README.md
CHANGED
|
@@ -12,20 +12,24 @@
|
|
|
12
12
|
<a href="https://flowbite.com/docs/getting-started/license/"><img src="https://img.shields.io/badge/license-MIT-blue" alt="License"></a>
|
|
13
13
|
</p>
|
|
14
14
|
|
|
15
|
+
[](https://cursor.com/en-US/install-mcp?name=flowbite&config=eyJlbnYiOnsiRklHTUFfQUNDRVNTX1RPS0VOIjoiWU9VUl9QRVJTT05BTF9GSUdNQV9BQ0NFU1NfVE9LRU4ifSwiY29tbWFuZCI6Im5weCAteSBmbG93Yml0ZS1tY3AifQ%3D%3D)
|
|
16
|
+
|
|
15
17
|
An MCP server that enables AI assistants to access the [Flowbite](https://flowbite.com/) library of Tailwind CSS components—including UI elements, forms, typography, and plugins—while offering an intelligent theme generator for creating custom branded designs within AI-driven development environments.
|
|
16
18
|
|
|
17
19
|
## MCP Features
|
|
18
20
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
-
|
|
22
|
-
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
-
|
|
27
|
-
|
|
28
|
-
|
|
21
|
+
### Tools:
|
|
22
|
+
|
|
23
|
+
- **🎨 [NEW] Figma to code** - Copy the Figma node url and generate code ([video demo](https://x.com/zoltanszogyenyi/status/1996953610966405547))
|
|
24
|
+
- **🎯 Theme file generator** - Create custom branded themes from any branded hex color
|
|
25
|
+
|
|
26
|
+
### Resources:
|
|
27
|
+
|
|
28
|
+
- **📦 60+ UI components** - Complete access to the [Flowbite UI components](https://flowbite.com/docs/getting-started/introduction/)
|
|
29
|
+
### Server:
|
|
30
|
+
|
|
31
|
+
- **🌐 Dual transport support** - Standard I/O (stdio) for CLI or HTTP Streamable for server deployments
|
|
32
|
+
- **⚡ Production ready** - Docker support with health checks and monitoring
|
|
29
33
|
|
|
30
34
|
## Quickstart
|
|
31
35
|
|
|
@@ -44,7 +48,7 @@ npx flowbite-mcp --help
|
|
|
44
48
|
npx flowbite-mcp --mode http --port 3000
|
|
45
49
|
```
|
|
46
50
|
|
|
47
|
-
## Transport Modes
|
|
51
|
+
## Local Transport Modes
|
|
48
52
|
|
|
49
53
|
### Standard I/O (stdio)
|
|
50
54
|
|
|
@@ -54,17 +58,22 @@ The default mode for local development and CLI integrations:
|
|
|
54
58
|
# Start in stdio mode (default)
|
|
55
59
|
node build/index.js
|
|
56
60
|
|
|
57
|
-
# Configure in
|
|
61
|
+
# Configure in MCP client (ie. Cursor, Windsurf, Claude)
|
|
58
62
|
{
|
|
59
63
|
"mcpServers": {
|
|
60
64
|
"flowbite": {
|
|
61
65
|
"command": "node",
|
|
62
|
-
"args": ["/path/to/flowbite-mcp/build/index.js"]
|
|
66
|
+
"args": ["/path/to/flowbite-mcp/build/index.js"],
|
|
67
|
+
"env": {
|
|
68
|
+
"FIGMA_ACCESS_TOKEN": "YOUR_PERSONAL_FIGMA_ACCESS_TOKEN"
|
|
69
|
+
}
|
|
63
70
|
}
|
|
64
71
|
}
|
|
65
72
|
}
|
|
66
73
|
```
|
|
67
74
|
|
|
75
|
+
Learn how to get the [Figma personal access token](https://help.figma.com/hc/en-us/articles/8085703771159-Manage-personal-access-tokens) to enable the Figma to code generation tool.
|
|
76
|
+
|
|
68
77
|
### HTTP server
|
|
69
78
|
|
|
70
79
|
HTTP-based transport for production and multi-client scenarios:
|
|
@@ -77,6 +86,17 @@ This will make the MCP server available at 'http://localhost:3000/mcp'.
|
|
|
77
86
|
|
|
78
87
|
### Environment variables
|
|
79
88
|
|
|
89
|
+
Currently you only need the Figma personal access token if you want to enable the [Figma to code generation tool](https://help.figma.com/hc/en-us/articles/8085703771159-Manage-personal-access-tokens). You set this variable in your MCP client configuration file.
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
// other options
|
|
93
|
+
"env": {
|
|
94
|
+
"FIGMA_ACCESS_TOKEN": "YOUR_PERSONAL_FIGMA_ACCESS_TOKEN"
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Hosting variables
|
|
99
|
+
|
|
80
100
|
Configure the server behavior with these environment variables:
|
|
81
101
|
|
|
82
102
|
```bash
|
|
@@ -93,48 +113,23 @@ MCP_HOST=0.0.0.0
|
|
|
93
113
|
MCP_CORS_ORIGINS=http://localhost:3000,https://myapp.com
|
|
94
114
|
```
|
|
95
115
|
|
|
96
|
-
##
|
|
97
|
-
|
|
98
|
-
Make sure that you have the following installed:
|
|
99
|
-
|
|
100
|
-
- Node.js 16+ installed
|
|
101
|
-
- Tailwind CSS v4+ (for generated themes)
|
|
102
|
-
|
|
103
|
-
### Local development
|
|
104
|
-
|
|
105
|
-
```bash
|
|
106
|
-
# Clone the repository
|
|
107
|
-
git clone https://github.com/themesberg/flowbite-mcp.git
|
|
108
|
-
cd flowbite-mcp
|
|
109
|
-
|
|
110
|
-
# Install dependencies
|
|
111
|
-
npm install
|
|
112
|
-
|
|
113
|
-
# Build the project
|
|
114
|
-
npm run build
|
|
115
|
-
|
|
116
|
-
# Run in stdio mode (for Claude Desktop, Cursor)
|
|
117
|
-
npm start
|
|
118
|
-
|
|
119
|
-
# Run inspector
|
|
120
|
-
npm run start inspector
|
|
121
|
-
|
|
122
|
-
# Run in HTTP server mode (for production/multi-client)
|
|
123
|
-
MCP_TRANSPORT_MODE=http npm start
|
|
124
|
-
```
|
|
116
|
+
## Integration examples
|
|
125
117
|
|
|
126
|
-
|
|
118
|
+
Use the following configuration examples to install the Flowbite MCP server in popular clients such as Cursor, Claude, Windsurf, and more.
|
|
127
119
|
|
|
128
120
|
### Claude desktop
|
|
129
121
|
|
|
130
|
-
|
|
122
|
+
Update the `claude_desktop_config.json` file and add the following configuration:
|
|
131
123
|
|
|
132
124
|
```json
|
|
133
125
|
{
|
|
134
126
|
"mcpServers": {
|
|
135
127
|
"flowbite": {
|
|
136
128
|
"command": "npx",
|
|
137
|
-
"args": ["-y", "flowbite-mcp"]
|
|
129
|
+
"args": ["-y", "flowbite-mcp"],
|
|
130
|
+
"env": {
|
|
131
|
+
"FIGMA_ACCESS_TOKEN": "YOUR_PERSONAL_FIGMA_ACCESS_TOKEN"
|
|
132
|
+
}
|
|
138
133
|
}
|
|
139
134
|
}
|
|
140
135
|
}
|
|
@@ -142,52 +137,69 @@ MCP_TRANSPORT_MODE=http npm start
|
|
|
142
137
|
|
|
143
138
|
### Cursor editor
|
|
144
139
|
|
|
145
|
-
|
|
140
|
+
[](https://cursor.com/en-US/install-mcp?name=flowbite&config=eyJlbnYiOnsiRklHTUFfQUNDRVNTX1RPS0VOIjoiWU9VUl9QRVJTT05BTF9GSUdNQV9BQ0NFU1NfVE9LRU4ifSwiY29tbWFuZCI6Im5weCAteSBmbG93Yml0ZS1tY3AifQ%3D%3D)
|
|
141
|
+
|
|
142
|
+
Update the `mcp.json` file and add the following configuration:
|
|
146
143
|
|
|
147
144
|
```json
|
|
148
145
|
{
|
|
149
146
|
"mcpServers": {
|
|
150
147
|
"flowbite": {
|
|
151
148
|
"command": "npx",
|
|
152
|
-
"args": ["-y", "flowbite-mcp"]
|
|
149
|
+
"args": ["-y", "flowbite-mcp"],
|
|
150
|
+
"env": {
|
|
151
|
+
"FIGMA_ACCESS_TOKEN": "YOUR_PERSONAL_FIGMA_ACCESS_TOKEN"
|
|
152
|
+
}
|
|
153
153
|
}
|
|
154
154
|
}
|
|
155
155
|
}
|
|
156
156
|
```
|
|
157
157
|
|
|
158
|
-
###
|
|
158
|
+
### Windsurf editor
|
|
159
|
+
|
|
160
|
+
Update the `mcp_config.json` file and add the following configuration:
|
|
159
161
|
|
|
160
162
|
```json
|
|
161
163
|
{
|
|
162
|
-
"mcpServers":
|
|
163
|
-
{
|
|
164
|
-
"name": "flowbite",
|
|
164
|
+
"mcpServers": {
|
|
165
|
+
"flowbite": {
|
|
165
166
|
"command": "npx",
|
|
166
|
-
"args": ["-y", "flowbite-mcp"]
|
|
167
|
+
"args": ["-y", "flowbite-mcp"],
|
|
168
|
+
"env": {
|
|
169
|
+
"FIGMA_ACCESS_TOKEN": "YOUR_PERSONAL_FIGMA_ACCESS_TOKEN"
|
|
170
|
+
}
|
|
167
171
|
}
|
|
168
|
-
|
|
172
|
+
}
|
|
169
173
|
}
|
|
170
174
|
```
|
|
171
175
|
|
|
172
|
-
###
|
|
176
|
+
### Glama.ai
|
|
177
|
+
|
|
178
|
+
<a href="https://glama.ai/mcp/servers/@zoltanszogyenyi/flowbite-mcp">
|
|
179
|
+
<img width="380" height="200" src="https://glama.ai/mcp/servers/@zoltanszogyenyi/flowbite-mcp/badge" />
|
|
180
|
+
</a>
|
|
173
181
|
|
|
174
|
-
|
|
182
|
+
### Local development
|
|
175
183
|
|
|
176
184
|
```bash
|
|
185
|
+
# Clone the repository
|
|
186
|
+
git clone https://github.com/themesberg/flowbite-mcp.git
|
|
187
|
+
cd flowbite-mcp
|
|
188
|
+
|
|
177
189
|
# Install dependencies
|
|
178
190
|
npm install
|
|
179
191
|
|
|
180
192
|
# Build the project
|
|
181
193
|
npm run build
|
|
182
194
|
|
|
183
|
-
# Run in stdio mode
|
|
195
|
+
# Run in stdio mode (for Claude Desktop, Cursor)
|
|
184
196
|
npm start
|
|
185
197
|
|
|
186
|
-
# Run
|
|
187
|
-
npm run start
|
|
198
|
+
# Run inspector
|
|
199
|
+
npm run start inspector
|
|
188
200
|
|
|
189
|
-
#
|
|
190
|
-
npm
|
|
201
|
+
# Run in HTTP server mode (for production/multi-client)
|
|
202
|
+
MCP_TRANSPORT_MODE=http npm start
|
|
191
203
|
```
|
|
192
204
|
|
|
193
205
|
### Production deployment (HTTP Mode)
|
|
@@ -318,7 +330,7 @@ This project is licensed under the MIT License License - see the [LICENSE](LICEN
|
|
|
318
330
|
- [x] AI-powered theme generator
|
|
319
331
|
- [x] Dual transport support (stdio + HTTP)
|
|
320
332
|
- [ ] Flowbite Pro blocks integration (with license authentication)
|
|
321
|
-
- [
|
|
333
|
+
- [x] Figma to code conversion tool
|
|
322
334
|
- [ ] Enhanced theme customization options
|
|
323
335
|
- [ ] Component search and filtering
|
|
324
336
|
- [ ] Real-time component preview generation
|
package/build/index.js
CHANGED
|
@@ -551,6 +551,22 @@ const getDataPath = (relativePath) => {
|
|
|
551
551
|
};
|
|
552
552
|
// Function to setup all resources and tools
|
|
553
553
|
const setupServer = (server) => {
|
|
554
|
+
server.resource("flowbite_overview", "flowbite://overview/file", {
|
|
555
|
+
description: "Overview of the Flowbite MCP server and its capabilities.",
|
|
556
|
+
title: "Flowbite Overview",
|
|
557
|
+
mimeType: "text/markdown",
|
|
558
|
+
}, async (uri) => {
|
|
559
|
+
const overviewContent = readFileSync(getDataPath("overview.md"), "utf-8");
|
|
560
|
+
return {
|
|
561
|
+
contents: [
|
|
562
|
+
{
|
|
563
|
+
uri: uri.href,
|
|
564
|
+
text: overviewContent,
|
|
565
|
+
mimeType: "text/markdown",
|
|
566
|
+
},
|
|
567
|
+
],
|
|
568
|
+
};
|
|
569
|
+
});
|
|
554
570
|
server.resource("flowbite_theme", "flowbite://theme/file", {
|
|
555
571
|
description: "The theme file that sets the Tailwind CSS variables to make UI look unique for every website.",
|
|
556
572
|
title: "Flowbite Theme",
|
|
@@ -615,41 +631,368 @@ const setupServer = (server) => {
|
|
|
615
631
|
};
|
|
616
632
|
});
|
|
617
633
|
});
|
|
618
|
-
server.tool('convert-figma-to-code', '
|
|
619
|
-
figmaNodeUrl: z.string().describe('The URL of the Figma node
|
|
634
|
+
server.tool('convert-figma-to-code', 'Fetches a Figma node and its rendered image from the Figma API and converts it to a code block. Requires FIGMA_ACCESS_TOKEN environment variable to be set.', {
|
|
635
|
+
figmaNodeUrl: z.string().describe('The URL of the Figma node (e.g., https://www.figma.com/design/fileKey/fileName?node-id=123-456)'),
|
|
620
636
|
}, async ({ figmaNodeUrl }) => {
|
|
621
637
|
try {
|
|
638
|
+
// Get Figma access token from environment variables
|
|
639
|
+
const figmaAccessToken = process.env.FIGMA_ACCESS_TOKEN;
|
|
640
|
+
if (!figmaAccessToken) {
|
|
641
|
+
return {
|
|
642
|
+
content: [
|
|
643
|
+
{
|
|
644
|
+
type: 'text',
|
|
645
|
+
text: `Error: FIGMA_ACCESS_TOKEN environment variable is not set.
|
|
646
|
+
|
|
647
|
+
To use this tool, you need to:
|
|
648
|
+
1. Generate a Personal Access Token from Figma:
|
|
649
|
+
- Go to Figma > Settings > Account > Personal access tokens
|
|
650
|
+
- Generate a new token
|
|
651
|
+
2. Set the FIGMA_ACCESS_TOKEN environment variable with your token
|
|
652
|
+
|
|
653
|
+
Example for your MCP config:
|
|
654
|
+
{
|
|
655
|
+
"env": {
|
|
656
|
+
"FIGMA_ACCESS_TOKEN": "your-personal-access-token"
|
|
657
|
+
}
|
|
658
|
+
}`,
|
|
659
|
+
},
|
|
660
|
+
],
|
|
661
|
+
};
|
|
662
|
+
}
|
|
663
|
+
// Parse Figma URL to extract fileKey and nodeId
|
|
664
|
+
// URL formats:
|
|
665
|
+
// https://www.figma.com/file/{fileKey}/{fileName}?node-id={nodeId}
|
|
666
|
+
// https://www.figma.com/design/{fileKey}/{fileName}?node-id={nodeId}
|
|
667
|
+
const urlPattern = /figma\.com\/(file|design)\/([a-zA-Z0-9]+)(?:\/[^?]*)?(?:\?.*node-id=([^&]+))?/;
|
|
668
|
+
const match = figmaNodeUrl.match(urlPattern);
|
|
669
|
+
if (!match) {
|
|
670
|
+
return {
|
|
671
|
+
content: [
|
|
672
|
+
{
|
|
673
|
+
type: 'text',
|
|
674
|
+
text: `Error: Invalid Figma URL format.
|
|
675
|
+
|
|
676
|
+
Expected formats:
|
|
677
|
+
- https://www.figma.com/file/{fileKey}/{fileName}?node-id={nodeId}
|
|
678
|
+
- https://www.figma.com/design/{fileKey}/{fileName}?node-id={nodeId}
|
|
679
|
+
|
|
680
|
+
Provided URL: ${figmaNodeUrl}`,
|
|
681
|
+
},
|
|
682
|
+
],
|
|
683
|
+
};
|
|
684
|
+
}
|
|
685
|
+
const fileKey = match[2];
|
|
686
|
+
const nodeId = match[3] ? decodeURIComponent(match[3]) : null;
|
|
687
|
+
if (!nodeId) {
|
|
688
|
+
return {
|
|
689
|
+
content: [
|
|
690
|
+
{
|
|
691
|
+
type: 'text',
|
|
692
|
+
text: `Error: No node-id found in the Figma URL.
|
|
693
|
+
|
|
694
|
+
Please make sure your URL includes a node-id parameter.
|
|
695
|
+
Example: https://www.figma.com/design/${fileKey}/FileName?node-id=123-456
|
|
696
|
+
|
|
697
|
+
Provided URL: ${figmaNodeUrl}`,
|
|
698
|
+
},
|
|
699
|
+
],
|
|
700
|
+
};
|
|
701
|
+
}
|
|
702
|
+
// API headers
|
|
703
|
+
const headers = {
|
|
704
|
+
'X-Figma-Token': figmaAccessToken,
|
|
705
|
+
};
|
|
706
|
+
// Fetch node data
|
|
707
|
+
const nodeApiUrl = `https://api.figma.com/v1/files/${fileKey}/nodes?ids=${encodeURIComponent(nodeId)}`;
|
|
708
|
+
const nodeResponse = await fetch(nodeApiUrl, { headers });
|
|
709
|
+
if (!nodeResponse.ok) {
|
|
710
|
+
const errorText = await nodeResponse.text();
|
|
711
|
+
return {
|
|
712
|
+
content: [
|
|
713
|
+
{
|
|
714
|
+
type: 'text',
|
|
715
|
+
text: `Error fetching Figma node data:
|
|
716
|
+
Status: ${nodeResponse.status} ${nodeResponse.statusText}
|
|
717
|
+
Response: ${errorText}
|
|
718
|
+
|
|
719
|
+
API URL: ${nodeApiUrl}`,
|
|
720
|
+
},
|
|
721
|
+
],
|
|
722
|
+
};
|
|
723
|
+
}
|
|
724
|
+
const nodeData = await nodeResponse.json();
|
|
725
|
+
// Fetch node image
|
|
726
|
+
const imageApiUrl = `https://api.figma.com/v1/images/${fileKey}?ids=${encodeURIComponent(nodeId)}&scale=2`;
|
|
727
|
+
const imageResponse = await fetch(imageApiUrl, { headers });
|
|
728
|
+
if (!imageResponse.ok) {
|
|
729
|
+
const errorText = await imageResponse.text();
|
|
730
|
+
return {
|
|
731
|
+
content: [
|
|
732
|
+
{
|
|
733
|
+
type: 'text',
|
|
734
|
+
text: `Error fetching Figma node image:
|
|
735
|
+
Status: ${imageResponse.status} ${imageResponse.statusText}
|
|
736
|
+
Response: ${errorText}
|
|
737
|
+
|
|
738
|
+
API URL: ${imageApiUrl}
|
|
739
|
+
Node data was retrieved successfully.`,
|
|
740
|
+
},
|
|
741
|
+
],
|
|
742
|
+
};
|
|
743
|
+
}
|
|
744
|
+
const imageData = await imageResponse.json();
|
|
745
|
+
// Extract the image URL from the response
|
|
746
|
+
const imageUrl = imageData.images?.[nodeId] || imageData.images?.[Object.keys(imageData.images)[0]] || null;
|
|
747
|
+
// Helper function to simplify Figma node data - extracts only essential info for code conversion
|
|
748
|
+
const simplifyNode = (node) => {
|
|
749
|
+
if (!node)
|
|
750
|
+
return null;
|
|
751
|
+
const simplified = {
|
|
752
|
+
type: node.type,
|
|
753
|
+
name: node.name,
|
|
754
|
+
};
|
|
755
|
+
// Add dimensions if available
|
|
756
|
+
if (node.absoluteBoundingBox) {
|
|
757
|
+
simplified.size = {
|
|
758
|
+
width: Math.round(node.absoluteBoundingBox.width),
|
|
759
|
+
height: Math.round(node.absoluteBoundingBox.height),
|
|
760
|
+
};
|
|
761
|
+
}
|
|
762
|
+
// Add layout info for frames
|
|
763
|
+
if (node.layoutMode) {
|
|
764
|
+
simplified.layout = {
|
|
765
|
+
mode: node.layoutMode, // HORIZONTAL, VERTICAL, NONE
|
|
766
|
+
padding: node.paddingLeft || node.paddingTop ? {
|
|
767
|
+
top: node.paddingTop,
|
|
768
|
+
right: node.paddingRight,
|
|
769
|
+
bottom: node.paddingBottom,
|
|
770
|
+
left: node.paddingLeft,
|
|
771
|
+
} : undefined,
|
|
772
|
+
gap: node.itemSpacing,
|
|
773
|
+
align: node.primaryAxisAlignItems,
|
|
774
|
+
justify: node.counterAxisAlignItems,
|
|
775
|
+
};
|
|
776
|
+
}
|
|
777
|
+
// Add corner radius
|
|
778
|
+
if (node.cornerRadius) {
|
|
779
|
+
simplified.borderRadius = node.cornerRadius;
|
|
780
|
+
}
|
|
781
|
+
else if (node.rectangleCornerRadii) {
|
|
782
|
+
simplified.borderRadius = node.rectangleCornerRadii;
|
|
783
|
+
}
|
|
784
|
+
// Add fills (background colors)
|
|
785
|
+
if (node.fills && node.fills.length > 0) {
|
|
786
|
+
simplified.fills = node.fills
|
|
787
|
+
.filter((fill) => fill.visible !== false)
|
|
788
|
+
.map((fill) => ({
|
|
789
|
+
type: fill.type,
|
|
790
|
+
color: fill.color ? {
|
|
791
|
+
r: Math.round(fill.color.r * 255),
|
|
792
|
+
g: Math.round(fill.color.g * 255),
|
|
793
|
+
b: Math.round(fill.color.b * 255),
|
|
794
|
+
a: fill.color.a !== undefined ? Math.round(fill.color.a * 100) / 100 : 1,
|
|
795
|
+
} : undefined,
|
|
796
|
+
opacity: fill.opacity,
|
|
797
|
+
}));
|
|
798
|
+
}
|
|
799
|
+
// Add strokes (borders)
|
|
800
|
+
if (node.strokes && node.strokes.length > 0) {
|
|
801
|
+
simplified.strokes = node.strokes
|
|
802
|
+
.filter((stroke) => stroke.visible !== false)
|
|
803
|
+
.map((stroke) => ({
|
|
804
|
+
type: stroke.type,
|
|
805
|
+
color: stroke.color ? {
|
|
806
|
+
r: Math.round(stroke.color.r * 255),
|
|
807
|
+
g: Math.round(stroke.color.g * 255),
|
|
808
|
+
b: Math.round(stroke.color.b * 255),
|
|
809
|
+
} : undefined,
|
|
810
|
+
}));
|
|
811
|
+
if (node.strokeWeight) {
|
|
812
|
+
simplified.strokeWeight = node.strokeWeight;
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
// Add effects (shadows, blur)
|
|
816
|
+
if (node.effects && node.effects.length > 0) {
|
|
817
|
+
simplified.effects = node.effects
|
|
818
|
+
.filter((effect) => effect.visible !== false)
|
|
819
|
+
.map((effect) => ({
|
|
820
|
+
type: effect.type,
|
|
821
|
+
radius: effect.radius,
|
|
822
|
+
offset: effect.offset,
|
|
823
|
+
color: effect.color ? {
|
|
824
|
+
r: Math.round(effect.color.r * 255),
|
|
825
|
+
g: Math.round(effect.color.g * 255),
|
|
826
|
+
b: Math.round(effect.color.b * 255),
|
|
827
|
+
a: Math.round(effect.color.a * 100) / 100,
|
|
828
|
+
} : undefined,
|
|
829
|
+
}));
|
|
830
|
+
}
|
|
831
|
+
// Add text-specific properties
|
|
832
|
+
if (node.type === 'TEXT') {
|
|
833
|
+
simplified.text = node.characters;
|
|
834
|
+
if (node.style) {
|
|
835
|
+
simplified.textStyle = {
|
|
836
|
+
fontFamily: node.style.fontFamily,
|
|
837
|
+
fontWeight: node.style.fontWeight,
|
|
838
|
+
fontSize: node.style.fontSize,
|
|
839
|
+
lineHeight: node.style.lineHeightPx,
|
|
840
|
+
letterSpacing: node.style.letterSpacing,
|
|
841
|
+
textAlign: node.style.textAlignHorizontal,
|
|
842
|
+
};
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
// Recursively process children
|
|
846
|
+
if (node.children && node.children.length > 0) {
|
|
847
|
+
simplified.children = node.children.map(simplifyNode).filter(Boolean);
|
|
848
|
+
}
|
|
849
|
+
return simplified;
|
|
850
|
+
};
|
|
851
|
+
// Simplify the node data
|
|
852
|
+
const simplifiedNodeData = nodeData.nodes ?
|
|
853
|
+
Object.keys(nodeData.nodes).reduce((acc, key) => {
|
|
854
|
+
const node = nodeData.nodes[key];
|
|
855
|
+
acc[key] = {
|
|
856
|
+
document: simplifyNode(node.document),
|
|
857
|
+
components: node.components ? Object.keys(node.components).length + ' components' : undefined,
|
|
858
|
+
styles: node.styles ? Object.keys(node.styles).length + ' styles' : undefined,
|
|
859
|
+
};
|
|
860
|
+
return acc;
|
|
861
|
+
}, {})
|
|
862
|
+
: simplifyNode(nodeData);
|
|
863
|
+
// Return combined result with AI instructions
|
|
622
864
|
return {
|
|
623
865
|
content: [
|
|
624
866
|
{
|
|
625
867
|
type: 'text',
|
|
626
|
-
text:
|
|
868
|
+
text: `# Figma to Code Conversion Task
|
|
869
|
+
|
|
870
|
+
## Instructions for AI
|
|
871
|
+
|
|
872
|
+
You have received a Figma design that needs to be converted to code. Follow these steps:
|
|
873
|
+
|
|
874
|
+
### Step 1: Analyze the Design
|
|
875
|
+
Look at the rendered image below and the node structure data to understand:
|
|
876
|
+
- The layout and component hierarchy
|
|
877
|
+
- Colors, typography, and spacing used
|
|
878
|
+
- Interactive elements (buttons, inputs, links, etc.)
|
|
879
|
+
- Component patterns that match Flowbite components
|
|
880
|
+
|
|
881
|
+
### Step 2: Use Flowbite MCP Resources
|
|
882
|
+
Before writing code, fetch the relevant Flowbite component documentation using the MCP resources. Based on the design, you may need:
|
|
883
|
+
|
|
884
|
+
**Common Components to Check:**
|
|
885
|
+
- \`flowbite://components/buttons\` - For button styles
|
|
886
|
+
- \`flowbite://components/card\` - For card layouts
|
|
887
|
+
- \`flowbite://components/navbar\` - For navigation bars
|
|
888
|
+
- \`flowbite://components/modal\` - For modal dialogs
|
|
889
|
+
- \`flowbite://components/forms\` - For form layouts
|
|
890
|
+
- \`flowbite://forms/input-field\` - For input fields
|
|
891
|
+
- \`flowbite://components/avatar\` - For user avatars
|
|
892
|
+
- \`flowbite://components/badge\` - For badges/tags
|
|
893
|
+
- \`flowbite://components/tables\` - For data tables
|
|
894
|
+
- \`flowbite://components/tabs\` - For tab navigation
|
|
895
|
+
- \`flowbite://components/dropdowns\` - For dropdown menus
|
|
896
|
+
- \`flowbite://components/sidebar\` - For sidebar navigation
|
|
897
|
+
- \`flowbite://components/footer\` - For footer sections
|
|
898
|
+
- \`flowbite://typography/headings\` - For heading styles
|
|
899
|
+
- \`flowbite://typography/text\` - For text styles
|
|
900
|
+
|
|
901
|
+
### Step 3: Write the Code
|
|
902
|
+
Generate clean, semantic HTML with Tailwind CSS classes following these guidelines:
|
|
903
|
+
|
|
904
|
+
1. **Use Flowbite Components**: Match the Figma design to Flowbite components whenever possible
|
|
905
|
+
2. **Tailwind CSS Classes**: Use Tailwind utility classes for styling
|
|
906
|
+
3. **Responsive Design**: Include responsive breakpoints (sm:, md:, lg:, xl:)
|
|
907
|
+
4. **Semantic HTML**: Use proper HTML5 semantic elements
|
|
908
|
+
5. **Accessibility**: Include ARIA attributes and proper alt texts
|
|
909
|
+
6. **Match Colors**: Use Flowbite variables and secondly Tailwind color classes that best match the Figma design colors
|
|
910
|
+
7. **Match Spacing**: Use Tailwind spacing utilities (p-*, m-*, gap-*) to match the design
|
|
911
|
+
|
|
912
|
+
### Step 4: Output Format - IMPORTANT
|
|
913
|
+
|
|
914
|
+
**⚠️ ONLY output the component code block - DO NOT include:**
|
|
915
|
+
- \`<!DOCTYPE html>\`
|
|
916
|
+
- \`<html>\`, \`</html>\` tags
|
|
917
|
+
- \`<head>\`, \`</head>\` tags
|
|
918
|
+
- \`<body>\`, \`</body>\` tags
|
|
919
|
+
- \`<link>\` tags (CSS imports)
|
|
920
|
+
- \`<script>\` tags (JS imports)
|
|
921
|
+
- Any meta tags or document structure
|
|
922
|
+
- ':dark' variant classes unless explicitly requested
|
|
923
|
+
|
|
924
|
+
**✅ DO output:**
|
|
925
|
+
- Only the component HTML markup itself
|
|
926
|
+
- The actual UI component code that would go inside a \`<body>\` tag
|
|
927
|
+
- Clean, well-formatted code block with proper indentation
|
|
928
|
+
- Just the reusable component/section code
|
|
929
|
+
- When possible use the "brand" variables from Flowbite instead of hardcoded colors from Tailwind CSS
|
|
930
|
+
|
|
931
|
+
**Example of what to output:**
|
|
932
|
+
\`\`\`html
|
|
933
|
+
<div class="bg-neutral-primary-soft block max-w-sm p-6 border border-default rounded-base shadow-xs">
|
|
934
|
+
<h5 class="mb-3 text-2xl font-semibold tracking-tight text-heading leading-8">Noteworthy technology acquisitions 2021</h5>
|
|
935
|
+
<p class="text-body mb-6">Here are the biggest technology acquisitions of 2025 so far, in reverse chronological order.</p>
|
|
936
|
+
<a href="#" class="inline-flex items-center text-white bg-brand box-border border border-transparent hover:bg-brand-strong focus:ring-4 focus:ring-brand-medium shadow-xs font-medium leading-5 rounded-base text-sm px-4 py-2.5 focus:outline-none">
|
|
937
|
+
Read more
|
|
938
|
+
<svg class="w-4 h-4 ms-1.5 rtl:rotate-180 -me-0.5" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24"><path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 12H5m14 0-4 4m4-4-4-4"/></svg>
|
|
939
|
+
</a>
|
|
940
|
+
</div>
|
|
941
|
+
\`\`\`
|
|
942
|
+
|
|
943
|
+
---
|
|
944
|
+
|
|
945
|
+
## Figma Design Data
|
|
946
|
+
|
|
947
|
+
### File Information
|
|
948
|
+
- **File Key**: ${fileKey}
|
|
949
|
+
- **Node ID**: ${nodeId}
|
|
950
|
+
- **Source URL**: ${figmaNodeUrl}
|
|
951
|
+
|
|
952
|
+
### Rendered Design Image
|
|
953
|
+
${imageUrl ? `
|
|
954
|
+
|
|
955
|
+
<img src="${imageUrl}">
|
|
956
|
+
|
|
957
|
+
**Direct Image URL**: ${imageUrl}` : '⚠️ No image URL available - analyze the node data structure below'}
|
|
958
|
+
|
|
959
|
+
### Node Structure Data (Simplified)
|
|
960
|
+
The following JSON contains the essential Figma node structure for code conversion:
|
|
961
|
+
|
|
962
|
+
\`\`\`json
|
|
963
|
+
${JSON.stringify(simplifiedNodeData, null, 2)}
|
|
964
|
+
\`\`\`
|
|
965
|
+
|
|
966
|
+
---
|
|
967
|
+
|
|
968
|
+
## Now Convert This Design
|
|
969
|
+
|
|
970
|
+
Based on the image and node data above:
|
|
971
|
+
1. Identify the UI components visible in the design
|
|
972
|
+
2. Fetch the relevant Flowbite component documentation from the MCP resources
|
|
973
|
+
3. Generate ONLY the component HTML/Tailwind CSS code (no document wrapper, no \`<html>\`, \`<head>\`, \`<body>\`, \`<link>\`, or \`<script>\` tags)
|
|
974
|
+
4. Ensure the code is production-ready with proper responsiveness and accessibility`,
|
|
627
975
|
},
|
|
628
976
|
],
|
|
629
977
|
};
|
|
630
978
|
}
|
|
631
979
|
catch (error) {
|
|
632
|
-
console.error(`Error
|
|
980
|
+
console.error(`Error fetching Figma node: ${error}`);
|
|
633
981
|
return {
|
|
634
982
|
content: [
|
|
635
983
|
{
|
|
636
984
|
type: 'text',
|
|
637
|
-
text: `Error
|
|
985
|
+
text: `Error fetching Figma node: ${error instanceof Error ? error.message : String(error)}
|
|
986
|
+
|
|
987
|
+
Please check:
|
|
988
|
+
1. Your FIGMA_ACCESS_TOKEN is valid
|
|
989
|
+
2. The Figma URL is correct
|
|
990
|
+
3. You have access to the Figma file`,
|
|
638
991
|
},
|
|
639
992
|
],
|
|
640
993
|
};
|
|
641
994
|
}
|
|
642
995
|
});
|
|
643
|
-
server.tool('get_session', 'gets the session id and context', {}, async ({}) => {
|
|
644
|
-
return {
|
|
645
|
-
content: [
|
|
646
|
-
{
|
|
647
|
-
type: 'text',
|
|
648
|
-
text: `session`,
|
|
649
|
-
},
|
|
650
|
-
],
|
|
651
|
-
};
|
|
652
|
-
});
|
|
653
996
|
server.tool('generate-theme', 'Generates a custom Flowbite theme CSS file based on a brand color (hex format) and user instructions. The AI will intelligently analyze the instructions and customize ALL theme variables (border radius, spacing, colors, typography, etc.) to match the desired aesthetic. This tool creates color shades and variations, adapting the entire theme system to match your brand identity.', {
|
|
654
997
|
brandColor: z.string().describe('The primary brand color in hex format (e.g., #3B82F6, #FF5733). This will be used as the base for generating all brand color variations.'),
|
|
655
998
|
instructions: z.string().describe('Natural language instructions describing the desired theme aesthetic and customizations. The AI will interpret these instructions to modify all relevant theme variables. Examples: "Make it modern and minimalist with soft rounded corners", "Create a luxury feel with gold accents and elegant spacing", "Design for a playful children\'s app with bright colors", "Professional corporate style with subtle borders", etc.'),
|
package/data/overview.md
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Flowbite MCP Server Overview
|
|
2
|
+
|
|
3
|
+
This MCP server provides access to Flowbite's extensive library of Tailwind CSS components and theme generation capabilities.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- resources that have access to the full Flowbite component library including the open source components, plugins, and typography
|
|
8
|
+
- tools to allow the generation of UI components, layouts and the theme file that allow customization
|
|
9
|
+
|
|
10
|
+
## Supporting Flowbite
|
|
11
|
+
|
|
12
|
+
To support the open-source development of Flowbite please consider purchasing the [Pro version of Flowbite](https://flowbite.com/pro/#pricing) to get access to hundreds of premium building blocks, a Figma design system, and other templates like dashboard layouts and marketing websites.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "flowbite-mcp",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"description": "Model Context Protocol server providing AI assistants with access to Flowbite UI components and an intelligent theme generator for Tailwind CSS",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -11,8 +11,7 @@
|
|
|
11
11
|
"build",
|
|
12
12
|
"data",
|
|
13
13
|
"README.md",
|
|
14
|
-
"LICENSE"
|
|
15
|
-
"CHANGELOG.md"
|
|
14
|
+
"LICENSE"
|
|
16
15
|
],
|
|
17
16
|
"publishConfig": {
|
|
18
17
|
"access": "public"
|