|
| 1 | +# Smithery Deployment Fix Summary |
| 2 | + |
| 3 | +## Issues Identified and Fixed |
| 4 | + |
| 5 | +### 1. **Tool Discovery Failure** |
| 6 | +- **Problem**: Smithery couldn't scan tools from the server, getting "TypeError: fetch failed" |
| 7 | +- **Root Cause**: Server wasn't properly handling HTTP requests for tool discovery |
| 8 | +- **Fix**: Created proper ASGI app using FastMCP's `http_app()` method with middleware support |
| 9 | + |
| 10 | +### 2. **Configuration Handling** |
| 11 | +- **Problem**: Server expected environment variables, but Smithery passes config as query parameters |
| 12 | +- **Root Cause**: Misunderstanding of how Smithery passes configuration |
| 13 | +- **Fix**: Implemented Starlette middleware to extract query parameters and update environment |
| 14 | + |
| 15 | +### 3. **Middleware Implementation** |
| 16 | +- **Problem**: Initial attempt used incorrect FastMCP middleware API |
| 17 | +- **Root Cause**: Used `@mcp.middleware()` decorator which doesn't exist |
| 18 | +- **Fix**: Used proper Starlette middleware passed to `http_app()` method |
| 19 | + |
| 20 | +### 4. **Server Startup** |
| 21 | +- **Problem**: Server needed to start without credentials for tool discovery |
| 22 | +- **Root Cause**: Lazy initialization wasn't properly configured |
| 23 | +- **Fix**: Ensured all environment variables are set for lazy init before imports |
| 24 | + |
| 25 | +## Key Changes Made |
| 26 | + |
| 27 | +### 1. **smithery_main.py** |
| 28 | +```python |
| 29 | +# Proper ASGI app creation with middleware |
| 30 | +def create_app(): |
| 31 | + mcp = create_mcp_server() |
| 32 | + middleware = [Middleware(SmitheryConfigMiddleware)] |
| 33 | + app = mcp.http_app(path="/mcp", middleware=middleware, transport="streamable-http") |
| 34 | + return app |
| 35 | + |
| 36 | +# Use uvicorn to run the ASGI app |
| 37 | +uvicorn.run(app, host="0.0.0.0", port=port) |
| 38 | +``` |
| 39 | + |
| 40 | +### 2. **Configuration Updates** |
| 41 | +- Updated `loaders.py` to support `LAZY_INIT` and `NON_INTERACTIVE` env vars |
| 42 | +- Made credentials optional in `smithery.yaml` for tool discovery |
| 43 | + |
| 44 | +### 3. **Dockerfile.smithery** |
| 45 | +- Added `CHROMEDRIVER_PATH` environment variable |
| 46 | +- Set all required environment variables for Smithery mode |
| 47 | + |
| 48 | +## How Smithery Integration Works |
| 49 | + |
| 50 | +1. **Tool Discovery Phase**: |
| 51 | + - Smithery sends requests to `/mcp` without credentials |
| 52 | + - Server must respond with available tools list |
| 53 | + - No Chrome driver or authentication needed |
| 54 | + |
| 55 | +2. **Tool Execution Phase**: |
| 56 | + - Smithery passes credentials as query parameters: `/mcp?linkedin_email=...&linkedin_password=...` |
| 57 | + - Middleware extracts these and updates environment |
| 58 | + - Chrome driver is initialized only when tools are actually called |
| 59 | + |
| 60 | +3. **Configuration Flow**: |
| 61 | + ``` |
| 62 | + Smithery UI → Query Parameters → Middleware → Environment Variables → Config Reset → Tool Execution |
| 63 | + ``` |
| 64 | + |
| 65 | +## Testing Commands |
| 66 | + |
| 67 | +```bash |
| 68 | +# Local testing |
| 69 | +chmod +x test_local_smithery.sh |
| 70 | +./test_local_smithery.sh |
| 71 | + |
| 72 | +# Manual server start |
| 73 | +PORT=8000 uv run python smithery_main.py |
| 74 | + |
| 75 | +# Test tool discovery |
| 76 | +curl -X POST http://localhost:8000/mcp \ |
| 77 | + -H "Content-Type: application/json" \ |
| 78 | + -d '{"jsonrpc":"2.0","method":"tools/list","params":{},"id":1}' |
| 79 | +``` |
| 80 | + |
| 81 | +## Deployment Steps |
| 82 | + |
| 83 | +1. **Commit and push changes**: |
| 84 | + ```bash |
| 85 | + git add -A |
| 86 | + git commit -m "Fix Smithery deployment - proper query param handling and lazy init" |
| 87 | + git push origin feat/smithery-http-transport |
| 88 | + ``` |
| 89 | + |
| 90 | +2. **Monitor Smithery deployment**: |
| 91 | + - Check Docker build succeeds |
| 92 | + - Verify "Tool scanning" passes |
| 93 | + - Test connection with credentials |
| 94 | + |
| 95 | +## Key Principles |
| 96 | + |
| 97 | +1. **Lazy Loading**: No resources initialized until needed |
| 98 | +2. **Query Parameter Config**: Smithery passes config via URL params, not env vars |
| 99 | +3. **ASGI Application**: Use FastMCP's `http_app()` for proper HTTP handling |
| 100 | +4. **Middleware**: Use Starlette middleware for HTTP request processing |
| 101 | +5. **Non-Interactive**: No prompts or user input in container environment |
| 102 | + |
| 103 | +## Troubleshooting |
| 104 | + |
| 105 | +If deployment still fails: |
| 106 | +1. Check Smithery logs for specific errors |
| 107 | +2. Ensure ChromeDriver is available at `/usr/bin/chromedriver` in container |
| 108 | +3. Verify all Python dependencies are installed |
| 109 | +4. Test locally with `test_local_smithery.sh` first |
0 commit comments