From 193eb9391230b0271f372b898cc30ebe68e26650 Mon Sep 17 00:00:00 2001 From: Bryan Thompson Date: Thu, 13 Nov 2025 09:47:24 -0600 Subject: [PATCH] Enhance README with testing, portability, and error handling guidance MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add comprehensive documentation for: - Variable substitution patterns for cross-platform portability - Four-phase testing approach (dev, clean environment, cross-platform, integration) - Common portability mistakes and solutions - Error message best practices with actionable examples These additions help developers create more robust and maintainable MCPB bundles. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- README.md | 127 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) diff --git a/README.md b/README.md index 608023e..cec7a00 100644 --- a/README.md +++ b/README.md @@ -129,6 +129,133 @@ bundle.mcpb (ZIP file) - Include all required shared libraries if dynamic linking used - Test on clean systems without development tools +### Using Variable Substitution for Portability + +The manifest supports variable substitution for cross-platform compatibility: + +**Available variables:** +- `${__dirname}` - Extension's installation directory +- `${HOME}` - User's home directory +- `${DESKTOP}` - User's desktop folder +- `${DOCUMENTS}` - User's documents folder +- `${DOWNLOADS}` - User's downloads folder +- `${pathSeparator}` or `${/}` - Platform-specific separator +- `${user_config.KEY}` - User-configured values + +**Common portability mistakes:** +```javascript +// ❌ WRONG - Hardcoded absolute paths +spawn('/usr/local/bin/node', ['script.js']); +spawn('C:\\Program Files\\tool\\bin.exe'); + +// ✅ CORRECT - Use runtime's executables +spawn(process.execPath, ['script.js']); + +// ❌ WRONG - Assuming global packages +spawn('npx', ['some-command']); + +// ✅ CORRECT - Bundle and reference locally +spawn('${__dirname}/node_modules/.bin/tool'); +``` + +**Testing portability:** +1. Fresh VM without development tools +2. Different OS than development machine +3. Verify variable substitution works +4. Check all paths resolve correctly + +## Testing Your MCPB + +Before distributing your MCPB, follow this four-phase testing approach: + +### Phase 1: Development Testing +- Unit tests for your server code +- Manual testing on your development machine +- Tool functionality verification +- Error handling validation + +### Phase 2: Clean Environment Testing ⚠️ Critical +Test on a fresh system without development tools to catch portability issues: + +**Using Docker (recommended):** +```bash +# Create clean test environment +docker run -it node:20 bash + +# Copy ONLY your MCPB bundle (no global packages) +# Test installation exactly as users would +``` + +**What this catches:** +- Missing bundled dependencies +- Hardcoded paths +- Global package assumptions +- Platform-specific code issues + +**Common issues found:** +- ❌ `spawn('/usr/local/bin/node')` - Hardcoded path +- ✅ `spawn(process.execPath)` - Runtime's own Node.js +- ❌ Assuming `npx` is globally installed +- ✅ Bundling all required executables + +### Phase 3: Cross-Platform Testing +- Test on different OS than you developed on +- Verify paths work correctly on both macOS and Windows +- Use forward slashes in paths (automatically converted) +- Test platform-specific features with fallbacks + +### Phase 4: Integration Testing +- Install in actual host application (Claude Desktop, etc.) +- Test complete end-to-end workflows +- Verify error messages are helpful +- Check performance and responsiveness + +## Error Message Best Practices + +Well-crafted error messages dramatically reduce support burden. Include three components: + +### 1. What went wrong (specific diagnosis) +```javascript +// ❌ Generic +throw new Error("An error occurred"); + +// ✅ Specific +throw new Error("Failed to read config file at path/to/config.json"); +``` + +### 2. Why it happened (context) +```javascript +// ❌ Vague +return { isError: true, content: [{ type: "text", text: "Authentication failed" }] }; + +// ✅ Clear +return { + isError: true, + content: [{ + type: "text", + text: "API key is invalid or has expired. Generate a new key at Settings → API" + }] +}; +``` + +### 3. How to fix it (actionable steps) +```javascript +// ❌ Unhelpful +throw new Error("Check your settings"); + +// ✅ Actionable +throw new Error("Missing API key. Add it in Settings → Extensions → [Your Extension] → API Key field"); +``` + +### Error Categories +Return structured errors via MCP protocol with clear `isError` flags: + +- **Configuration errors** - Missing or invalid settings +- **Authentication errors** - Invalid credentials with regeneration instructions +- **Resource errors** - File not found, network unavailable with paths/URLs +- **Permission errors** - Access denied with required permission details +- **Validation errors** - Invalid input with expected format + # Contributing We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.