diff --git a/package-lock.json b/package-lock.json index 9cad096..aaf81ce 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,15 +1,15 @@ { "name": "@21st-dev/magic", - "version": "0.1.1-beta.1", + "version": "0.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@21st-dev/magic", - "version": "0.1.1-beta.1", + "version": "0.1.0", "license": "ISC", "dependencies": { - "@modelcontextprotocol/sdk": "^1.8.0", + "@modelcontextprotocol/sdk": "^1.25.1", "@types/cors": "^2.8.17", "@types/express": "^5.0.0", "cors": "^2.8.5", @@ -554,6 +554,17 @@ "dev": true, "license": "MIT" }, + "node_modules/@hono/node-server": { + "version": "1.19.7", + "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.7.tgz", + "integrity": "sha512-vUcD0uauS7EU2caukW8z5lJKtoGMokxNbJtBiwHgpqxEXokaHCBkQUmCHhjFB1VUTWdqj25QoMkMKzgjq+uhrw==", + "engines": { + "node": ">=18.14.1" + }, + "peerDependencies": { + "hono": "^4" + } + }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -927,24 +938,41 @@ } }, "node_modules/@modelcontextprotocol/sdk": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.8.0.tgz", - "integrity": "sha512-e06W7SwrontJDHwCawNO5SGxG+nU9AAx+jpHHZqGl/WrDBdWOpvirC+s58VpJTB5QemI4jTRcjWT4Pt3Q1NPQQ==", - "license": "MIT", + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.25.1.tgz", + "integrity": "sha512-yO28oVFFC7EBoiKdAn+VqRm+plcfv4v0xp6osG/VsCB0NlPZWi87ajbCZZ8f/RvOFLEu7//rSRmuZZ7lMoe3gQ==", "dependencies": { + "@hono/node-server": "^1.19.7", + "ajv": "^8.17.1", + "ajv-formats": "^3.0.1", "content-type": "^1.0.5", "cors": "^2.8.5", - "cross-spawn": "^7.0.3", + "cross-spawn": "^7.0.5", "eventsource": "^3.0.2", + "eventsource-parser": "^3.0.0", "express": "^5.0.1", "express-rate-limit": "^7.5.0", - "pkce-challenge": "^4.1.0", + "jose": "^6.1.1", + "json-schema-typed": "^8.0.2", + "pkce-challenge": "^5.0.0", "raw-body": "^3.0.0", - "zod": "^3.23.8", - "zod-to-json-schema": "^3.24.1" + "zod": "^3.25 || ^4.0", + "zod-to-json-schema": "^3.25.0" }, "engines": { "node": ">=18" + }, + "peerDependencies": { + "@cfworker/json-schema": "^4.1.1", + "zod": "^3.25 || ^4.0" + }, + "peerDependenciesMeta": { + "@cfworker/json-schema": { + "optional": true + }, + "zod": { + "optional": false + } } }, "node_modules/@modelcontextprotocol/sdk/node_modules/accepts": { @@ -1186,6 +1214,22 @@ "node": ">= 0.6" } }, + "node_modules/@modelcontextprotocol/sdk/node_modules/zod": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.2.1.tgz", + "integrity": "sha512-0wZ1IRqGGhMP76gLqz8EyfBXKk0J2qo2+H3fi4mcUP/KtTocoX08nmIAHl1Z2kJIZbZee8KOpBCSNPRgauucjw==", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/zod-to-json-schema": { + "version": "3.25.0", + "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.25.0.tgz", + "integrity": "sha512-HvWtU2UG41LALjajJrML6uQejQhNJx+JBO9IflpSja4R03iNWfKXrj6W2h7ljuLyc1nKS+9yDyL/9tD1U/yBnQ==", + "peerDependencies": { + "zod": "^3.25 || ^4" + } + }, "node_modules/@sinclair/typebox": { "version": "0.27.8", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", @@ -1467,6 +1511,37 @@ "node": ">= 0.6" } }, + "node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, "node_modules/ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", @@ -2637,6 +2712,11 @@ "license": "MIT", "peer": true }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -2644,6 +2724,21 @@ "dev": true, "license": "MIT" }, + "node_modules/fast-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ] + }, "node_modules/fb-watchman": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", @@ -2978,6 +3073,15 @@ "node": ">= 0.4" } }, + "node_modules/hono": { + "version": "4.11.1", + "resolved": "https://registry.npmjs.org/hono/-/hono-4.11.1.tgz", + "integrity": "sha512-KsFcH0xxHes0J4zaQgWbYwmz3UPOOskdqZmItstUG93+Wk1ePBLkLGwbP9zlmh1BFUiL8Qp+Xfu9P7feJWpGNg==", + "peer": true, + "engines": { + "node": ">=16.9.0" + } + }, "node_modules/html-escaper": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", @@ -3965,6 +4069,14 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, + "node_modules/jose": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/jose/-/jose-6.1.3.tgz", + "integrity": "sha512-0TpaTfihd4QMNwrz/ob2Bp7X04yuxJkjRGi4aKmOqwhov54i6u79oCv7T+C7lo70MKH6BesI3vscD1yb/yzKXQ==", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -4006,6 +4118,16 @@ "dev": true, "license": "MIT" }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, + "node_modules/json-schema-typed": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-8.0.2.tgz", + "integrity": "sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==" + }, "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", @@ -4560,10 +4682,9 @@ } }, "node_modules/pkce-challenge": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-4.1.0.tgz", - "integrity": "sha512-ZBmhE1C9LcPoH9XZSdwiPtbPHZROwAnMy+kIFQVrnMCxY4Cudlz3gBOpzilgc0jOgRaiT3sIWfpMomW2ar2orQ==", - "license": "MIT", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.1.tgz", + "integrity": "sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==", "engines": { "node": ">=16.20.0" } @@ -4742,6 +4863,14 @@ "node": ">=0.10.0" } }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/resolve": { "version": "1.22.10", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", @@ -5647,15 +5776,6 @@ "funding": { "url": "https://github.com/sponsors/colinhacks" } - }, - "node_modules/zod-to-json-schema": { - "version": "3.24.1", - "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.24.1.tgz", - "integrity": "sha512-3h08nf3Vw3Wl3PK+q3ow/lIil81IT2Oa7YpQyUUDsEWbXveMesdfK1xBd2RhCkynwZndAxixji/7SYJJowr62w==", - "license": "ISC", - "peerDependencies": { - "zod": "^3.24.1" - } } } } diff --git a/package.json b/package.json index 3c6a994..f78b3a5 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,7 @@ "author": "serafim@21st.dev", "license": "ISC", "dependencies": { - "@modelcontextprotocol/sdk": "^1.8.0", + "@modelcontextprotocol/sdk": "^1.25.1", "@types/cors": "^2.8.17", "@types/express": "^5.0.0", "cors": "^2.8.5", diff --git a/src/tools/create-ui.ts b/src/tools/create-ui.ts index 07e8cf0..4650786 100644 --- a/src/tools/create-ui.ts +++ b/src/tools/create-ui.ts @@ -1,6 +1,6 @@ import open from "open"; import { z } from "zod"; -import { BaseTool } from "../utils/base-tool.js"; +import { BaseTool, ToolAnnotations } from "../utils/base-tool.js"; import { CallbackServer } from "../utils/callback-server.js"; import { config } from "../utils/config.js"; import { git } from "../utils/git-operations.js"; @@ -19,6 +19,11 @@ interface CreateUiResponse { export class CreateUiTool extends BaseTool { name = UI_TOOL_NAME; description = UI_TOOL_DESCRIPTION; + annotations: ToolAnnotations = { + title: "Create UI Component", + destructiveHint: true, + openWorldHint: true, + }; schema = z.object({ message: z.string().describe("Full users message"), diff --git a/src/tools/fetch-ui.ts b/src/tools/fetch-ui.ts index eb30e5f..e533042 100644 --- a/src/tools/fetch-ui.ts +++ b/src/tools/fetch-ui.ts @@ -1,5 +1,5 @@ import { z } from "zod"; -import { BaseTool } from "../utils/base-tool.js"; +import { BaseTool, ToolAnnotations } from "../utils/base-tool.js"; import { twentyFirstClient } from "../utils/http-client.js"; const FETCH_UI_TOOL_NAME = "21st_magic_component_inspiration"; @@ -15,6 +15,11 @@ interface FetchUiResponse { export class FetchUiTool extends BaseTool { name = FETCH_UI_TOOL_NAME; description = FETCH_UI_TOOL_DESCRIPTION; + annotations: ToolAnnotations = { + title: "Fetch UI Inspiration", + readOnlyHint: true, + openWorldHint: true, + }; schema = z.object({ message: z.string().describe("Full users message"), diff --git a/src/tools/logo-search.ts b/src/tools/logo-search.ts index 46ffb0e..48036c0 100644 --- a/src/tools/logo-search.ts +++ b/src/tools/logo-search.ts @@ -1,6 +1,6 @@ import { z } from "zod"; import { promises as fs } from "fs"; -import { BaseTool } from "../utils/base-tool.js"; +import { BaseTool, ToolAnnotations } from "../utils/base-tool.js"; // Types for SVGL API responses interface ThemeOptions { @@ -49,6 +49,11 @@ Each result includes: export class LogoSearchTool extends BaseTool { name = LOGO_TOOL_NAME; description = LOGO_TOOL_DESCRIPTION; + annotations: ToolAnnotations = { + title: "Search Logos", + destructiveHint: true, + openWorldHint: true, + }; schema = z.object({ queries: z diff --git a/src/tools/refine-ui.ts b/src/tools/refine-ui.ts index c02be7f..8610a66 100644 --- a/src/tools/refine-ui.ts +++ b/src/tools/refine-ui.ts @@ -1,5 +1,5 @@ import { z } from "zod"; -import { BaseTool } from "../utils/base-tool.js"; +import { BaseTool, ToolAnnotations } from "../utils/base-tool.js"; import { twentyFirstClient } from "../utils/http-client.js"; import { getContentOfFile } from "../utils/get-content-of-file.js"; @@ -17,6 +17,11 @@ interface RefineUiResponse { export class RefineUiTool extends BaseTool { name = REFINE_UI_TOOL_NAME; description = REFINE_UI_TOOL_DESCRIPTION; + annotations: ToolAnnotations = { + title: "Refine UI Component", + destructiveHint: true, + openWorldHint: true, + }; schema = z.object({ userMessage: z.string().describe("Full user's message about UI refinement"), diff --git a/src/utils/base-tool.ts b/src/utils/base-tool.ts index 14195f2..739eaec 100644 --- a/src/utils/base-tool.ts +++ b/src/utils/base-tool.ts @@ -1,16 +1,21 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { ToolAnnotations } from "@modelcontextprotocol/sdk/types.js"; import { z } from "zod"; +export { ToolAnnotations }; + export abstract class BaseTool { abstract name: string; abstract description: string; abstract schema: z.ZodObject; + abstract annotations: ToolAnnotations; register(server: McpServer) { server.tool( this.name, this.description, this.schema.shape, + this.annotations, this.execute.bind(this) ); }