Skip to content

YNU-912: Package SDK MCP for npm publishing#716

Merged
ihsraham merged 2 commits into
mainfrom
codex/package-sdk-mcp
May 6, 2026
Merged

YNU-912: Package SDK MCP for npm publishing#716
ihsraham merged 2 commits into
mainfrom
codex/package-sdk-mcp

Conversation

@ihsraham
Copy link
Copy Markdown
Collaborator

@ihsraham ihsraham commented Apr 30, 2026

Summary

Packages sdk/mcp for public npm distribution as @yellow-org/sdk-mcp, so Claude, Codex, Cursor, VS Code, and other stdio MCP clients can run the Yellow SDK / Nitrolite protocol context server without cloning the Nitrolite monorepo.

What changed

  • Adds npm publish metadata for sdk/mcp: compiled dist entrypoint, executable yellow-sdk-mcp bin, public publish config, minimal package files, and mcpName.
  • Adds a release-time content/ snapshot builder so published installs can serve SDK/protocol docs from packaged files while local monorepo development still reads live source first.
  • Adds server_info for package, SDK, compat, Go module, protocol, transport, and content-mode debugging.
  • Adds MCP Registry metadata in server.json and a tag-triggered mcp-v* workflow that builds, packs, validates, smoke-tests, publishes to npm, then publishes registry metadata.
  • Updates the README with install snippets for Claude Code, Claude Desktop, Codex, Cursor, VS Code, and local development.

Release safety

The workflow now publishes the exact tarball it verifies. It asserts critical package paths, blocks source/test file leakage, installs the packed tarball into a temp app, and exercises packaged-snapshot mode through server_info, lookup_method, and lookup_rpc_method before publish.

mcp-publisher is pinned to v1.7.6 with SHA256 verification instead of using a floating latest download.

Validation run locally

  • npm run typecheck from sdk/mcp
  • npm run build from sdk/mcp
  • package contents assertion against npm pack --json
  • temp tarball install + MCP client smoke test for server_info, lookup_method, and lookup_rpc_method
  • MCP Registry metadata validation
  • git diff --cached --check

Notes for reviewers

  • Package version intentionally mirrors @yellow-org/sdk (1.2.1) so @yellow-org/sdk-mcp@^1 tracks v1 SDK docs.
  • Commit was created with --no-gpg-sign because the local 1Password SSH signing agent failed during commit creation.

Summary by CodeRabbit

Release Notes

  • New Features

    • Added server_info tool providing server metadata and version information.
    • Enabled npm package distribution with automated MCP registry publishing.
    • Runtime now prefers local sources with fallback to packaged content snapshots.
  • Documentation

    • Expanded README with setup guides for multiple MCP clients (Claude, Cursor, VS Code).
    • Added publishing documentation and version policy.
  • Chores

    • Version bumped to 1.2.1.
    • Enhanced package validation and verification workflows.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 30, 2026

📝 Walkthrough

Walkthrough

The PR establishes a complete publishing pipeline for the Yellow SDK MCP server package. It adds a GitHub Actions workflow that validates package contents, performs smoke tests, publishes to npm, and registers with the MCP registry. Supporting changes include package metadata restructuring, content preparation scripts, runtime logic for supporting both monorepo and packaged content modes, and expanded documentation covering multiple client integrations.

Changes

Package Publishing & Content Management

Layer / File(s) Summary
Package Manifest & Metadata
sdk/mcp/package.json, sdk/mcp/server.json, sdk/mcp/.gitignore
Version bumped to 1.2.1; main entry shifted to dist/index.js with typings; bin renamed to yellow-sdk-mcp; files whitelist expanded to include dist, content, README.md, server.json. New server.json manifest declares MCP server identity, registry metadata, and stdio transport configuration. Content directory added to .gitignore.
Content Preparation & Validation
sdk/mcp/scripts/prepare-package-content.mjs, sdk/mcp/scripts/verify-package-content.mjs, sdk/mcp/scripts/verify-release-preflight.mjs, sdk/mcp/scripts/set-executable.mjs
New scripts prepare release content by copying specified source trees, generate release.json and manifest.json metadata with SHA-256 hashes. Verification scripts validate pack integrity (required/prohibited files, cross-file consistency), confirm version matching across manifests, and verify npm package and Git tag availability. Executable marking script ensures compiled binaries have proper permissions.
Server Runtime & Version Management
sdk/mcp/src/index.ts
Server branding updated to Yellow SDK. Startup logic now prefers monorepo source files with fallback to packaged content/ snapshot. Version identity derived at runtime from multiple package.json files (PACKAGE_ROOT, ts, ts-compat) rather than static constants. New server_info MCP tool exposes metadata (versions, content mode, manifest stats). Content manifest (release.json, manifest.json) loaded with runtime guards. Scaffold templates updated to use dynamic version and Go module references.
Publishing Workflow & Documentation
.github/workflows/publish-sdk-mcp.yml, sdk/mcp/README.md
New 320-line CI workflow triggers on version tags (mcp-v*) to verify pack content, run smoke tests against live MCP server, validate registry metadata consistency, publish tarball to npm with provenance, and publish MCP registry metadata. README rebranded to Yellow SDK, expanded with concrete setup examples for Claude Code/Desktop, Codex, Cursor, and VS Code including config snippets and npx commands. New "Publishing" section documents build/pack/publish commands, tarball contents, release workflow, and version policy.

