Skip to content

Conversation

@raydocs
Copy link
Contributor

@raydocs raydocs commented Jan 5, 2026

Problem

The remote MCP endpoint https://mcp.exa.ai/mcp requires API key authentication via x-api-key header. Without this header, the connection hangs indefinitely waiting for authentication, eventually timing out with:

websearch_exa: Operation timed out after 5000ms

Root Cause Analysis

  1. The Exa MCP server accepts connections but waits for authentication
  2. Current config only provides type, url, and enabled - no auth headers
  3. Network latency is fine (3-8ms ping), but HTTP requests never complete
  4. Exa's main API (api.exa.ai) and website work fine - only MCP endpoint affected

Solution

  • Read EXA_API_KEY from environment variable (same as local exa-mcp-server does)
  • Pass it as x-api-key header when available
  • Update RemoteMcpConfig type to support optional headers field

Changes

src/mcp/websearch-exa.ts

export const websearch_exa = {
  type: "remote" as const,
  url: "https://mcp.exa.ai/mcp?tools=web_search_exa",
  enabled: true,
  headers: process.env.EXA_API_KEY
    ? { "x-api-key": process.env.EXA_API_KEY }
    : undefined,
}

src/mcp/index.ts

  • Added headers?: Record<string, string> to RemoteMcpConfig type

Testing

  1. Set EXA_API_KEY in environment (e.g., in .zshrc)
  2. Restart OpenCode
  3. websearch_exa MCP should connect successfully

References


Summary by cubic

Add EXA API key header support to the websearch MCP to fix connection timeouts when connecting to https://mcp.exa.ai/mcp. Reads EXA_API_KEY from the environment and sends it as the x-api-key header; RemoteMcpConfig now supports optional headers.

  • Bug Fixes

    • Authenticate remote Exa MCP by passing x-api-key when EXA_API_KEY is set.
    • Add headers?: Record<string, string> to RemoteMcpConfig (no breaking changes).
  • Migration

    • Set EXA_API_KEY in your environment to enable the connection.

Written for commit 156588e. Summary will update on new commits.

The remote MCP endpoint https://mcp.exa.ai/mcp requires API key authentication
via x-api-key header. Without this, the connection times out waiting for auth.

This change:
- Reads EXA_API_KEY from environment variable
- Passes it as x-api-key header when available
- Updates RemoteMcpConfig type to support optional headers
@github-actions
Copy link
Contributor

github-actions bot commented Jan 5, 2026

All contributors have signed the CLA. Thank you! ✅
Posted by the CLA Assistant Lite bot.

@greptile-apps
Copy link

greptile-apps bot commented Jan 5, 2026

Greptile Summary

This PR fixes authentication for the Exa MCP server by adding support for API key headers. The RemoteMcpConfig type now includes an optional headers field, and websearch_exa reads EXA_API_KEY from the environment to pass as the x-api-key header.

Key Changes:

  • Extended RemoteMcpConfig type with optional headers?: Record<string, string> field in src/mcp/index.ts:12
  • Added conditional header injection in websearch_exa configuration using process.env.EXA_API_KEY
  • Headers field follows the same pattern as McpRemoteConfig in the Claude Code MCP loader (src/features/claude-code-mcp-loader/types.ts:27)

Implementation:
The fix correctly handles the optional API key - when EXA_API_KEY is not set, headers will be undefined, allowing the MCP to work without authentication if the server supports it. The type definition aligns with the existing McpRemoteConfig interface used in the Claude Code compatibility layer.

Confidence Score: 5/5

  • This PR is safe to merge with minimal risk
  • The changes are minimal, well-scoped, and follow existing patterns in the codebase. The type definition matches the existing McpRemoteConfig interface, and the conditional header logic safely handles missing environment variables
  • No files require special attention

Important Files Changed

Filename Overview
src/mcp/index.ts Added headers field to RemoteMcpConfig type to support HTTP authentication headers for remote MCP servers
src/mcp/websearch-exa.ts Added conditional x-api-key header from EXA_API_KEY environment variable to authenticate with Exa MCP endpoint

Sequence Diagram

sequenceDiagram
    participant ENV as Environment Variables
    participant Config as websearch_exa.ts
    participant Type as RemoteMcpConfig Type
    participant Handler as config-handler.ts
    participant MCP as Exa MCP Server

    Note over ENV,MCP: MCP Connection Initialization Flow

    ENV->>Config: Read EXA_API_KEY
    Config->>Config: Check if EXA_API_KEY exists
    alt EXA_API_KEY is set
        Config->>Config: Set headers: { "x-api-key": EXA_API_KEY }
    else EXA_API_KEY not set
        Config->>Config: Set headers: undefined
    end
    
    Config->>Type: Return config object with optional headers
    Note over Config,Type: Config conforms to<br/>RemoteMcpConfig interface
    
    Handler->>Config: Call createBuiltinMcps()
    Handler->>Handler: Merge builtin MCPs into config.mcp
    
    Handler->>MCP: Connect to https://mcp.exa.ai/mcp
    alt Headers present
        Handler->>MCP: Include x-api-key header
        MCP->>MCP: Authenticate with API key
        MCP-->>Handler: Connection successful
    else No headers
        Handler->>MCP: Connect without headers
        MCP-->>Handler: May timeout or succeed<br/>(depending on server config)
    end
Loading

@greptile-apps
Copy link

greptile-apps bot commented Jan 5, 2026

Greptile found no issues!

From now on, if a review finishes and we haven't found any issues, we will not post anything, but you can confirm that we reviewed your changes in the status check section.

This feature can be toggled off in your Code Review Settings by deselecting "Create a status check for each PR".

@raydocs
Copy link
Contributor Author

raydocs commented Jan 5, 2026

I have read the CLA Document and I hereby sign the CLA

github-actions bot added a commit that referenced this pull request Jan 5, 2026
Copy link

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 2 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

@junhoyeo junhoyeo assigned junhoyeo and unassigned junhoyeo Jan 6, 2026
@junhoyeo junhoyeo self-requested a review January 6, 2026 20:58
Copy link
Collaborator

@junhoyeo junhoyeo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm!

@junhoyeo junhoyeo changed the title fix: add EXA_API_KEY header support for websearch_exa MCP fix: add EXA_API_KEY header support for websearch_exa MCP Jan 6, 2026
@junhoyeo
Copy link
Collaborator

junhoyeo commented Jan 6, 2026

Hi @raydocs, thanks for the fix! 👋

I've merged dev into your branch to resolve the conflicts. Here's what changed while your PR was open:

File Rename

  • websearch-exa.tswebsearch.ts
  • MCP name changed from websearch_exawebsearch

This happened in PR #549 which restored Exa support after it was temporarily removed due to timeout issues (the exact issue your fix addresses!).

Type Change

Your original PR used McpName[] for disabledMcps, but I kept the current string[] from dev because:

  • Allows graceful handling of old MCP names (e.g., websearch_exa)
  • Supports custom MCP names without type errors
  • Changed intentionally in commit 72445d2

Your header fix is still the correct solution - it just needed adapting to the new file structure. Thanks for the contribution! 🙏

@junhoyeo junhoyeo merged commit 7981c86 into code-yeongyu:dev Jan 6, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants