flowbite-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.
Files changed (77) hide show
  1. package/LICENSE.md +21 -0
  2. package/README.md +324 -0
  3. package/build/index.js +975 -0
  4. package/build/server-runner.js +228 -0
  5. package/data/components/accordion.md +860 -0
  6. package/data/components/alerts.md +739 -0
  7. package/data/components/avatar.md +178 -0
  8. package/data/components/badge.md +420 -0
  9. package/data/components/banner.md +145 -0
  10. package/data/components/bottom-navigation.md +513 -0
  11. package/data/components/breadcrumb.md +273 -0
  12. package/data/components/button-group.md +410 -0
  13. package/data/components/buttons.md +405 -0
  14. package/data/components/card.md +711 -0
  15. package/data/components/carousel.md +858 -0
  16. package/data/components/chat-bubble.md +1063 -0
  17. package/data/components/clipboard.md +1029 -0
  18. package/data/components/datepicker.md +673 -0
  19. package/data/components/device-mockups.md +152 -0
  20. package/data/components/drawer.md +1353 -0
  21. package/data/components/dropdowns.md +1925 -0
  22. package/data/components/footer.md +299 -0
  23. package/data/components/forms.md +371 -0
  24. package/data/components/gallery.md +322 -0
  25. package/data/components/indicators.md +262 -0
  26. package/data/components/jumbotron.md +213 -0
  27. package/data/components/kbd.md +217 -0
  28. package/data/components/list-group.md +365 -0
  29. package/data/components/mega-menu.md +558 -0
  30. package/data/components/modal.md +1309 -0
  31. package/data/components/navbar.md +1053 -0
  32. package/data/components/pagination.md +472 -0
  33. package/data/components/popover.md +826 -0
  34. package/data/components/progress.md +95 -0
  35. package/data/components/qr-code.md +280 -0
  36. package/data/components/rating.md +323 -0
  37. package/data/components/sidebar.md +1067 -0
  38. package/data/components/skeleton.md +221 -0
  39. package/data/components/speed-dial.md +1270 -0
  40. package/data/components/spinner.md +222 -0
  41. package/data/components/stepper.md +271 -0
  42. package/data/components/tables.md +3127 -0
  43. package/data/components/tabs.md +808 -0
  44. package/data/components/timeline.md +304 -0
  45. package/data/components/toast.md +341 -0
  46. package/data/components/tooltips.md +524 -0
  47. package/data/components/typography.md +269 -0
  48. package/data/components/video.md +95 -0
  49. package/data/forms/checkbox.md +375 -0
  50. package/data/forms/file-input.md +98 -0
  51. package/data/forms/floating-label.md +185 -0
  52. package/data/forms/input-field.md +222 -0
  53. package/data/forms/number-input.md +1099 -0
  54. package/data/forms/phone-input.md +577 -0
  55. package/data/forms/radio.md +315 -0
  56. package/data/forms/range.md +83 -0
  57. package/data/forms/search-input.md +280 -0
  58. package/data/forms/select.md +259 -0
  59. package/data/forms/textarea.md +155 -0
  60. package/data/forms/timepicker.md +732 -0
  61. package/data/forms/toggle.md +176 -0
  62. package/data/plugins/charts.md +2683 -0
  63. package/data/plugins/datatables.md +1922 -0
  64. package/data/plugins/datepicker.md +5 -0
  65. package/data/plugins/wysiwyg.md +2377 -0
  66. package/data/quickstart.md +169 -0
  67. package/data/theme.md +231 -0
  68. package/data/toc.md +79 -0
  69. package/data/typography/blockquote.md +182 -0
  70. package/data/typography/headings.md +174 -0
  71. package/data/typography/hr.md +74 -0
  72. package/data/typography/images.md +168 -0
  73. package/data/typography/links.md +118 -0
  74. package/data/typography/lists.md +387 -0
  75. package/data/typography/paragraphs.md +186 -0
  76. package/data/typography/text.md +249 -0
  77. package/package.json +71 -0
@@ -0,0 +1,228 @@
1
+ import express from "express";
2
+ import { randomUUID } from "node:crypto";
3
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
4
+ import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
5
+ import { InMemoryEventStore } from "@modelcontextprotocol/sdk/examples/shared/inMemoryEventStore.js";
6
+ import { isInitializeRequest } from "@modelcontextprotocol/sdk/types.js";
7
+ const PORT = process.env.PORT || 3000;
8
+ export const ExpressHttpStreamableMcpServer = (options, setupCb) => {
9
+ const server = new McpServer({
10
+ name: options.name,
11
+ version: "1.0.0",
12
+ }, {
13
+ capabilities: {
14
+ logging: {},
15
+ tools: {
16
+ listChanged: false
17
+ }
18
+ }
19
+ });
20
+ setupCb(server);
21
+ const app = express();
22
+ app.use(express.json());
23
+ // Map to store transports by session ID
24
+ const transports = {};
25
+ // Handle POST requests for client-to-server communication
26
+ app.post('/mcp', async (req, res) => {
27
+ console.log(`Request received: ${req.method} ${req.url}`, { body: req.body });
28
+ // Capture response data for logging
29
+ const originalJson = res.json;
30
+ res.json = function (body) {
31
+ console.log(`Response being sent:`, JSON.stringify(body, null, 2));
32
+ return originalJson.call(this, body);
33
+ };
34
+ try {
35
+ // Check for existing session ID
36
+ const sessionId = req.headers['mcp-session-id'];
37
+ let transport;
38
+ if (sessionId && transports[sessionId]) {
39
+ // Reuse existing transport
40
+ console.log(`Reusing session: ${sessionId}`);
41
+ transport = transports[sessionId];
42
+ }
43
+ else if (!sessionId && isInitializeRequest(req.body)) {
44
+ console.log(`New session request: ${req.body.method}`);
45
+ // New initialization request
46
+ const eventStore = new InMemoryEventStore();
47
+ transport = new StreamableHTTPServerTransport({
48
+ sessionIdGenerator: () => randomUUID(),
49
+ enableJsonResponse: true,
50
+ eventStore, // Enable resumability
51
+ onsessioninitialized: (sessionId) => {
52
+ // Store the transport by session ID
53
+ console.log(`Session initialized: ${sessionId}`);
54
+ transports[sessionId] = transport;
55
+ }
56
+ });
57
+ // Clean up transport when closed
58
+ transport.onclose = () => {
59
+ const sid = transport.sessionId;
60
+ if (sid && transports[sid]) {
61
+ console.log(`Transport closed for session ${sid}, removing from transports map`);
62
+ delete transports[sid];
63
+ }
64
+ };
65
+ // Connect to the MCP server BEFORE handling the request
66
+ console.log(`Connecting transport to MCP server...`);
67
+ await server.connect(transport);
68
+ console.log(`Transport connected to MCP server successfully`);
69
+ console.log(`Handling initialization request...`);
70
+ await transport.handleRequest(req, res, req.body);
71
+ console.log(`Initialization request handled, response sent`);
72
+ return; // Already handled
73
+ }
74
+ else {
75
+ console.error('Invalid request: No valid session ID or initialization request');
76
+ // Invalid request
77
+ res.status(400).json({
78
+ jsonrpc: '2.0',
79
+ error: {
80
+ code: -32000,
81
+ message: 'Bad Request: No valid session ID provided',
82
+ },
83
+ id: null,
84
+ });
85
+ return;
86
+ }
87
+ console.log(`Handling request for session: ${transport.sessionId}`);
88
+ console.log(`Request body:`, JSON.stringify(req.body, null, 2));
89
+ // Handle the request with existing transport
90
+ console.log(`Calling transport.handleRequest...`);
91
+ const startTime = Date.now();
92
+ await transport.handleRequest(req, res, req.body);
93
+ const duration = Date.now() - startTime;
94
+ console.log(`Request handling completed in ${duration}ms for session: ${transport.sessionId}`);
95
+ }
96
+ catch (error) {
97
+ console.error('Error handling MCP request:', error);
98
+ if (!res.headersSent) {
99
+ res.status(500).json({
100
+ jsonrpc: '2.0',
101
+ error: {
102
+ code: -32603,
103
+ message: 'Internal server error',
104
+ },
105
+ id: null,
106
+ });
107
+ }
108
+ }
109
+ });
110
+ // Handle GET requests for server-to-client notifications via HTTP Streaming
111
+ app.get('/mcp', async (req, res) => {
112
+ console.log(`GET Request received: ${req.method} ${req.url}`);
113
+ try {
114
+ const sessionId = req.headers['mcp-session-id'];
115
+ if (!sessionId || !transports[sessionId]) {
116
+ console.log(`Invalid session ID in GET request: ${sessionId}`);
117
+ res.status(400).send('Invalid or missing session ID');
118
+ return;
119
+ }
120
+ // Check for Last-Event-ID header for resumability
121
+ const lastEventId = req.headers['last-event-id'];
122
+ if (lastEventId) {
123
+ console.log(`Client reconnecting with Last-Event-ID: ${lastEventId}`);
124
+ }
125
+ else {
126
+ console.log(`Establishing new HTTP stream for session ${sessionId}`);
127
+ }
128
+ const transport = transports[sessionId];
129
+ // Set up connection close monitoring
130
+ res.on('close', () => {
131
+ console.log(`HTTP stream closed for session ${sessionId}`);
132
+ });
133
+ console.log(`Starting HTTP transport.handleRequest for session ${sessionId}...`);
134
+ const startTime = Date.now();
135
+ await transport.handleRequest(req, res);
136
+ const duration = Date.now() - startTime;
137
+ console.log(`HTTP stream setup completed in ${duration}ms for session: ${sessionId}`);
138
+ }
139
+ catch (error) {
140
+ console.error('Error handling GET request:', error);
141
+ if (!res.headersSent) {
142
+ res.status(500).send('Internal server error');
143
+ }
144
+ }
145
+ });
146
+ // Handle DELETE requests for session termination
147
+ app.delete('/mcp', async (req, res) => {
148
+ console.log(`DELETE Request received: ${req.method} ${req.url}`);
149
+ try {
150
+ const sessionId = req.headers['mcp-session-id'];
151
+ if (!sessionId || !transports[sessionId]) {
152
+ console.log(`Invalid session ID in DELETE request: ${sessionId}`);
153
+ res.status(400).send('Invalid or missing session ID');
154
+ return;
155
+ }
156
+ console.log(`Received session termination request for session ${sessionId}`);
157
+ const transport = transports[sessionId];
158
+ // Capture response for logging
159
+ const originalSend = res.send;
160
+ res.send = function (body) {
161
+ console.log(`DELETE response being sent:`, body);
162
+ return originalSend.call(this, body);
163
+ };
164
+ console.log(`Processing session termination...`);
165
+ const startTime = Date.now();
166
+ await transport.handleRequest(req, res);
167
+ const duration = Date.now() - startTime;
168
+ console.log(`Session termination completed in ${duration}ms for session: ${sessionId}`);
169
+ // Check if transport was actually closed
170
+ setTimeout(() => {
171
+ if (transports[sessionId]) {
172
+ console.log(`Note: Transport for session ${sessionId} still exists after DELETE request`);
173
+ }
174
+ else {
175
+ console.log(`Transport for session ${sessionId} successfully removed after DELETE request`);
176
+ }
177
+ }, 100);
178
+ }
179
+ catch (error) {
180
+ console.error('Error handling DELETE request:', error);
181
+ if (!res.headersSent) {
182
+ res.status(500).send('Error processing session termination');
183
+ }
184
+ }
185
+ });
186
+ const express_server = app.listen(PORT, () => {
187
+ console.log(`MCP Streamable HTTP Server listening on port ${PORT}`);
188
+ });
189
+ // Add server event listeners for better visibility
190
+ express_server.on('connect', (transport) => {
191
+ console.log(`[Server] Transport connected: ${transport}`);
192
+ });
193
+ express_server.on('disconnect', (transport) => {
194
+ console.log(`[Server] Transport disconnected: ${transport.sessionId}`);
195
+ });
196
+ express_server.on('request', (request, transport) => {
197
+ console.log(`[Server] Received request: ${request.method} from transport: ${transport}`);
198
+ });
199
+ express_server.on('response', (response, transport) => {
200
+ console.log(`[Server] Sending response for id: ${response.id} to transport: ${transport.sessionId}`);
201
+ });
202
+ express_server.on('notification', (notification, transport) => {
203
+ console.log(`[Server] Sending notification: ${notification.method} to transport: ${transport.sessionId}`);
204
+ });
205
+ express_server.on('error', (error, transport) => {
206
+ console.error(`[Server] Error with transport ${transport?.sessionId || 'unknown'}:`, error);
207
+ });
208
+ // Handle server shutdown
209
+ process.on('SIGINT', async () => {
210
+ console.log('Shutting down server...');
211
+ // Close all active transports to properly clean up resources
212
+ for (const sessionId in transports) {
213
+ try {
214
+ console.log(`Closing transport for session ${sessionId}`);
215
+ await transports[sessionId].close();
216
+ delete transports[sessionId];
217
+ }
218
+ catch (error) {
219
+ console.error(`Error closing transport for session ${sessionId}:`, error);
220
+ }
221
+ }
222
+ await express_server.close();
223
+ await server.close();
224
+ console.log('Server shutdown complete');
225
+ process.exit(0);
226
+ });
227
+ return { process, server, express_server };
228
+ };