uiplug-mcp 1.1.1 → 1.2.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 (2) hide show
  1. package/dist/index.js +80 -7
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -28,12 +28,8 @@ async function validateApiKey(apiKey) {
28
28
  if (error || !data) {
29
29
  return { userId: null, error: "Invalid or revoked API key." };
30
30
  }
31
- // Fire-and-forget: update usage stats
32
- supabase
33
- .from("api_keys")
34
- .update({ last_used_at: new Date().toISOString(), usage_total: data.usage_total + 1 })
35
- .eq("id", data.id)
36
- .then(() => { });
31
+ // Fire-and-forget: update usage stats via SECURITY DEFINER RPC (bypasses RLS)
32
+ supabase.rpc("increment_api_key_usage", { p_key_id: data.id }).then(() => { });
37
33
  return { userId: data.user_id, error: null };
38
34
  }
39
35
  // ── MCP Server ────────────────────────────────────────────────────────────────
@@ -100,13 +96,59 @@ server.setRequestHandler(ListToolsRequestSchema, async () => ({
100
96
  },
101
97
  },
102
98
  },
99
+ {
100
+ name: "create_component",
101
+ description: "Submit a new UI component to the UIPlug marketplace. " +
102
+ "The component will be submitted for review (status: pending) and visible in your dashboard at uiplug.com/dashboard/components. " +
103
+ "Use this after building a component to share it with the community.",
104
+ inputSchema: {
105
+ type: "object",
106
+ required: ["name", "description", "framework", "category", "code"],
107
+ properties: {
108
+ name: {
109
+ type: "string",
110
+ description: "Component name (e.g. 'Gradient Button').",
111
+ },
112
+ description: {
113
+ type: "string",
114
+ description: "A clear description of what the component does and its key features.",
115
+ },
116
+ framework: {
117
+ type: "string",
118
+ description: "Framework: React | Vue | Svelte | Angular | HTML / CSS | " +
119
+ "Jetpack Compose | Compose Multiplatform | Flutter | SwiftUI | React Native",
120
+ },
121
+ category: {
122
+ type: "string",
123
+ description: "Category: Layout | Navigation | Input | Data Display | Feedback | Sensors",
124
+ },
125
+ code: {
126
+ type: "string",
127
+ description: "Full component source code.",
128
+ },
129
+ installation: {
130
+ type: "string",
131
+ description: "Optional dependency/installation snippet (e.g. 'npm install some-package').",
132
+ },
133
+ tags: {
134
+ type: "array",
135
+ items: { type: "string" },
136
+ description: "Optional tag names (e.g. ['button', 'gradient', 'animation']).",
137
+ },
138
+ model: {
139
+ type: "string",
140
+ description: "Optional — AI model used to build this (e.g. 'Claude Sonnet 4.6').",
141
+ },
142
+ },
143
+ },
144
+ },
103
145
  ],
104
146
  }));
105
147
  // ── Tool handlers ─────────────────────────────────────────────────────────────
106
148
  server.setRequestHandler(CallToolRequestSchema, async (request) => {
107
149
  const { name, arguments: args } = request.params;
108
150
  // ── Validate API key ─────────────────────────────────────────────────────────
109
- const { error: authError } = await validateApiKey(process.env.UIPLUG_API_KEY);
151
+ const { userId, error: authError } = await validateApiKey(process.env.UIPLUG_API_KEY);
110
152
  if (authError) {
111
153
  return { content: [{ type: "text", text: authError }], isError: true };
112
154
  }
@@ -286,6 +328,37 @@ ${c.code_component}
286
328
  `;
287
329
  return { content: [{ type: "text", text: output }] };
288
330
  }
331
+ // ── create_component ────────────────────────────────────────────────────────
332
+ if (name === "create_component") {
333
+ const { name: compName, description, framework, category, code, installation, tags, model, } = (args ?? {});
334
+ const { data: componentId, error } = await supabase.rpc("create_component", {
335
+ p_user_id: userId,
336
+ p_name: compName,
337
+ p_description: description,
338
+ p_framework: framework,
339
+ p_category: category,
340
+ p_code: code,
341
+ p_installation: installation ?? null,
342
+ p_tags: tags ?? [],
343
+ p_model: model ?? null,
344
+ });
345
+ if (error) {
346
+ return { content: [{ type: "text", text: `Error submitting component: ${error.message}` }], isError: true };
347
+ }
348
+ return {
349
+ content: [
350
+ {
351
+ type: "text",
352
+ text: `Component submitted for review!\n\n` +
353
+ `**Name:** ${compName}\n` +
354
+ `**Framework:** ${framework}\n` +
355
+ `**Category:** ${category}\n` +
356
+ `**ID:** ${componentId}\n\n` +
357
+ `View and manage it at: https://uiplug.com/dashboard/components`,
358
+ },
359
+ ],
360
+ };
361
+ }
289
362
  return {
290
363
  content: [{ type: "text", text: `Unknown tool: ${name}` }],
291
364
  isError: true,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "uiplug-mcp",
3
- "version": "1.1.1",
3
+ "version": "1.2.0",
4
4
  "description": "MCP server for UIPlug — gives AI agents access to the UIPlug UI component marketplace",
5
5
  "type": "module",
6
6
  "bin": {