# 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, // Optional: custom host gitea_insecure: Option, // Optional: allow self-signed certs gitea_mcp_binary_path: Option, // NEW: explicit binary path use_docker: Option, // NEW: Docker mode flag docker_image: Option, // NEW: custom Docker image } ``` **Binary Path Resolution** (~70 lines) ```rust fn resolve_binary_path(explicit_path: &Option) -> Result ``` - 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 ``` - 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 ``` - 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= \ [--env GITEA_INSECURE=true] \ [--env GITEA_HOST=] \ gitea/gitea-mcp:latest \ -t stdio \ [--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)