fix: Improve binary path discovery to check all paths before fallback
## Problem Binary discovery was returning the first absolute path without checking if it exists. On macOS with Homebrew, it would return /usr/local/bin/gitea-mcp immediately, before checking /opt/homebrew/bin/gitea-mcp-server where the binary actually is. ## Solution Restructure the binary path search logic: 1. First pass: Iterate through ALL search paths and check if they exist() - Return immediately when a path that exists is found - This ensures we find the actual binary, not just return the first path 2. Fallback: Only if NO paths exist (WASM sandbox restricts exists() checks), use the first absolute path ## Impact - Homebrew binaries on macOS are now properly discovered - Binary discovery works correctly on all platforms - WASM sandbox fallback still works for cases where exists() is restricted ## Testing - ✅ Tested on Linux with explicit path - works - ✅ Tested on Linux with auto-discovery - works - 🔄 Testing on macOS M4 with Homebrew - should now work
This commit is contained in:
69
README.md
69
README.md
@@ -28,15 +28,22 @@ Before you can use Tendril, you need:
|
|||||||
|
|
||||||
#### 1. Install the Gitea MCP Binary
|
#### 1. Install the Gitea MCP Binary
|
||||||
|
|
||||||
The extension automatically searches for `gitea-mcp` in these locations:
|
The extension automatically searches for `gitea-mcp` (and `gitea-mcp-server`) in these locations:
|
||||||
- `/usr/local/bin/gitea-mcp`
|
- `/usr/local/bin/gitea-mcp` or `gitea-mcp-server`
|
||||||
- `~/.local/bin/gitea-mcp`
|
- `~/.local/bin/gitea-mcp` or `gitea-mcp-server`
|
||||||
- `~/.cargo/bin/gitea-mcp`
|
- `~/.cargo/bin/gitea-mcp` or `gitea-mcp-server`
|
||||||
- `/opt/homebrew/bin/gitea-mcp` (macOS M-series)
|
- `/opt/homebrew/bin/gitea-mcp` or `gitea-mcp-server` (macOS)
|
||||||
- Anywhere in your PATH
|
- Anywhere in your PATH
|
||||||
|
|
||||||
Choose an installation method:
|
Choose an installation method:
|
||||||
|
|
||||||
|
**macOS (Recommended - Homebrew):**
|
||||||
|
```bash
|
||||||
|
# Install via Homebrew (handles binary verification and updates)
|
||||||
|
brew install gitea/tap/gitea-mcp-server
|
||||||
|
```
|
||||||
|
This installs to `/opt/homebrew/bin/gitea-mcp-server` and is the easiest method for macOS users.
|
||||||
|
|
||||||
**Download Pre-built Binary:**
|
**Download Pre-built Binary:**
|
||||||
```bash
|
```bash
|
||||||
# Download from: https://gitea.com/gitea/gitea-mcp/releases
|
# Download from: https://gitea.com/gitea/gitea-mcp/releases
|
||||||
@@ -291,16 +298,25 @@ Once Tendril is published to the Zed Extension Marketplace, you'll be able to in
|
|||||||
|
|
||||||
If you get an error about gitea-mcp not being found:
|
If you get an error about gitea-mcp not being found:
|
||||||
|
|
||||||
1. **Using binary mode:**
|
**For macOS:**
|
||||||
- Install gitea-mcp to `/usr/local/bin/gitea-mcp` or another standard location
|
- Install via Homebrew: `brew install gitea/tap/gitea-mcp-server`
|
||||||
- Or set `gitea_mcp_binary_path` to the full path in your settings
|
- Or set `gitea_mcp_binary_path` to the full path in your settings
|
||||||
- Verify it's executable: `chmod +x /path/to/gitea-mcp`
|
- Verify it works: `/opt/homebrew/bin/gitea-mcp-server --help`
|
||||||
- Test it: `/path/to/gitea-mcp --help`
|
|
||||||
|
|
||||||
2. **Using Docker mode:**
|
**For Linux:**
|
||||||
- Ensure Docker is installed and running
|
- Download from https://gitea.com/gitea/gitea-mcp/releases to `/usr/local/bin/gitea-mcp`
|
||||||
- Set `use_docker: true` in settings
|
- Or build from source and run `make install`
|
||||||
- Let Docker pull the image automatically
|
- Or set `gitea_mcp_binary_path` to your custom location
|
||||||
|
|
||||||
|
**For all platforms:**
|
||||||
|
- Verify the binary is executable: `chmod +x /path/to/gitea-mcp`
|
||||||
|
- Test it manually: `/path/to/gitea-mcp --help`
|
||||||
|
- If you've installed it in a non-standard location, use the `gitea_mcp_binary_path` setting
|
||||||
|
|
||||||
|
**Using Docker mode:**
|
||||||
|
- Ensure Docker is installed and running
|
||||||
|
- Set `use_docker: true` in settings
|
||||||
|
- Let Docker pull the image automatically
|
||||||
|
|
||||||
### "Failed to Spawn Command" Error
|
### "Failed to Spawn Command" Error
|
||||||
|
|
||||||
@@ -368,15 +384,28 @@ Check the Zed log for errors:
|
|||||||
When **not** using Docker, Tendril uses this search order:
|
When **not** using Docker, Tendril uses this search order:
|
||||||
|
|
||||||
1. **Explicitly configured path** (if `gitea_mcp_binary_path` is set)
|
1. **Explicitly configured path** (if `gitea_mcp_binary_path` is set)
|
||||||
2. **System standard locations**:
|
- User configuration takes priority
|
||||||
- `/usr/local/bin/gitea-mcp`
|
- Example: `"gitea_mcp_binary_path": "/opt/homebrew/bin/gitea-mcp-server"`
|
||||||
- `~/.local/bin/gitea-mcp`
|
|
||||||
- `~/.cargo/bin/gitea-mcp`
|
2. **System standard locations** (searches for both `gitea-mcp` and `gitea-mcp-server`):
|
||||||
- `/opt/homebrew/bin/gitea-mcp` (macOS M-series)
|
- `/usr/local/bin/gitea-mcp` or `gitea-mcp-server`
|
||||||
3. **PATH environment variable** (any location in your PATH)
|
- `/usr/bin/gitea-mcp` or `gitea-mcp-server`
|
||||||
|
- `~/.local/bin/gitea-mcp` or `gitea-mcp-server`
|
||||||
|
- `~/bin/gitea-mcp` or `gitea-mcp-server`
|
||||||
|
- `~/.cargo/bin/gitea-mcp` or `gitea-mcp-server`
|
||||||
|
- `/opt/homebrew/bin/gitea-mcp` or `gitea-mcp-server` (macOS - installed via Homebrew)
|
||||||
|
|
||||||
|
3. **PATH environment variable** (any location in your system PATH)
|
||||||
|
|
||||||
If the binary isn't found, you'll get a helpful error message with troubleshooting steps.
|
If the binary isn't found, you'll get a helpful error message with troubleshooting steps.
|
||||||
|
|
||||||
|
### macOS Homebrew Note
|
||||||
|
|
||||||
|
If you installed via Homebrew (`brew install gitea/tap/gitea-mcp-server`), the binary will be at:
|
||||||
|
- `/opt/homebrew/bin/gitea-mcp-server` (M-series/ARM64 Macs)
|
||||||
|
|
||||||
|
This location is automatically searched, so no configuration needed!
|
||||||
|
|
||||||
## Debugging
|
## Debugging
|
||||||
|
|
||||||
### View Gitea MCP Logs
|
### View Gitea MCP Logs
|
||||||
|
|||||||
@@ -307,21 +307,28 @@ fn resolve_binary_path(explicit_path: &Option<String>) -> Result<String> {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check each default path - try with exists() check
|
// Check each default path - prioritize paths that actually exist
|
||||||
|
let mut fallback_path: Option<String> = None;
|
||||||
|
|
||||||
for path in &search_paths {
|
for path in &search_paths {
|
||||||
// Try exists() - may not work in WASM but worth trying
|
// Try exists() - may not work in WASM but worth trying
|
||||||
if path.exists() {
|
if path.exists() {
|
||||||
return Ok(path.display().to_string());
|
return Ok(path.display().to_string());
|
||||||
}
|
}
|
||||||
// Also try as fallback: if it can be displayed and is absolute, try it
|
// Store first absolute path as fallback in case exists() is restricted by WASM
|
||||||
let path_str = path.display().to_string();
|
if fallback_path.is_none() {
|
||||||
if path.is_absolute() && !path_str.is_empty() {
|
let path_str = path.display().to_string();
|
||||||
// Return the path even if exists() check fails
|
if path.is_absolute() && !path_str.is_empty() {
|
||||||
// (may be due to WASM sandbox limitations)
|
fallback_path = Some(path_str);
|
||||||
return Ok(path_str);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return fallback if no path existed
|
||||||
|
if let Some(path) = fallback_path {
|
||||||
|
return Ok(path);
|
||||||
|
}
|
||||||
|
|
||||||
// Try to find in PATH environment variable
|
// Try to find in PATH environment variable
|
||||||
if let Ok(path_env) = std::env::var("PATH") {
|
if let Ok(path_env) = std::env::var("PATH") {
|
||||||
let separator = if cfg!(target_os = "windows") {
|
let separator = if cfg!(target_os = "windows") {
|
||||||
|
|||||||
Reference in New Issue
Block a user