Skip to content

Instantly share code, notes, and snippets.

@simonholm
Created July 2, 2025 05:32
Show Gist options
  • Save simonholm/f867c22034dd4e14a16426117878a5c5 to your computer and use it in GitHub Desktop.
Save simonholm/f867c22034dd4e14a16426117878a5c5 to your computer and use it in GitHub Desktop.

DXT Development Secret Source Documentation

The hard-won lessons from building a working Claude Desktop Extension

๐Ÿšจ Critical Checks Before Starting

1. Verify Current DXT Specification

โš ๏ธ The DXT spec changes frequently!

# Always check the latest official docs FIRST
curl -s https://api.github.com/repos/anthropics/dxt | jq '.pushed_at'

Essential URLs to check:

Key version indicators:

  • DXT version is currently "0.1" (NOT "0.1.0" or "1.0")
  • MCP protocol version: "2024-11-05"

2. Environment Compatibility Check

# Verify Claude Desktop version
# Check Settings โ†’ About for latest version

# Verify system compatibility
echo "OS: $(uname -a)"
echo "Node.js: $(node --version)"
echo "Git: $(git --version)"

๐Ÿ’€ Major Pitfalls We Encountered

1. DXT Specification Evolution

Problem: Documentation lags behind implementation

  • Used dxt_version: "1.0" โ†’ WRONG (should be "0.1")
  • Tried server.type: "http" โ†’ WRONG (should be "node")
  • Missing mcp_config inside server object

Solution:

{
  "dxt_version": "0.1",
  "server": {
    "type": "node",
    "entry_point": "index.js", 
    "mcp_config": {
      "command": "node",
      "args": ["${__dirname}/index.js"]
    }
  }
}

2. MCP vs HTTP Architecture Confusion

Problem: Early examples showed HTTP servers, but DXT now requires MCP over stdio

Wrong approach:

// โŒ This doesn't work in current DXT
const server = http.createServer(...)

Correct approach:

// โœ… MCP over stdio
process.stdin.on('data', async (data) => {
  const request = JSON.parse(data.toString().trim());
  // Handle MCP protocol...
});

3. Character Encoding Issues (WSL/Vim)

Problem: Template literals get corrupted when copying between WSL and Windows

Solutions:

  • Use string concatenation instead of template literals
  • Avoid backticks in artifacts
  • Test scripts in isolated environments

4. Working Directory Confusion

Problem: Gemini CLI analyzes current working directory, not project directory

Current limitation:

// Gemini analyzes wherever Claude Desktop runs from
spawn('gemini', ['-p', prompt])

Future enhancement needed:

// TODO: Add directory parameter
spawn('gemini', ['-p', prompt], { cwd: userSpecifiedDirectory })

๐Ÿ› ๏ธ Debugging Workflow

Phase 1: Manifest Validation

  1. Start with minimal manifest:

    {
      "dxt_version": "0.1",
      "name": "test",
      "version": "0.1.0", 
      "author": {"name": "Test"},
      "server": {
        "type": "node",
        "entry_point": "index.js"
      }
    }
  2. Add complexity gradually

  3. Test installation after each change

Phase 2: MCP Protocol Testing

  1. Create minimal MCP server:

    process.stdin.on('data', (data) => {
      const request = JSON.parse(data.toString().trim());
      if (request.method === 'initialize') {
        // Respond with minimal capabilities
      }
    });
  2. Test each MCP method individually:

    • initialize
    • tools/list
    • tools/call

Phase 3: Integration Testing

  1. Use Claude Code CLI for development (better for debugging)
  2. Test in Claude Desktop for final validation
  3. Verify actual tool execution

๐Ÿ“‹ Error Message Decoder

"Invalid manifest: server: Required, Required"

Cause: Missing required fields in server object Fix: Add type and proper mcp_config

"Invalid enum value. Expected 'python' | 'node' | 'binary', received 'http'"

Cause: Using old HTTP-based architecture Fix: Change to MCP with "type": "node"

"Extension Preview Failed: Invalid manifest: dxt_version: Required"

Cause: Missing or wrong DXT version Fix: Use "dxt_version": "0.1"

"Failed to preview extension: Invalid manifest: server: Invalid enum value"

Cause: Server type not recognized Fix: Use "node", "python", or "binary"

๐ŸŽฏ Best Practices Learned

1. Development Environment

  • Use Claude Code CLI for development
  • Use Claude Desktop for final testing
  • Avoid mixing WSL/Windows paths during development

2. File Organization

project/
โ”œโ”€โ”€ manifest.json          # DXT configuration
โ”œโ”€โ”€ server/
โ”‚   โ””โ”€โ”€ index.js          # MCP server implementation  
โ”œโ”€โ”€ package.json          # Dependencies (if needed)
โ”œโ”€โ”€ create_dxt.js         # Build script
โ”œโ”€โ”€ test-files/           # Sample code for testing
โ””โ”€โ”€ README.md             # Usage instructions

3. Build Script Pattern

// Always use timestamped naming
const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, -5);
const outputFile = `extension_${timestamp}.dxt`;

// Clean up old versions
const oldFiles = ['old_v1.dxt', 'old_v2.dxt'];
oldFiles.forEach(file => fs.existsSync(file) && fs.unlinkSync(file));

4. Testing Strategy

  1. Create minimal test project with diverse file types
  2. Test locally with Gemini CLI first
  3. Verify DXT package creation
  4. Test installation in Claude Desktop
  5. Test actual tool execution

๐Ÿ”ฎ Future Enhancement Areas

1. Directory Parameter Support

Current limitation: Analyzes Claude Desktop's working directory

// Enhancement needed:
{
  "prompt": "Analyze this code",
  "directory": "/path/to/project"  // Add this parameter
}

2. Error Handling Improvements

  • Better timeout management
  • More descriptive error messages
  • Graceful handling of missing Gemini CLI

3. Configuration Options

  • Gemini API model selection
  • Custom analysis prompts
  • Output formatting options

๐Ÿ“š Essential Resources

Official Documentation

Community Resources

Debugging Tools

# Check DXT package contents
unzip -l your-extension.dxt

# Validate JSON
cat manifest.json | jq '.'

# Test MCP server manually
echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}' | node server/index.js

โšก Quick Troubleshooting Checklist

Installation fails?

  • Check dxt_version is "0.1"
  • Verify server.type is valid enum
  • Ensure all required fields present
  • Test manifest with jq '.' manifest.json

Tool not appearing?

  • Check Claude Desktop Extensions settings
  • Verify DXT package installed successfully
  • Restart Claude Desktop
  • Check extension logs

Tool fails to execute?

  • Test Gemini CLI directly: gemini -p "test"
  • Check authentication: gemini auth
  • Verify PATH contains gemini executable
  • Check Claude Desktop working directory

Development workflow broken?

  • Use Claude Code CLI instead of Desktop for development
  • Avoid WSL/Windows path mixing
  • Test in clean environment
  • Use timestamped builds to avoid confusion

๐ŸŽ–๏ธ Achievement Unlocked

You've successfully navigated the complex world of DXT development and created a working extension that bridges two AI systems. This documentation captures the hard-won lessons to save future developers from the same pitfalls.

Remember: The DXT ecosystem is rapidly evolving. Always check official sources for the latest specifications before starting development.

"The code that works is more valuable than the code that's perfect."

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment