Skip to content

refactor: update terminology from "server" to "tool" in MCP components#14

Merged
maximedogawa merged 1 commit into
mainfrom
13-bug-mcp-tools-are-not-loaded-on-native-build
Apr 11, 2026
Merged

refactor: update terminology from "server" to "tool" in MCP components#14
maximedogawa merged 1 commit into
mainfrom
13-bug-mcp-tools-are-not-loaded-on-native-build

Conversation

@maximedogawa
Copy link
Copy Markdown
Collaborator

@maximedogawa maximedogawa commented Apr 11, 2026

  • Changed references in AddServerForm, McpServerCard, and McpToolsPanel to use "tool" instead of "server" for consistency.
  • Updated error messages and UI labels to reflect the new terminology.
  • Enhanced comments and documentation to clarify the purpose of the components related to tools.
  • Introduced a new module for resolving executable paths for subprocesses, improving command handling in the MCP context.

Summary by CodeRabbit

  • New Features

    • Added environment variable override for MCP configuration path resolution
    • Enhanced tool schema compatibility with support for multiple field naming conventions
  • Improvements

    • Improved error messages with resolved command executable paths
    • Refined tool filtering to respect deprecation status correctly
    • Standardized UI terminology throughout the application for consistency: "servers" → "tools", "tools" → "commands"

- Changed references in `AddServerForm`, `McpServerCard`, and `McpToolsPanel` to use "tool" instead of "server" for consistency.
- Updated error messages and UI labels to reflect the new terminology.
- Enhanced comments and documentation to clarify the purpose of the components related to tools.
- Introduced a new module for resolving executable paths for subprocesses, improving command handling in the MCP context.
@maximedogawa maximedogawa self-assigned this Apr 11, 2026
@maximedogawa maximedogawa linked an issue Apr 11, 2026 that may be closed by this pull request
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 11, 2026

📝 Walkthrough

Walkthrough

This PR introduces a new executable path resolver module to centralize CLI command resolution for subprocess spawning, refactors runtime binary candidate generation to use this shared logic, updates MCP tool registry filtering and configuration resolution with environment variable override support, and rewords user-facing MCP terminology from "servers" to "tools" / "commands" throughout the UI.

Changes

Cohort / File(s) Summary
Executable Resolution Infrastructure
src-tauri/src/infrastructure/executable_resolve.rs, src-tauri/src/infrastructure/mod.rs
New module exports runtime_binary_candidates() to generate candidate paths from environment PATH and OS-specific directories, and resolve_command_for_spawn() to locate and validate executables before subprocess spawning.
MCP Registry & Configuration
src-tauri/src/modules/mcp/registry.rs, src-tauri/src/modules/mcp/service.rs, src-tauri/src/modules/mcp/types.rs
Added mcp_tool_count(), tool_names(), and is_empty() registry methods. Updated tool filtering from should_expose_to_model() to is_deprecated_mcp_tool() (removes REDUNDANT_TOOLS allowlist). Added environment variable override (PENGINE_MCP_CONFIG) and debug vs. release config path resolution logic with updated documentation.
MCP Integration Updates
src-tauri/src/modules/mcp/client.rs, src-tauri/src/modules/mcp/transport.rs, src-tauri/src/modules/tool_engine/runtime.rs
Extended parse_tools() to recognize both inputSchema and input_schema fields. Updated StdioTransport::spawn() to resolve commands via new executable resolver with improved error reporting. Refactored runtime.rs to delegate binary candidate generation to centralized resolver.
MCP UI Terminology
src/modules/mcp/components/AddServerForm.tsx, src/modules/mcp/components/McpServerCard.tsx, src/modules/mcp/components/McpToolsPanel.tsx, src/pages/DashboardPage.tsx
Reworded labels, error messages, and section headers from "server" terminology to "tool" / "command" terminology throughout MCP-related components.

Sequence Diagram(s)

sequenceDiagram
    participant Client as StdioTransport::spawn
    participant Resolver as resolve_command_for_spawn
    participant Candidates as runtime_binary_candidates
    participant PATH as System PATH
    participant FileSystem as File System
    
    Client->>Resolver: resolve_command_for_spawn(command)
    Resolver->>Resolver: Check if empty/absolute/contains-separator
    alt Path resolves directly
        Resolver-->>Client: Return original path
    else Need to search
        Resolver->>Candidates: runtime_binary_candidates(name)
        Candidates->>PATH: Scan environment PATH
        Candidates->>FileSystem: Check OS-specific dirs<br/>(Homebrew, /usr/local/bin, etc.)
        Candidates-->>Resolver: Return candidate paths
        Resolver->>FileSystem: Iterate candidates<br/>validate executable bit
        FileSystem-->>Resolver: First valid executable
        Resolver-->>Client: Return resolved path
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

