diff --git a/package.json b/package.json index 396b75f..f7b85c3 100644 --- a/package.json +++ b/package.json @@ -26,14 +26,16 @@ "types": "./dist/cli.d.ts", "import": "./dist/cli.js", "require": "./dist/cli.js" - } + }, + "./mcpb-manifest.schema.json": "./dist/mcpb-manifest.schema.json" }, "bin": "dist/cli/cli.js", "files": [ - "dist" + "dist", + "schemas" ], "scripts": { - "build": "yarn run build:code", + "build": "yarn run build:code && yarn run build:schema", "build:code": "tsc", "build:schema": "node ./scripts/build-mcpb-schema.js", "dev": "tsc --watch", @@ -71,7 +73,8 @@ "ignore": "^7.0.5", "node-forge": "^1.3.1", "pretty-bytes": "^5.6.0", - "zod": "^3.25.67" + "zod": "^3.25.67", + "zod-to-json-schema": "^3.24.6" }, "resolutions": { "@babel/helpers": "7.27.1", diff --git a/schemas/mcpb-manifest.schema.json b/schemas/mcpb-manifest.schema.json new file mode 100644 index 0000000..fc522b9 --- /dev/null +++ b/schemas/mcpb-manifest.schema.json @@ -0,0 +1,327 @@ +{ + "type": "object", + "properties": { + "$schema": { + "type": "string" + }, + "dxt_version": { + "type": "string", + "const": "0.2", + "description": "@deprecated Use manifest_version instead" + }, + "manifest_version": { + "type": "string", + "const": "0.2" + }, + "name": { + "type": "string" + }, + "display_name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "description": { + "type": "string" + }, + "long_description": { + "type": "string" + }, + "author": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "email": { + "type": "string", + "format": "email" + }, + "url": { + "type": "string", + "format": "uri" + } + }, + "required": [ + "name" + ], + "additionalProperties": false + }, + "repository": { + "type": "object", + "properties": { + "type": { + "type": "string" + }, + "url": { + "type": "string", + "format": "uri" + } + }, + "required": [ + "type", + "url" + ], + "additionalProperties": false + }, + "homepage": { + "type": "string", + "format": "uri" + }, + "documentation": { + "type": "string", + "format": "uri" + }, + "support": { + "type": "string", + "format": "uri" + }, + "icon": { + "type": "string" + }, + "screenshots": { + "type": "array", + "items": { + "type": "string" + } + }, + "server": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "python", + "node", + "binary" + ] + }, + "entry_point": { + "type": "string" + }, + "mcp_config": { + "type": "object", + "properties": { + "command": { + "type": "string" + }, + "args": { + "type": "array", + "items": { + "type": "string" + } + }, + "env": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "platform_overrides": { + "type": "object", + "additionalProperties": { + "type": "object", + "properties": { + "command": { + "$ref": "#/properties/server/properties/mcp_config/properties/command" + }, + "args": { + "$ref": "#/properties/server/properties/mcp_config/properties/args" + }, + "env": { + "$ref": "#/properties/server/properties/mcp_config/properties/env" + } + }, + "additionalProperties": false + } + } + }, + "required": [ + "command" + ], + "additionalProperties": false + } + }, + "required": [ + "type", + "entry_point", + "mcp_config" + ], + "additionalProperties": false + }, + "tools": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "required": [ + "name" + ], + "additionalProperties": false + } + }, + "tools_generated": { + "type": "boolean" + }, + "prompts": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "arguments": { + "type": "array", + "items": { + "type": "string" + } + }, + "text": { + "type": "string" + } + }, + "required": [ + "name", + "text" + ], + "additionalProperties": false + } + }, + "prompts_generated": { + "type": "boolean" + }, + "keywords": { + "type": "array", + "items": { + "type": "string" + } + }, + "license": { + "type": "string" + }, + "privacy_policies": { + "type": "array", + "items": { + "type": "string", + "format": "uri" + } + }, + "compatibility": { + "type": "object", + "properties": { + "claude_desktop": { + "type": "string" + }, + "platforms": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "darwin", + "win32", + "linux" + ] + } + }, + "runtimes": { + "type": "object", + "properties": { + "python": { + "type": "string" + }, + "node": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + "user_config": { + "type": "object", + "additionalProperties": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "string", + "number", + "boolean", + "directory", + "file" + ] + }, + "title": { + "type": "string" + }, + "description": { + "type": "string" + }, + "required": { + "type": "boolean" + }, + "default": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "number" + }, + { + "type": "boolean" + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ] + }, + "multiple": { + "type": "boolean" + }, + "sensitive": { + "type": "boolean" + }, + "min": { + "type": "number" + }, + "max": { + "type": "number" + } + }, + "required": [ + "type", + "title", + "description" + ], + "additionalProperties": false + } + } + }, + "required": [ + "name", + "version", + "description", + "author", + "server" + ], + "additionalProperties": false, + "$schema": "http://json-schema.org/draft-07/schema#" +} \ No newline at end of file diff --git a/scripts/build-mcpb-schema.js b/scripts/build-mcpb-schema.js index 28d813c..a359274 100644 --- a/scripts/build-mcpb-schema.js +++ b/scripts/build-mcpb-schema.js @@ -1,8 +1,8 @@ import { McpbManifestSchema, McpbSignatureInfoSchema, -} from "../dist/schemas.js"; -import * as z from "zod/v4"; +} from "../dist/schemas/latest.js"; +import { zodToJsonSchema } from "zod-to-json-schema"; import fs from "node:fs/promises"; import path from "node:path"; @@ -11,15 +11,23 @@ const schemasToWrite = { "mcpb-signature-info": McpbSignatureInfoSchema, }; -await fs.mkdir(path.join(import.meta.dirname, "../dist"), { recursive: true }); +const distDir = path.join(import.meta.dirname, "../dist"); +const schemasDir = path.join(import.meta.dirname, "../schemas"); +// Generate all schemas to dist/ +await fs.mkdir(distDir, { recursive: true }); for (const key in schemasToWrite) { - const schema = z.toJSONSchema(schemasToWrite[key]); - await fs.writeFile( - path.join(import.meta.dirname, "../dist", `${key}.schema.json`), - JSON.stringify(schema, null, 2), - { - encoding: "utf8", - }, - ); + const schema = zodToJsonSchema(schemasToWrite[key]); + const filePath = path.join(distDir, `${key}.schema.json`); + await fs.writeFile(filePath, JSON.stringify(schema, null, 2), { + encoding: "utf8", + }); } + +// Generate only manifest schema to schemas/ +await fs.mkdir(schemasDir, { recursive: true }); +const manifestSchema = zodToJsonSchema(McpbManifestSchema); +const manifestPath = path.join(schemasDir, "mcpb-manifest.schema.json"); +await fs.writeFile(manifestPath, JSON.stringify(manifestSchema, null, 2), { + encoding: "utf8", +}); diff --git a/yarn.lock b/yarn.lock index c10fbe1..593a7a5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -42,6 +42,7 @@ __metadata: ts-jest: "npm:^29.3.2" typescript: "npm:^5.6.3" zod: "npm:^3.25.67" + zod-to-json-schema: "npm:^3.24.6" bin: mcpb: dist/cli/cli.js languageName: unknown @@ -6387,6 +6388,15 @@ __metadata: languageName: node linkType: hard +"zod-to-json-schema@npm:^3.24.6": + version: 3.24.6 + resolution: "zod-to-json-schema@npm:3.24.6" + peerDependencies: + zod: ^3.24.1 + checksum: 10c0/b907ab6d057100bd25a37e5545bf5f0efa5902cd84d3c3ec05c2e51541431a47bd9bf1e5e151a244273409b45f5986d55b26e5d207f98abc5200702f733eb368 + languageName: node + linkType: hard + "zod@npm:^3.25.67": version: 3.25.67 resolution: "zod@npm:3.25.67"