Merge pull request #114 from anthropics/feat/versioned-schemas

feat: versioned schemas
This commit is contained in:
joan-anthropic 2025-10-20 17:12:19 -07:00 • committed by GitHub
commit d595dd66dc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
23 changed files with 495 additions and 54 deletions

View file

@ -1,4 +1,5 @@
// Browser-compatible exports
export * from "./schemas.js";
export * from "./schemas/latest.js";
export * from "./shared/config.js";
export * from "./shared/constants.js";
export * from "./types.js";

View file

@ -3,8 +3,9 @@ export * from "./cli/init.js";
export * from "./cli/pack.js";
// Include all shared exports
export * from "./schemas.js";
export * from "./schemas/latest.js";
export * from "./shared/config.js";
export * from "./shared/constants.js";
export * from "./types.js";
// Include node exports since CLI needs them

View file

@ -2,7 +2,7 @@ import { confirm, input, select } from "@inquirer/prompts";
import { existsSync, readFileSync, writeFileSync } from "fs";
import { basename, join, resolve } from "path";
import { CURRENT_MANIFEST_VERSION } from "../schemas.js";
import { LATEST_MANIFEST_VERSION } from "../shared/constants.js";
import type { McpbManifest } from "../types.js";
interface PackageJson {
@ -774,7 +774,7 @@ export function buildManifest(
const { keywords, license, repository } = optionalFields;
return {
manifest_version: CURRENT_MANIFEST_VERSION,
manifest_version: LATEST_MANIFEST_VERSION,
name,
...(displayName && displayName !== name
? { display_name: displayName }

View file

@ -13,7 +13,10 @@ import { basename, join, relative, resolve, sep } from "path";
import { getAllFilesWithCount, readMcpbIgnorePatterns } from "../node/files.js";
import { validateManifest } from "../node/validate.js";
import { CURRENT_MANIFEST_VERSION, McpbManifestSchema } from "../schemas.js";
import {
LATEST_MANIFEST_SCHEMA,
LATEST_MANIFEST_VERSION,
} from "../shared/constants.js";
import { getLogger } from "../shared/log.js";
import { initExtension } from "./init.js";
@ -92,7 +95,7 @@ export async function packExtension({
try {
const manifestContent = readFileSync(manifestPath, "utf-8");
const manifestData = JSON.parse(manifestContent);
manifest = McpbManifestSchema.parse(manifestData);
manifest = LATEST_MANIFEST_SCHEMA.parse(manifestData);
} catch (error) {
logger.error("ERROR: Failed to parse manifest.json");
if (error instanceof Error) {
@ -102,12 +105,12 @@ export async function packExtension({
}
const manifestVersion = manifest.manifest_version || manifest.dxt_version;
if (manifestVersion !== CURRENT_MANIFEST_VERSION) {
if (manifestVersion !== LATEST_MANIFEST_VERSION) {
logger.error(
`ERROR: Manifest version mismatch. Expected "${CURRENT_MANIFEST_VERSION}", found "${manifestVersion}"`,
`ERROR: Manifest version mismatch. Expected "${LATEST_MANIFEST_VERSION}", found "${manifestVersion}"`,
);
logger.error(
` Please update the manifest_version in your manifest.json to "${CURRENT_MANIFEST_VERSION}"`,
` Please update the manifest_version in your manifest.json to "${LATEST_MANIFEST_VERSION}"`,
);
return false;
}

View file

@ -5,6 +5,7 @@ export * from "./cli/unpack.js";
export * from "./node/files.js";
export * from "./node/sign.js";
export * from "./node/validate.js";
export * from "./schemas.js";
export * from "./schemas/latest.js";
export * from "./shared/config.js";
export * from "./shared/constants.js";
export * from "./types.js";

View file

@ -4,6 +4,7 @@ export * from "./node/sign.js";
export * from "./node/validate.js";
// Include all shared exports
export * from "./schemas.js";
export * from "./schemas/latest.js";
export * from "./shared/config.js";
export * from "./shared/constants.js";
export * from "./types.js";

View file

@ -6,8 +6,10 @@ import { join, resolve } from "path";
import prettyBytes from "pretty-bytes";
import { unpackExtension } from "../cli/unpack.js";
import { McpbManifestSchema } from "../schemas.js";
import { McpbManifestSchema as LooseMcpbManifestSchema } from "../schemas-loose.js";
import {
LATEST_MANIFEST_SCHEMA,
LATEST_MANIFEST_SCHEMA_LOOSE,
} from "../shared/constants.js";
export function validateManifest(inputPath: string): boolean {
try {
@ -22,7 +24,7 @@ export function validateManifest(inputPath: string): boolean {
const manifestContent = readFileSync(manifestPath, "utf-8");
const manifestData = JSON.parse(manifestContent);
const result = McpbManifestSchema.safeParse(manifestData);
const result = LATEST_MANIFEST_SCHEMA.safeParse(manifestData);
if (result.success) {
console.log("Manifest schema validation passes!");
@ -72,7 +74,7 @@ export async function cleanMcpb(inputPath: string) {
const manifestPath = resolve(unpackPath, "manifest.json");
const originalManifest = await fs.readFile(manifestPath, "utf-8");
const manifestData = JSON.parse(originalManifest);
const result = LooseMcpbManifestSchema.safeParse(manifestData);
const result = LATEST_MANIFEST_SCHEMA_LOOSE.safeParse(manifestData);
if (!result.success) {
throw new Error(

124
src/schemas/0.1.ts Normal file
View file

@ -0,0 +1,124 @@
import * as z from "zod";
export const MANIFEST_VERSION = "0.1";
export const McpServerConfigSchema = z.strictObject({
command: z.string(),
args: z.array(z.string()).optional(),
env: z.record(z.string(), z.string()).optional(),
});
export const McpbManifestAuthorSchema = z.strictObject({
name: z.string(),
email: z.string().email().optional(),
url: z.string().url().optional(),
});
export const McpbManifestRepositorySchema = z.strictObject({
type: z.string(),
url: z.string().url(),
});
export const McpbManifestPlatformOverrideSchema =
McpServerConfigSchema.partial();
export const McpbManifestMcpConfigSchema = McpServerConfigSchema.extend({
platform_overrides: z
.record(z.string(), McpbManifestPlatformOverrideSchema)
.optional(),
});
export const McpbManifestServerSchema = z.strictObject({
type: z.enum(["python", "node", "binary"]),
entry_point: z.string(),
mcp_config: McpbManifestMcpConfigSchema,
});
export const McpbManifestCompatibilitySchema = z.strictObject({
claude_desktop: z.string().optional(),
platforms: z.array(z.enum(["darwin", "win32", "linux"])).optional(),
runtimes: z
.strictObject({
python: z.string().optional(),
node: z.string().optional(),
})
.optional(),
});
export const McpbManifestToolSchema = z.strictObject({
name: z.string(),
description: z.string().optional(),
});
export const McpbManifestPromptSchema = z.strictObject({
name: z.string(),
description: z.string().optional(),
arguments: z.array(z.string()).optional(),
text: z.string(),
});
export const McpbUserConfigurationOptionSchema = z.strictObject({
type: z.enum(["string", "number", "boolean", "directory", "file"]),
title: z.string(),
description: z.string(),
required: z.boolean().optional(),
default: z
.union([z.string(), z.number(), z.boolean(), z.array(z.string())])
.optional(),
multiple: z.boolean().optional(),
sensitive: z.boolean().optional(),
min: z.number().optional(),
max: z.number().optional(),
});
export const McpbUserConfigValuesSchema = z.record(
z.string(),
z.union([z.string(), z.number(), z.boolean(), z.array(z.string())]),
);
export const McpbManifestSchema = z
.strictObject({
$schema: z.string().optional(),
dxt_version: z
.literal(MANIFEST_VERSION)
.optional()
.describe("@deprecated Use manifest_version instead"),
manifest_version: z.literal(MANIFEST_VERSION).optional(),
name: z.string(),
display_name: z.string().optional(),
version: z.string(),
description: z.string(),
long_description: z.string().optional(),
author: McpbManifestAuthorSchema,
repository: McpbManifestRepositorySchema.optional(),
homepage: z.string().url().optional(),
documentation: z.string().url().optional(),
support: z.string().url().optional(),
icon: z.string().optional(),
screenshots: z.array(z.string()).optional(),
server: McpbManifestServerSchema,
tools: z.array(McpbManifestToolSchema).optional(),
tools_generated: z.boolean().optional(),
prompts: z.array(McpbManifestPromptSchema).optional(),
prompts_generated: z.boolean().optional(),
keywords: z.array(z.string()).optional(),
license: z.string().optional(),
compatibility: McpbManifestCompatibilitySchema.optional(),
user_config: z
.record(z.string(), McpbUserConfigurationOptionSchema)
.optional(),
_meta: z.record(z.string(), z.record(z.string(), z.any())).optional(),
})
.refine((data) => !!(data.dxt_version || data.manifest_version), {
message:
"Either 'dxt_version' (deprecated) or 'manifest_version' must be provided",
});
export const McpbSignatureInfoSchema = z.strictObject({
status: z.enum(["signed", "unsigned", "self-signed"]),
publisher: z.string().optional(),
issuer: z.string().optional(),
valid_from: z.string().optional(),
valid_to: z.string().optional(),
fingerprint: z.string().optional(),
});

124
src/schemas/0.2.ts Normal file
View file

@ -0,0 +1,124 @@
import * as z from "zod";
export const MANIFEST_VERSION = "0.2";
export const McpServerConfigSchema = z.strictObject({
command: z.string(),
args: z.array(z.string()).optional(),
env: z.record(z.string(), z.string()).optional(),
});
export const McpbManifestAuthorSchema = z.strictObject({
name: z.string(),
email: z.string().email().optional(),
url: z.string().url().optional(),
});
export const McpbManifestRepositorySchema = z.strictObject({
type: z.string(),
url: z.string().url(),
});
export const McpbManifestPlatformOverrideSchema =
McpServerConfigSchema.partial();
export const McpbManifestMcpConfigSchema = McpServerConfigSchema.extend({
platform_overrides: z
.record(z.string(), McpbManifestPlatformOverrideSchema)
.optional(),
});
export const McpbManifestServerSchema = z.strictObject({
type: z.enum(["python", "node", "binary"]),
entry_point: z.string(),
mcp_config: McpbManifestMcpConfigSchema,
});
export const McpbManifestCompatibilitySchema = z.strictObject({
claude_desktop: z.string().optional(),
platforms: z.array(z.enum(["darwin", "win32", "linux"])).optional(),
runtimes: z
.strictObject({
python: z.string().optional(),
node: z.string().optional(),
})
.optional(),
});
export const McpbManifestToolSchema = z.strictObject({
name: z.string(),
description: z.string().optional(),
});
export const McpbManifestPromptSchema = z.strictObject({
name: z.string(),
description: z.string().optional(),
arguments: z.array(z.string()).optional(),
text: z.string(),
});
export const McpbUserConfigurationOptionSchema = z.strictObject({
type: z.enum(["string", "number", "boolean", "directory", "file"]),
title: z.string(),
description: z.string(),
required: z.boolean().optional(),
default: z
.union([z.string(), z.number(), z.boolean(), z.array(z.string())])
.optional(),
multiple: z.boolean().optional(),
sensitive: z.boolean().optional(),
min: z.number().optional(),
max: z.number().optional(),
});
export const McpbUserConfigValuesSchema = z.record(
z.string(),
z.union([z.string(), z.number(), z.boolean(), z.array(z.string())]),
);
export const McpbManifestSchema = z
.strictObject({
$schema: z.string().optional(),
dxt_version: z
.literal(MANIFEST_VERSION)
.optional()
.describe("@deprecated Use manifest_version instead"),
manifest_version: z.literal(MANIFEST_VERSION).optional(),
name: z.string(),
display_name: z.string().optional(),
version: z.string(),
description: z.string(),
long_description: z.string().optional(),
author: McpbManifestAuthorSchema,
repository: McpbManifestRepositorySchema.optional(),
homepage: z.string().url().optional(),
documentation: z.string().url().optional(),
support: z.string().url().optional(),
icon: z.string().optional(),
screenshots: z.array(z.string()).optional(),
server: McpbManifestServerSchema,
tools: z.array(McpbManifestToolSchema).optional(),
tools_generated: z.boolean().optional(),
prompts: z.array(McpbManifestPromptSchema).optional(),
prompts_generated: z.boolean().optional(),
keywords: z.array(z.string()).optional(),
license: z.string().optional(),
privacy_policies: z.array(z.string().url()).optional(),
compatibility: McpbManifestCompatibilitySchema.optional(),
user_config: z
.record(z.string(), McpbUserConfigurationOptionSchema)
.optional(),
})
.refine((data) => !!(data.dxt_version || data.manifest_version), {
message:
"Either 'dxt_version' (deprecated) or 'manifest_version' must be provided",
});
export const McpbSignatureInfoSchema = z.strictObject({
status: z.enum(["signed", "unsigned", "self-signed"]),
publisher: z.string().optional(),
issuer: z.string().optional(),
valid_from: z.string().optional(),
valid_to: z.string().optional(),
fingerprint: z.string().optional(),
});

126
src/schemas/0.3.ts Normal file
View file

@ -0,0 +1,126 @@
// WIP: This schema is under development and not yet finalized
import * as z from "zod";
export const MANIFEST_VERSION = "0.3";
export const McpServerConfigSchema = z.strictObject({
command: z.string(),
args: z.array(z.string()).optional(),
env: z.record(z.string(), z.string()).optional(),
});
export const McpbManifestAuthorSchema = z.strictObject({
name: z.string(),
email: z.string().email().optional(),
url: z.string().url().optional(),
});
export const McpbManifestRepositorySchema = z.strictObject({
type: z.string(),
url: z.string().url(),
});
export const McpbManifestPlatformOverrideSchema =
McpServerConfigSchema.partial();
export const McpbManifestMcpConfigSchema = McpServerConfigSchema.extend({
platform_overrides: z
.record(z.string(), McpbManifestPlatformOverrideSchema)
.optional(),
});
export const McpbManifestServerSchema = z.strictObject({
type: z.enum(["python", "node", "binary"]),
entry_point: z.string(),
mcp_config: McpbManifestMcpConfigSchema,
});
export const McpbManifestCompatibilitySchema = z.strictObject({
claude_desktop: z.string().optional(),
platforms: z.array(z.enum(["darwin", "win32", "linux"])).optional(),
runtimes: z
.strictObject({
python: z.string().optional(),
node: z.string().optional(),
})
.optional(),
});
export const McpbManifestToolSchema = z.strictObject({
name: z.string(),
description: z.string().optional(),
});
export const McpbManifestPromptSchema = z.strictObject({
name: z.string(),
description: z.string().optional(),
arguments: z.array(z.string()).optional(),
text: z.string(),
});
export const McpbUserConfigurationOptionSchema = z.strictObject({
type: z.enum(["string", "number", "boolean", "directory", "file"]),
title: z.string(),
description: z.string(),
required: z.boolean().optional(),
default: z
.union([z.string(), z.number(), z.boolean(), z.array(z.string())])
.optional(),
multiple: z.boolean().optional(),
sensitive: z.boolean().optional(),
min: z.number().optional(),
max: z.number().optional(),
});
export const McpbUserConfigValuesSchema = z.record(
z.string(),
z.union([z.string(), z.number(), z.boolean(), z.array(z.string())]),
);
export const McpbManifestSchema = z
.strictObject({
$schema: z.string().optional(),
dxt_version: z
.literal(MANIFEST_VERSION)
.optional()
.describe("@deprecated Use manifest_version instead"),
manifest_version: z.literal(MANIFEST_VERSION).optional(),
name: z.string(),
display_name: z.string().optional(),
version: z.string(),
description: z.string(),
long_description: z.string().optional(),
author: McpbManifestAuthorSchema,
repository: McpbManifestRepositorySchema.optional(),
homepage: z.string().url().optional(),
documentation: z.string().url().optional(),
support: z.string().url().optional(),
icon: z.string().optional(),
screenshots: z.array(z.string()).optional(),
server: McpbManifestServerSchema,
tools: z.array(McpbManifestToolSchema).optional(),
tools_generated: z.boolean().optional(),
prompts: z.array(McpbManifestPromptSchema).optional(),
prompts_generated: z.boolean().optional(),
keywords: z.array(z.string()).optional(),
license: z.string().optional(),
privacy_policies: z.array(z.string().url()).optional(),
compatibility: McpbManifestCompatibilitySchema.optional(),
user_config: z
.record(z.string(), McpbUserConfigurationOptionSchema)
.optional(),
_meta: z.record(z.string(), z.record(z.string(), z.any())).optional(),
})
.refine((data) => !!(data.dxt_version || data.manifest_version), {
message:
"Either 'dxt_version' (deprecated) or 'manifest_version' must be provided",
});
export const McpbSignatureInfoSchema = z.strictObject({
status: z.enum(["signed", "unsigned", "self-signed"]),
publisher: z.string().optional(),
issuer: z.string().optional(),
valid_from: z.string().optional(),
valid_to: z.string().optional(),
fingerprint: z.string().optional(),
});

8
src/schemas/index.ts Normal file
View file

@ -0,0 +1,8 @@
export * as v0_1 from "./0.1.js";
export * as v0_2 from "./0.2.js";
export * as v0_3 from "./0.3.js";
export * as latest from "./latest.js";
export {
MANIFEST_VERSION as LATEST_MANIFEST_VERSION,
McpbManifestSchema,
} from "./latest.js";

1
src/schemas/latest.ts Normal file
View file

@ -0,0 +1 @@
export * from "./0.2.js";

126
src/schemas_loose/0.1.ts Normal file
View file

@ -0,0 +1,126 @@
import * as z from "zod";
export const MANIFEST_VERSION = "0.1";
export const McpServerConfigSchema = z.object({
command: z.string(),
args: z.array(z.string()).optional(),
env: z.record(z.string(), z.string()).optional(),
});
export const McpbManifestAuthorSchema = z.object({
name: z.string(),
email: z.string().email().optional(),
url: z.string().url().optional(),
});
export const McpbManifestRepositorySchema = z.object({
type: z.string(),
url: z.string().url(),
});
export const McpbManifestPlatformOverrideSchema =
McpServerConfigSchema.partial();
export const McpbManifestMcpConfigSchema = McpServerConfigSchema.extend({
platform_overrides: z
.record(z.string(), McpbManifestPlatformOverrideSchema)
.optional(),
});
export const McpbManifestServerSchema = z.object({
type: z.enum(["python", "node", "binary"]),
entry_point: z.string(),
mcp_config: McpbManifestMcpConfigSchema,
});
export const McpbManifestCompatibilitySchema = z
.object({
claude_desktop: z.string().optional(),
platforms: z.array(z.enum(["darwin", "win32", "linux"])).optional(),
runtimes: z
.object({
python: z.string().optional(),
node: z.string().optional(),
})
.optional(),
})
.passthrough();
export const McpbManifestToolSchema = z.object({
name: z.string(),
description: z.string().optional(),
});
export const McpbManifestPromptSchema = z.object({
name: z.string(),
description: z.string().optional(),
arguments: z.array(z.string()).optional(),
text: z.string(),
});
export const McpbUserConfigurationOptionSchema = z.object({
type: z.enum(["string", "number", "boolean", "directory", "file"]),
title: z.string(),
description: z.string(),
required: z.boolean().optional(),
default: z
.union([z.string(), z.number(), z.boolean(), z.array(z.string())])
.optional(),
multiple: z.boolean().optional(),
sensitive: z.boolean().optional(),
min: z.number().optional(),
max: z.number().optional(),
});
export const McpbUserConfigValuesSchema = z.record(
z.string(),
z.union([z.string(), z.number(), z.boolean(), z.array(z.string())]),
);
export const McpbManifestSchema = z
.object({
$schema: z.string().optional(),
dxt_version: z
.literal(MANIFEST_VERSION)
.optional()
.describe("@deprecated Use manifest_version instead"),
manifest_version: z.literal(MANIFEST_VERSION).optional(),
name: z.string(),
display_name: z.string().optional(),
version: z.string(),
description: z.string(),
long_description: z.string().optional(),
author: McpbManifestAuthorSchema,
repository: McpbManifestRepositorySchema.optional(),
homepage: z.string().url().optional(),
documentation: z.string().url().optional(),
support: z.string().url().optional(),
icon: z.string().optional(),
screenshots: z.array(z.string()).optional(),
server: McpbManifestServerSchema,
tools: z.array(McpbManifestToolSchema).optional(),
tools_generated: z.boolean().optional(),
prompts: z.array(McpbManifestPromptSchema).optional(),
prompts_generated: z.boolean().optional(),
keywords: z.array(z.string()).optional(),
license: z.string().optional(),
compatibility: McpbManifestCompatibilitySchema.optional(),
user_config: z
.record(z.string(), McpbUserConfigurationOptionSchema)
.optional(),
_meta: z.record(z.string(), z.record(z.string(), z.any())).optional(),
})
.refine((data) => !!(data.dxt_version || data.manifest_version), {
message:
"Either 'dxt_version' (deprecated) or 'manifest_version' must be provided",
});
export const McpbSignatureInfoSchema = z.object({
status: z.enum(["signed", "unsigned", "self-signed"]),
publisher: z.string().optional(),
issuer: z.string().optional(),
valid_from: z.string().optional(),
valid_to: z.string().optional(),
fingerprint: z.string().optional(),
});

127
src/schemas_loose/0.2.ts Normal file
View file

@ -0,0 +1,127 @@
import * as z from "zod";
export const MANIFEST_VERSION = "0.2";
export const McpServerConfigSchema = z.object({
command: z.string(),
args: z.array(z.string()).optional(),
env: z.record(z.string(), z.string()).optional(),
});
export const McpbManifestAuthorSchema = z.object({
name: z.string(),
email: z.string().email().optional(),
url: z.string().url().optional(),
});
export const McpbManifestRepositorySchema = z.object({
type: z.string(),
url: z.string().url(),
});
export const McpbManifestPlatformOverrideSchema =
McpServerConfigSchema.partial();
export const McpbManifestMcpConfigSchema = McpServerConfigSchema.extend({
platform_overrides: z
.record(z.string(), McpbManifestPlatformOverrideSchema)
.optional(),
});
export const McpbManifestServerSchema = z.object({
type: z.enum(["python", "node", "binary"]),
entry_point: z.string(),
mcp_config: McpbManifestMcpConfigSchema,
});
export const McpbManifestCompatibilitySchema = z
.object({
claude_desktop: z.string().optional(),
platforms: z.array(z.enum(["darwin", "win32", "linux"])).optional(),
runtimes: z
.object({
python: z.string().optional(),
node: z.string().optional(),
})
.optional(),
})
.passthrough();
export const McpbManifestToolSchema = z.object({
name: z.string(),
description: z.string().optional(),
});
export const McpbManifestPromptSchema = z.object({
name: z.string(),
description: z.string().optional(),
arguments: z.array(z.string()).optional(),
text: z.string(),
});
export const McpbUserConfigurationOptionSchema = z.object({
type: z.enum(["string", "number", "boolean", "directory", "file"]),
title: z.string(),
description: z.string(),
required: z.boolean().optional(),
default: z
.union([z.string(), z.number(), z.boolean(), z.array(z.string())])
.optional(),
multiple: z.boolean().optional(),
sensitive: z.boolean().optional(),
min: z.number().optional(),
max: z.number().optional(),
});
export const McpbUserConfigValuesSchema = z.record(
z.string(),
z.union([z.string(), z.number(), z.boolean(), z.array(z.string())]),
);
export const McpbManifestSchema = z
.object({
$schema: z.string().optional(),
dxt_version: z
.literal(MANIFEST_VERSION)
.optional()
.describe("@deprecated Use manifest_version instead"),
manifest_version: z.literal(MANIFEST_VERSION).optional(),
name: z.string(),
display_name: z.string().optional(),
version: z.string(),
description: z.string(),
long_description: z.string().optional(),
author: McpbManifestAuthorSchema,
repository: McpbManifestRepositorySchema.optional(),
homepage: z.string().url().optional(),
documentation: z.string().url().optional(),
support: z.string().url().optional(),
icon: z.string().optional(),
screenshots: z.array(z.string()).optional(),
server: McpbManifestServerSchema,
tools: z.array(McpbManifestToolSchema).optional(),
tools_generated: z.boolean().optional(),
prompts: z.array(McpbManifestPromptSchema).optional(),
prompts_generated: z.boolean().optional(),
keywords: z.array(z.string()).optional(),
license: z.string().optional(),
privacy_policies: z.array(z.string().url()).optional(),
compatibility: McpbManifestCompatibilitySchema.optional(),
user_config: z
.record(z.string(), McpbUserConfigurationOptionSchema)
.optional(),
})
.passthrough()
.refine((data) => !!(data.dxt_version || data.manifest_version), {
message:
"Either 'dxt_version' (deprecated) or 'manifest_version' must be provided",
});
export const McpbSignatureInfoSchema = z.object({
status: z.enum(["signed", "unsigned", "self-signed"]),
publisher: z.string().optional(),
issuer: z.string().optional(),
valid_from: z.string().optional(),
valid_to: z.string().optional(),
fingerprint: z.string().optional(),
});

View file

@ -0,0 +1,3 @@
export * as v0_1 from "./0.1.js";
export * as v0_2 from "./0.2.js";
export * as latest from "./latest.js";

View file

@ -0,0 +1 @@
export * from "./0.2.js";

37
src/shared/constants.ts Normal file
View file

@ -0,0 +1,37 @@
import { McpbManifestSchema as ManifestSchemaV0_1 } from "../schemas/0.1.js";
import { McpbManifestSchema as ManifestSchemaV0_2 } from "../schemas/0.2.js";
import { McpbManifestSchema as CurrentManifestSchema } from "../schemas/latest.js";
import { McpbManifestSchema as LooseManifestSchemaV0_1 } from "../schemas_loose/0.1.js";
import { McpbManifestSchema as LooseManifestSchemaV0_2 } from "../schemas_loose/0.2.js";
import { McpbManifestSchema as CurrentLooseManifestSchema } from "../schemas_loose/latest.js";
/**
* Latest manifest version - the version that new manifests should use
*/
export const LATEST_MANIFEST_VERSION = "0.2" as const;
/**
* Map of manifest versions to their strict schemas
*/
export const MANIFEST_SCHEMAS = {
"0.1": ManifestSchemaV0_1,
"0.2": ManifestSchemaV0_2,
} as const;
/**
* Map of manifest versions to their loose schemas (with passthrough)
*/
export const MANIFEST_SCHEMAS_LOOSE = {
"0.1": LooseManifestSchemaV0_1,
"0.2": LooseManifestSchemaV0_2,
} as const;
/**
* Get the latest manifest schema based on LATEST_MANIFEST_VERSION
*/
export const LATEST_MANIFEST_SCHEMA = CurrentManifestSchema;
/**
* Get the latest loose manifest schema based on LATEST_MANIFEST_VERSION
*/
export const LATEST_MANIFEST_SCHEMA_LOOSE = CurrentLooseManifestSchema;

View file

@ -14,7 +14,7 @@ import type {
McpbUserConfigurationOptionSchema,
McpbUserConfigValuesSchema,
McpServerConfigSchema,
} from "./schemas.js";
} from "./schemas/latest.js";
export type McpServerConfig = z.infer<typeof McpServerConfigSchema>;

View file

@ -2,7 +2,7 @@ import { execSync } from "node:child_process";
import fs from "node:fs";
import { join } from "node:path";
import { CURRENT_MANIFEST_VERSION } from "../src/schemas.js";
import { LATEST_MANIFEST_VERSION } from "../src/schemas/index.js";
interface ExecSyncError extends Error {
stdout: Buffer;
@ -93,7 +93,7 @@ describe("DXT CLI", () => {
fs.writeFileSync(
join(tempDir, "manifest.json"),
JSON.stringify({
manifest_version: CURRENT_MANIFEST_VERSION,
manifest_version: LATEST_MANIFEST_VERSION,
name: "Test Extension",
version: "1.0.0",
description: "A test extension",
@ -190,7 +190,7 @@ describe("DXT CLI", () => {
fs.writeFileSync(
join(tempExecDir, "manifest.json"),
JSON.stringify({
manifest_version: CURRENT_MANIFEST_VERSION,
manifest_version: LATEST_MANIFEST_VERSION,
name: "Test Executable Extension",
version: "1.0.0",
description: "A test extension with executable files",

View file

@ -90,7 +90,7 @@ describe("getMcpConfigForManifest", () => {
};
const baseManifest: McpbManifest = {
manifest_version: "1.0.0",
manifest_version: "0.2",
name: "test-extension",
version: "1.0.0",
description: "Test extension",
@ -305,7 +305,7 @@ describe("getMcpConfigForManifest", () => {
describe("hasRequiredConfigMissing", () => {
const baseManifest: McpbManifest = {
manifest_version: "1.0.0",
manifest_version: "0.2",
name: "test-extension",
version: "1.0.0",
description: "Test extension",

Some files were not shown because too many files have changed in this diff Show more