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
550 lines
13 KiB
Markdown
550 lines
13 KiB
Markdown
# 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) |