@getflip/swirl-mcp 0.0.0 → 0.1.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.
@@ -0,0 +1,283 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/create-server.ts
4
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
5
+
6
+ // src/data-source.ts
7
+ var DataSource = class {
8
+ constructor(version) {
9
+ this.version = version;
10
+ }
11
+ async readJson(relativePath) {
12
+ const url = `${this.baseUrl}/${relativePath}`;
13
+ const res = await fetch(url);
14
+ if (!res.ok) {
15
+ throw new Error(
16
+ `Failed to fetch ${url}: ${res.status} ${res.statusText}`
17
+ );
18
+ }
19
+ return await res.json();
20
+ }
21
+ async readText(relativePath) {
22
+ const url = `${this.baseUrl}/${relativePath}`;
23
+ try {
24
+ const res = await fetch(url);
25
+ if (!res.ok) {
26
+ return void 0;
27
+ }
28
+ return await res.text();
29
+ } catch {
30
+ return void 0;
31
+ }
32
+ }
33
+ get baseUrl() {
34
+ return `https://unpkg.com/@getflip/swirl-ai@${this.version}/dist/agent`;
35
+ }
36
+ };
37
+
38
+ // src/artifact-library.ts
39
+ var ArtifactLibrary = class _ArtifactLibrary {
40
+ catalog;
41
+ tagIndex;
42
+ dataSource;
43
+ constructor(catalog, dataSource) {
44
+ this.catalog = catalog;
45
+ this.dataSource = dataSource;
46
+ this.tagIndex = /* @__PURE__ */ new Map();
47
+ for (const entry of this.catalog) {
48
+ this.tagIndex.set(entry.tag, entry);
49
+ }
50
+ }
51
+ /**
52
+ * Load artifacts from a remote base URL (CDN).
53
+ */
54
+ static async fromRemote(version) {
55
+ const ds = new DataSource(version);
56
+ const json = await ds.readJson(
57
+ "components-index.json"
58
+ );
59
+ return new _ArtifactLibrary(json.components, ds);
60
+ }
61
+ getByCategory(category) {
62
+ return this.catalog.filter((c) => categorize(c.tag) === category);
63
+ }
64
+ getByTag(tag) {
65
+ return this.tagIndex.get(tag);
66
+ }
67
+ async getComponentMarkdown(tag) {
68
+ return this.dataSource.readText(`components/${tag}.md`);
69
+ }
70
+ async getGuide(name) {
71
+ return this.dataSource.readText(`${name}.md`);
72
+ }
73
+ };
74
+ function categorize(tag) {
75
+ if (tag.startsWith("swirl-icon-")) {
76
+ return "icon";
77
+ }
78
+ if (tag.startsWith("swirl-symbol-")) {
79
+ return "symbol";
80
+ }
81
+ if (tag.startsWith("swirl-emoji-")) {
82
+ return "emoji";
83
+ }
84
+ return "core";
85
+ }
86
+
87
+ // src/library-cache.ts
88
+ var LibraryCache = class {
89
+ cache = /* @__PURE__ */ new Map();
90
+ maxSize;
91
+ constructor(maxSize = 20) {
92
+ this.maxSize = maxSize;
93
+ }
94
+ get(version) {
95
+ const lib = this.cache.get(version);
96
+ if (lib) {
97
+ this.cache.delete(version);
98
+ this.cache.set(version, lib);
99
+ }
100
+ return lib;
101
+ }
102
+ set(version, lib) {
103
+ if (this.cache.has(version)) {
104
+ this.cache.delete(version);
105
+ } else if (this.cache.size >= this.maxSize) {
106
+ const oldest = this.cache.keys().next().value;
107
+ this.cache.delete(oldest);
108
+ }
109
+ this.cache.set(version, lib);
110
+ }
111
+ };
112
+
113
+ // src/tools/list-components.ts
114
+ import { z } from "zod";
115
+ var VERSION_DESCRIPTION = "The @getflip/swirl-components version installed in the project. Read the user's package.json or node_modules/@getflip/swirl-components/package.json to find this.";
116
+ function registerListComponents(server, loadLibrary2) {
117
+ registerListTool(
118
+ server,
119
+ loadLibrary2,
120
+ "list_components",
121
+ "List all Swirl design system UI components (buttons, modals, forms, etc.) with brief summaries and related components. Does NOT include icons, symbols, or emojis \u2014 use list_icons, list_symbols, or list_emojis for those. Use get_component_details for full props, events, slots, and examples. IMPORTANT: First read the user's package.json to determine their installed @getflip/swirl-components version, then pass it as the 'version' parameter.",
122
+ "core"
123
+ );
124
+ }
125
+ function registerListIcons(server, loadLibrary2) {
126
+ registerListTool(
127
+ server,
128
+ loadLibrary2,
129
+ "list_icons",
130
+ "List all Swirl icon components (swirl-icon-*). Use get_component_details for full details on a specific icon. IMPORTANT: First read the user's package.json to determine their installed @getflip/swirl-components version, then pass it as the 'version' parameter.",
131
+ "icon"
132
+ );
133
+ }
134
+ function registerListSymbols(server, loadLibrary2) {
135
+ registerListTool(
136
+ server,
137
+ loadLibrary2,
138
+ "list_symbols",
139
+ "List all Swirl symbol components (swirl-symbol-*). Use get_component_details for full details on a specific symbol. IMPORTANT: First read the user's package.json to determine their installed @getflip/swirl-components version, then pass it as the 'version' parameter.",
140
+ "symbol"
141
+ );
142
+ }
143
+ function registerListEmojis(server, loadLibrary2) {
144
+ registerListTool(
145
+ server,
146
+ loadLibrary2,
147
+ "list_emojis",
148
+ "List all Swirl emoji components (swirl-emoji-*). Use get_component_details for full details on a specific emoji. IMPORTANT: First read the user's package.json to determine their installed @getflip/swirl-components version, then pass it as the 'version' parameter.",
149
+ "emoji"
150
+ );
151
+ }
152
+ function registerListTool(server, loadLibrary2, name, description, category) {
153
+ server.registerTool(
154
+ name,
155
+ {
156
+ description,
157
+ inputSchema: {
158
+ version: z.string().describe(VERSION_DESCRIPTION)
159
+ }
160
+ },
161
+ // @ts-ignore - MCP SDK + zod 3.x causes excessively deep type instantiation
162
+ async ({ version }) => {
163
+ const lib = await loadLibrary2(version);
164
+ const components = lib.getByCategory(category);
165
+ return {
166
+ content: [{ type: "text", text: JSON.stringify(components) }]
167
+ };
168
+ }
169
+ );
170
+ }
171
+
172
+ // src/tools/get-component-details.ts
173
+ import { z as z2 } from "zod";
174
+ var VERSION_DESCRIPTION2 = "The @getflip/swirl-components version installed in the project. Read the user's package.json or node_modules/@getflip/swirl-components/package.json to find this.";
175
+ function registerGetComponentDetails(server, loadLibrary2) {
176
+ server.registerTool(
177
+ "get_component_details",
178
+ {
179
+ description: "Get full details for a Swirl component including all props with types and defaults, events, methods, slots, accessibility info, and usage examples. IMPORTANT: First read the user's package.json to determine their installed @getflip/swirl-components version, then pass it as the 'version' parameter.",
180
+ inputSchema: {
181
+ tag: z2.string().describe('The component tag name, e.g. "swirl-button"'),
182
+ version: z2.string().describe(VERSION_DESCRIPTION2)
183
+ }
184
+ },
185
+ // @ts-ignore - MCP SDK + zod 3.x causes excessively deep type instantiation
186
+ async ({ tag, version }) => {
187
+ const lib = await loadLibrary2(version);
188
+ const entry = lib.getByTag(tag);
189
+ if (!entry) {
190
+ return {
191
+ content: [
192
+ {
193
+ type: "text",
194
+ text: `Component "${tag}" not found. Use list_components to see available components.`
195
+ }
196
+ ]
197
+ };
198
+ }
199
+ const markdown = await lib.getComponentMarkdown(tag);
200
+ if (!markdown) {
201
+ return {
202
+ content: [
203
+ {
204
+ type: "text",
205
+ text: `Component "${tag}" exists but no detailed documentation was found.`
206
+ }
207
+ ]
208
+ };
209
+ }
210
+ return {
211
+ content: [{ type: "text", text: markdown }]
212
+ };
213
+ }
214
+ );
215
+ }
216
+
217
+ // src/tools/get-started.ts
218
+ import { z as z3 } from "zod";
219
+ var VERSION_DESCRIPTION3 = "The @getflip/swirl-components version installed in the project. Read the user's package.json or node_modules/@getflip/swirl-components/package.json to find this.";
220
+ function registerGetStarted(server, loadLibrary2) {
221
+ server.registerTool(
222
+ "get_started",
223
+ {
224
+ description: "Get installation and setup instructions for Swirl components. Covers Web Components, Angular, and React wrapper libraries. IMPORTANT: First read the user's package.json to determine their installed @getflip/swirl-components version, then pass it as the 'version' parameter.",
225
+ inputSchema: {
226
+ version: z3.string().describe(VERSION_DESCRIPTION3)
227
+ }
228
+ },
229
+ async ({ version }) => {
230
+ const lib = await loadLibrary2(version);
231
+ const markdown = await lib.getGuide("get-started");
232
+ if (!markdown) {
233
+ return {
234
+ content: [
235
+ {
236
+ type: "text",
237
+ text: "Getting started guide not found."
238
+ }
239
+ ]
240
+ };
241
+ }
242
+ return {
243
+ content: [{ type: "text", text: markdown }]
244
+ };
245
+ }
246
+ );
247
+ }
248
+
249
+ // src/create-server.ts
250
+ var cache = new LibraryCache();
251
+ async function loadLibrary(version) {
252
+ const cached = cache.get(version);
253
+ if (cached) {
254
+ return cached;
255
+ }
256
+ try {
257
+ const lib = await ArtifactLibrary.fromRemote(version);
258
+ cache.set(version, lib);
259
+ return lib;
260
+ } catch (error) {
261
+ const message = error instanceof Error ? error.message : String(error);
262
+ throw new Error(
263
+ `Version "${version}" not found or failed to load. Make sure the version matches your installed @getflip/swirl-components version. Details: ${message}`
264
+ );
265
+ }
266
+ }
267
+ function createMcpServer() {
268
+ const server = new McpServer({
269
+ name: "swirl-mcp",
270
+ version: "0.1.0"
271
+ });
272
+ registerListComponents(server, loadLibrary);
273
+ registerListIcons(server, loadLibrary);
274
+ registerListSymbols(server, loadLibrary);
275
+ registerListEmojis(server, loadLibrary);
276
+ registerGetComponentDetails(server, loadLibrary);
277
+ registerGetStarted(server, loadLibrary);
278
+ return server;
279
+ }
280
+
281
+ export {
282
+ createMcpServer
283
+ };
@@ -0,0 +1,56 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ createMcpServer
4
+ } from "../chunk-656TS2QU.js";
5
+
6
+ // src/transports/http.ts
7
+ import { createServer } from "http";
8
+ import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
9
+ var PORT = Number(process.env.PORT ?? 3e3);
10
+ var httpServer = createServer(async (req, res) => {
11
+ if (req.method === "GET" && req.url === "/health") {
12
+ res.writeHead(200, { "Content-Type": "application/json" });
13
+ res.end(JSON.stringify({ status: "ok" }));
14
+ return;
15
+ }
16
+ if (req.method === "POST" && req.url === "/mcp") {
17
+ try {
18
+ const mcpServer = createMcpServer();
19
+ const transport = new StreamableHTTPServerTransport({
20
+ sessionIdGenerator: void 0
21
+ // stateless
22
+ });
23
+ await mcpServer.connect(transport);
24
+ await transport.handleRequest(req, res);
25
+ res.on("close", () => {
26
+ transport.close().catch(() => {
27
+ });
28
+ mcpServer.close().catch(() => {
29
+ });
30
+ });
31
+ } catch (error) {
32
+ console.error("MCP request error:", error);
33
+ if (!res.headersSent) {
34
+ res.writeHead(500, { "Content-Type": "application/json" });
35
+ res.end(JSON.stringify({ error: "Internal server error" }));
36
+ }
37
+ }
38
+ return;
39
+ }
40
+ if (req.url === "/mcp") {
41
+ res.writeHead(405, { "Content-Type": "application/json" });
42
+ res.end(
43
+ JSON.stringify({
44
+ error: "Method not allowed. Use POST for MCP requests."
45
+ })
46
+ );
47
+ return;
48
+ }
49
+ res.writeHead(404, { "Content-Type": "application/json" });
50
+ res.end(JSON.stringify({ error: "Not found" }));
51
+ });
52
+ httpServer.listen(PORT, () => {
53
+ console.error(`Swirl MCP HTTP Server listening on port ${PORT}`);
54
+ console.error(` MCP endpoint: POST http://localhost:${PORT}/mcp`);
55
+ console.error(` Health check: GET http://localhost:${PORT}/health`);
56
+ });
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ createMcpServer
4
+ } from "../chunk-656TS2QU.js";
5
+
6
+ // src/transports/stdio.ts
7
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
8
+ async function main() {
9
+ const server = createMcpServer();
10
+ await server.connect(new StdioServerTransport());
11
+ console.error("Swirl MCP Server running on stdio");
12
+ }
13
+ main().catch((error) => {
14
+ console.error("Fatal error:", error);
15
+ process.exit(1);
16
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@getflip/swirl-mcp",
3
- "version": "0.0.0",
3
+ "version": "0.1.0",
4
4
  "description": "MCP server for Swirl Design System — lets AI agents discover and use Swirl components",
5
5
  "author": "Flip GmbH",
6
6
  "repository": {