🐰 A rabbit hops through paths so clear,
Finding binaries far and near!
From HOME to /usr with springy feet,
Each tool resolved, the task complete.
No server stands—just tools and commands take the stage! 🥕✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and accurately summarizes the main change: updating MCP component terminology from 'server' to 'tool'.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ 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 13-bug-mcp-tools-are-not-loaded-on-native-build

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

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (4)
src-tauri/src/modules/mcp/service.rs (1)

275-280: Semantic mismatch: logging provider count as "tools".

mcp_tool_count() returns providers.len() (the number of MCP server entries), but the log message says "ready ({n} tool{})". This could mislead users into thinking it's the total number of commands/tools exposed.

If the intent is to log provider count, consider rewording the message:

♻️ Suggested log message clarification
     let n = state.mcp.read().await.mcp_tool_count();
     state
         .emit_log(
             "mcp",
-            &format!("ready ({n} tool{})", if n == 1 { "" } else { "s" }),
+            &format!("ready ({n} provider{})", if n == 1 { "" } else { "s" }),
         )
         .await;

Or, if the intent is to log actual tool/command count:

-    let n = state.mcp.read().await.mcp_tool_count();
+    let n = state.mcp.read().await.tool_names().len();
     state
         .emit_log(
             "mcp",
-            &format!("ready ({n} tool{})", if n == 1 { "" } else { "s" }),
+            &format!("ready ({n} command{})", if n == 1 { "" } else { "s" }),
         )
         .await;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src-tauri/src/modules/mcp/service.rs` around lines 275 - 280, The log message
uses mcp_tool_count() (which returns the number of MCP providers) but text says
"tool(s)", causing a semantic mismatch; update the emit_log call to reflect
providers instead of tools (e.g., "ready ({n} provider{})") or, if you intended
to log the total number of commands/tools, replace the call to mcp_tool_count()
with the correct function that sums commands across providers (or implement a
new method like mcp_command_count()) and use that value in the emit_log call;
adjust the formatting grammar logic (if n == 1) accordingly and keep emit_log
and state.mcp references intact.
src-tauri/src/modules/mcp/registry.rs (1)

146-149: Method name mcp_tool_count is misleading — it counts providers, not tools.

The method returns providers.len(), which is the number of MCP server/provider entries (e.g., dice, te_*), not the total count of individual tools/commands exposed by those providers. The doc comment clarifies the intent, but the method name suggests counting tools.

Consider renaming to provider_count() or server_count() for clarity, or change the implementation to return the actual tool count if that's the intended behavior.

Option 1: Rename to reflect actual behavior
-    /// Number of MCP tools connected (one per `servers` entry in `mcp.json`: `dice`, `te_*`, …).
-    pub fn mcp_tool_count(&self) -> usize {
+    /// Number of MCP providers connected (one per `servers` entry in `mcp.json`: `dice`, `te_*`, …).
+    pub fn provider_count(&self) -> usize {
         self.providers.len()
     }
Option 2: Return actual tool count
     /// Number of MCP tools connected (one per `servers` entry in `mcp.json`: `dice`, `te_*`, …).
-    pub fn mcp_tool_count(&self) -> usize {
-        self.providers.len()
+    pub fn mcp_tool_count(&self) -> usize {
+        self.cached_tool_names.len()
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src-tauri/src/modules/mcp/registry.rs` around lines 146 - 149, The method
mcp_tool_count currently returns self.providers.len() which counts provider
entries, not individual tools; either rename the function to provider_count
(update the doc comment and replace all calls to mcp_tool_count with
provider_count) to reflect the actual behavior, or if the intended behavior is
to count tools, change mcp_tool_count to iterate over self.providers and sum the
per-provider tool counts (e.g., sum the length of each provider's tool list),
and update the doc comment accordingly; reference the mcp_tool_count function
and the providers field when making the change and update all callers/usages.
src-tauri/src/infrastructure/executable_resolve.rs (2)

101-114: Test coverage is too narrow for the new resolver module.

Only absolute-path passthrough is covered. Consider adding cases for PATH candidate resolution and non-executable candidate rejection to prevent subtle regressions.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src-tauri/src/infrastructure/executable_resolve.rs` around lines 101 - 114,
Add unit tests for resolve_command_for_spawn to expand coverage: keep the
existing resolve_keeps_absolute_paths test, then add a test that simulates a
command name found via PATH (e.g., create a temp dir, place an executable file
there, prepend that dir to PATH, call resolve_command_for_spawn("mycmd") and
assert it returns the temp executable PathBuf) and another test that ensures
non-executable candidates are rejected (e.g., place a non-executable file with
the command name in a PATH directory and assert resolve_command_for_spawn
returns an error or a different result per current API). Use the
resolve_command_for_spawn symbol and the tests module to locate where to add
these cases and clean up temp PATH changes after each test.

23-31: Use std::env::var_os + std::env::split_paths for PATH parsing.

The current manual separator splitting is less robust and duplicates cross-platform logic from the standard library. Using var_os handles non-UTF8 environment values correctly, while split_paths provides idiomatic, platform-aware PATH parsing.

♻️ Suggested refactor
-    if let Ok(path_var) = std::env::var("PATH") {
-        let sep = if cfg!(windows) { ';' } else { ':' };
-        for dir in path_var.split(sep) {
-            if dir.is_empty() {
-                continue;
-            }
-            push_candidate(&mut out, Path::new(dir).join(name));
-        }
-    }
+    if let Some(path_var) = std::env::var_os("PATH") {
+        for dir in std::env::split_paths(&path_var) {
+            if dir.as_os_str().is_empty() {
+                continue;
+            }
+            push_candidate(&mut out, dir.join(name));
+        }
+    }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src-tauri/src/infrastructure/executable_resolve.rs` around lines 23 - 31, The
PATH parsing currently uses std::env::var and manual separator logic; replace
this with std::env::var_os and std::env::split_paths to correctly handle
non-UTF8 PATHs and platform-specific separators. In the block that builds
candidates (where push_candidate(&mut out, Path::new(dir).join(name)) is
called), call std::env::var_os("PATH"), and if Some(val) use
std::env::split_paths(&val) to iterate PathBufs, skip empty entries as needed,
join each PathBuf with name, and call push_candidate for each; remove the manual
sep and cfg!(windows) logic. Ensure the rest of the function (including
push_candidate) continues to receive Path values as before.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src-tauri/src/infrastructure/executable_resolve.rs`:
- Around line 101-114: Add unit tests for resolve_command_for_spawn to expand
coverage: keep the existing resolve_keeps_absolute_paths test, then add a test
that simulates a command name found via PATH (e.g., create a temp dir, place an
executable file there, prepend that dir to PATH, call
resolve_command_for_spawn("mycmd") and assert it returns the temp executable
PathBuf) and another test that ensures non-executable candidates are rejected
(e.g., place a non-executable file with the command name in a PATH directory and
assert resolve_command_for_spawn returns an error or a different result per
current API). Use the resolve_command_for_spawn symbol and the tests module to
locate where to add these cases and clean up temp PATH changes after each test.
- Around line 23-31: The PATH parsing currently uses std::env::var and manual
separator logic; replace this with std::env::var_os and std::env::split_paths to
correctly handle non-UTF8 PATHs and platform-specific separators. In the block
that builds candidates (where push_candidate(&mut out,
Path::new(dir).join(name)) is called), call std::env::var_os("PATH"), and if
Some(val) use std::env::split_paths(&val) to iterate PathBufs, skip empty
entries as needed, join each PathBuf with name, and call push_candidate for
each; remove the manual sep and cfg!(windows) logic. Ensure the rest of the
function (including push_candidate) continues to receive Path values as before.

In `@src-tauri/src/modules/mcp/registry.rs`:
- Around line 146-149: The method mcp_tool_count currently returns
self.providers.len() which counts provider entries, not individual tools; either
rename the function to provider_count (update the doc comment and replace all
calls to mcp_tool_count with provider_count) to reflect the actual behavior, or
if the intended behavior is to count tools, change mcp_tool_count to iterate
over self.providers and sum the per-provider tool counts (e.g., sum the length
of each provider's tool list), and update the doc comment accordingly; reference
the mcp_tool_count function and the providers field when making the change and
update all callers/usages.

In `@src-tauri/src/modules/mcp/service.rs`:
- Around line 275-280: The log message uses mcp_tool_count() (which returns the
number of MCP providers) but text says "tool(s)", causing a semantic mismatch;
update the emit_log call to reflect providers instead of tools (e.g., "ready
({n} provider{})") or, if you intended to log the total number of
commands/tools, replace the call to mcp_tool_count() with the correct function
that sums commands across providers (or implement a new method like
mcp_command_count()) and use that value in the emit_log call; adjust the
formatting grammar logic (if n == 1) accordingly and keep emit_log and state.mcp
references intact.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 805d6bdb-0097-4231-856f-2c894733c70d

📥 Commits

Reviewing files that changed from the base of the PR and between 8285cac and edf4697.

📒 Files selected for processing (12)
  • src-tauri/src/infrastructure/executable_resolve.rs
  • src-tauri/src/infrastructure/mod.rs
  • src-tauri/src/modules/mcp/client.rs
  • src-tauri/src/modules/mcp/registry.rs
  • src-tauri/src/modules/mcp/service.rs
  • src-tauri/src/modules/mcp/transport.rs
  • src-tauri/src/modules/mcp/types.rs
  • src-tauri/src/modules/tool_engine/runtime.rs
  • src/modules/mcp/components/AddServerForm.tsx
  • src/modules/mcp/components/McpServerCard.tsx
  • src/modules/mcp/components/McpToolsPanel.tsx
  • src/pages/DashboardPage.tsx

@maximedogawa maximedogawa merged commit 676d3f5 into main Apr 11, 2026
1 check passed
@maximedogawa maximedogawa deleted the 13-bug-mcp-tools-are-not-loaded-on-native-build branch April 11, 2026 20:26
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.

[BUG] MCP Tools are not loaded on native build

1 participant