feat: Add binary path resolution and Docker support (v0.1.0)
This release adds intelligent binary discovery and Docker support to Tendril, making it more flexible and cross-platform compatible. ## Features ### Binary Path Resolution - Intelligent binary discovery with smart fallbacks - Explicit user configuration via gitea_mcp_binary_path setting - Standard system paths (/usr/local/bin, /usr/bin) - User home directories (~/.local/bin, ~/.cargo/bin, ~/bin) - Platform-specific paths (/opt/homebrew/bin on macOS M-series) - System PATH environment variable search - Robust WASM sandbox handling for filesystem checks - Comprehensive error messages with troubleshooting guidance - Removed hardcoded /usr/local/bin/gitea-mcp path ### Docker Support - New use_docker configuration option for containerized deployment - New docker_image configuration for custom images (default: gitea/gitea-mcp-server:latest) - Automatic docker binary detection at /usr/bin/docker or other standard locations - Proper gitea-mcp command-line flag formatting (-token, -t stdio, -host, -insecure) - STDIO communication through Docker containers ### Cross-Platform Support - Linux: Standard system and user paths - macOS Intel: Same as Linux - macOS M-series (ARM64): Optimized for /opt/homebrew/bin - Windows: Program Files paths (code ready, untested) - Proper PATH separator handling (: on Unix, ; on Windows) ## Bug Fixes - Fixed WASM sandbox filesystem access limitations - Corrected Docker image name to gitea/gitea-mcp-server:latest - Fixed Docker command flag formatting for gitea-mcp arguments - Improved error handling with helpful resolution steps ## Documentation - Updated README.md with Docker mode examples and configuration reference - Expanded DEVELOPMENT.md with architecture and testing roadmap - Updated PROJECT_STATUS.md with v0.1.0 feature status - Updated configuration with all new options and detailed comments - Added comprehensive inline code comments ## Testing - Binary mode auto-detection: Tested and working - Binary mode custom path: Tested and working - Docker mode with default image: Tested and working - Self-hosted Gitea instances: Tested and working - Self-signed certificate support: Tested and working ## Files Changed - src/mcp_server_gitea.rs: Core extension (~350 lines) - configuration/default_settings.jsonc: New settings - configuration/installation_instructions.md: Updated guide - README.md: Expanded documentation - DEVELOPMENT.md: Complete developer guide - PROJECT_STATUS.md: Updated status - .gitignore: Added comprehensive ignore file ## Breaking Changes None - fully backward compatible. ## Next Steps (v0.2.0) - Cross-platform testing - Interactive configuration wizard - Performance optimizations - Marketplace publication
This commit is contained in:
550
DEVELOPMENT.md
Normal file
550
DEVELOPMENT.md
Normal file
@@ -0,0 +1,550 @@
|
||||
# Tendril Development Guide
|
||||
|
||||
## Current State (v0.1.0)
|
||||
|
||||
Tendril is a Zed IDE extension that integrates with a Gitea MCP server. The extension is now feature-complete with cross-platform binary discovery and Docker support.
|
||||
|
||||
### What's Working
|
||||
|
||||
✅ **Core Extension**
|
||||
- Zed extension loads and compiles successfully
|
||||
- Context server registration working
|
||||
- Settings schema generation implemented
|
||||
- Full configuration through settings.json
|
||||
|
||||
✅ **Binary Path Resolution**
|
||||
- Intelligent search across common installation locations
|
||||
- Cross-platform support (Linux, macOS, Windows)
|
||||
- Explicit path configuration option
|
||||
- Platform-specific paths (e.g., macOS M-series Homebrew)
|
||||
- Comprehensive error messages with troubleshooting steps
|
||||
|
||||
✅ **Docker Support**
|
||||
- Docker mode as alternative to local binary
|
||||
- Configurable Docker image selection
|
||||
- Proper environment variable passing
|
||||
- STDIN/STDOUT communication through Docker
|
||||
|
||||
✅ **Transport Modes**
|
||||
- STDIO mode (default, fully tested) - Direct stdin/stdout communication
|
||||
- Proper argument passing to gitea-mcp binary
|
||||
- Environment variable setup for authentication
|
||||
|
||||
✅ **Configuration**
|
||||
- Gitea access token setting (required)
|
||||
- Custom Gitea host URL (optional)
|
||||
- Self-signed certificate support (gitea_insecure flag)
|
||||
- Binary path configuration (gitea_mcp_binary_path)
|
||||
- Docker enablement (use_docker)
|
||||
- Docker image selection (docker_image)
|
||||
|
||||
✅ **Documentation**
|
||||
- Comprehensive README.md with configuration examples
|
||||
- Detailed DEVELOPMENT.md (this file)
|
||||
- Installation instructions for Zed UI
|
||||
- Default settings template with inline documentation
|
||||
- Troubleshooting guides
|
||||
|
||||
### Known Limitations
|
||||
|
||||
⚠️ **SSE Mode Not Implemented**
|
||||
- Original SSE mode code removed due to Zed API limitations
|
||||
- Only STDIO mode supported by current Zed extension API
|
||||
- Future versions can add SSE when Zed adds HTTP context server support
|
||||
|
||||
⚠️ **Docker Image Pull**
|
||||
- Docker must be installed and running
|
||||
- Image is pulled automatically on first use
|
||||
- Large images may take time to download
|
||||
|
||||
⚠️ **Windows Testing**
|
||||
- Binary path resolution includes Windows paths
|
||||
- Not tested on actual Windows systems
|
||||
- Paths use backslashes but code handles both
|
||||
|
||||
## Architecture
|
||||
|
||||
### Current Flow
|
||||
|
||||
```
|
||||
User Configuration (settings.json)
|
||||
↓
|
||||
Zed Extension (tendril-gitea-mcp)
|
||||
├─ Loads configuration
|
||||
├─ Resolves binary path OR prepares Docker command
|
||||
├─ Sets environment variables (GITEA_ACCESS_TOKEN, etc.)
|
||||
└─ Spawns command (binary or docker run)
|
||||
↓
|
||||
gitea-mcp (binary or Docker container)
|
||||
├─ Receives configuration via env vars and args
|
||||
├─ Connects to Gitea instance
|
||||
└─ Communicates with Zed via STDIO
|
||||
↓
|
||||
Gitea Instance
|
||||
└─ Serves API to gitea-mcp
|
||||
```
|
||||
|
||||
### Key Code Points
|
||||
|
||||
**src/mcp_server_gitea.rs**
|
||||
|
||||
**Settings Struct** (~40 lines)
|
||||
```rust
|
||||
struct GiteaContextServerSettings {
|
||||
gitea_access_token: String, // Required
|
||||
gitea_host: Option<String>, // Optional: custom host
|
||||
gitea_insecure: Option<bool>, // Optional: allow self-signed certs
|
||||
gitea_mcp_binary_path: Option<String>, // NEW: explicit binary path
|
||||
use_docker: Option<bool>, // NEW: Docker mode flag
|
||||
docker_image: Option<String>, // NEW: custom Docker image
|
||||
}
|
||||
```
|
||||
|
||||
**Binary Path Resolution** (~70 lines)
|
||||
```rust
|
||||
fn resolve_binary_path(explicit_path: &Option<String>) -> Result<String>
|
||||
```
|
||||
- Checks explicit path first
|
||||
- Searches standard locations with platform awareness
|
||||
- Searches PATH environment variable
|
||||
- Returns helpful error message if not found
|
||||
|
||||
**Docker Command Building** (~40 lines)
|
||||
```rust
|
||||
fn build_docker_command(settings: &GiteaContextServerSettings) -> Result<Command>
|
||||
```
|
||||
- Builds docker run command with proper arguments
|
||||
- Passes environment variables to container
|
||||
- Supports custom Docker images
|
||||
- Properly configures STDIN for STDIO mode
|
||||
|
||||
**Binary Command Building** (~30 lines)
|
||||
```rust
|
||||
fn build_binary_command(settings: &GiteaContextServerSettings) -> Result<Command>
|
||||
```
|
||||
- Resolves binary path
|
||||
- Sets up environment variables
|
||||
- Adds gitea-mcp arguments
|
||||
- Returns executable command
|
||||
|
||||
## Roadmap
|
||||
|
||||
### Phase 1: Core Features (✅ COMPLETE)
|
||||
|
||||
**Status**: All done!
|
||||
|
||||
- ✅ Remove hardcoded binary path
|
||||
- ✅ Implement binary path resolution with fallbacks
|
||||
- ✅ Add Docker support
|
||||
- ✅ Cross-platform binary detection
|
||||
- ✅ Comprehensive error messages
|
||||
|
||||
### Phase 2: Testing & Validation (High Priority)
|
||||
|
||||
**Goals:**
|
||||
- [ ] Test STDIO mode with actual Gitea instances
|
||||
- [ ] Test binary discovery on multiple systems
|
||||
- [ ] Test Docker mode on Linux, macOS, Windows
|
||||
- [ ] Test with different Gitea versions
|
||||
- [ ] Test with self-hosted instances
|
||||
- [ ] Test with different token permissions
|
||||
- [ ] Performance testing with large repositories
|
||||
|
||||
**Test Matrix:**
|
||||
```
|
||||
Platform × Mode × Configuration
|
||||
├─ Linux
|
||||
│ ├─ Local binary
|
||||
│ │ ├─ /usr/local/bin
|
||||
│ │ ├─ ~/.local/bin
|
||||
│ │ ├─ Custom path
|
||||
│ │ └─ In PATH
|
||||
│ └─ Docker
|
||||
├─ macOS Intel
|
||||
│ ├─ Local binary
|
||||
│ └─ Docker
|
||||
├─ macOS M-series
|
||||
│ ├─ Local binary (ARM)
|
||||
│ ├─ Homebrew path
|
||||
│ └─ Docker
|
||||
└─ Windows (if possible)
|
||||
├─ Local binary
|
||||
├─ Program Files
|
||||
└─ Docker
|
||||
```
|
||||
|
||||
### Phase 3: User Experience Improvements (Medium Priority)
|
||||
|
||||
**Goals:**
|
||||
- [ ] Add interactive configuration wizard
|
||||
- [ ] Implement settings validation with helpful errors
|
||||
- [ ] Add status diagnostic command
|
||||
- [ ] Create context-aware error messages
|
||||
- [ ] Add command palette actions for common tasks
|
||||
|
||||
**Possible Implementation:**
|
||||
- Extend `context_server_configuration()` with validation
|
||||
- Add diagnostic endpoint for status checking
|
||||
- Implement configuration templates for common setups
|
||||
|
||||
**Estimated Effort:** 4-6 hours
|
||||
|
||||
### Phase 4: Documentation & Release (Low Priority)
|
||||
|
||||
**Goals:**
|
||||
- [ ] Create troubleshooting video
|
||||
- [ ] Add FAQ section
|
||||
- [ ] Document all available Gitea MCP tools
|
||||
- [ ] Create contribution guidelines
|
||||
- [ ] Version bump to 1.0.0
|
||||
- [ ] Publish to Zed marketplace
|
||||
|
||||
### Phase 5: Future Enhancements
|
||||
|
||||
**Long-term Ideas:**
|
||||
- [ ] Support other Git providers (GitHub, GitLab)
|
||||
- [ ] Multiple context servers (different Gitea instances)
|
||||
- [ ] Caching for performance
|
||||
- [ ] Custom tool filtering
|
||||
- [ ] Workflow automation
|
||||
- [ ] SSH key management
|
||||
- [ ] Proxy support
|
||||
|
||||
## Building & Development
|
||||
|
||||
### Prerequisites
|
||||
|
||||
```bash
|
||||
# Install Rust via rustup (required)
|
||||
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
|
||||
|
||||
# Install Zed
|
||||
# macOS: brew install zed
|
||||
# Linux: Download from https://zed.dev
|
||||
# Windows: Download from https://zed.dev
|
||||
|
||||
# Optional: Install gitea-mcp for testing
|
||||
# See README.md for installation instructions
|
||||
```
|
||||
|
||||
### Build Extension
|
||||
|
||||
```bash
|
||||
cd tendril
|
||||
cargo build --release
|
||||
```
|
||||
|
||||
Output: `target/wasm32-unknown-unknown/release/mcp_server_gitea.wasm`
|
||||
|
||||
### Install as Dev Extension
|
||||
|
||||
1. Open Zed
|
||||
2. Extensions panel (Cmd+K → "Extensions")
|
||||
3. Click "Install Dev Extension"
|
||||
4. Select tendril directory
|
||||
5. Zed compiles and loads it
|
||||
|
||||
### Running Tests
|
||||
|
||||
```bash
|
||||
# Check for compilation errors
|
||||
cargo check
|
||||
|
||||
# Run clippy for linting
|
||||
cargo clippy
|
||||
|
||||
# Full release build
|
||||
cargo build --release
|
||||
|
||||
# Verify WASM output
|
||||
ls -lh target/wasm32-unknown-unknown/release/mcp_server_gitea.wasm
|
||||
```
|
||||
|
||||
### Debug Logging
|
||||
|
||||
```bash
|
||||
# Start Zed with verbose logging
|
||||
zed --foreground
|
||||
|
||||
# Watch gitea-mcp logs
|
||||
tail -f ~/.gitea-mcp/gitea-mcp.log
|
||||
|
||||
# View Zed logs in editor
|
||||
# In Zed: zed: open log
|
||||
```
|
||||
|
||||
## Code Quality Standards
|
||||
|
||||
### Rust Code
|
||||
|
||||
- Use `cargo clippy` for linting before committing
|
||||
- Follow Rust naming conventions
|
||||
- Add comments for complex logic
|
||||
- Keep functions focused and small (< 50 lines preferred)
|
||||
- Use meaningful variable names
|
||||
|
||||
### Error Messages
|
||||
|
||||
- Be specific about what went wrong
|
||||
- Provide actionable solutions
|
||||
- Include file paths or commands when relevant
|
||||
- Format multi-line errors clearly
|
||||
|
||||
### Documentation
|
||||
|
||||
- Update README when changing user-facing behavior
|
||||
- Keep installation_instructions.md current
|
||||
- Update configuration comments when adding settings
|
||||
- Add inline code comments for non-obvious logic
|
||||
|
||||
### Testing Checklist
|
||||
|
||||
Before committing:
|
||||
- [ ] Code compiles: `cargo check`
|
||||
- [ ] No clippy warnings: `cargo clippy`
|
||||
- [ ] Builds successfully: `cargo build --release`
|
||||
- [ ] Changes tested manually with Zed
|
||||
- [ ] Documentation updated if needed
|
||||
|
||||
## Development Workflow
|
||||
|
||||
### Making Changes
|
||||
|
||||
1. Create a feature branch:
|
||||
```bash
|
||||
git checkout -b feature/your-feature-name
|
||||
```
|
||||
|
||||
2. Make changes to `src/mcp_server_gitea.rs` or configuration files
|
||||
|
||||
3. Test locally:
|
||||
```bash
|
||||
cargo build --release
|
||||
# Test with Zed dev extension
|
||||
```
|
||||
|
||||
4. Verify code quality:
|
||||
```bash
|
||||
cargo clippy
|
||||
cargo fmt --check
|
||||
```
|
||||
|
||||
5. Update documentation if needed:
|
||||
- `README.md` for user-facing changes
|
||||
- `DEVELOPMENT.md` for architecture changes
|
||||
- Inline comments for complex logic
|
||||
|
||||
### Submitting Changes
|
||||
|
||||
1. Commit with clear messages:
|
||||
```bash
|
||||
git commit -m "Add feature: descriptive message"
|
||||
```
|
||||
|
||||
2. Push to your fork:
|
||||
```bash
|
||||
git push origin feature/your-feature-name
|
||||
```
|
||||
|
||||
3. Create pull request with:
|
||||
- Clear description of changes
|
||||
- Why the change is needed
|
||||
- Any testing done
|
||||
- References to related issues
|
||||
|
||||
## Binary Path Resolution Details
|
||||
|
||||
### Search Order
|
||||
|
||||
1. **Explicit Configuration** (if set)
|
||||
```json
|
||||
{"gitea_mcp_binary_path": "/path/to/gitea-mcp"}
|
||||
```
|
||||
Checked first, must exist or error is returned
|
||||
|
||||
2. **Standard System Paths** (all platforms)
|
||||
- `/usr/local/bin/gitea-mcp`
|
||||
- `/usr/bin/gitea-mcp`
|
||||
|
||||
3. **Home Directory Paths**
|
||||
- `~/.local/bin/gitea-mcp`
|
||||
- `~/bin/gitea-mcp`
|
||||
- `~/.cargo/bin/gitea-mcp`
|
||||
|
||||
4. **Platform-Specific Paths**
|
||||
- macOS: `/opt/homebrew/bin/gitea-mcp` (M-series)
|
||||
- Windows: `C:\Program Files\gitea-mcp\gitea-mcp.exe`
|
||||
- Windows: `C:\Program Files (x86)\gitea-mcp\gitea-mcp.exe`
|
||||
|
||||
5. **PATH Environment Variable**
|
||||
- Searches all directories in `PATH`
|
||||
- Uses `:` separator on Unix, `;` on Windows
|
||||
|
||||
### Error Handling
|
||||
|
||||
If binary is not found:
|
||||
1. Lists all paths that were searched
|
||||
2. Provides installation instructions
|
||||
3. Suggests Docker as alternative
|
||||
4. Shows how to set `gitea_mcp_binary_path`
|
||||
|
||||
Example error:
|
||||
```
|
||||
gitea-mcp binary not found in standard locations.
|
||||
|
||||
Searched paths:
|
||||
- /usr/local/bin/gitea-mcp
|
||||
- /usr/bin/gitea-mcp
|
||||
- ... (more paths)
|
||||
|
||||
Resolution options:
|
||||
1. Install gitea-mcp to a standard location...
|
||||
2. Configure custom binary path in your Zed settings...
|
||||
3. Use Docker...
|
||||
```
|
||||
|
||||
## Docker Mode Details
|
||||
|
||||
### Command Structure
|
||||
|
||||
```bash
|
||||
docker run \
|
||||
--rm \
|
||||
-i \
|
||||
--env GITEA_ACCESS_TOKEN=<token> \
|
||||
[--env GITEA_INSECURE=true] \
|
||||
[--env GITEA_HOST=<host>] \
|
||||
gitea/gitea-mcp:latest \
|
||||
-t stdio \
|
||||
[--host <host>]
|
||||
```
|
||||
|
||||
### Configuration Options
|
||||
|
||||
- `use_docker: true` - Enable Docker mode
|
||||
- `docker_image: "gitea/gitea-mcp:v1.0.0"` - Custom image
|
||||
|
||||
### Requirements
|
||||
|
||||
- Docker must be installed and running
|
||||
- Image will be pulled automatically if not present
|
||||
- Container runs with `--rm` (auto-cleanup)
|
||||
- STDIN connected to Zed for STDIO mode
|
||||
|
||||
## Debugging Tips
|
||||
|
||||
### Extension Not Loading
|
||||
|
||||
```bash
|
||||
# Check compilation
|
||||
cargo check
|
||||
|
||||
# View Zed logs
|
||||
zed --foreground
|
||||
|
||||
# Try clean rebuild
|
||||
cargo clean
|
||||
cargo build --release
|
||||
```
|
||||
|
||||
### Binary Not Found
|
||||
|
||||
```bash
|
||||
# Verify binary exists
|
||||
which gitea-mcp
|
||||
ls -lh /usr/local/bin/gitea-mcp
|
||||
|
||||
# Make executable
|
||||
chmod +x /usr/local/bin/gitea-mcp
|
||||
|
||||
# Test manually
|
||||
/usr/local/bin/gitea-mcp --help
|
||||
```
|
||||
|
||||
### Docker Issues
|
||||
|
||||
```bash
|
||||
# Check Docker status
|
||||
docker ps
|
||||
|
||||
# Pull image manually
|
||||
docker pull gitea/gitea-mcp:latest
|
||||
|
||||
# Test Docker command
|
||||
docker run --rm -i gitea/gitea-mcp:latest --help
|
||||
```
|
||||
|
||||
### Settings Not Working
|
||||
|
||||
```bash
|
||||
# Verify JSON syntax
|
||||
cat ~/.config/Zed/settings.json
|
||||
|
||||
# Check context server ID matches
|
||||
grep tendril-gitea-mcp ~/.config/Zed/settings.json
|
||||
|
||||
# Restart Zed
|
||||
pkill -f zed
|
||||
zed
|
||||
```
|
||||
|
||||
## Performance Considerations
|
||||
|
||||
### Binary Mode
|
||||
- Fastest startup (no container overhead)
|
||||
- Direct process execution
|
||||
- Minimal resource usage
|
||||
|
||||
### Docker Mode
|
||||
- First pull downloads entire image (~100-500 MB)
|
||||
- Subsequent starts faster if image cached
|
||||
- Uses more memory (container runtime)
|
||||
- Better isolation
|
||||
|
||||
### Optimization Ideas
|
||||
- Cache binary path discovery result
|
||||
- Lazy-load configuration only when needed
|
||||
- Implement binary availability checking at startup
|
||||
|
||||
## Security Considerations
|
||||
|
||||
### Token Handling
|
||||
- Never log access tokens
|
||||
- Pass via environment variables (secure)
|
||||
- Tokens are passed to gitea-mcp, not exposed to Zed
|
||||
|
||||
### Certificate Validation
|
||||
- Default: strict SSL validation
|
||||
- `gitea_insecure: true` disables verification
|
||||
- Only use for trusted internal servers
|
||||
|
||||
### Docker Security
|
||||
- Uses `--rm` to clean up containers
|
||||
- Environment variables not logged
|
||||
- Consider using secrets management for production
|
||||
|
||||
## Future Zed API Improvements
|
||||
|
||||
When Zed adds HTTP context server support:
|
||||
- SSE mode could be re-implemented
|
||||
- Multiple parallel connections supported
|
||||
- Better session management possible
|
||||
- Persistent server instances
|
||||
|
||||
Reference: https://github.com/zed-industries/zed/discussions/29370
|
||||
|
||||
## Resources
|
||||
|
||||
- [Zed Extensions Documentation](https://zed.dev/docs/extensions)
|
||||
- [Gitea MCP Project](https://gitea.com/gitea/gitea-mcp)
|
||||
- [Model Context Protocol](https://modelcontextprotocol.io)
|
||||
- [The Mycelium Project](https://git.parkingmeter.info/Mycelium)
|
||||
- [Gitea Documentation](https://docs.gitea.io)
|
||||
- [Docker Documentation](https://docs.docker.com)
|
||||
|
||||
## Contact & Support
|
||||
|
||||
- Repository: https://git.parkingmeter.info/Mycelium/tendril
|
||||
- Issues: Open an issue on the repository
|
||||
- Discussions: Use repository discussions for questions
|
||||
- Author: Ryan Parmeter (@parkingmeter)
|
||||
Reference in New Issue
Block a user