feat: add stdio bridge and npm publish workflow - #19
Conversation
- Add stdio-bridge.cjs: a stdio MCP proxy that manages oc port-forward internally, enabling local Claude Code sessions to connect to an in-cluster che-mcp-server without manual port-forwarding - Add publish-npm.yml: GitHub Actions workflow that publishes to npm on GitHub Release with provenance - Add che-mcp-bridge bin entry to package.json - Update README with local connection instructions via npx - Set version to 0.0.1 Usage after publish: claude mcp add --transport stdio che-mcp -- npx che-mcp-server che-mcp-bridge Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Signed-off-by: Oleksii Kurinnyi <okurinny@redhat.com>
|
Warning Review limit reached
Next review available in: 41 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
📝 WalkthroughWalkthroughAdds a Node.js stdio-to-HTTP bridge script (stdio-bridge.cjs) that manages oc port-forward and relays JSON-RPC/SSE messages, registers it as a new CLI bin and packaged file, updates package version, documents its usage in README, and introduces a GitHub Actions workflow publishing the package to npm on release. ChangesStdio Bridge Feature
NPM Publish Workflow
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant Client as MCP Client
participant Bridge as stdio-bridge.cjs
participant OC as oc port-forward
participant Service as MCP Service (K8s)
Bridge->>OC: spawn oc port-forward (namespace, service, port)
OC->>Service: forward local port to service port
Bridge->>Bridge: wait for local port readiness
Client->>Bridge: JSON-RPC message via stdin
Bridge->>Service: POST /mcp (with session header)
Service-->>Bridge: JSON or SSE response
Bridge->>Client: write response to stdout
OC--)Bridge: unexpected exit
Bridge->>OC: restart port-forward (up to MAX_RESTARTS)
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
|
Image built: |
|
@coderabbitai review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
Actionable comments posted: 6
🧹 Nitpick comments (2)
.github/workflows/publish-npm.yml (2)
14-14: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick winSet
persist-credentials: falseon checkout to prevent token persistence.
actions/checkout@v4defaults to persisting theGITHUB_TOKENinto the local git config. While this workflow doesn't perform git pushes, disabling credential persistence is a supply-chain hardening best practice that prevents token leakage through cached artifacts or compromised dependencies.🔒️ Proposed hardening
- uses: actions/checkout@v4 + with: + persist-credentials: false🤖 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-npm.yml at line 14, The checkout step in the publish workflow is persisting the GITHUB_TOKEN by default, so update the actions/checkout@v4 usage to disable credential persistence. Add persist-credentials: false to the checkout step in the workflow so the repository is still fetched normally but the token is not stored in local git config.Source: Linters/SAST tools
24-31: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low valueBuild runs twice due to
prepublishOnlyhook.The explicit
npm run buildstep at line 25 and theprepublishOnlyhook (which also runsnpm run build) both execute the build, doubling CI time for this step. Either remove the explicit build step (relying on the hook) or pass--ignore-scriptstonpm publishand keep the explicit build. Removing the explicit step is simpler sinceprepublishOnlyguarantees a build before publish.♻️ Remove redundant build step
- run: npm ci - - name: Build - run: npm run build - - name: Run tests run: npm test🤖 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-npm.yml around lines 24 - 31, The publish workflow is building the package twice because the explicit Build step and the package’s prepublishOnly hook both run npm run build. Update the publish job in publish-npm.yml by removing the standalone build step and letting npm publish invoke prepublishOnly, or alternatively keep the build step and add --ignore-scripts to the npm publish command; the simpler fix is to remove the redundant Build step and leave Run tests and Publish intact.
🤖 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.
Inline comments:
In `@README.md`:
- Around line 26-33: The README’s npx example is invoking the package entrypoint
instead of the che-mcp-bridge bin, so update the “Via npx” command to use npx
with -p che-mcp-server and then call che-mcp-bridge directly. Keep the
global-install example unchanged, and make sure the surrounding setup text in
README clearly distinguishes the npx path from the globally installed bin path.
In `@stdio-bridge.cjs`:
- Around line 31-37: The fallback namespace in detectNamespace is hardcoded to a
personal value, which will be published publicly; remove that default and
replace it with a safe generic fallback or explicit failure path when oc is
unavailable or misconfigured. Update detectNamespace so it either returns the
detected project namespace from execFileSync('oc', ['project', '-q'], ...) or
handles the error without leaking a user-specific namespace, keeping the
behavior in stdio-bridge.cjs generic for all consumers.
- Around line 169-193: The queue drain logic in drain() and rl.on('close') never
exits after stdin has closed and the pending queue is fully processed. Track the
stdin-closed state in the bridge, and when drain() reaches an empty queue after
close, call cleanup() (or equivalent shutdown logic) instead of only setting
processing = false. Make sure the close handler and processLine()/drain() paths
both use the same completion check so the process exits once all queued items
are handled.
- Around line 106-153: The forwardRequest HTTP call in stdio-bridge.cjs can hang
forever because it has no timeout, causing queued stdin lines to stall. Add a
30s timeout to the http.request in forwardRequest, and make sure the timeout
path aborts/destroys the request and rejects or otherwise resolves the promise
cleanly so the bridge can continue processing. Use the existing req/res handling
around req.on('error'), res.on('data'), and res.on('end') to locate the change.
- Around line 179-186: The stdin bridge in processLine should not let JSON.parse
failures escape, because malformed input currently drops the request without any
JSON-RPC response. Update processLine in stdio-bridge.cjs to catch parse errors
around JSON.parse(line) and emit a proper error response for that input before
returning, while keeping the existing forwardRequest and process.stdout.write
flow for valid messages.
- Around line 116-137: The SSE handling in the response parsing path resolves on
the first data event and destroys the stream, so it can drop later events from
the same request. Update the event processing in stdio-bridge.cjs to keep
consuming the full SSE stream, collect each data: payload, and only resolve with
the final JSON-RPC response rather than the first notification. Make the change
in the text/event-stream branch around the res.on('data') logic and the
resolved/res.destroy flow so the parser does not terminate early.
---
Nitpick comments:
In @.github/workflows/publish-npm.yml:
- Line 14: The checkout step in the publish workflow is persisting the
GITHUB_TOKEN by default, so update the actions/checkout@v4 usage to disable
credential persistence. Add persist-credentials: false to the checkout step in
the workflow so the repository is still fetched normally but the token is not
stored in local git config.
- Around line 24-31: The publish workflow is building the package twice because
the explicit Build step and the package’s prepublishOnly hook both run npm run
build. Update the publish job in publish-npm.yml by removing the standalone
build step and letting npm publish invoke prepublishOnly, or alternatively keep
the build step and add --ignore-scripts to the npm publish command; the simpler
fix is to remove the redundant Build step and leave Run tests and Publish
intact.
🪄 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: 7d3d94f7-d998-49c9-81c2-b163f1971766
📒 Files selected for processing (4)
.github/workflows/publish-npm.ymlREADME.mdpackage.jsonstdio-bridge.cjs
- Remove hardcoded personal namespace fallback; exit with clear error message when oc context is unavailable - Add 30s timeout on HTTP forwarding requests - Fix SSE parser to collect all events and resolve with the last response instead of the first (handles notifications before final) - Fix process hang after stdin close with pending queue items - Add JSON.parse error handling for malformed stdin input - Fix npx command in README: use -p flag to specify package - Add persist-credentials: false to checkout step (hardening) - Remove redundant build step (prepublishOnly handles it) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Signed-off-by: Oleksii Kurinnyi <okurinny@redhat.com>
|
All 6 actionable findings and 2 nitpicks addressed in 92b257d: Inline findings (6):
Nitpicks (2):
|
|
Image built: |
Summary
stdio-bridge.cjs— a stdio MCP proxy that managesoc port-forwardinternally, auto-starts, monitors, and restarts on failure. Enables local Claude Code sessions to connect to an in-cluster che-mcp-server without manual port-forwarding.publish-npm.yml— GitHub Actions workflow that publishes to npm on GitHub Release (with provenance).che-mcp-bridgebin entry so users can run vianpx che-mcp-server che-mcp-bridge.How it works
The bridge is a single-file Node.js script (CJS, zero dependencies) that:
occontextoc port-forward svc/che-mcp-server <ephemeral-port>:8080Usage (after npm publish)
Setup required for first publish
NPM_TOKENsecret in the repov0.0.1) — the workflow triggers automaticallyTest plan
echo '{"jsonrpc":"2.0","method":"initialize","id":1,...}' | node stdio-bridge.cjsreturns valid MCP responseSummary by CodeRabbit
New Features
Documentation
Chores