Skip to content

fix(mcp): harvest trusted workspace MCP config#2770

Merged
Hmbown merged 1 commit into
codex/v0.9.0-stewardshipfrom
codex/harvest-2751-workspace-mcp-config
Jun 5, 2026
Merged

fix(mcp): harvest trusted workspace MCP config#2770
Hmbown merged 1 commit into
codex/v0.9.0-stewardshipfrom
codex/harvest-2751-workspace-mcp-config

Conversation

@Hmbown

@Hmbown Hmbown commented Jun 5, 2026

Copy link
Copy Markdown
Owner

Summary

  • harvest fix(mcp): merge workspace MCP config #2751 so trusted workspaces can merge .codewhale/mcp.json with global MCP config
  • default project stdio MCP cwd to the workspace and reject project cwd escapes
  • route TUI engine, runtime API, doctor, and codewhale mcp read/connect/validate flows through the merged view
  • keep project MCP ignored until workspace trust is recorded in user-owned config; checked-in legacy trust markers do not unlock MCP subprocesses

Verification

  • cargo test -p codewhale-tui workspace_mcp --all-features --locked -- --nocapture
  • cargo test -p codewhale-tui reload_if_config_changed --all-features --locked -- --nocapture
  • cargo test -p codewhale-tui doctor_mcp --all-features --locked -- --nocapture
  • cargo test -p codewhale-tui mcp_pool_call_tool --all-features --locked -- --nocapture
  • cargo fmt --all -- --check
  • git diff --check
  • ./scripts/release/check-versions.sh
  • cargo check -p codewhale-tui --all-features --locked
  • cargo clippy -p codewhale-tui --all-features --locked -- -D warnings
  • python3 scripts/check-coauthor-trailers.py --author-map .github/AUTHOR_MAP --range origin/codex/v0.9.0-stewardship..HEAD --check-authors

Stewardship

Merge global MCP config with trusted workspace .codewhale/mcp.json files so project MCP servers appear in TUI, CLI, doctor, and runtime API flows. Project stdio servers default cwd to the workspace, project cwd escapes are rejected, and project MCP is ignored until workspace trust is recorded in user-owned config.

Fixes #2749

Reported by @yekern

Harvested from PR #2751 by @cyq1017

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Hmbown has reached the 50-review limit for trial accounts. To continue receiving code reviews, upgrade your plan.

@Hmbown Hmbown merged commit 95e2419 into codex/v0.9.0-stewardship Jun 5, 2026
2 checks passed

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

Copy link
Copy Markdown
Contributor

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 workspace-local MCP configurations (".codewhale/mcp.json") that merge with the global configuration, allowing project-specific MCP servers and custom working directories ("cwd") for stdio servers. It updates "McpPool" to track multiple configuration sources and dynamically reload on changes, while also making CLI commands and the runtime API workspace-aware. Feedback on the changes highlights a potential path traversal vulnerability in "crates/tui/src/mcp.rs" where comparing non-canonicalized paths against canonicalized paths could bypass workspace boundary checks; canonicalizing the "cwd" path before validation is recommended to ensure robust security.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread crates/tui/src/mcp.rs
Comment on lines +2653 to +2657
let cwd = match server.cwd.as_deref() {
Some(cwd) if cwd.is_relative() => normalize_path_components(&workspace.join(cwd)),
Some(cwd) => normalize_path_components(cwd),
None => workspace.to_path_buf(),
};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

security-high high

Comparing non-canonicalized paths against canonicalized paths can lead to both false positives (rejecting valid paths due to symlinks in the workspace path) and false negatives (failing to detect path traversal escapes via symlinks pointing outside the workspace).

Resolving symlinks by canonicalizing the cwd path (with a fallback to syntactic normalization if the path does not exist yet) makes the security check robust.

            let cwd = match server.cwd.as_deref() {
                Some(cwd) if cwd.is_relative() => workspace.join(cwd),
                Some(cwd) => cwd.to_path_buf(),
                None => workspace.to_path_buf(),
            };
            let cwd = cwd.canonicalize().unwrap_or_else(|_| normalize_path_components(&cwd));

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.

2 participants