Add web search to Claude Code, Cursor and ChatGPT with MCP
Install the ContextFetch MCP server and your assistant gets tools to search the web, read any URL as Markdown, research a question and crawl a site. In Claude Code it is one command, and it works without a key for 25 calls a day. ChatGPT and Claude.ai connect to the remote server URL instead. This guide covers each client and shows the raw MCP calls, so you can see exactly what your agent receives.
1. Claude Code
Run the first command below. Claude Code starts the server with npx whenever it needs it. Without a key it allows 25 calls per IP address per UTC day. To spend your key's credits instead, pass the key as an environment variable when you add the server.
claude mcp add contextfetch -- npx -y @contextfetch/mcp # or with a keyclaude mcp add contextfetch -e CONTEXTFETCH_API_KEY=cf_live_... -- npx -y @contextfetch/mcp2. Cursor, Claude Desktop and other clients
Clients that read a JSON config run the same npm package. Add this block to the client's MCP settings: in Cursor that is .cursor/mcp.json in your project or ~/.cursor/mcp.json for every project, and in Claude Desktop it is claude_desktop_config.json. Leave out env to run keyless.
{ "mcpServers": { "contextfetch": { "command": "npx", "args": ["-y", "@contextfetch/mcp"], "env": { "CONTEXTFETCH_API_KEY": "cf_live_..." } } }}3. ChatGPT and Claude.ai
Web apps cannot start a local process, so they connect to the remote server at https://api.contextfetch.dev/mcp, which speaks streamable HTTP. In ChatGPT, open Settings, then Connectors, turn on developer mode and add the URL. In Claude.ai, open Settings, then Connectors, and add a custom connector with the same URL.
4. What the tools do
contextfetch_search: web search, returning the passages of each result that match the query.contextfetch_extract_url: any URL as Markdown.contextfetch_research: up to 5 searches at once, merged into one evidence pack with numbered sources.contextfetch_answer: quoted passages that answer a question, with citations.contextfetch_crawlandcontextfetch_map: a site's pages as Markdown, or just its URLs.contextfetch_get_free_key: claims a free key with 2,500 credits when the keyless allowance runs out.
When credits run out, the tools return the payment link as an error result instead of crashing, so the agent can show it to you. The program below lists the tools and makes one search over the remote server, which is exactly what your client does.
The complete code
Shell, runnable as is with CONTEXTFETCH_API_KEY set. We ran it against the live API; the output below is what it printed.
#!/usr/bin/env bashset -euo pipefailMCP=https://api.contextfetch.dev/mcp call() { curl -s "$MCP" \ -H "Authorization: Bearer $CONTEXTFETCH_API_KEY" \ -H "Content-Type: application/json" \ -H "Accept: application/json, text/event-stream" \ -d "$1"} echo "Tools your agent gets:"call '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | python3 -c 'import json, sys; [print(" -", t["name"]) for t in json.load(sys.stdin)["result"]["tools"]]' echoecho "What one contextfetch_search call returns (first 600 characters):"call '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"contextfetch_search","arguments":{"query":"python asyncio timeout","num_results":2}}}' | python3 -c 'import json, sys; print(json.load(sys.stdin)["result"]["content"][0]["text"][:600])' Tools your agent gets:
- contextfetch_search
- contextfetch_extract_url
- contextfetch_find_similar
- contextfetch_research
- contextfetch_deep_research
- contextfetch_answer
- contextfetch_crawl
- contextfetch_map
- contextfetch_balance
- contextfetch_auto_reload
- contextfetch_get_free_key
- search
- fetch
What one contextfetch_search call returns (first 600 characters):
## 1. GitHub - aio-libs-abandoned/async-timeout: asyncio-compatible timeout class
https://github.com/aio-libs-abandoned/async-timeout · published 2026-05-21 · score 1.000
asyncio-compatible timeout context manager.
This library has effectively been upstreamed into Python 3.11+.
Therefore this library is considered deprecated and no longer actively supported.
Version 5.0+ provides dual-mode when executed on Python 3.11+:
`asyncio_timeout.Timeout` is fully compatible with `asyncio.Timeout` *and* old
versions of the library.
Anyway, using upstream is highly recommended. `asyncio_timeout` exThe same call with curl
The raw HTTP request, and the response it returned (long text fields and lists shortened).
curl -s https://api.contextfetch.dev/mcp \ -H "Authorization: Bearer $CONTEXTFETCH_API_KEY" \ -H "Content-Type: application/json" \ -H "Accept: application/json, text/event-stream" \ -d '{"jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": {"name": "contextfetch_answer", "arguments": {"query": "what does asyncio.timeout do"}}}'{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "Extractive answer (passages quoted verbatim, nothing generated):\n\n# asyncio.timeout() To Wait and Cancel Tasks – SuperFastPython SuperFastPython Tutorial Archive asyncio.timeout() To Wait and Cancel Tasks November 26, 2023 Python Asyncio We often need to execute long-running task…"
}
],
"isError": false
}
}