Sequence Diagram

sequenceDiagram
    participant Trigger as Git Tag<br/>mcp-v*
    participant GHA as GitHub Actions
    participant Pack as npm pack
    participant Test as Smoke Test<br/>(stdio)
    participant NPM as npm Registry
    participant Verify as verify-release<br/>-preflight
    participant Registry as MCP Registry
    
    Trigger->>GHA: Trigger on mcp-v* tag
    GHA->>GHA: Install deps, build
    GHA->>Pack: Run npm pack
    Pack-->>GHA: tarball created
    GHA->>Test: Install tarball, connect to server
    Test->>Test: Assert tools, versions, content mode
    Test-->>GHA: Smoke test passed
    GHA->>Verify: Validate versions across<br/>package.json, server.json,<br/>release.json
    Verify-->>GHA: Preflight passed
    GHA->>NPM: Publish with NPM_TOKEN<br/>+ provenance
    NPM-->>GHA: Published
    GHA->>Registry: Download mcp-publisher,<br/>login with github-oidc
    GHA->>Registry: Publish MCP registry<br/>metadata
    Registry-->>GHA: Metadata published
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Suggested reviewers

  • philanton
  • dimast-x
  • nksazonov

Poem

🐇 A hop through version fields and files,
Where packaged content reconciles,
From monorepo roots to npm's shore,
Yellow SDK opens up the door!
With tests and tags and registry cheer, 🎉

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 9.09% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'YNU-912: Package SDK MCP for npm publishing' clearly and directly summarizes the main objective of the pull request—preparing the SDK MCP for npm distribution.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/package-sdk-mcp

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@ihsraham ihsraham force-pushed the codex/package-sdk-mcp branch from 59ef506 to daebf7f Compare April 30, 2026 07:21
@ihsraham ihsraham marked this pull request as ready for review April 30, 2026 07:26
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
sdk/mcp/src/index.ts (1)

28-29: ⚡ Quick win

Avoid hardcoded release versions in runtime metadata and scaffolds.

'1.2.1'/'v1.2.1' literals can drift on the next release and make server_info plus generated go.mod inaccurate. Derive these from runtime package versions instead.

Suggested fix
-const GO_MODULE_VERSION = 'v1.2.1';
+let GO_MODULE_VERSION = 'unknown';
...
-const serverVersion = readPackageVersion(resolve(PACKAGE_ROOT, 'package.json')) ?? '1.2.1';
+const serverVersion = readPackageVersion(resolve(PACKAGE_ROOT, 'package.json')) ?? 'unknown';
 const sdkVersion = readPackageVersion(resolve(SDK_ROOT, 'package.json')) ?? 'unknown';
 const compatVersion = readPackageVersion(resolve(COMPAT_ROOT, 'package.json')) ?? 'unknown';
+if (sdkVersion !== 'unknown') GO_MODULE_VERSION = `v${sdkVersion}`;

Also applies to: 974-977, 1761-1763, 2056-2056

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@sdk/mcp/src/index.ts` around lines 28 - 29, Replace hardcoded version and
name literals by deriving them from package/module metadata at runtime: update
GO_MODULE_VERSION and SERVER_NAME in sdk/mcp/src/index.ts (and other occurrences
around the noted locations) to read the package version and name (e.g., from
package.json or process env populated from build) and use those values when
composing server_info and generating go.mod; ensure any code that writes go.mod
or server_info uses this derived value so releases don’t drift from actual
package version.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@sdk/mcp/package.json`:
- Line 21: The "build" npm script uses a platform-specific chmod call which
breaks on Windows; update the package.json "build" script (and ensure
"prepublishOnly" still chains correctly) to avoid direct use of chmod by either
1) removing the chmod step and marking the executable via package.json "bin"
metadata, or 2) replacing the chmod call with a cross-platform approach such as
adding a devDependency like "chmod-cli" and invoking it in the "build" script,
or invoking a small Node script that calls fs.chmodSync("dist/index.js", 0o755)
(create a scripts/set-executable.js and call it from "build"); pick one approach
and update package.json scripts and devDependencies accordingly so builds
succeed on Windows and Unix.

