Skip to content

Unify MCPBManifest: 4 divergent definitions across codebase #66

@shwetank-dev

Description

@shwetank-dev

Problem

The MCPB manifest type/schema is defined independently in 4 places with divergent shapes. There is no single source of truth, and the definitions disagree on required vs optional fields, nesting structure, and which spec version they represent.

1. Registry — apps/registry/src/types.ts:16 (v0.2)

export interface MCPBManifest {
  name: string;
  version: string;
  display_name?: string;
  description?: string;
  author?: { name: string; email?: string; url?: string };
  homepage?: string;
  license?: string;
  icon?: string;
  repository?: { type?: string; url?: string };
  server_type: 'node' | 'python' | 'binary';         // flat, top-level
  platforms?: { [platform: string]: { command?: string; args?: string[]; env?: Record<string, string> } };
  tools?: Array<{ name: string; description?: string }>;
  prompts?: Array<{ name: string; description?: string }>;
  resources?: Array<{ name: string; description?: string }>;
}
  • No manifest_version, no server object, no user_config, no entry_point
  • server_type is flat at the top level
  • platforms map instead of server.mcp_config

2. Registry validator — apps/registry/src/services/manifest-validator.ts

// Imperative validator, accepts BOTH v0.2 and v0.3 shapes:
const serverObj = manifest['server'] as Record<string, unknown> | undefined;
const serverType = (serverObj?.['type'] as string) ?? (manifest['server_type'] as string);
  • Accepts server.type (v0.3) or server_type (v0.2) — loose duck-typing
  • No Zod, no shared schema — hand-rolled instanceof-style checks
  • Validates a different field set than the MCPBManifest interface it type-guards

3. SDK — packages/sdk-typescript/src/cache.ts:37 (v0.3, Zod)

const McpbManifestSchema = z.object({
  manifest_version: z.string(),
  name: z.string(),
  version: z.string(),
  description: z.string(),                              // required (not optional)
  user_config: z.record(z.string(), UserConfigFieldSchema).optional(),
  server: z.object({
    type: z.enum(["node", "python", "binary"]),
    entry_point: z.string(),
    mcp_config: z.object({
      command: z.string(),
      args: z.array(z.string()),
      env: z.record(z.string(), z.string()).optional(),
    }),
  }),
});
  • description is required here, optional in all other definitions
  • Has manifest_version, user_config, nested server.mcp_config
  • Only Zod schema — not shared via packages/schemas

4. Web app — apps/web/src/lib/manifest.ts:40 (v0.3-ish, TypeScript)

export interface MCPBManifest {
  manifest_version: string;
  name: string;
  version: string;
  description?: string;                                  // optional here
  author?: { name: string; email?: string; url?: string };
  homepage?: string;
  license?: string;
  icon?: string;
  user_config?: Record<string, UserConfigField>;
  server?: ManifestServer;                               // optional here
  tools?: Array<{ name: string; description?: string }>;
  prompts?: Array<{ name: string; description?: string }>;
  resources?: Array<{ name: string; description?: string }>;
}
  • v0.3 shape but server and description are optional (SDK requires both)
  • mcp_config and args are optional inside ManifestServer (SDK requires them)
  • No Zod, just TypeScript interfaces

5. CLI — packages/cli/src/commands/packages/run.ts:50 (v0.3, local)

interface McpbManifest {
  manifest_version: string;
  name: string;
  version: string;
  description: string;
  user_config?: Record<string, UserConfigField>;
  server: { type: "node" | "python" | "binary"; entry_point: string; mcp_config: McpConfig };
}

Divergence summary

Field Registry v0.2 Validator SDK v0.3 Web v0.3 CLI v0.3
manifest_version required required required
description optional optional required optional required
server (nested) accepts both required optional required
server_type (flat) required accepts both
user_config optional optional optional
entry_point required optional required
mcp_config required optional required
author optional optional optional
tools/prompts/resources optional validated optional
platforms optional optional

Proposed fix

  1. Create McpbManifestSchema (Zod) in packages/schemas/src/manifest.ts — single source of truth for the v0.3 spec
  2. Export McpbManifest type from packages/schemas — all consumers import from here
  3. Update SDK cache.ts — delete local schema, import from @nimblebrain/mpak-schemas
  4. Update web app manifest.ts — delete local interfaces, import from @nimblebrain/mpak-schemas
  5. Update registry types.ts — either migrate to v0.3 or keep v0.2 as MCPBManifestV2 alongside v0.3
  6. Update registry validator — rewrite using Zod .safeParse() from the shared schema (or keep imperative for backward compat with v0.2 uploads)
  7. CLI local copy — already being removed in Move bundle runtime, config, and cache functions from CLI to SDK #59

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions