Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
127 changes: 127 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down