From 1f08795e500cd3cd42f648134574bf939070f0db Mon Sep 17 00:00:00 2001 From: Akshay Dodeja Date: Mon, 19 Oct 2026 10:31:50 -0700 Subject: [PATCH] fix: match the existing OpenAI app's MCP URL in the ZIP OpenAI rejected the upload because the ZIP's MCP URL must match the existing app's exactly, and the app was registered as https://mcp.terminal49.com/ with a trailing slash. Set mcpUrl in openai/listing.json and apply it only to the OpenAI ZIP. Co-Authored-By: Claude Opus 5.5 --- README.md | 2 +- openai/listing.json | 3 ++- scripts/build-openai-zip.mjs | 8 +++++++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 39c82e7..1cfa48e 100644 --- a/README.md +++ b/README.md @@ -100,7 +100,7 @@ account with trade intelligence enabled. ├── .claude-plugin/marketplace.json # Claude Code and Copilot marketplace ├── .cursor-plugin/marketplace.json # Cursor marketplace ├── openai/review.json # OpenAI directory review cases, merged into the ZIP -├── openai/listing.json # OpenAI package name, version, and category for the existing plugin +├── openai/listing.json # OpenAI package name, version, category, and MCP URL for the existing plugin ├── scripts/ │ ├── build-openai-zip.mjs # Builds the OpenAI directory ZIP │ └── validate.mjs diff --git a/openai/listing.json b/openai/listing.json index 052da8a..b5517d2 100644 --- a/openai/listing.json +++ b/openai/listing.json @@ -1,5 +1,6 @@ { "name": "app-69f5795de4a48191a35dc5c448520676", "version": "1.1.0", - "category": "Business & Operations" + "category": "Business & Operations", + "mcpUrl": "https://mcp.terminal49.com/" } diff --git a/scripts/build-openai-zip.mjs b/scripts/build-openai-zip.mjs index e778d16..cdc029c 100644 --- a/scripts/build-openai-zip.mjs +++ b/scripts/build-openai-zip.mjs @@ -33,7 +33,10 @@ await writeStaged( `${JSON.stringify({ ...manifest, name: listing.name, version: listing.version, interface: { ...manifest.interface, category: listing.category }, extensions: { "com.openai": { review, publication } } }, null, 2)}\n`, ); // The Codex-format .mcp.json in the submission guide names only the url. -const servers = Object.fromEntries(Object.entries(mcp.mcpServers).map(([name, { url }]) => [name, { url }])); +// OpenAI requires the ZIP's MCP URL to match the existing app's URL exactly. +const servers = Object.fromEntries( + Object.entries(mcp.mcpServers).map(([name, { url }]) => [name, { url: listing.mcpUrl ?? url }]), +); await writeStaged(".mcp.json", `${JSON.stringify({ mcpServers: servers }, null, 2)}\n`); await cp(join(pluginDir, "skills"), join(stage, "skills"), { recursive: true }); for (const icon of icons) await cp(join(pluginDir, icon), join(stage, icon)); @@ -69,6 +72,9 @@ for (const file of zipped) { if (!/^[a-z0-9]+(-[a-z0-9]+)*$/.test(listing.name ?? "") || listing.name.length > 64) { errors.push("openai/listing.json name must be the OpenAI package name"); } +if (listing.mcpUrl !== undefined && !/^https:\/\/mcp\.terminal49\.com(\/[a-z]*)?$/.test(listing.mcpUrl)) { + errors.push("openai/listing.json mcpUrl must be a Terminal49 MCP https URL"); +} if (!listing.category) errors.push("openai/listing.json category must match the dashboard category title"); if (!/^\d+\.\d+\.\d+$/.test(listing.version ?? "")) errors.push("openai/listing.json version must be semver"); if (Object.keys(servers).length !== 1) errors.push("the ZIP must declare exactly one MCP server");