Skip to content

feat(cli/mcp): 'zeus mcp' subcommand scaffold#24

Merged
kanywst merged 6 commits into
mainfrom
feat/mcp-server
May 25, 2026
Merged

feat(cli/mcp): 'zeus mcp' subcommand scaffold#24
kanywst merged 6 commits into
mainfrom
feat/mcp-server

Conversation

@kanywst
Copy link
Copy Markdown
Member

@kanywst kanywst commented May 24, 2026

Goal

Add zeus mcp (and equivalent code mcp) as a CLI subcommand. This is the entry point for exposing Zeus as an MCP server. Real implementation lands in a follow-up; this PR scaffolds the surface so other PRs can hang implementation off it.

Design doc: docs/zeus-mcp-server.md

What this PR ships

  • cli/src/commands/mcp.rs — stub command handler
  • cli/src/commands/args.rsMcpArgs { --transport, --port, --workspace } + McpTransport { Stdio, Sse }
  • cli/src/commands.rs — module registration
  • cli/src/bin/code/main.rs — dispatch
  • docs/zeus-mcp-server.md — design / tool surface

Verified locally

  • cargo check passes
  • cargo build --bin code passes
  • ./target/debug/code mcp --help shows the new options
  • ./target/debug/code mcp and ./target/debug/code mcp --transport sse --port 8000 dispatch to the stub correctly

Acceptance criteria (when impl lands)

  • code mcp boots, prints transport info, accepts an MCP initialize request
  • buffer_get / buffer_set round-trip a small file in tests
  • Refuses paths outside --workspace
  • Plays nicely as a subprocess of Claude Code CLI

Depends on: feat/zeus-conventions (for .zeus/mcp.json shape, only loosely)

Part of the MCP-first pivot. See zeus-internal/ARCHITECTURE.md.

Summary by CodeRabbit

  • New Features

    • Introduced the zeus mcp subcommand with configurable transport selection (Stdio and SSE)
    • Added support for specifying workspace root directory
    • Added SSE server binding address and port configuration options
    • Implemented default security controls restricting non-loopback access
  • Documentation

    • Added documentation detailing MCP server configuration and supported operations

Review Change Stack

