fix: remove overly broad endsWith guard that double-starts MCP server#137
Open
SyntaxSmith wants to merge 3 commits intosteipete:mainfrom
Open
fix: remove overly broad endsWith guard that double-starts MCP server#137SyntaxSmith wants to merge 3 commits intosteipete:mainfrom
SyntaxSmith wants to merge 3 commits intosteipete:mainfrom
Conversation
When `oracle-mcp` is invoked via an nvm/npm bin symlink, `process.argv[1]`
resolves to a path like `.../bin/oracle-mcp` which matches the
`endsWith("oracle-mcp")` guard in server.ts. This causes `startMcpServer()`
to be called twice — once by `bin/oracle-mcp.ts` and once by the guard —
resulting in two MCP server instances sharing stdin/stdout. Every JSON-RPC
request gets two responses, which violates the protocol and causes Claude
Code (and other MCP clients) to immediately disconnect.
The `endsWith` fallback was originally added for `npx @steipete/oracle
oracle-mcp`, but that path is already handled by `bin/oracle-cli.ts`
(lines 9-12) which checks `process.argv[2] === "oracle-mcp"` and calls
`startMcpServer()` directly. The `import.meta.url` check alone is
sufficient for the case when `server.ts` is run as a standalone script.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR fixes a double-start condition for the oracle-mcp MCP stdio server when invoked via npm/nvm symlinks, which previously resulted in duplicate JSON-RPC responses and client disconnects.
Changes:
- Removed the
process.argv[1]?.endsWith("oracle-mcp")fallback that could triggerstartMcpServer()from module scope even when imported by a bin entrypoint. - Kept the “run when executed directly” guard based solely on the
import.meta.urlcheck.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| } | ||
|
|
||
| if (import.meta.url === `file://${process.argv[1]}` || process.argv[1]?.endsWith("oracle-mcp")) { | ||
| if (import.meta.url === `file://${process.argv[1]}`) { |
Replace the single-flight busy guard in `oracle serve` with a FIFO queue (max 8 pending). When a run arrives while another is active, the server now holds the HTTP connection open (200 + ndjson stream) and sends a "Queued at position N" log event. When the active run finishes, the next queued request is woken and executed immediately. This lets multiple Claude Code sessions (or other MCP clients) share one `oracle serve` instance without getting spurious "busy" errors that previously required manual retry or complex polling workarounds. Queue overflow (>8 pending) returns 429 with `queue_full` instead of 409. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add `mcp` section to `~/.oracle/config.json` that lets operators constrain what callers can pass to the `consult` MCP tool: - `allowedThinkingTimes`: reject or auto-correct disallowed browserThinkingTime values (e.g., block "heavy" when ChatGPT UI only shows Standard/Extended) - `thinkingTimeFallback`: value to substitute when a disallowed thinking time is passed (instead of hard-rejecting) - `defaultModel`: model to use when caller omits it - `maxFiles`: cap on attached files to prevent upload issues - `toolHint`: free-text string prepended to the consult tool description so LLM callers always see operator constraints Policy is enforced server-side in consult.ts before any session is created, so even callers that skip reading skill documentation get hard guardrails. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
oracle-mcpis invoked via nvm/npm bin symlink,process.argv[1]resolves to a path like.../bin/oracle-mcpwhich matches theendsWith("oracle-mcp")guard inserver.ts:43startMcpServer()twice — once frombin/oracle-mcp.tsand once from the module-level guard — creating two MCP server instances on the same stdin/stdoutendsWith("oracle-mcp")fallback. Theimport.meta.urlcheck alone covers the standalone-script case, andbin/oracle-cli.ts(lines 9–12) already handlesnpx @steipete/oracle oracle-mcpTest plan
echo '<init>' | oracle-mcpreturns 1 response line (was 2 before fix)echo '<init>' | oracle oracle-mcpstill returns 1 response line (unaffected)pnpm test:mcp:unit— 5 files, 7 tests passed🤖 Generated with Claude Code