MCP vs API: one is transport, the other is a tool layer
The short answer: they sit on different layers
A REST API moves data. You send an HTTP request to an endpoint, it returns JSON or CSV, and everything about that exchange (auth, rate limits, schemas, error shapes) is arranged between your code and the server. The API neither knows nor cares whether a human, a script, or an agent is reading the response.
MCP (Model Context Protocol) is a layer on top of that world. An MCP server exposes tools: named functions with declared parameters and result shapes, listed in a catalog the agent can read. The agent picks a tool, fills in the arguments, and gets back structured text it can reason over. Under the hood the server is free to be a thin wrapper over one or several plain HTTP APIs. That is exactly what dataset-mcp is: five tools over CSV and JSON files that ship as ordinary HTTPS downloads.
So "MCP vs API" is a layer question, and the useful version is: who does the calling? Code you wrote calls APIs directly. Agents call tools. The rest of this page runs one real job through both layers so the trade-offs are visible instead of abstract.
The job: every 2025 NFL game, with its closing spread
Concretely: pull the 2025 season out of NFL game data and show each game's closing spread. Both paths end with the same 285 rows. They differ in what you set up and what you maintain.
Path one: curl against the raw CSV
The nflverse project publishes game data as a flat CSV on GitHub:
curl -sL -o games.csv \
https://raw.githubusercontent.com/nflverse/nfldata/master/data/games.csv
# 200 OK, 2,177,168 bytes, 7,549 lines (header + 7,548 games), 46 columns
# 2025 rows with a final score, column 11 = home_score:
awk -F, 'NR>1 && $2==2025 && $11!=""' games.csv | wc -l
# 285
You get all 7,548 games in one shot, 2.1 MB, no key, no rate limit. The costs sit elsewhere: you locate the URL yourself, read the schema yourself, and the filtering logic is column-position awk (or a pandas script) that breaks silently if the publisher inserts a column. Repeat for a second source and you write it all again, because every API defines its own auth, pagination, and field names.
Path two: query_dataset over MCP
Install the server once (config below), and the agent sees five tools. Then the same job is one call:
query_dataset("nfl-games", {
where: [{ column: "season", op: "=", value: 2025 }],
columns: ["game_id", "spread_line", "result"],
limit: 3
})
Verbatim output from the 2026-09-10 run:
{
"slug": "nfl-games",
"file": "nfl-games.csv",
"total_rows_in_file": 7548,
"total_matched": 285,
"returned": 3,
"next_offset": 3,
"rows": [
{ "game_id": "2025_01_DAL_PHI", "spread_line": "8.5", "result": "4" },
{ "game_id": "2025_01_KC_LAC", "spread_line": "-3", "result": "6" },
{ "game_id": "2025_01_TB_ATL", "spread_line": "-1.5","result": "-3" }
]
}
Nothing about NFL schemas was written into the agent: the tool call was assembled from the tool description plus get_dataset_info("nfl-games"), which returns the column list and query tips. The server handled the download, verified the file against its manifest SHA-256, cached it in ~/.cache/dataset-mcp/, and answered from memory. The same five tools also reach HUD rents (51,895 ZIP rows), Airbnb listings in six cities (90,169 rows), and Superteam Earn bounties: 153,866 rows across 15 data files behind one interface, with no per-source glue code.
The same job, side by side
| Dimension | curl + code (REST) | dataset-mcp (tool layer) |
|---|---|---|
| Setup | Zero install; find the endpoint and read its schema | One config block, then the agent discovers tools on its own |
| Per-source cost | New auth, pagination, and parsing per endpoint | Same five tools across every dataset in the catalog |
| Result size | Unbounded; the full 2.1 MB file in one response | 100 rows per call, paged via next_offset |
| Typing | Whatever the publisher returns; positions shift | Declared params: where, columns, limit, offset, format |
| Summaries | You write the group-by | get_stats returns counts, min/max/mean, top values |
| Best consumer | Your script, notebook, or pipeline | An agent working in a loop |
When a plain API wins
- No agent is involved. A scheduled job or a one-off analysis should call the endpoint directly; fewer layers, fewer failure modes, and the 2.1 MB bulk download beats paging 100 rows at a time.
- You need tight control: streaming, custom retries, sub-second latency, or response fields the tool layer never exposes.
- The integration is long-lived and single-purpose. One endpoint, one consumer, stable schema: the API contract is the product.
When the MCP layer wins
- An agent is in the loop. The tool catalog is the discovery mechanism: the agent finds
query_datasetitself and learns the parameters from the tool schema, with no prompt engineering per dataset. - Many sources, one interface. NFL, HUD, Airbnb, and Earn data answer to the same five tools instead of four bespoke integrations.
- You want correctness rails: typed where clauses, hash-pinned caches, and a summary tool, so the agent filters data instead of pasting it into context and hoping.
- The schema may change underneath you. The server author absorbs that once, and every agent using the tool keeps working.
The config, from the dataset-mcp README
Claude Desktop (claude_desktop_config.json):
{
"mcpServers": {
"dataset-mcp": {
"command": "npx",
"args": ["-y", "github:jayjex/dataset-mcp"]
}
}
}
pi, Codex, and other TOML-based agents:
[mcp_servers.dataset-mcp]
command = "npx"
args = ["-y", "github:jayjex/dataset-mcp"]
npm 12 refuses git-based installs by default (EALLOWGIT). Pass the flag through npx, or set allow-git=github.com in ~/.npmrc. npm 10 and 11 need no flag:
{
"mcpServers": {
"dataset-mcp": {
"command": "npx",
"args": ["--allow-git=all", "-y", "github:jayjex/dataset-mcp"]
}
}
}
After the restart, ask the agent list_datasets as a smoke test. Five tools should come back, including query_dataset and get_stats. A broader server comparison, including other free picks, is in the MCP tools for Claude guide, and the full tool reference is on the dataset-mcp page.
Try both layers yourself
The curl path needs nothing but the URL above. The MCP path needs the config block and about a minute of restart time. Free sample rows for every dataset are downloadable straight from this site (start at the free datasets index or the NFL dataset page) if you want to see the schemas before installing anything.
Query access through dataset-mcp is free. Related reading: CSV vs API for the data-format side of the same question.
MCP vs API questions
Is MCP a replacement for REST APIs?
No. MCP is a layer above the transport. A REST API moves bytes between machines; an MCP server describes callable tools so an agent can discover and use them. Most MCP servers call REST APIs behind the scenes, dataset-mcp included. Code reads APIs; agents read tool catalogs.
When should I skip MCP and call the API directly?
When no agent is involved. Pipelines and scripts should hit the endpoint directly, and bulk jobs should take the bulk path: one 2.1 MB download versus paging 100 rows at a time. MCP earns its keep when an agent is the consumer and tool discovery plus typed parameters remove the glue code.
What does dataset-mcp expose?
Five tools (list_datasets, get_dataset_info, get_sample, query_dataset, get_stats) over four datasets and 153,866 rows: NFL games 1999-2026, HUD FMR FY2026, Airbnb six-city listings, and Superteam Earn bounties. Install is one npx line; use --allow-git=all on npm 12+.