Files
2025-11-30 08:24:23 +08:00

394 lines
6.8 KiB
Markdown

# Common Issues and Troubleshooting
Detailed troubleshooting for the 15 most common Cloudflare MCP server errors.
---
## 1. McpAgent Class Not Exported
**Error**: `TypeError: Cannot read properties of undefined (reading 'serve')`
**Diagnosis**: Check if your McpAgent class is exported
**Solution**:
```typescript
// ✅ CORRECT
export class MyMCP extends McpAgent { ... }
// ❌ WRONG
class MyMCP extends McpAgent { ... } // Missing export!
```
---
## 2. Transport Mismatch
**Error**: `Connection failed: Unexpected response format`
**Diagnosis**: Client and server transport don't match
**Debug**:
```bash
# Check what your server supports
curl https://my-mcp.workers.dev/sse
curl https://my-mcp.workers.dev/mcp
```
**Solution**: Serve both transports (see SKILL.md Transport section)
---
## 3. OAuth Redirect URI Mismatch
**Error**: `OAuth error: redirect_uri does not match`
**Diagnosis**: Check client configuration vs deployed URL
**Common causes**:
- Developed with localhost, deployed to workers.dev
- HTTP vs HTTPS
- Missing `/oauth/callback` path
- Typo in domain
**Solution**:
```json
// Update after deployment
{
"mcpServers": {
"my-mcp": {
"url": "https://my-mcp.YOUR_ACCOUNT.workers.dev/sse",
"auth": {
"authorizationUrl": "https://my-mcp.YOUR_ACCOUNT.workers.dev/authorize",
"tokenUrl": "https://my-mcp.YOUR_ACCOUNT.workers.dev/token"
}
}
}
}
```
---
## 4. WebSocket Hibernation State Loss
**Error**: State not found after WebSocket reconnect
**Diagnosis**: Using in-memory state instead of storage
**Wrong**:
```typescript
class MyMCP extends McpAgent {
userId: string; // ❌ Lost on hibernation!
async init() {
this.userId = "123";
}
}
```
**Correct**:
```typescript
class MyMCP extends McpAgent {
async init() {
await this.state.storage.put("userId", "123"); // ✅ Persisted
}
}
```
---
## 5. Durable Objects Binding Missing
**Error**: `Cannot read properties of undefined (reading 'idFromName')`
**Diagnosis**: Check wrangler.jsonc
**Solution**:
```jsonc
{
"durable_objects": {
"bindings": [
{
"name": "MY_MCP",
"class_name": "MyMCP",
"script_name": "my-mcp-server"
}
]
}
}
```
---
## 6. Migration Not Defined
**Error**: `Durable Object class MyMCP has no migration defined`
**Diagnosis**: First DO deployment needs migration
**Solution**:
```jsonc
{
"migrations": [
{
"tag": "v1",
"new_classes": ["MyMCP"]
}
]
}
```
**After first deployment**, migrations are locked. Subsequent changes require new migration tags (v2, v3, etc.).
---
## 7. CORS Errors
**Error**: `Access blocked by CORS policy`
**Diagnosis**: Remote MCP server needs CORS headers
**Solution**: Use OAuthProvider (handles CORS automatically) or add headers:
```typescript
return new Response(body, {
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
}
});
```
---
## 8. Client Configuration Format Error
**Error**: Claude Desktop doesn't see MCP server
**Diagnosis**: Check JSON format
**Wrong**:
```json
{
"mcpServers": [ // ❌ Array instead of object!
{
"name": "my-mcp",
"url": "..."
}
]
}
```
**Correct**:
```json
{
"mcpServers": { // ✅ Object with named servers
"my-mcp": {
"url": "..."
}
}
}
```
**Location**:
- Mac: `~/.config/claude/claude_desktop_config.json`
- Windows: `%APPDATA%/Claude/claude_desktop_config.json`
- Linux: `~/.config/claude/claude_desktop_config.json`
---
## 9. serializeAttachment() Not Used
**Error**: WebSocket metadata lost on hibernation
**Solution**:
```typescript
// Store metadata on WebSocket
webSocket.serializeAttachment({
userId: "123",
sessionId: "abc",
connectedAt: Date.now()
});
// Retrieve on wake
const metadata = webSocket.deserializeAttachment();
console.log(metadata.userId); // "123"
```
---
## 10. OAuth Consent Screen Disabled
**Security risk**: Users don't know what they're authorizing
**Wrong**:
```typescript
allowConsentScreen: false // ❌ Never in production!
```
**Correct**:
```typescript
allowConsentScreen: true // ✅ Always in production
```
---
## 11. JWT Signing Key Missing
**Error**: `JWT_SIGNING_KEY environment variable not set`
**Solution**:
```bash
# Generate secure key
openssl rand -base64 32
# Add to secrets
npx wrangler secret put JWT_SIGNING_KEY
# Or add to wrangler.jsonc (less secure)
"vars": {
"JWT_SIGNING_KEY": "generated-key-here"
}
```
---
## 12. Environment Variables Not Configured
**Error**: `env.MY_VAR is undefined`
**Diagnosis**: Variables only in `.dev.vars`, not in wrangler.jsonc
**Wrong**:
```bash
# .dev.vars only (works locally, fails in production)
MY_VAR=value
```
**Correct**:
```jsonc
// wrangler.jsonc
{
"vars": {
"MY_VAR": "production-value"
}
}
```
**For secrets**:
```bash
npx wrangler secret put MY_SECRET
```
---
## 13. Tool Schema Validation Error
**Error**: `ZodError: Invalid input type`
**Diagnosis**: Client sends different type than schema expects
**Solution**: Use Zod transforms or coerce
```typescript
// Client sends string "123", but you need number
{
count: z.string().transform(val => parseInt(val, 10))
}
// Or use coerce
{
count: z.coerce.number()
}
```
---
## 14. Multiple Transport Endpoints Conflicting
**Error**: `/sse` returns 404 after adding `/mcp`
**Diagnosis**: Path matching issue
**Wrong**:
```typescript
if (pathname === "/sse") { // ❌ Misses /sse/message
return MyMCP.serveSSE("/sse").fetch(request, env, ctx);
}
```
**Correct**:
```typescript
if (pathname === "/sse" || pathname.startsWith("/sse/")) { // ✅
return MyMCP.serveSSE("/sse").fetch(request, env, ctx);
}
```
---
## 15. Local Testing Limitations
**Error**: OAuth flow fails in `npm run dev`
**Diagnosis**: Miniflare doesn't support all DO features
**Solutions**:
**Option 1**: Use remote dev
```bash
npx wrangler dev --remote
```
**Option 2**: Test OAuth on deployed Worker
```bash
npx wrangler deploy
# Test at https://my-mcp.workers.dev
```
**Option 3**: Mock OAuth for local testing
```typescript
if (env.ENVIRONMENT === "development") {
// Skip OAuth, use mock user
return {
userId: "test-user",
email: "test@example.com"
};
}
```
---
## General Debugging Tips
### Check Logs
```bash
npx wrangler tail
```
### Test with MCP Inspector
```bash
npx @modelcontextprotocol/inspector@latest
```
### Verify Bindings
```bash
npx wrangler kv:namespace list
npx wrangler d1 list
```
### Check Deployment
```bash
npx wrangler deployments list
```
### View Worker Code
```bash
npx wrangler whoami
# Visit dashboard: https://dash.cloudflare.com/
```
---
**Still stuck?** Check:
- Cloudflare Docs: https://developers.cloudflare.com/agents/
- MCP Spec: https://modelcontextprotocol.io/
- Community: https://community.cloudflare.com/