Skip to content

Add Grok CLI connect support#1015

Open
khaliqgant wants to merge 1 commit into
mainfrom
codex/grok-cli-relay-connect
Open

Add Grok CLI connect support#1015
khaliqgant wants to merge 1 commit into
mainfrom
codex/grok-cli-relay-connect

Conversation

@khaliqgant
Copy link
Copy Markdown
Member

Summary

  • add xAI/Grok to CLI auth config, provider aliases, supported provider lists, and SDK CLI registries
  • configure Relay MCP for Grok via grok mcp add with Relay env vars and track ~/.grok/config.toml side effects
  • include Grok in TS/Python SDK CLI types and worker PATH lookup

Tests

  • npm --prefix packages/config test -- cli-auth-config.test.ts
  • npm test -- --run packages/cloud/src/connect.test.ts
  • npm test -- --run packages/cli/src/cli/commands/cloud.test.ts
  • cargo test -p agent-relay-broker grok_mcp_add_args_use_equals_form_for_dash_args
  • npm run build:config && npm --prefix packages/cloud run build
  • npm --prefix packages/github-primitive run build && npm --prefix packages/slack-primitive run build && npm run build:utils && npm run build:trajectory && npm run build:policy && npm run build:hooks && npm run build:memory && npm run build:telemetry && npm run build:sdk && cd packages/cli && npx tsc --noEmit

@khaliqgant khaliqgant requested a review from willwashburn as a code owner May 29, 2026 08:32
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 29, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 5956e5e6-848e-4b83-8420-0d3a8cd84019

📥 Commits

Reviewing files that changed from the base of the PR and between 9eb948b and 4358c39.

📒 Files selected for processing (15)
  • crates/broker/src/cli_mcp_args.rs
  • crates/broker/src/pty.rs
  • crates/broker/src/snippets.rs
  • packages/cli/src/cli/commands/cloud.test.ts
  • packages/cli/src/cli/lib/auth-ssh.ts
  • packages/cli/src/cli/lib/connect-daytona.ts
  • packages/cloud/src/connect.test.ts
  • packages/cloud/src/connect.ts
  • packages/cloud/src/permissions.ts
  • packages/cloud/src/types.ts
  • packages/config/src/cli-auth-config.test.ts
  • packages/config/src/cli-auth-config.ts
  • packages/sdk-py/src/agent_relay/types.py
  • packages/sdk/src/cli-registry.ts
  • packages/sdk/src/relay.ts

📝 Walkthrough

Walkthrough

This PR adds comprehensive support for Grok (xAI) as a supported CLI provider throughout the relay codebase. Provider aliases map grokxai, CLI registry and PATH resolution enable discovery, auth configuration handles Grok login, and MCP setup configures the relaycast server for Grok integration.

Changes

Grok/xAI Provider Support

Layer / File(s) Summary
Provider type system and aliases
packages/cloud/src/permissions.ts, packages/cloud/src/types.ts, packages/cloud/src/connect.ts, packages/cli/src/cli/lib/auth-ssh.ts, packages/cli/src/cli/lib/connect-daytona.ts, packages/cloud/src/connect.test.ts, packages/cli/src/cli/commands/cloud.test.ts, packages/sdk-py/src/agent_relay/types.py
Exported types updated to include 'grok' in AgentCli and 'xai' in SUPPORTED_PROVIDERS; provider alias mapping added to normalize grokxai across auth-ssh, connect-daytona, and connect modules; JSDoc on ConnectProviderOptions updated; test coverage added for alias normalization and help text inclusion.
CLI discovery and resolution
packages/sdk/src/cli-registry.ts, packages/sdk/src/relay.ts, crates/broker/src/pty.rs
COMMON_SEARCH_PATHS extended to include ~/.grok/bin; CLI_REGISTRY gains grok entry with binary name, non-interactive args (-p <task>), bypass flag (--always-approve), and search path; DEFAULT_AGENT_NAMES maps grokGrok; Unix fallback PATH construction includes ~/.grok/bin and ~/.opencode/bin when PATH is missing.
Authentication configuration
packages/config/src/cli-auth-config.ts, packages/config/src/cli-auth-config.test.ts
New xai provider entry in CLI_AUTH_CONFIG defines Grok login command/args, device-flow support, credential storage at ~/.grok/auth.json, auth URL extraction, success/error patterns, and interactive prompt handlers; test validates command, args, device-flow args, and credential path.
MCP/relaycast configuration for Grok
crates/broker/src/cli_mcp_args.rs, crates/broker/src/snippets.rs
Added grok side-effect file path (~/.grok/config.toml); integrated Grok detection and branching in configure_relaycast_mcp_with_result; implemented configure_grok_mcp async function that executes mcp remove relaycast followed by mcp add relaycast with formatted args (repeated --args=... and --env key=value for API key, base URL, agent identity, tokens, and workspace variables) within 15s timeout; unit test validates Grok MCP arg generation and environment variable inclusion.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • AgentWorkforce/relay#977: Updates relaycast MCP server invocation approach in crates/broker/src/snippets.rs, overlapping with this PR's Grok-specific configure_relaycast_mcp_with_result integration.

Suggested reviewers

  • willwashburn

Poem

🐰 A grok provider hops into the relay,
With xai aliases lighting the way,
Auth flows and registries in place,
MCP configs embrace this new space,
The rabbit declares: "Onward we race!" 🚀

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% 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
Title check ✅ Passed The title 'Add Grok CLI connect support' clearly and concisely summarizes the main objective of the PR, which is to add support for connecting the Grok CLI through the relay system.
Description check ✅ Passed The PR description includes a comprehensive Summary section detailing all major changes and a Tests section listing verification steps, matching the required template structure.
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/grok-cli-relay-connect

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.

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces support for the Grok CLI and xAI provider across the broker, CLI, cloud, and SDK packages, including authentication, MCP configuration, and path resolution. The review feedback identifies two key issues in the broker's MCP setup: a potential deadlock risk caused by piping stderr without reading it, and a blocking synchronous process call on an async thread that should be converted to use Tokio's async command execution.

Comment on lines +1235 to +1279
let mut mcp_cmd = Command::new(&exe);
mcp_cmd.args(grok_mcp_add_args(
api_key,
base_url,
agent_name,
agent_token,
workspaces_json,
default_workspace,
));
mcp_cmd
.stdin(Stdio::null())
.stdout(Stdio::null())
.stderr(Stdio::piped());

