glam/EXA_BUG_FIX.md
2025-11-19 23:25:22 +01:00

171 lines
4.5 KiB
Markdown

# EXA MCP Server Bug Fix
## Problem Summary
The `exa_web_search_exa` and `exa_get_code_context_exa` tools were returning 400 errors on all requests, even though the EXA API itself worked perfectly when called directly with curl.
## Root Cause
The issue was **NOT a bug in the exa-mcp-server package**. The source code is correct and properly formatted.
**The actual problem**: The OpenCode configuration file used an environment variable reference `{env:EXA_API_KEY}` but the environment variable was not set in the shell where OpenCode runs.
## Configuration Files
### Before (BROKEN)
`/Users/kempersc/.config/opencode/opencode.json`:
```json
{
"mcp": {
"exa": {
"type": "local",
"command": ["npx", "-y", "exa-mcp-server"],
"enabled": true,
"environment": {
"EXA_API_KEY": "{env:EXA_API_KEY}" This env var wasn't set
}
}
}
}
```
### After (FIXED)
`/Users/kempersc/.config/opencode/opencode.json`:
```json
{
"mcp": {
"exa": {
"type": "local",
"command": ["npx", "-y", "exa-mcp-server"],
"enabled": true,
"environment": {
"EXA_API_KEY": "dba69040-f87e-46a2-85d7-5b2e9fe17497" Direct API key
}
}
}
}
```
## How the EXA MCP Server Works
### Source Code Analysis
**Repository**: https://github.com/exa-labs/exa-mcp-server
**Key files**:
- `src/index.ts` - Main server initialization
- `src/tools/webSearch.ts` - Web search tool implementation
- `src/tools/exaCode.ts` - Code context search implementation
- `src/tools/config.ts` - API configuration
**API Configuration** (`src/tools/config.ts:1-11`):
```typescript
export const API_CONFIG = {
BASE_URL: 'https://api.exa.ai',
ENDPOINTS: {
SEARCH: '/search',
RESEARCH_TASKS: '/research/v0/tasks',
CONTEXT: '/context'
},
DEFAULT_NUM_RESULTS: 8,
DEFAULT_MAX_CHARACTERS: 2000
} as const;
```
**HTTP Request Format** (from `src/tools/webSearch.ts:24-52`):
```typescript
const axiosInstance = axios.create({
baseURL: API_CONFIG.BASE_URL,
headers: {
'accept': 'application/json',
'content-type': 'application/json',
'x-api-key': config?.exaApiKey || process.env.EXA_API_KEY || ''
},
timeout: 25000
});
const searchRequest: ExaSearchRequest = {
query,
type: "auto",
numResults: numResults || API_CONFIG.DEFAULT_NUM_RESULTS,
contents: {
text: {
maxCharacters: API_CONFIG.DEFAULT_MAX_CHARACTERS
},
livecrawl: 'preferred'
}
};
const response = await axiosInstance.post<ExaSearchResponse>(
API_CONFIG.ENDPOINTS.SEARCH,
searchRequest,
{ timeout: 25000 }
);
```
This exactly matches our working curl command:
```bash
curl -X POST "https://api.exa.ai/search" \
-H "Content-Type: application/json" \
-H "x-api-key: dba69040-f87e-46a2-85d7-5b2e9fe17497" \
-d '{"query": "Belgium ISIL registry", "numResults": 3}'
```
## Why the Error Occurred
When `EXA_API_KEY` environment variable is not set:
1. OpenCode spawns `npx -y exa-mcp-server` with `EXA_API_KEY=""` (empty string)
2. The axios request includes header: `x-api-key: ""` (empty)
3. EXA API rejects the request with **400 Bad Request**
## Solution
**Option 1** (APPLIED): Set API key directly in OpenCode config
- ✅ Simple, works immediately after OpenCode restart
- ❌ API key visible in config file (but it's in your home directory)
**Option 2**: Set shell environment variable globally
```bash
# In ~/.zshrc or ~/.bashrc
export EXA_API_KEY=dba69040-f87e-46a2-85d7-5b2e9fe17497
```
- ✅ More secure (not in config files)
- ❌ Requires shell restart, affects all processes
**Option 3**: Load from project .env file
- Would require modifying exa-mcp-server to load .env
- Not practical for this use case
## Next Steps
1. **Restart OpenCode** to reload MCP server with new configuration
2. **Test the tools**:
```
Use exa_web_search_exa to search for "Belgium ISIL registry"
```
3. **Verify** we get proper search results instead of 400 errors
## Verification Commands
After restarting OpenCode, test with:
```
Search for "Belgium heritage institutions ISIL registry"
```
Expected: JSON results with Belgian GLAM institution URLs
## Source Code Findings
The exa-mcp-server package (v3.0.7) is **correctly implemented**:
- ✅ Proper HTTP headers (`x-api-key`)
- ✅ Correct API endpoints (`/search`, `/context`)
- ✅ Valid request formatting
- ✅ Error handling with detailed messages
- ✅ Timeout handling (25-30 seconds)
No bugs found in the source code. The issue was purely configuration.
---
**Date**: November 6, 2025
**Fixed by**: Configuration update to `/Users/kempersc/.config/opencode/opencode.json`