Skip to content

fix: detect claude CLI with inline args for MCP injection#584

Merged
khaliqgant merged 2 commits intomainfrom
claude-mcp-spawned
Mar 18, 2026
Merged

fix: detect claude CLI with inline args for MCP injection#584
khaliqgant merged 2 commits intomainfrom
claude-mcp-spawned

Conversation

@khaliqgant
Copy link
Member

@khaliqgant khaliqgant commented Mar 18, 2026

Summary

  • fix Claude MCP injection provider detection to parse the CLI command token before matching provider name
  • ensure claude --model style values still get --mcp-config + relaycast server config
  • add regression test for inline-args Claude detection

Why

PR #583 fixed workspace context forwarding, but spawned agents can still miss Relaycast MCP tools when the configured CLI string includes inline args. In that case provider detection could fail and skip MCP config injection.

Testing

  • cargo test claude_ -- --nocapture

Open with Devin

devin-ai-integration[bot]

This comment was marked as resolved.

When cli contains inline args (e.g. 'gemini --model foo'),
Command::new(cli) fails because it treats the entire string as
an executable path. Now extract just the binary via shlex::split
before passing to Command::new and manual_cmd.
@khaliqgant khaliqgant merged commit a4bb3ad into main Mar 18, 2026
39 of 40 checks passed
@khaliqgant khaliqgant deleted the claude-mcp-spawned branch March 18, 2026 12:29
khaliqgant added a commit that referenced this pull request Mar 19, 2026
* fix: detect claude CLI with inline args for MCP injection

* fix: extract executable from cli string in gemini/droid mcp setup

When cli contains inline args (e.g. 'gemini --model foo'),
Command::new(cli) fails because it treats the entire string as
an executable path. Now extract just the binary via shlex::split
before passing to Command::new and manual_cmd.
khaliqgant added a commit that referenced this pull request Mar 19, 2026
* feat: add workflow to polish CLI output with listr2 + chalk

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* ci: add workflow validation and dry-run check on PR

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(ci): fetch full history for git diff, run dry-run on all workflow types

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(sdk): polish workflow CLI output with listr2 spinners and chalk colors

- Replace plain console.log progress in cli.ts with listr2 task list
- Per-step spinners show owner, retry, nudge, force-release, and review events
- chalk colors: cyan for timestamps, green/red/yellow for status, dim for metadata
- logRunSummary() and broker stderr use chalk for visual hierarchy

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* test: add smoke test workflow for listr2 output rendering

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: use ESM-compatible import for check-sdk step

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(sdk): export createWorkflowRenderer for listr2 output in TS workflows

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: pre-attach catch to prevent unhandled rejection on fast-failing steps

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: use worker preset for verify step, mute console during listr rendering

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: filter [broker]/[workflow] noise, show observer URL, add unmount()

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: add missing unhandled-rejection guards and output filter to YAML path

- cli.ts: installOutputFilter() in runWithListr so YAML workflows also
  suppress [broker]/[workflow HH:MM] noise during listr rendering
- cli.ts: done.catch()/workflowDone.catch() guards for fast-failing steps
- listr-renderer.ts: workflowDone.catch() guard for instant run:failed
- listr-renderer.ts: add renderer.unmount() to JSDoc example

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: address PR review feedback for workflow output polish

- Output filter: use regex .test() instead of startsWith/^ anchor so
  chalk-colored [broker] and [workflow HH:MM] lines are properly suppressed
- Resume mode: add event listener for step progress reporting
- GHA workflow: fix grep exit code with || true, use env var instead of
  raw ${{ }} interpolation (script injection), use npx tsx instead of
  non-existent 'run' subcommand, only validate/dry-run YAML files
- Workflow: fix incorrect CJS assumption (SDK is ESM), add final
  type-check gate after review step

* fix: CI failures and skipped-step visibility

- Add chalk and listr2 to root package.json (Build & Validate requires them)
- Dynamic import listr2 so SDK loads on Node 18 (styleText not available)
- Show steps skipped without prior start event in listr output
- Remove unused ListrType import