match mcp_cmd.spawn() {
Ok(mut child) => match tokio::time::timeout(Duration::from_secs(15), child.wait()).await {
Ok(Ok(status)) if !status.success() => {
anyhow::bail!(
"failed to configure relaycast MCP for {cli}: `{cli} mcp add` exited with code {:?}. \
Please configure the relaycast MCP server manually:\n {manual_cmd}",
status.code()
);
}
Ok(Err(error)) => {
anyhow::bail!(
"failed to configure relaycast MCP for {cli}: {error}. \
Please configure the relaycast MCP server manually:\n {manual_cmd}"
);
}
Err(_) => {
let _ = child.kill().await;
anyhow::bail!(
"failed to configure relaycast MCP for {cli}: `{cli} mcp add` timed out after 15s. \
Please configure the relaycast MCP server manually:\n {manual_cmd}"
);
}
_ => {}
},
Err(error) => {
anyhow::bail!(
"failed to configure relaycast MCP for {cli}: could not run `{cli} mcp add`: {error}. \
Please configure the relaycast MCP server manually:\n {manual_cmd}"
);
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

Piping stderr without reading it introduces a deadlock risk if the child process writes more than the OS pipe buffer limit (typically 64KB), causing it to block indefinitely.

To prevent this and provide better error reporting, we can use child.wait_with_output() to safely read the output into memory, and include the captured stderr in the error message when the command fails. Additionally, configuring .kill_on_drop(true) on the command ensures the child process is automatically cleaned up if the timeout expires.

    let mut mcp_cmd = Command::new(&exe);
    mcp_cmd.kill_on_drop(true);
    mcp_cmd.args(grok_mcp_add_args(
        api_key,
        base_url,
        agent_name,
        agent_token,
        workspaces_json,
        default_workspace,
    ));
    mcp_cmd
        .stdin(Stdio::null())
        .stdout(Stdio::null())
        .stderr(Stdio::piped());

    match mcp_cmd.spawn() {
        Ok(child) => match tokio::time::timeout(Duration::from_secs(15), child.wait_with_output()).await {
            Ok(Ok(output)) if !output.status.success() => {
                let stderr = String::from_utf8_lossy(&output.stderr);
                anyhow::bail!(
                    "failed to configure relaycast MCP for {cli}: `{cli} mcp add` exited with code {:?}.\nStderr: {stderr}\n\
                     Please configure the relaycast MCP server manually:\n  {manual_cmd}",
                    output.status.code()
                );
            }
            Ok(Err(error)) => {
                anyhow::bail!(
                    "failed to configure relaycast MCP for {cli}: {error}. \
                     Please configure the relaycast MCP server manually:\n  {manual_cmd}"
                );
            }
            Err(_) => {
                anyhow::bail!(
                    "failed to configure relaycast MCP for {cli}: `{cli} mcp add` timed out after 15s. \
                     Please configure the relaycast MCP server manually:\n  {manual_cmd}"
                );
            }
            _ => {}
        },
        Err(error) => {
            anyhow::bail!(
                "failed to configure relaycast MCP for {cli}: could not run `{cli} mcp add`: {error}. \
                 Please configure the relaycast MCP server manually:\n  {manual_cmd}"
            );
        }
    }

Comment on lines +1227 to +1233
let _ = std::process::Command::new(&exe)
.args(["mcp", "remove", "relaycast"])
.stdin(Stdio::null())
.stdout(Stdio::null())
.stderr(Stdio::null())
.spawn()
.and_then(|mut child| child.wait());
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

In an asynchronous context, spawning a synchronous process and blocking the thread with std::process::Command and .wait() can block the Tokio executor thread. Since tokio::process::Command is already imported as Command in this file, we should use it to perform the mcp remove operation asynchronously and non-blockingly.

Suggested change
let _ = std::process::Command::new(&exe)
.args(["mcp", "remove", "relaycast"])
.stdin(Stdio::null())
.stdout(Stdio::null())
.stderr(Stdio::null())
.spawn()
.and_then(|mut child| child.wait());
let _ = Command::new(&exe)
.args(["mcp", "remove", "relaycast"])
.stdin(Stdio::null())
.stdout(Stdio::null())
.stderr(Stdio::null())
.status()
.await;

Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

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

1 issue found across 15 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="crates/broker/src/snippets.rs">

<violation number="1" location="crates/broker/src/snippets.rs:1213">
P2: `configure_grok_mcp` duplicates the subprocess orchestration/error-handling logic already implemented in `configure_gemini_droid_mcp`, which increases maintenance drift risk. Consider extracting a shared helper for "remove existing MCP + run mcp add with timeout + standardized error mapping".</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

args
}

async fn configure_grok_mcp(
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2: configure_grok_mcp duplicates the subprocess orchestration/error-handling logic already implemented in configure_gemini_droid_mcp, which increases maintenance drift risk. Consider extracting a shared helper for "remove existing MCP + run mcp add with timeout + standardized error mapping".

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At crates/broker/src/snippets.rs, line 1213:

<comment>`configure_grok_mcp` duplicates the subprocess orchestration/error-handling logic already implemented in `configure_gemini_droid_mcp`, which increases maintenance drift risk. Consider extracting a shared helper for "remove existing MCP + run mcp add with timeout + standardized error mapping".</comment>

<file context>
@@ -1148,6 +1160,127 @@ async fn configure_gemini_droid_mcp(
+    args
+}
+
+async fn configure_grok_mcp(
+    cli: &str,
+    api_key: Option<&str>,
</file context>

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