OptimAI Search MCP
Official# @optimai-network/search-mcp
MCP (Model Context Protocol) server that wraps the **OptimAI External Search API**, enabling any MCP-compatible AI host to run Web3-focused web searches.
---
## Tools
| Tool | Description |
|---|---|
| `optimai_start_search` | Start a search and return the search ID immediately. Searches commonly take 60-90 seconds; call `optimai_get_search` with the ID to fetch progress/results. |
| `optimai_search` | Convenience search that waits briefly for results. If still running, returns the search ID for `optimai_get_search`. |
| `optimai_get_search` | Fetch current status/result of a past search by ID |
| `optimai_list_searches` | List recent searches (filterable by status, date) |
| `optimai_cancel_search` | Cancel a running or pending search |
---
## Setup
### Environment variables
| Variable | Required | Description |
|---|---|---|
| `OPTIMAI_API_KEY` | ✅ | Your OptimAI External API key (`X-API-Key`) |
Create or manage API keys at https://search.optimai.network/api-keys.
The API base URL is hardcoded to `https://api-onchain.optimai.network`.
---
## MCP Integrations
### Codex CLI
```bash
export OPTIMAI_API_KEY="sk-..."
codex mcp add optimai-search \
--env OPTIMAI_API_KEY="$OPTIMAI_API_KEY" \
-- npx -y @optimai-network/search-mcp
```
Then restart Codex and run `/mcp` to confirm `optimai-search` is enabled.
### Claude Desktop, Cursor, and other stdio hosts
For a published npm install, add this to your MCP host configuration:
```json
{
"mcpServers": {
"optimai-search": {
"command": "npx",
"args": ["-y", "@optimai-network/search-mcp"],
"env": {
"OPTIMAI_API_KEY": "sk-your-key-here"
}
}
}
}
```
Claude Desktop uses the same format in `~/Library/Application Support/Claude/claude_desktop_config.json` on macOS or `%APPDATA%\Claude\claude_desktop_config.json` on Windows.
Cursor can use the same format in `.cursor/mcp.json` in your project or in the global Cursor MCP config.
### GitHub Copilot CLI
You can add the server interactively with `/mcp add`, or edit `~/.copilot/mcp-config.json`:
```json
{
"mcpServers": {
"optimai-search": {
"type": "local",
"command": "npx",
"args": ["-y", "@optimai-network/search-mcp"],
"env": {
"OPTIMAI_API_KEY": "sk-your-key-here"
},
"tools": ["*"]
}
}
}
```
### GitHub Copilot cloud agent
Add an environment secret or variable named `COPILOT_MCP_OPTIMAI_API_KEY`, then add this MCP configuration in the repository's Copilot cloud agent settings:
```json
{
"mcpServers": {
"optimai-search": {
"type": "local",
"command": "npx",
"args": ["-y", "@optimai-network/search-mcp"],
"env": {
"OPTIMAI_API_KEY": "$COPILOT_MCP_OPTIMAI_API_KEY"
},
"tools": [
"optimai_start_search",
"optimai_get_search",
"optimai_list_searches"
]
}
}
}
```
Use `tools: ["*"]` if you want to expose every tool, including `optimai_search` and `optimai_cancel_search`.
---
## Smoke Test (MCP Inspector)
```bash
OPTIMAI_API_KEY=sk-... npx @modelcontextprotocol/inspector npx -y @optimai-network/search-mcp
```
## Tests
```bash
npm test
```
`npm test` only starts the MCP server and validates the tool schema. It does not call live OptimAI API tools.
To intentionally run a live backend smoke test:
```bash
OPTIMAI_API_KEY=sk-... npm run test:live
```
---
## Architecture Notes
- **Recommended reliable flow**: `optimai_start_search` creates a search and returns immediately with an ID. Use `optimai_get_search` to check progress and retrieve the completed answer.
- **Blocking convenience flow**: `optimai_search` creates a search then polls `GET /:id` every 2s until terminal status or local timeout. It defaults to 45s and is capped at 55s to stay below common MCP client request timeouts.
- **Future streaming**: `src/client.ts` has a `TODO: streamSearch()` stub. Upgrading to SSE only requires implementing that method and adding a new `optimai_search_stream` tool — the blocking tool is unaffected.
- **Auth**: API key is read from env at startup. Never logged or exposed in tool responses.
TDQS
Scored across 5 tools
The tools optimai_search and optimai_start_search are nearly identical in purpose: both initiate a search and return a search ID if the search is not complete. The only difference is that optimai_search waits briefly for results, but in typical long-running searches, they behave the same. This overlap creates significant ambiguity for an agent deciding which tool to use.
The naming pattern is mostly consistent with the optimai_ prefix and verb_noun structure: get_search, list_searches, cancel_search, start_search. However, optimai_search is a bare verb and does not follow the verb_noun pattern, standing out as a deviation. This is a minor inconsistency but does not severely hinder readability.
Five tools is well-scoped for a search API, covering initiation, retrieval, listing, and cancellation without unnecessary bloat. Each tool serves a distinct lifecycle function, and the count feels appropriate for the domain.
The tool set provides complete lifecycle coverage for asynchronous searches: start a search (start_search, or the combined optimai_search), check status/results (get_search), list past searches (list_searches), and cancel in-progress ones (cancel_search). No important operations are missing, and the composite optimai_search covers the synchronous wait case.