* fix: detect claude CLI with inline args for MCP injection (#584)

* fix: detect claude CLI with inline args for MCP injection

* fix: extract executable from cli string in gemini/droid mcp setup

When cli contains inline args (e.g. 'gemini --model foo'),
Command::new(cli) fails because it treats the entire string as
an executable path. Now extract just the binary via shlex::split
before passing to Command::new and manual_cmd.

* chore(release): v3.2.8

* bump versions (#590)

* bump versions

* fix: refresh lockfile for relaycast sdk 1.0.0 bump

* fix: bump gemini relay extension to relaycast mcp 1.0.0

* chore(release): v3.2.9

* feat(sdk): polish workflow CLI output with listr2 spinners and chalk colors

- Replace plain console.log progress in cli.ts with listr2 task list
- Per-step spinners show owner, retry, nudge, force-release, and review events
- chalk colors: cyan for timestamps, green/red/yellow for status, dim for metadata
- logRunSummary() and broker stderr use chalk for visual hierarchy

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: MCP tools unavailable for agents spawned via agent_add

Two root causes prevented agents spawned via the Relaycast API
(agent_add MCP tool) from loading MCP tools:

1. Claude: --strict-mcp-config blocked .mcp.json loading. Removed it
   so --mcp-config is additive — only passes relaycast config while
   Claude loads user MCP servers from .mcp.json independently.

2. All CLIs: The WS AgentSpawnRequested handler had no agent
   pre-registration. The AgentSpawnRequestedPayload struct doesn't
   include a token field, so relaycast_ws_spawn_token() always
   returned None. Added broker-side register_agent_token() calls
   (matching the SDK spawn_agent path) to both WS spawn handlers.

Tests:
- New integration test (agent-spawns-agent.test.ts) exercises the
  exact agent_add flow for claude, codex, and gemini
- Updated unit tests and e2e tests for new --mcp-config behavior
- All 220 lib + 8 e2e Rust tests pass

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* style: auto-format Rust code with cargo fmt

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: GitHub Actions <actions@github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
khaliqgant added a commit that referenced this pull request Mar 19, 2026
* feat: add workflow to polish CLI output with listr2 + chalk

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* ci: add workflow validation and dry-run check on PR

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(ci): fetch full history for git diff, run dry-run on all workflow types

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(sdk): polish workflow CLI output with listr2 spinners and chalk colors

- Replace plain console.log progress in cli.ts with listr2 task list
- Per-step spinners show owner, retry, nudge, force-release, and review events
- chalk colors: cyan for timestamps, green/red/yellow for status, dim for metadata
- logRunSummary() and broker stderr use chalk for visual hierarchy

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* test: add smoke test workflow for listr2 output rendering

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: use ESM-compatible import for check-sdk step

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(sdk): export createWorkflowRenderer for listr2 output in TS workflows

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: pre-attach catch to prevent unhandled rejection on fast-failing steps

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: use worker preset for verify step, mute console during listr rendering

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: filter [broker]/[workflow] noise, show observer URL, add unmount()

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: add missing unhandled-rejection guards and output filter to YAML path

- cli.ts: installOutputFilter() in runWithListr so YAML workflows also
  suppress [broker]/[workflow HH:MM] noise during listr rendering
- cli.ts: done.catch()/workflowDone.catch() guards for fast-failing steps
- listr-renderer.ts: workflowDone.catch() guard for instant run:failed
- listr-renderer.ts: add renderer.unmount() to JSDoc example

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: address PR review feedback for workflow output polish

- Output filter: use regex .test() instead of startsWith/^ anchor so
  chalk-colored [broker] and [workflow HH:MM] lines are properly suppressed
- Resume mode: add event listener for step progress reporting
- GHA workflow: fix grep exit code with || true, use env var instead of
  raw ${{ }} interpolation (script injection), use npx tsx instead of
  non-existent 'run' subcommand, only validate/dry-run YAML files
- Workflow: fix incorrect CJS assumption (SDK is ESM), add final
  type-check gate after review step

* fix: CI failures and skipped-step visibility

- Add chalk and listr2 to root package.json (Build & Validate requires them)
- Dynamic import listr2 so SDK loads on Node 18 (styleText not available)
- Show steps skipped without prior start event in listr output
- Remove unused ListrType import

* fix: detect claude CLI with inline args for MCP injection (#584)

* fix: detect claude CLI with inline args for MCP injection

* fix: extract executable from cli string in gemini/droid mcp setup

When cli contains inline args (e.g. 'gemini --model foo'),
Command::new(cli) fails because it treats the entire string as
an executable path. Now extract just the binary via shlex::split
before passing to Command::new and manual_cmd.

* chore(release): v3.2.8

* bump versions (#590)

* bump versions

* fix: refresh lockfile for relaycast sdk 1.0.0 bump

* fix: bump gemini relay extension to relaycast mcp 1.0.0

* chore(release): v3.2.9

* feat(sdk): polish workflow CLI output with listr2 spinners and chalk colors

- Replace plain console.log progress in cli.ts with listr2 task list
- Per-step spinners show owner, retry, nudge, force-release, and review events
- chalk colors: cyan for timestamps, green/red/yellow for status, dim for metadata
- logRunSummary() and broker stderr use chalk for visual hierarchy

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: regenerate lockfile with npm 11 for Node 24 ci compatibility

* fix: address remaining workflow review feedback

- pass yaml path before --validate in workflow validation CI
- add trail start/complete/abandon to polish workflow script
- fix remaining ESM wording/install command in planning prompt
- queue listr tasks before lazy renderer initialization completes

* fix: mark test-only MCP merge helpers as dead-code allowed

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: GitHub Actions <actions@github.com>
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.

1 participant