# Build an MCP tool for live web data

> Connect Claude Desktop, Claude Code or the OpenAI and Anthropic APIs to everydata.io's hosted MCP server: live Amazon, YouTube and shop data in minutes.

- URL: https://everydata.io/guides/mcp-server-for-live-web-data
- Updated: 2026-10-27
- Publisher: everydata.io (https://everydata.io)

AI assistants such as Claude can use outside tools, but each app needs to know which tools exist and how to use them. The Model Context Protocol (MCP) is an open standard for exactly that: a tool provider offers one address, and every app that speaks MCP can find the tools behind it and use them.

A language model on its own only knows what it learned during training. With live data it can answer “What does this cost on Amazon right now?” or “How many views does this video have today?” from the real page instead of guessing. everydata.io runs a hosted MCP server with 31 ready-made tools for Amazon, Walmart, Zalando, Otto, Zillow, Yahoo Finance, YouTube and more. You add one address and your API key to your assistant – there is nothing to install or run.

## What you will have at the end

- Claude Desktop or Claude Code connected to everydata.io, answering with live data.
- The same tools in your own agent through the OpenAI or Anthropic API.
- Know what to do when a tool call fails – and, if you need it, how to run your own server instead.

## What you need

- A free everydata.io API key – [create one here](https://everydata.io/login).
- An MCP-capable app or API: Claude Desktop (with [Node.js](https://nodejs.org/) installed), Claude Code, the OpenAI Responses API or the Anthropic Messages API.

## 1. What happens when the assistant asks for data

- Your app connects to `https://api.everydata.io/mcp` and asks which tools there are – for example `amazon_product_by_asin`, `amazon_search`, `amazon_reviews`, `walmart_search`, `zalando_search`, `otto_search`, `youtube_video`, `youtube_comments` and `yahoo_quotes`.
- When a question needs live data, the model picks a tool and fills in its inputs, such as an ASIN or a video ID.
- everydata.io loads the page, returns the data, and the model answers with it.
- Your API key goes with every request, so each tool call counts against your plan like a normal API request – with the same weights. Calls that fail on our side are not charged.

Two tools cover everything else: `list_endpoints` lists every data endpoint with its inputs, and `call_endpoint` calls any of them. `account_quota` tells the model how much of your monthly quota is left. The full tool list is in the [MCP server docs](https://everydata.io/docs/mcp).

## 2. Connect Claude Desktop

The quickest way: in Claude Desktop (or claude.ai) open Settings → Connectors → Add custom connector and enter `https://api.everydata.io/mcp`. Claude sends you to everydata.io, you sign in with your e-mail link and approve access – no key to copy. Prefer to use an API key instead? Connect through [mcp-remote](https://www.npmjs.com/package/mcp-remote), a small bridge that Claude Desktop starts on your machine and that forwards every request – with your key – to the hosted server, as shown below.

Open Settings → Developer → Edit config, add the entry below to `claude_desktop_config.json`, put your key after `Bearer ` and restart Claude Desktop.

`claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "everydata": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote",
        "https://api.everydata.io/mcp",
        "--header",
        "Authorization:${EVERYDATA_AUTH}"
      ],
      "env": {
        "EVERYDATA_AUTH": "Bearer ds_your_key"
      }
    }
  }
}
```

> The key sits in `env` and the header has no space after the colon on purpose: Claude Desktop on Windows does not pass spaces inside `args` through correctly, and mcp-remote fills in `${EVERYDATA_AUTH}` from `env`. The same entry works on macOS.

After the restart, ask a question that needs live data (see the test below) – Claude asks for permission to use an everydata tool. If no tools show up, Settings → Developer shows whether the bridge is running and its last error. A missing Node.js (`npx` not found) is the most common cause.

## 3. Connect Claude Code

Claude Code talks to remote MCP servers directly. One command registers the server with your key:

`terminal`:

```shell
export EVERYDATA_KEY="ds_your_key"
claude mcp add --transport http everydata https://api.everydata.io/mcp \
  --header "Authorization: Bearer $EVERYDATA_KEY"

# check that it is connected
claude mcp list
```

Your shell fills in `$EVERYDATA_KEY` when you run the command, and Claude Code saves the header in its settings. Add `--scope user` to use the server in every project, not just the current one. Inside Claude Code, `/mcp` shows the connection and its tools.

## 4. Use it from the OpenAI or Anthropic API

If you build your own agent, both APIs can call a remote MCP server for you: you pass the address and the key, and the provider lists the tools, calls them and hands the results to the model. You do not write any tool code yourself. Both examples read your key from the `EVERYDATA_KEY` environment variable.

OpenAI Responses API – an `mcp` tool with the key in `headers`:

`openai_mcp.py`:

```python
import os

from openai import OpenAI

client = OpenAI()

resp = client.responses.create(
    model="gpt-6-astra",
    input="How many views does the Despacito video on YouTube have right now?",
    tools=[{
        "type": "mcp",
        "server_label": "everydata",
        "server_url": "https://api.everydata.io/mcp",
        "headers": {"Authorization": f"Bearer {os.environ['EVERYDATA_KEY']}"},
        "require_approval": "never",
    }],
)
print(resp.output_text)
```

Anthropic Messages API – the MCP connector takes the server in `mcp_servers`, a matching `mcp_toolset` in `tools`, and the `mcp-client-2025-11-20` beta header (the SDK sets it from `betas`):

`anthropic_mcp.py`:

```python
import os

import anthropic

client = anthropic.Anthropic()

resp = client.beta.messages.create(
    model="claude-opus-5",
    max_tokens=1024,
    messages=[{"role": "user", "content": "How many views does the Despacito video on YouTube have right now?"}],
    mcp_servers=[{
        "type": "url",
        "url": "https://api.everydata.io/mcp",
        "name": "everydata",
        "authorization_token": os.environ["EVERYDATA_KEY"],  # sent as "Authorization: Bearer …"
    }],
    tools=[{"type": "mcp_toolset", "mcp_server_name": "everydata"}],
    betas=["mcp-client-2025-11-20"],
)
print(resp.content[-1].text)
```

> In the ChatGPT app, add a custom connector with the URL `https://api.everydata.io/mcp` (the option depends on your ChatGPT plan). You'll sign in to everydata.io and approve access; you can revoke it any time in your dashboard under API keys.

## 5. Try it: one question, one tool call

Ask your assistant “How many views does the Despacito video on YouTube have right now?”. The model picks `youtube_video` and sends the video ID:

`tool call`:

```json
{
  "name": "youtube_video",
  "arguments": { "id": "kJQP7kiw5Fk" }
}
```

The tool returns the same answer as the REST endpoint, and the assistant replies with the current numbers. Shortened documented example:

Example response of `GET /ytb/youtube-video-details`:

```json
{
  "responseStatus": "PAGE_FOUND",
  "responseMessage": "Page successfully found!",
  "videoId": "kJQP7kiw5Fk",
  "title": "Luis Fonsi - Despacito ft. Daddy Yankee",
  "channelName": "LuisFonsiVEVO",
  "viewCount": 9125159593,
  "likeCount": 56673581,
  "commentCount": 4300000,
  "publishedAt": "2017-01-12T21:00:02-08:00"
}
```

This call counts as one request. Very long answers – many reviews or search results – are shortened for the model, and the tool tells it to ask for less, for example a smaller page.

## 6. When a tool call fails

Errors come back to the model as a failed tool call with the status code in the text, so the assistant can usually tell you what went wrong.

- `401` – the key or sign-in is missing or wrong. Check that the header reads `Authorization: Bearer ds_…` (or send the key as `x-api-key`). With a connector sign-in, disconnect and connect again.
- `429` – too many requests at once for your plan. Wait for the number of seconds in the message and try again. A `403` means this month's quota is used up; `account_quota` shows what is left.
- `503` or another `5xx` – the site could not be loaded right now. These calls are not charged; simply ask again a little later.
- Timeout – a tool call gets 50 seconds. Slow pages (many reviews, large searches) can take longer; the call then fails, is not charged, and a narrower request usually works.

The limits per plan are in [Limits & quota](https://everydata.io/docs/getting-started#rate-limits).

## 7. Alternative: run your own MCP server

If you want to decide exactly which endpoints and fields the model sees, you can write a small server yourself with the official MCP Python SDK (`pip install "mcp[cli]>=2" requests`, or let [uv](https://docs.astral.sh/uv/) install both). Each tool is one function: one everydata.io request, a few selected fields. The docstring is what the model reads.

`server.py`:

```python
"""A minimal MCP server that gives AI assistants live product and video data from everydata.io."""
import os

import requests
from mcp.server.mcpserver import MCPServer

API = "https://api.everydata.io"
KEY = os.environ["EVERYDATA_API_KEY"]

mcp = MCPServer("everydata")


def _get(path: str, params: dict) -> dict:
    """One everydata.io request. Errors come back as data, so the assistant can explain them."""
    try:
        resp = requests.get(f"{API}{path}", params=params, headers={"x-api-key": KEY}, timeout=60)
    except requests.RequestException as exc:
        return {"error": "network", "detail": str(exc)[:300]}
    if resp.status_code >= 400:  # e.g. 429 = too many requests at once, 5xx = page could not be loaded
        return {"error": resp.status_code, "detail": resp.text[:300]}
    return resp.json()


def _pick(data: dict, keys: tuple) -> dict:
    return data if "error" in data else {k: data.get(k) for k in keys}


@mcp.tool()
def amazon_product(asin: str, domainCode: str = "com") -> dict:
    """Live title, price, list price, availability and rating of an Amazon product.
    asin is the 10-character product ID; domainCode is the marketplace (com, de, co.uk …).
    A price of 0 means the page shows no price right now."""
    data = _get("/amz/amazon-lookup-product-by-asin", {"asin": asin, "domainCode": domainCode})
    return _pick(data, ("productTitle", "asin", "price", "retailPrice", "currency",
                        "productRating", "countReview", "warehouseAvailability"))


@mcp.tool()
def zalando_search(keyword: str, page: int = 1) -> dict:
    """Search the Zalando shop (zalando.de by default) and return up to 10 products with price and link."""
    data = _get("/zal/zalando-search-by-keyword", {"keyword": keyword, "page": page})
    if "error" in data:
        return data
    keep = ("productDescription", "manufacturer", "price", "retailPrice", "currency", "dpUrl")
    return {"results": [{k: p.get(k) for k in keep} for p in data.get("searchProductDetails", [])[:10]]}


@mcp.tool()
def youtube_video(video: str) -> dict:
    """Current view, like and comment counts of a YouTube video. video is the video ID or its URL."""
    data = _get("/ytb/youtube-video-details", {"id": video})
    return _pick(data, ("videoId", "title", "channelName", "viewCount", "likeCount", "commentCount", "publishedAt"))


if __name__ == "__main__":
    mcp.run()  # the assistant app starts this script and talks to it directly
```

Claude Desktop starts the script itself. Use full paths (`which uv` shows where uv is), because Claude Desktop does not start from your terminal:

`claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "everydata-local": {
      "command": "/Users/you/.local/bin/uv",
      "args": ["run", "--with", "mcp[cli]>=2", "--with", "requests",
               "python", "/Users/you/everydata-mcp/server.py"],
      "env": { "EVERYDATA_API_KEY": "ds_your_key" }
    }
  }
}
```

In Claude Code:

`terminal`:

```shell
claude mcp add everydata-local --env EVERYDATA_API_KEY=ds_your_key -- uv run --with "mcp[cli]>=2" --with requests python /absolute/path/to/server.py
```

## Endpoints used in this guide

- `GET /ytb/youtube-video-details`
- `GET /amz/amazon-lookup-product-by-asin`
- `GET /zal/zalando-search-by-keyword`

## More

- [All platforms](https://everydata.io/apis) · [Pricing](https://everydata.io/pricing) · [API reference](https://everydata.io/docs) · [Getting started](https://everydata.io/docs/getting-started) · [MCP server](https://everydata.io/docs/mcp) · [Status](https://everydata.io/status)
- Machine-readable: [llms.txt](https://everydata.io/llms.txt), [llms-full.txt](https://everydata.io/llms-full.txt), [OpenAPI](https://api.everydata.io/openapi.json)