In `@sdk/mcp/scripts/prepare-package-content.mjs`:
- Around line 54-56: The code currently logs and continues when a required
sourcePath is missing (the if block using existsSync(sourcePath)), which allows
creating an incomplete snapshot; change this to fail fast by throwing an Error
or calling process.exit(1) with a descriptive message that includes the
relative(repoRoot, sourcePath) so the build aborts immediately; update the block
around existsSync(sourcePath) in prepare-package-content.mjs to stop execution
rather than continue.

---

Nitpick comments:
In `@sdk/mcp/src/index.ts`:
- Around line 28-29: Replace hardcoded version and name literals by deriving
them from package/module metadata at runtime: update GO_MODULE_VERSION and
SERVER_NAME in sdk/mcp/src/index.ts (and other occurrences around the noted
locations) to read the package version and name (e.g., from package.json or
process env populated from build) and use those values when composing
server_info and generating go.mod; ensure any code that writes go.mod or
server_info uses this derived value so releases don’t drift from actual package
version.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b7bf73bc-a523-4a02-a343-12750994641e

📥 Commits

Reviewing files that changed from the base of the PR and between 04619fe and daebf7f.

⛔ Files ignored due to path filters (1)
  • sdk/mcp/package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (7)
  • .github/workflows/publish-sdk-mcp.yml
  • sdk/mcp/.gitignore
  • sdk/mcp/README.md
  • sdk/mcp/package.json
  • sdk/mcp/scripts/prepare-package-content.mjs
  • sdk/mcp/server.json
  • sdk/mcp/src/index.ts

Comment thread sdk/mcp/package.json Outdated
Comment thread sdk/mcp/scripts/prepare-package-content.mjs
@ihsraham ihsraham changed the title [codex] Package SDK MCP for npm publishing YNU-912: Package SDK MCP for npm publishing May 5, 2026
Comment thread .github/workflows/publish-sdk-mcp.yml
Comment thread .github/workflows/publish-sdk-mcp.yml Outdated
Comment thread .github/workflows/publish-sdk-mcp.yml Outdated
Comment thread .github/workflows/publish-sdk-mcp.yml Outdated
Comment thread sdk/mcp/scripts/prepare-package-content.mjs
Comment thread sdk/mcp/package.json Outdated
Comment thread sdk/mcp/src/index.ts Outdated
@ihsraham ihsraham force-pushed the codex/package-sdk-mcp branch from daebf7f to d565102 Compare May 6, 2026 13:44
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
sdk/mcp/scripts/verify-release-preflight.mjs (1)

52-53: 💤 Low value

Optional: Mirror verify-package-content.mjs's explicit npm package presence assertion for clearer errors.

If serverJson.packages happens to omit an npm entry, npmPackage?.version === version fails with the generic "version must match" message even though the entry itself is missing. The companion verify-package-content.mjs asserts presence explicitly (line 68–69) — aligning the two keeps error messages on missing/unmatched entries unambiguous.

♻️ Proposed alignment
 const npmPackage = serverJson.packages.find((entry) => entry.registryType === 'npm');
