MCP server
The same corpus as the API, handed to your agent in the protocol it already speaks. One URL, no key, no signup, no rate plan. Paste it into Claude, Cursor, VS Code or your own client and the model gets 28 tools it can call on its own.
https://freenewsapi.ai/mcpConnect your client
Claude Code
One command, and the tools are there in the next message:
claude mcp add --transport http freenewsapi https://freenewsapi.ai/mcpClaude Desktop, Cursor, Windsurf, Zed
All of them read the same shape of config file. Add one block:
{
"mcpServers": {
"freenewsapi": {
"type": "http",
"url": "https://freenewsapi.ai/mcp"
}
}
}VS Code
code --add-mcp '{"name":"freenewsapi","type":"http","url":"https://freenewsapi.ai/mcp"}'OpenAI Agents SDK, LangChain, anything else
Point any Streamable HTTP MCP client at https://freenewsapi.ai/mcp. There is no
authorization step: we do not issue tokens, so there is nothing to paste after the URL.
Clients that insist on a header can send whatever they like — it is ignored.
The six shortcuts
These six are written by hand, and they are the ones to reach for first. Each answers a whole question in one call and returns a trimmed result — a model pays for every token it reads, and the raw endpoints below will happily hand it fifty full articles.
Two of them answer completely different questions and get confused for each other, so
the split is worth stating once. search_news returns articles matching
words. get_trends returns events the press is covering, already
grouped, whether or not you can guess the words. A model asking “what is happening
in Poland” wants the second one.
search_news Find articles
Full-text search across the whole corpus — 18.8 million articles from 25 312 publishers in 99 languages, kept for 90 days and refreshed every minute.
Words to look for. Matched against title, description and body, all terms required.
Where the publisher is, not what the article is about.
Language of the article: de,fr.
Restrict to particular publishers.
How far back to look. Default 7.
Default relevance.
Default 10.
Ask it for articles. Ask get_trends for events.
get_trends See what is happening
Stories rather than articles. A robot groups what publishers write into events and recomputes every country every five minutes; roughly 24 000 stories are alive at any moment.
Whose press. Omit for all 115.
15m, 30m, 1h, 3h, 6h, 12h, 24h, 7d, 30d. Default 24h.
politics, business, markets, tech, sport, health, science, culture, crime, conflict, weather, society.
Keep only stories built on these words.
Drop stories fewer outlets carry.
Default 15.
Each story comes back with two headlines and a link to its human page, so a model can cite something a reader can open.
trend_keywords Read the shape of the day
The words the news is built on right now, with how many stories and how many national presses carry each.
Narrow to one press.
Default 24h.
Ignore words holding fewer stories. Default 2.
Default 30.
A word carried in 70 countries is a global event; the same word in one country is domestic, however loud it sounds there.
find_publishers Look up a source
Who we read: name, domain, country, language, and how many articles a day we actually take from each.
Name or domain fragment.
Publishers registered there.
Publishers writing in it.
Default 20.
The coverage field says how deeply we read a site, not how big it is — rich and normal are the 8 606 we follow properly, thin and hidden the long tail we see a handful of articles from.
list_countries Check what is live
Which of the 115 countries have stories right now, how many, and how many minutes ago each was recomputed.
No arguments.
Useful as a first call: it tells a model where there is anything to ask about before it starts guessing country codes.
market_vs_news Price against coverage
A price series next to how much the world wrote about it in the same hours — 14 instruments: crypto, gold, currencies, European power.
bitcoin, ethereum, gold, usd-try, eur-usd … a wrong name returns the full list, so a model can recover in one extra call.
Default 7d.
Coverage volume is not sentiment. It says the press was loud, not that the press was bullish.
Every endpoint, as a tool
Besides the six, every endpoint of the HTTP API is exposed as its own tool — 20 of them — with every parameter it accepts, its defaults and its limits. That list is not typed out anywhere. It is generated from the running service, so a tool cannot promise a parameter the API does not take, and a new endpoint becomes a new tool without anyone remembering to add it. This page is built from the same catalogue: if the table below is wrong, the server is wrong.
| tool | endpoint | what it returns | parameters |
|---|---|---|---|
| news_get_btc_summary | GET /v1/btc/summary | Latest price, recent moves and the tone of today news | — |
| news_get_btc_price | GET /v1/btc/price | BTC/USDT candles | interval, from, to |
| news_get_btc_sentiment | GET /v1/btc/sentiment | News tone per period | interval, from, to |
| news_get_btc_series | GET /v1/btc/series | Price and news tone aligned on one timeline | interval, from, to |
| news_get_btc_correlation | GET /v1/btc/correlation | Correlation between news tone and price move, by shift | interval, from, to, max_shift |
| news_get_btc_news | GET /v1/btc/news | Crypto articles with their sentiment label | from, to, label, host, lang, q… |
| news_get_btc_sources | GET /v1/btc/sources | Which outlets drive crypto coverage, and how they lean | from, to, by, top |
| news_get_trends | GET /v1/trends | Trending stories, filtered | country, window, date, since, until, category… |
| news_get_trends_keywords | GET /v1/trends/keywords | Words the stories are built on | country, window, date, since, until, category… |
| news_get_trends_countries | GET /v1/trends/countries | Countries we track, and how fresh | min_trends |
| news_get_trends_cc_slug | GET /v1/trends/{cc}/{slug} | One trend with its articles | cc, slug, size |
| news_get_markets | GET /v1/markets | Instruments we track | — |
| news_get_markets_slug | GET /v1/markets/{slug} | Price and coverage on one timeline | slug, window |
| news_get_search | GET /v1/search | Search news articles | q, country, lang, tld, host, date… |
| news_get_stats | GET /v1/stats | Aggregated breakdown of a slice | q, country, lang, tld, host, date… |
| news_get_article | GET /v1/article | Fetch a single article by URL | url, full_text |
| news_get_health | GET /health | Service health and corpus size | — |
| news_get_rss | GET /v1/rss | The same search as RSS 2.0 | q, country, lang, tld, host, date… |
| news_get_atom | GET /v1/atom | The same search as Atom 1.0 | q, country, lang, tld, host, date… |
| news_get_feed_json | GET /v1/feed.json | The same search as JSON Feed 1.1 | q, country, lang, tld, host, date… |
Two more sit on top of them. news_list_endpoints returns this same
catalogue, so a model can discover what exists at runtime instead of guessing.
news_get calls any endpoint by path, for clients that show the model only
part of a long tool list.
Calls run inside the service, not over HTTP to itself. That is not a detail: the API runs four worker processes, and a server that answers its own requests can end up with all four waiting on each other.
Machine-readable catalogue
The same list, one GET, no protocol handshake — useful for checking what exists before wiring anything up:
curl -s 'https://freenewsapi.ai/mcp?format=json'It returns the server name, transport, protocol version, every tool with its arguments, and every endpoint with its description. The page you are reading and the tools your client sees are both rendered from it.
Raw protocol
JSON-RPC 2.0 over a plain POST — Streamable HTTP, the transport remote MCP servers settled on. You can drive it with curl, which is the quickest way to see whether a problem is ours or your client's:
curl -s -X POST https://freenewsapi.ai/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'And a real call:
curl -s -X POST https://freenewsapi.ai/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":
{"name":"get_trends","arguments":{"country":"UA","window":"6h"}}}'We implement initialize, ping, tools/list,
tools/call, and accept notifications with 202. Protocol version
2025-06-18. Batched requests work. There are no sessions to keep: every call
stands alone, so nothing breaks if your client reconnects, and there is no
Mcp-Session-Id to carry.
A tool that fails comes back as a result with isError set, not as a
protocol error — that is deliberate, so the model sees what went wrong and fixes its
own arguments instead of the client deciding the server is broken.
Limits and honesty
It is free and it stays free. Same as the API: no key, no plan, no per-call billing. The polite thing, if you build something on it, is to say who you are — one optional parameter, and it is the only reason we would ever know you exist.
Result sizes are capped at 50 items per call, 200 for keywords. Models pay for every token they read; a tool that dumps 500 articles into a context window is a tool that gets uninstalled.
Country means the publisher, not the subject. An article about Kenya in a French
newspaper is FR. This is the single most common misreading of the whole
dataset.
Publisher counts are coverage, not importance. Outlets copy each other — a syndicated wire story on forty sites looks like forty newsrooms.
Ninety days. Older articles are dropped. If you need history, keep what you fetch.
No sentiment, no summaries, no ranking by importance. The tools hand over what was published and how much of it; deciding what matters is the model's job, and pretending otherwise would be selling a judgement we have not made.
Why an MCP server as well as an API
The API is for code you write. This is for models you did not write. An agent with the
endpoint in its config can decide by itself that a question needs today's news, call
get_trends, and cite a link the reader can open — without anyone having
wrapped our endpoints in a function schema first. That wrapping is exactly what MCP was
invented to stop repeating, and we would rather write it once than have a hundred people
write it badly.
If you would rather do the wrapping yourself, the hand-written function schemas are still on the agents pages, and the plain HTTP endpoints are documented under Docs. Nothing is deprecated; this is a third door into the same building.