Registers 'code mcp' (Zeus's 'zeus mcp') as a clap subcommand that
takes --transport (stdio|sse), --port, and --workspace flags. The
handler is a stub that prints which transport was selected; real
implementation lands in a follow-up PR.

'cargo check' and 'cargo build --bin code' pass locally. Smoke tested:

    $ ./target/debug/code mcp --help
    $ ./target/debug/code mcp
    zeus mcp: stdio transport not yet implemented (workspace=...)

Design doc: docs/zeus-mcp-server.md
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 24, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7e23692a-e115-4fda-bb49-23b30784043b

📥 Commits

Reviewing files that changed from the base of the PR and between b82d214 and ec322b0.

📒 Files selected for processing (5)
  • cli/src/bin/code/main.rs
  • cli/src/commands.rs
  • cli/src/commands/args.rs
  • cli/src/commands/mcp.rs
  • docs/zeus-mcp-server.md

📝 Walkthrough

Walkthrough

This PR scaffolds a new zeus mcp CLI subcommand to expose the editor as a Model Context Protocol server. It defines argument types for transport and workspace selection, wires the dispatcher, validates workspace and enforces loopback-only binding defaults, and documents the planned feature.

Changes

MCP Command Scaffolding

Layer / File(s) Summary
MCP command arguments and transport types
cli/src/commands/args.rs
The Commands enum gains a new Mcp variant holding McpArgs, which defines transport selection, SSE bind address/port, allow-non-loopback flag, and optional workspace root. McpTransport enumerates Stdio and Sse variants for Clap parsing.
CLI module export and command dispatch wiring
cli/src/commands.rs, cli/src/bin/code/main.rs
The mcp module is exported from commands, and the CLI dispatcher imports the mcp handler and adds a match arm routing Commands::Mcp to the async mcp entrypoint with logger context.
MCP entry-point scaffold with workspace and transport validation
cli/src/commands/mcp.rs
The mcp async function resolves workspace from args or CWD, canonicalizes and validates it is a directory, then branches on transport: Stdio and Sse both return not-implemented errors (Sse enforces loopback-only binding unless opt-in flag is set), with workspace and config details in the error.
MCP server documentation
docs/zeus-mcp-server.md
Documents the zeus mcp subcommand syntax and flags, enumerates the planned MCP tool surface, describes authentication and workspace isolation behavior, and notes that this PR is scaffolding-only with stub responses pending implementation.

🎯 2 (Simple) | ⏱️ ~10 minutes

🐰 A new CLI command hops into view,
MCP transport routes both old and new,
Workspace validated, loopback in place,
The server scaffold finds its place!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.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
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title accurately describes the main change: adding a new 'zeus mcp' subcommand scaffold to the CLI, which is the primary focus of the changeset.
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 feat/mcp-server

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 implements a scaffold for the Model Context Protocol (MCP) server, adding a new mcp subcommand to the CLI with support for stdio and sse transports. The changes include argument parsing, a stub implementation for the command, and detailed documentation. Review feedback identifies a type mismatch in the main command dispatcher that would prevent compilation, recommends more robust error handling when resolving the current working directory, and suggests correcting documentation to ensure diagnostic output is consistently directed to stderr.

Comment thread cli/src/bin/code/main.rs Outdated
Comment thread cli/src/commands/mcp.rs Outdated
Comment thread docs/zeus-mcp-server.md Outdated
@kanywst kanywst marked this pull request as ready for review May 24, 2026 11:56
- cli/src/commands/mcp.rs: replace expect() on current_dir() with ?
  via wrap(). Prevents a panic if cwd is inaccessible.
- docs/zeus-mcp-server.md: clarify that the chosen SSE port is printed
  on stderr (was 'stdout'). Stdout is reserved for protocol traffic on
  stdio transport; stderr is consistent across transports.

cargo check passes.
@kanywst
Copy link
Copy Markdown
Member Author

kanywst commented May 24, 2026

Re. main.rs:107 type mismatch — checked locally and this is a false positive. All match arms in the Some(args::Commands::...) block resolve to Result<i32, AnyError>:

  • serve_web::serve_web(...) (line 104) — async fn returning Result<i32, AnyError>
  • agent_ps::agent_ps(...) (line 110) — same shape
  • mcp::mcp(mcp_args).await (the new arm) — same shape

cargo check and cargo build --bin code both pass, and the subcommand dispatches correctly when invoked. No fix needed.

@kanywst
Copy link
Copy Markdown
Member Author

kanywst commented May 24, 2026

/gemini review

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 scaffolds the Model Context Protocol (MCP) server integration for the Zeus CLI, introducing the mcp subcommand and its associated configuration arguments. The feedback focuses on maintaining architectural consistency by passing CommandContext to the new command handler and ensuring the CLI implementation matches the design documentation. Specifically, suggestions were made to include missing network binding arguments, canonicalize workspace paths for security, and correct a contradiction in the documentation regarding whether authentication tokens are printed to stdout or stderr.

Comment thread cli/src/bin/code/main.rs Outdated
Comment thread cli/src/commands/args.rs
Comment thread cli/src/commands/mcp.rs Outdated
Comment thread cli/src/commands/mcp.rs Outdated
Comment thread docs/zeus-mcp-server.md Outdated
… canonicalize workspace

- mcp() now takes CommandContext like every other command handler.
  Real implementation will need it for logging and workbench
  discovery; passing it from the dispatch site now keeps the signature
  stable.
- McpArgs gains '--bind' (defaults to 127.0.0.1) and
  '--allow-non-loopback' (required when --bind is non-loopback). The
  docs already promised these — adding them now to keep the CLI
  surface in lockstep with the design.
- Workspace path is canonicalized at entry. The 'refuse paths outside
  the workspace' security check can then use byte-prefix comparison
  instead of re-resolving relative segments per request.
- docs/zeus-mcp-server.md: fix the stdout/stderr contradiction in
  the auth section. Bearer token is on stderr (stdout is reserved
  for protocol traffic on stdio transport).
@kanywst
Copy link
Copy Markdown
Member Author

kanywst commented May 24, 2026

/gemini review

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 a scaffold for the Model Context Protocol (MCP) server as a new mcp subcommand in the CLI, including argument parsing for transport types and workspace paths. It also adds documentation detailing the server's design and tool surface. Feedback recommends deriving equality traits for the transport enum and implementing validation logic for the workspace directory and security flags.

Comment thread cli/src/commands/args.rs Outdated
Comment thread cli/src/commands/mcp.rs
@kanywst
Copy link
Copy Markdown
Member Author

kanywst commented May 24, 2026

/gemini review

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 a scaffold for the Model Context Protocol (MCP) server in the Zeus CLI, adding a new mcp subcommand with support for stdio and sse transports. The implementation includes workspace canonicalization and basic security checks for network binding. Feedback from the review suggests improving the CLI argument handling by using std::net::IpAddr for the bind parameter to leverage clap's built-in validation, which would also eliminate the need for manual parsing in the command implementation. Additionally, it was noted that the help text should be updated to clarify that only IP literals are supported, as localhost is not compatible with the current parsing logic.

Comment thread cli/src/commands/args.rs Outdated
Comment thread cli/src/commands/args.rs
Comment thread cli/src/commands/mcp.rs Outdated
@kanywst
Copy link
Copy Markdown
Member Author

kanywst commented May 25, 2026

/gemini review

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 a scaffold for the Model Context Protocol (MCP) server within the Zeus CLI, adding the mcp subcommand and its associated argument parsing. The implementation includes workspace path canonicalization and security validations for network binding. Feedback focuses on improving CLI error handling by returning an error code for unimplemented transports and ensuring the documentation synopsis accurately reflects all available command-line flags.

Comment thread cli/src/commands/mcp.rs Outdated
Comment on lines +34 to +64
match args.transport {
McpTransport::Stdio => {
eprintln!(
"zeus mcp: stdio transport not yet implemented (workspace={})",
workspace.display()
);
}
McpTransport::Sse => {
// Refuse to bind to a non-loopback interface without explicit opt-in,
// to keep the default posture local-only. clap already parsed
// `--bind` into `IpAddr`, so no string-level validation needed here.
// See docs/zeus-mcp-server.md.
if !args.bind.is_loopback() && !args.allow_non_loopback {
return Err(SetupError(format!(
"refusing to bind SSE transport on non-loopback address {} \
without --allow-non-loopback (use 127.0.0.1 / ::1 for local-only)",
args.bind
))
.into());
}

eprintln!(
"zeus mcp: sse transport not yet implemented (port={}, bind={}, workspace={})",
args.port,
args.bind,
workspace.display()
);
}
}

Ok(0)
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

The command currently returns Ok(0) after printing that the transport is not yet implemented. For a CLI tool, it is more idiomatic to return an error (e.g., using SetupError) when a requested feature is unavailable, rather than exiting with a success code. This prevents scripts from proceeding as if the server had successfully started.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Agreed and changed in ec322b0. Both the stdio and sse arms now return SetupError for the unimplemented case, so the process exits non-zero. A script that pipes zeus mcp into an MCP client expecting it to work would otherwise see a silent exit 0 and parse an empty pipe as a successful (but malformed) MCP session.

Comment thread docs/zeus-mcp-server.md Outdated
## Subcommand surface

```text
zeus mcp [--transport stdio|sse] [--port N] [--workspace PATH]
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

The synopsis in the documentation is missing the --bind and --allow-non-loopback flags, which are implemented in the CLI arguments and discussed later in the 'Authentication' section. Including them here would provide a more complete overview of the command surface.

Suggested change
zeus mcp [--transport stdio|sse] [--port N] [--workspace PATH]
zeus mcp [--transport stdio|sse] [--port N] [--bind IP] [--allow-non-loopback] [--workspace PATH]

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Updated in ec322b0. The synopsis now reads zeus mcp [--transport stdio|sse] [--port N] [--bind IP] [--allow-non-loopback] [--workspace PATH], with bullets describing each flag and the loopback-default / acknowledgement-flag relationship.

…is in docs

Address remaining reviewer feedback:

- Replace Ok(0) returns for unimplemented stdio/sse transports with
  SetupError so a script that pipes 'zeus mcp' into a real MCP client
  doesn't appear to succeed silently. The eprintln!() lines were also
  redundant with the SetupError display, so they're folded in.
- Docs synopsis now lists --bind and --allow-non-loopback alongside
  --transport / --port / --workspace; previously the flags were
  implemented and documented further down, but the at-a-glance command
  line was incomplete.
@kanywst kanywst merged commit 2e7fdff into main May 25, 2026
4 checks passed
@kanywst kanywst deleted the feat/mcp-server branch May 25, 2026 14:10
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