-assert(npmPackage?.version === version, 'server.json npm package version must match package.json version');
+assert(npmPackage, 'server.json is missing an npm package entry');
+assert(npmPackage.version === version, 'server.json npm package version must match package.json version');
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@sdk/mcp/scripts/verify-release-preflight.mjs` around lines 52 - 53, The
current assertion uses npmPackage?.version which yields a vague failure if the
npm entry is missing; update the check in verify-release-preflight.mjs to first
assert that an npm package entry exists (e.g., assert(npmPackage, 'server.json
must contain an npm package entry')) and only then assert npmPackage.version ===
version so the error messages distinguish "missing npm package" from "version
mismatch"; reference the npmPackage variable and serverJson.packages find logic
when making the change.
.github/workflows/publish-sdk-mcp.yml (1)

126-137: ⚡ Quick win

Brittle exact-count assertions on tools/resources will block unrelated releases.

tools.tools.length !== 9 and resources.resources.length !== 31 will fail the entire publish pipeline the moment anyone adds (or temporarily removes) a tool or resource — even though that change is exactly the kind of thing that should ship in a release. This is inconsistent with the much more forgiving >= 70 floor used at line 162 for contentManifestFiles.

Prefer asserting presence of the tools/resources you actually depend on by name (you already do this for server_info), plus a sane lower-bound on count. That preserves the regression signal (catastrophically empty registries) without coupling CI to incidental inventory.

♻️ Suggested change
           const tools = await client.listTools();
-          if (tools.tools.length !== 9) {
-            throw new Error(`expected 9 tools, got ${tools.tools.length}`);
-          }
-          if (!tools.tools.some((tool) => tool.name === 'server_info')) {
-            throw new Error('server_info tool missing');
-          }
+          const requiredTools = [
+            'server_info',
+            'lookup_method',
+            'lookup_type',
+            'lookup_rpc_method',
+            'scaffold_project',
+          ];
+          for (const name of requiredTools) {
+            if (!tools.tools.some((tool) => tool.name === name)) {
+              throw new Error(`required tool missing: ${name}`);
+            }
+          }
+          if (tools.tools.length < requiredTools.length) {
+            throw new Error(`unexpected tool count ${tools.tools.length}`);
+          }
 
           const resources = await client.listResources();
-          if (resources.resources.length !== 31) {
-            throw new Error(`expected 31 resources, got ${resources.resources.length}`);
+          if (resources.resources.length < 20) {
+            throw new Error(`unexpected resource count ${resources.resources.length}`);
           }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/publish-sdk-mcp.yml around lines 126 - 137, Replace the
brittle exact-count checks on tools and resources with presence checks for the
specific dependencies and a reasonable lower-bound count: when calling
client.listTools() keep the existing presence assertion for 'server_info'
(tools.tools.some(...)) and change the equality check on tools.tools.length !==
9 to a floor check (e.g., tools.tools.length >= <sane_min_tools>) so the
pipeline only fails on catastrophically low inventories; do the same for
client.listResources() (keep any name-based assertions you depend on and change
resources.resources.length !== 31 to resources.resources.length >=
<sane_min_resources>); this mirrors the tolerant approach used for
contentManifestFiles and avoids blocking unrelated releases.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In @.github/workflows/publish-sdk-mcp.yml:
- Around line 126-137: Replace the brittle exact-count checks on tools and
resources with presence checks for the specific dependencies and a reasonable
lower-bound count: when calling client.listTools() keep the existing presence
assertion for 'server_info' (tools.tools.some(...)) and change the equality
check on tools.tools.length !== 9 to a floor check (e.g., tools.tools.length >=
<sane_min_tools>) so the pipeline only fails on catastrophically low
inventories; do the same for client.listResources() (keep any name-based
assertions you depend on and change resources.resources.length !== 31 to
resources.resources.length >= <sane_min_resources>); this mirrors the tolerant
approach used for contentManifestFiles and avoids blocking unrelated releases.

In `@sdk/mcp/scripts/verify-release-preflight.mjs`:
- Around line 52-53: The current assertion uses npmPackage?.version which yields
a vague failure if the npm entry is missing; update the check in
verify-release-preflight.mjs to first assert that an npm package entry exists
(e.g., assert(npmPackage, 'server.json must contain an npm package entry')) and
only then assert npmPackage.version === version so the error messages
distinguish "missing npm package" from "version mismatch"; reference the
npmPackage variable and serverJson.packages find logic when making the change.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 8b893ca4-ec22-4eab-8b44-006f75760f2c

📥 Commits

Reviewing files that changed from the base of the PR and between daebf7f and d565102.

⛔ Files ignored due to path filters (1)
  • sdk/mcp/package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (10)
  • .github/workflows/publish-sdk-mcp.yml
  • sdk/mcp/.gitignore
  • sdk/mcp/README.md
  • sdk/mcp/package.json
  • sdk/mcp/scripts/prepare-package-content.mjs
  • sdk/mcp/scripts/set-executable.mjs
  • sdk/mcp/scripts/verify-package-content.mjs
  • sdk/mcp/scripts/verify-release-preflight.mjs
  • sdk/mcp/server.json
  • sdk/mcp/src/index.ts

Copy link
Copy Markdown
Contributor

@nksazonov nksazonov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well done!

@ihsraham ihsraham merged commit d585fbe into main May 6, 2026
16 checks passed
@ihsraham ihsraham deleted the codex/package-sdk-mcp branch May 6, 2026 15:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants