About APITube News
APITube News is a hosted MCP server that gives AI assistants structured access to live and archived news. Its search and taxonomy tools support detailed filtering, including sentiment and named entities.
Key features
- 01Search live and archived news
- 02Filter by language, source, dates, and sentiment
- 03Enrich articles with entities and topics
- 04Resolve taxonomy IDs with suggest
- 05Sort, paginate, facet, and highlight results
Use cases
- 01Monitor company coverage and sentiment
- 02Ground an agent in recent news articles
- 03Track breaking stories by subject
- 04Compare coverage volume and sentiment
MCP support
Exposes the read-only `search_news` and `suggest` tools, plus prompts for monitoring companies, analyzing topic sentiment, finding breaking news, and comparing coverage. MCP clients connect to its hosted Streamable HTTP endpoint.
Configuration
Remote servers need no local install. Pick your client, then copy the config or install in one click.
https://mcp.apitube.io/claude mcp add --transport http io-apitube-news https://mcp.apitube.io/{"mcpServers":{"io-apitube-news":{"type":"http","url":"https://mcp.apitube.io/"}}}Open in Cursor{"servers":{"io-apitube-news":{"type":"http","url":"https://mcp.apitube.io/"}}}Open in VS Code{"mcpServers":{"io-apitube-news":{"type":"http","url":"https://mcp.apitube.io/"}}}{"mcpServers":{"io-apitube-news":{"serverUrl":"https://mcp.apitube.io/"}}}Run commands in a terminal; paste JSON into the client’s MCP config and restart. Servers that need sign-in will prompt on first connect.
https://mcp.apitube.io/Auth requiredTools
2| Parameter | Type | Required | Description |
|---|---|---|---|
| fl | string | No | Comma-separated fields to return (dot-notation supported), e.g. "id,title,source.name,sentiment.overall.score". |
| hl | boolean|object | No | Enable highlighting (true) or object form. |
| hl.fl | string | No | Fields to highlight, comma-separated. |
| hl.tag | object | No | |
| hl.tag.pre | string | No | |
| hl.tag.post | string | No | |
| hl.fragsize | integer | No | |
| hl.snippets | integer | No | |
| page | integer | No | Page number (default 1). |
| sort | object | No | |
| sort.by | enum | No | Field to sort by.published_at | created_at | id | source.rank.opr | read_time | sentiment.overall.score | sentiment.title.score | sentiment.body.score | media.images.count | media.videos.count | media.images.width.min | media.images.width.max | media.images.height.min | media.images.height.max | media_richness | shares.facebook.min | shares.facebook.max | shares.twitter.min | shares.twitter.max | shares.reddit.min | shares.reddit.max | relevance | engagement | quality | controversy | trust |
| sort.order | enum | No | Sort direction.asc | desc |
| brand | object | No | |
| brand.name | string | No | Brand name(s), comma-separated up to 3. |
| event | object | No | |
| event.name | string | No | Named event entity, comma-separated up to 3. The directory is nearly empty — prefer type/category; an unknown name returns 400 ER0228. |
| event.type | string | No | Event codes, comma-separated (max 5) — see /v1/news/event-types, e.g. layoffs, ipo, recall, wildfire. |
| event.category | enum | No | Event family.business | society | environment |
| facet | boolean|object | No | Enable faceting (true) or object form for analytics. |
| facet.field | string | No | Facet field(s), comma-separated. |
| facet.limit | integer | No | |
| facet.range | object | No | Range faceting → facet.range.* params. |
| facet.range.end | string | No | |
| facet.range.gap | string | No | e.g. "1MONTH" for dates or "0.25" for numbers. |
| facet.range.field | string | No | Numeric/date field to bucket. |
| facet.range.start | string | No | |
| facet.mincount | integer | No | |
| media | object | No | Media-content filter. |
| media.images | object | No | |
| media.images.count | object | No | |
| media.images.count.max | integer | No | |
| media.images.count.min | integer | No | |
| media.images.width | object | No | |
| media.images.width.max | integer | No | |
| media.images.width.min | integer | No | |
| media.images.height | object | No | |
| media.images.height.max | integer | No | |
| media.images.height.min | integer | No | |
| media.videos | object | No | |
| media.videos.count | object | No | |
| media.videos.count.max | integer | No | |
| media.videos.count.min | integer | No | |
| title | string | No | Search by article title. Up to 3 keywords comma-separated (OR). Phrase in quotes for exact match. |
| topic | object | No | |
| topic.id | string | No | Topic id(s), comma-separated up to 3. |
| author | object | No | |
| author.id | string | No | Author id(s), comma-separated up to 3. |
| author.name | string | No | Author name(s), comma-separated up to 3. |
| entity | object | No | Named-entity filter. |
| entity.id | string | No | Numeric entity id(s), comma-separated up to 3. |
| ignore | object | No | Exclusion filters — exclude articles matching these. Mirror the positive filters. |
| ignore.brand | object | No | |
| ignore.brand.name | string | No | |
| ignore.event | object | No | |
| ignore.event.name | string | No | Exclude these named events (up to 3). |
| ignore.event.type | string | No | Exclude these event codes (max 5). |
| ignore.title | string | No | Exclude titles with these keyword(s), comma-separated. |
| ignore.topic | object | No | |
| ignore.topic.id | string | No | |
| ignore.author | object | No | |
| ignore.author.id | string | No | |
| ignore.author.name | string | No | |
| ignore.entity | object | No | |
| ignore.entity.id | string | No | |
| ignore.person | object | No | |
| ignore.person.name | string | No | |
| ignore.source | object | No | |
| ignore.source.id | string | No | |
| ignore.source.bias | string | No | |
| ignore.source.domain | string | No | |
| ignore.source.country | object | No | |
| ignore.source.country.code | string | No | |
| ignore.disease | object | No | |
| ignore.disease.name | string | No | |
| ignore.category | object | No | |
| ignore.category.id | string | No | |
| ignore.disaster | object | No | |
| ignore.disaster.name | string | No | |
| ignore.industry | object | No | |
| ignore.industry.id | string | No | |
| ignore.language | object | No | |
| ignore.language.code | string | No | |
| ignore.location | object | No | |
| ignore.location.name | string | No | |
| ignore.organization | object | No | |
| ignore.organization.name | string | No | |
| person | object | No | |
| person.name | string | No | Person name(s), comma-separated up to 3. |
| source | object | No | Source filter. |
| source.id | string | No | Source id(s), comma-separated up to 3. |
| source.bias | enum | No | Media bias (comma-separated for multiple).left | center | right |
| source.rank | object | No | |
| source.rank.opr | object | No | OpenPageRank range (0-7). |
| source.rank.opr.max | number | No | |
| source.rank.opr.min | number | No | |
| source.domain | string | No | Domain(s), e.g. "cnn.com,bbc.com". |
| source.country | object | No | |
| source.country.code | string | No | Country code(s), e.g. "us,uk,de". |
| disease | object | No | |
| disease.name | string | No | Disease name(s), comma-separated up to 3. |
| category | object | No | IPTC category filter. |
| category.id | string | No | Category id, e.g. "medtop:04000000". Comma-separated up to 3. |
| disaster | object | No | |
| disaster.name | string | No | Disaster name(s), comma-separated up to 3. |
| industry | object | No | |
| industry.id | string | No | Industry id(s), comma-separated up to 3. |
| language | object | No | Language filter. |
| language.code | string | No | ISO codes, comma-separated up to 3 (e.g. "en,ru,fr"). |
| location | object | No | |
| location.name | string | No | Location name(s), comma-separated up to 3. |
| per_page | integer | No | Results per page (default 10). One response carries at most 25 articles. |
| has_image | enum | No | Articles with at least one image.0 | 1 |
| has_video | enum | No | Articles with at least one video.0 | 1 |
| read_time | object | No | Reading time in minutes. |
| read_time.max | integer | No | |
| read_time.min | integer | No | |
| sentiment | object | No | Sentiment filter. Scores range -1.0..1.0. |
| sentiment.body | object | No | |
| sentiment.body.score | object | No | |
| sentiment.body.score.max | number | No | |
| sentiment.body.score.min | number | No | |
| sentiment.mixed | enum | No | Title/body sentiment differ.0 | 1 |
| sentiment.title | object | No | |
| sentiment.title.score | object | No | |
| sentiment.title.score.max | number | No | |
| sentiment.title.score.min | number | No | |
| sentiment.overall | object | No | |
| sentiment.overall.score | object | No | |
| sentiment.overall.score.max | number | No | |
| sentiment.overall.score.min | number | No | |
| sentiment.overall.polarity | enum | No | Overall sentiment polarity.positive | negative | neutral |
| sentiment.consistent | enum | No | Title/body sentiment agree.0 | 1 |
| has_author | enum | No | Has an attributed author.0 | 1 |
| is_paywall | enum | No | 0 to exclude paywalled content.0 | 1 |
| is_breaking | enum | No | Breaking news only.0 | 1 |
| is_duplicate | enum | No | 0 to exclude duplicates.0 | 1 |
| is_long_read | enum | No | Read time >= 5 minutes.0 | 1 |
| organization | object | No | |
| organization.name | string | No | Organization name(s), comma-separated up to 3. |
| published_at | object | No | Publication date range (ISO 8601). |
| published_at.end | string | No | YYYY-MM-DD or RFC3339. |
| published_at.start | string | No | YYYY-MM-DD or RFC3339. |
| has_hq_images | enum | No | High-quality images (width >= 1200px).0 | 1 |
| is_media_rich | enum | No | Both images and videos.0 | 1 |
| is_short_read | enum | No | Read time < 3 minutes.0 | 1 |
| is_premium_source | enum | No | Premium sources (OPR >= 6).0 | 1 |
| is_verified_source | enum | No | Verified sources (OPR >= 5).0 | 1 |
Details
From the project READMEAPITube News MCP
Real-time and archived news search for AI agents, over the Model Context Protocol.
Hosted at https://mcp.apitube.io/ — no package to install, no local process to keep alive.
Quick Start • Tools • Filters • Prompts • Pricing • Troubleshooting • Docs • Support
300,000+ sources · 177 countries · 59 languages. Sentiment and entities on every article.
Overview
The APITube MCP server gives an assistant live access to the world's news as structured data, not scraped HTML. It exposes 2 tools:
search_news— most of the News API filter set in one call: keywords, language, country, source domain and quality rank, sentiment range, named entities, media, date ranges, sorting, faceting and highlighting.suggest— resolves a name like "Tesla" into the entity, category, topic and industry IDs the precise filters need.
Every article comes back enriched by the pipeline behind it: sentiment scores, extracted entities (people, organizations, locations, brands, events), IPTC categories, topics and industries.
MCP client → mcp.apitube.io → api.apitube.io
(this server) (News API)
JSON-RPC over HTTP, Authorization: Bearer <API_KEY>
| Property | Value |
|---|---|
| Endpoint | https://mcp.apitube.io/ |
| Transport | Streamable HTTP (POST /), JSON-RPC 2.0 |
| Protocol | 2025-11-25, negotiated down to your client's version (2024-11-05 works) |
| Server | APITube News MCP-Server 1.0.0 |
| Auth | Authorization: Bearer <API_KEY>, or X-API-Key: <API_KEY> |
| Registry | io.apitube/news (server.json) |
Quick Start
- Get an API key at apitube.io.
- Add the server to your client with the block below — each one is also a ready file in
configs/. - Restart the client and ask it something like "find positive breaking news about Tesla in English from the last week".
Claude Code
claude mcp add --transport http apitube-news https://mcp.apitube.io/ \
--header "Authorization: Bearer YOUR_API_KEY"
Check it with /mcp. To commit the server to a project instead, put
configs/claude-code.mcp.json at the repo root as .mcp.json.
Cline
MCP Servers → Configure, or ~/.cline/mcp.json for the CLI:
{
"mcpServers": {
"apitube-news": {
"type": "streamableHttp",
"url": "https://mcp.apitube.io/",
"headers": { "Authorization": "Bearer YOUR_API_KEY" },
"disabled": false,
"autoApprove": []
}
}
}
type must be set explicitly — without it Cline falls back to the legacy SSE transport, which this
server does not serve. Both tools are read-only, so autoApprove: ["search_news", "suggest"] is
safe if you would rather not confirm every call.
Cursor
~/.cursor/mcp.json (global) or .cursor/mcp.json (per project):
{
"mcpServers": {
"apitube-news": {
"url": "https://mcp.apitube.io/",
"headers": { "Authorization": "Bearer YOUR_API_KEY" }
}
}
}
Settings → MCP should list apitube-news as connected.
Claude Desktop
Claude Desktop only launches local processes, so bridge the hosted server with
mcp-remote. Edit claude_desktop_config.json
(~/Library/Application Support/Claude/ on macOS, %APPDATA%\Claude\ on Windows):
{
"mcpServers": {
"apitube-news": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://mcp.apitube.io/",
"--header",
"Authorization: Bearer YOUR_API_KEY"
]
}
}
}
Restart the app; the tools appear under the slider icon.
VS Code (GitHub Copilot)
.vscode/mcp.json, with the key prompted instead of stored in plain text:
{
"inputs": [
{ "type": "promptString", "id": "apitube-key", "description": "APITube API Key", "password": true }
],
"servers": {
"apitube-news": {
"type": "http",
"url": "https://mcp.apitube.io/",
"headers": { "Authorization": "Bearer ${input:apitube-key}" }
}
}
}
Open Copilot Chat in Agent mode and enable the apitube-news tools.
Windsurf
~/.codeium/windsurf/mcp_config.json — note serverUrl, not url:
{
"mcpServers": {
"apitube-news": {
"serverUrl": "https://mcp.apitube.io/",
"headers": { "Authorization": "Bearer YOUR_API_KEY" }
}
}
}
Windsurf Settings → Cascade → MCP Servers → refresh.
Any other client, or plain curl
Anything that speaks Streamable HTTP takes the URL directly; clients limited to stdio go through
mcp-remote, as in the Claude Desktop block. The handshake needs no key:
curl -s -X POST https://mcp.apitube.io/ \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"curl","version":"1.0.0"}},"id":1}'
{
"jsonrpc": "2.0",
"result": {
"protocolVersion": "2024-11-05",
"serverInfo": { "name": "APITube News MCP-Server", "version": "1.0.0" },
"capabilities": { "tools": { "listChanged": true }, "prompts": { "listChanged": true } }
}
}
A real search adds the key:
curl -s -X POST https://mcp.apitube.io/ \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_KEY" \
-d '{"jsonrpc":"2.0","method":"tools/call","params":{"name":"search_news","arguments":{"title":"Bitcoin","language":{"code":"en"},"per_page":5}},"id":1}'
Tools
| Tool | Title | Kind | What it does |
|---|---|---|---|
search_news | News Search | read-only | Searches articles across the News API filter set |
suggest | Resolve Taxonomy IDs | read-only | Turns a name or prefix into entity / category / topic / industry IDs |
search_news
Arguments are nested objects, never dotted strings:
{ "language": { "code": "en" } } // ✅
{ "language.code": "en" } // ❌ rejected
Three things worth knowing before the first call:
- The article body is not returned by default. The default field list is
id,title,href,published_at,description,source.domain. Ask for the text explicitly withfl: "title,href,body". - One response carries at most 25 articles.
per_pagedefaults to 10 and is clamped to 25; walk further withpage. If a result set still has to be cut — 25 articles of full text can be large — the response gains an_mcp_truncatedfield saying how many were omitted. - A title search spans at most 31 days. With no dates it covers the last 31 days; a wider explicit
range fails with
400 ER0110. Split longer periods into month-sized windows. Searches without a title filter have no range limit.
Misspelled arguments are rejected with JSON-RPC -32602 and a suggestion, instead of being
silently ignored:
Unknown parameter 'langauge.code'. Did you mean 'language.code'?
export, query and prompt are deliberately not exposed.
suggest
The precise filters take IDs you cannot guess, so resolve them first:
suggest({ type: "entities", prefix: "Tesla" })
// → [{ id: 474, name: "Tesla Robotaxi", type: "brand", … }, …]
search_news({ entity: { id: "474" }, language: { code: "en" } })
type is one of entities, categories, topics, industries; prefix is a name or its
beginning. Both are required. Matching is by prefix, so read the names before filtering on the
first hit.
Filters
Everything below belongs to search_news. Content, taxonomy, language, author and source filters
have an ignore.* twin for exclusion (ignore.title, ignore.entity.id, ignore.source.domain, …);
sentiment, media and time filters do not. Multi-value filters take up to 3 comma-separated values.
has_* and is_* take 0 or 1, not true/false.
Content and taxonomy
| Argument | Example |
|---|---|
title | "Bitcoin" — up to 3 comma-separated keywords, quotes for an exact phrase |
category.id | "medtop:04000000" — IPTC taxonomy |
topic.id | "industry.crypto_news" — slug, from suggest |
industry.id | "411" — numeric, from suggest |
entity.id | "474" — from suggest |
person.name · organization.name · location.name | "Elon Musk" · "Tesla,Apple" · "Tokyo" |
brand.name · event.name · disaster.name · disease.name | "Nike" · "Olympics" · "Earthquake" · "COVID-19" |
author.id · author.name · has_author | "123" · "Jane Smith" · 1 |
language.code | "en,de,fr" |
Sentiment
| Argument | Example |
|---|---|
sentiment.overall.polarity | "positive" | "negative" | "neutral" |
sentiment.overall.score.{min,max} | -1.0 … 1.0 |
sentiment.title.score · sentiment.body.score | same range, headline or body only |
sentiment.mixed · sentiment.consistent | 1 — title and body disagree / agree |
Sources and quality
| Argument | Example |
|---|---|
source.domain · source.id | "cnn.com,bbc.com" · "314" |
source.country.code | "us,uk,de" |
source.bias | "left" | "center" | "right" |
source.rank.opr.{min,max} | OpenPageRank, 0–7 |
is_premium_source · is_verified_source | OPR ≥ 6 · OPR ≥ 5 |
is_duplicate · is_paywall | 0 to exclude |
Media, shape and time
| Argument | Example |
|---|---|
has_image · has_video · has_hq_images · is_media_rich | 1 |
media.images.count.{min,max} · media.images.{width,height} · media.videos.count | { "min": 2 } |
is_breaking · is_long_read · is_short_read | 1 — read time ≥ 5 min / < 3 min |
read_time.{min,max} | minutes |
published_at.{start,end} | "2026-01-01" … "2026-01-31", ISO 8601 |
Output: sorting, paging, faceting, highlighting
| Argument | Example |
|---|---|
sort.by | published_at, relevance, engagement, quality, controversy, trust, source.rank.opr, sentiment.*.score, media.*, read_time, … |
sort.order | "asc" | "desc" |
page · per_page | 1 · 10 (max 25) |
fl | "id,title,source.name,sentiment.overall.score" — dot notation for nested fields |
facet | true, or { "field": "source.id,language.id", "limit": 20, "mincount": 5 } |
facet.range | { "field": "published_at", "start": "2026-01-01", "end": "2026-12-31", "gap": "1MONTH" } |
hl | true, or { "fl": "title,body", "fragsize": 300, "tag": { "pre": "<mark>", "post": "</mark>" } } |
Prompts
Slash commands in clients that support MCP prompts:
| Prompt | Arguments | What it does |
|---|---|---|
monitor_company | company (required), days | Recent coverage and sentiment for one company |
topic_sentiment | topic (required), language | Sentiment breakdown of coverage on a topic |
breaking_news | subject, country | Latest breaking stories, optionally narrowed |
compare_coverage | subject_a, subject_b (both required) | Volume and sentiment, two subjects side by side |
Use cases
| You want to | Ask for | Tools |
|---|---|---|
| Watch a brand across languages | mentions of the company with sentiment, last 7 days | suggest → search_news |
| Feed a trading or risk model | entity + industry filtered news with sentiment scores | suggest → search_news |
| Ground an agent in live news | recent articles with fl: "title,href,body" for RAG | search_news |
| Track a running story | is_breaking: 1, sorted by published_at | search_news |
| Measure share of voice | two subjects compared by volume and sentiment | compare_coverage |
| Study an archive | a date range with no title filter — no 31-day limit | search_news |
Pricing
The MCP server is part of the paid plans; the free tier covers the REST API only.
| Plan | Price | Requests | MCP server |
|---|---|---|---|
| Free | $0 | 100/day | — |
| Starter | $29/mo | 10,000/mo | ✅ |
| Basic | $99/mo | 50,000/mo | ✅ |
| Professional | $199/mo | 150,000/mo | ✅ |
Annual billing takes 20% off. Current numbers always live at apitube.io/pricing.
Page size is capped separately: through MCP one response holds at most 25 articles on every plan,
regardless of the larger per_page the REST API allows.
Troubleshooting
Auth and transport failures arrive as JSON-RPC -32000 with an APITube code in the message and the
matching HTTP status.
| Code | HTTP | Meaning | Fix |
|---|---|---|---|
ER0201 | 401 | No API key reached the server | The header is missing, or the client strips custom headers — use the mcp-remote bridge |
ER0202 | 401 | Key invalid or revoked | Re-copy it from apitube.io |
ER0230 | 401 | Key expired | Extend the expiry in the key's settings |
ER0601 / ER0602 | 403 | IP or referrer not allowed for this key | Adjust the key's restrictions |
ER0603 | 403 | Key not permitted to call this tool | Grant it access to search_news / suggest |
ER0429 | 429 | Over 120 requests/minute | Slow down — the limit is per key |
ER0900 | 503 | Key validation temporarily unavailable | Retry; the key is fine, do not reissue it |
Other symptoms
| Symptom | Cause |
|---|---|
| Client reconnects in a loop | It opened a GET SSE stream. Expected: the server answers 405 Allow: POST because it has no event stream, and compliant clients fall back to POST |
-32602 with a suggested name | Misspelled argument — arguments are nested objects, never dotted keys |
403 from a Python script | The default Python-urllib/3.x user agent is rejected at the edge. Send a real User-Agent, or use requests |
| Search returns nothing for an old story | A title search only covers 31 days. Add published_at and walk month by month |
| Articles arrive without text | The body is excluded by default. Add fl: "title,href,body" |
Documentation
| Resource | Link |
|---|---|
| MCP server reference | https://docs.apitube.io/platform/news-api/ai/mcp-server |
| Editor setup, one-click install links | https://docs.apitube.io/platform/news-api/ai/code-editors |
| All News API parameters | https://docs.apitube.io/platform/news-api/everything |
| Authentication | https://docs.apitube.io/platform/news-api/authentication |
| Machine-readable server card | https://docs.apitube.io/.well-known/mcp/server-card.json |
| Agent skill, SDKs, migration kits | https://github.com/apitube |
| Installing this server as an agent | llms-install.md |
Registry
Published in the official MCP Registry from
server.json in this repository:
mcp-name: io.apitube/news
See more on Claude Market's MCP directory.
Support
| Channel | Where |
|---|---|
| Bugs and corrections | open an issue |
| Account and billing | [email protected] |
| Everything else | https://apitube.io/contact |
Found an argument that behaves differently from what is written here? Open an issue with the request you sent and the response you got — those corrections are the most useful thing you can file.
License
MIT — see LICENSE.
Comments
New to MCP?
From what the protocol is to installing your first server, these answers cover most first questions.
An open protocol that defines how AI applications connect to external tools and data in a uniform way. Clients talk to the model; MCP servers provide tools, resources and prompt templates. They exchange standard messages, so one server can be reused by many clients.