A financial news API for AI agents: MCP, LangChain and tool calls

An agent that trades, researches or monitors a portfolio needs news it can reason over: structured, tagged, scored, and small enough to fit a context window. Here is how to wire the H1 News API into Claude, Cursor, LangChain, LlamaIndex, or a raw tool-calling loop.

Updated 2026-09-20 · 6 min read · every example runs against the live API

The problem with feeding an LLM a news API is not access, it is shape. Raw feeds make the model do entity resolution, deduplication and sentiment on the fly, in tokens you pay for, with results you cannot audit. The H1 News API does that work at ingest and returns rows an agent can filter, count and cite.

Claude Desktop, Cursor and Claude Code (MCP)

The h1news-mcp server exposes 15 tools — search, per-ticker news, halts, filings, regulators, central banks, sentiment, top-mentioned, earnings calendar, analyst ratings, the Sundown Digest, sources, ticker lookup and usage.

install
pip install h1news-mcp
claude_desktop_config.json
{
  "mcpServers": {
    "h1news": {
      "command": "h1news-mcp",
      "env": { "H1NEWS_API_KEY": "sk_..." }
    }
  }
}
Claude Code
claude mcp add h1news -e H1NEWS_API_KEY=sk_... -- h1news-mcp

Restart the client and ask in plain language: "Anything halted today?", "Negative news on my NVDA position this week, and from which sources?", "What did the ECB say this morning?". The model picks the tool, reads compact rows, and opens an article's url only when it needs the body.

LangChain and LangGraph

a react agent with seven news tools
from langchain_openai import ChatOpenAI
from langgraph.prebuilt import create_react_agent
from h1news.langchain_tool import h1news_tools          # pip install "h1news[langchain]"

agent = create_react_agent(ChatOpenAI(model="gpt-4o-mini"), h1news_tools("sk_..."))
result = agent.invoke({"messages": [
    ("user", "Is there anything I should worry about on my NVDA and TSLA positions this week? "
             "Check halts, filings and negative headlines, and tell me which sources.")
]})
print(result["messages"][-1].content)

The same seven tools ship as a LlamaIndex ToolSpec in h1news.llamaindex_tool.

What the model actually sees

Every tool returns rows like these — about 60 tokens each:

tool result
[
  {"id": 598112, "title": "Nvidia Supplier Warns of Slower Shipments Into Year-End",
   "source": "Google News: Markets", "published_at": "2026-09-19T16:01:13+00:00",
   "tickers": ["NVDA"], "sentiment": "negative", "category": "markets", "url": "https://…"},
  {"id": 598090, "title": "4 - NVIDIA CORP (0001045810) (Issuer)",
   "source": "SEC EDGAR 4", "published_at": "2026-09-19T14:52:41+00:00",
   "tickers": ["NVDA"], "sentiment": "neutral", "category": "filings", "url": "https://www.sec.gov/…"}
]

That is enough for the model to count, rank, group by source, and cite. When it wants the summary text it calls article(id).

Any function-calling API

If you are not on a framework, one tool definition and a fifteen-line handler cover the common case:

tool definition (Anthropic / OpenAI shape)
{
  "name": "search_financial_news",
  "description": "Ticker-tagged, sentiment-scored financial news from 135+ sources.",
  "input_schema": {
    "type": "object",
    "properties": {
      "ticker":    {"type": "string", "description": "Symbol, e.g. NVDA"},
      "query":     {"type": "string", "description": "Full-text; supports AND / OR"},
      "category":  {"type": "string", "enum": ["markets","earnings","macro","world","commodities",
                                                "forex","crypto","halts","filings","regulatory"]},
      "sentiment": {"type": "string", "enum": ["positive","negative","neutral"]},
      "date":      {"type": "string", "enum": ["today","yesterday","last7days","last30days"]},
      "limit":     {"type": "integer", "maximum": 50}
    }
  }
}
handler
import httpx

def search_financial_news(**args):
    r = httpx.get("https://api.heliusone.com/v1/news", params=args,
                  headers={"X-API-Key": "sk_..."}, timeout=20)
    r.raise_for_status()
    return [{k: a[k] for k in ("id", "title", "source", "published_at", "tickers", "category", "url")}
            | {"sentiment": a["sentiment"]["label"]} for a in r.json()["results"]]

Add trading_halts (/v1/news/halts), sec_filings (/v1/news/filings?form=) and market_sentiment (/v1/sentiment) the same way; the LangChain module is a worked example of all seven.

Patterns that work

  • Portfolio check-in. One ticker_news call per position with sentiment=negative, then sec_filings for the names that came back non-empty. Five positions, under ten calls, one paragraph of output.
  • Catalyst watch. trading_halts and regulatory_actions on a schedule; escalate to a human when a held name appears.
  • Grounded summaries. Ask for a market summary with citations; the rows carry source and url, so the model can quote and link instead of inventing.
  • Reacting, not answering. On Pro, stream categories=["halts","filings","regulatory"] into a queue and let the agent decide per event — the Alpaca example does this with a paper account.

Let the API do the reading

If what you want is "tell me what happened today", the /v1/sundown-digest endpoint generates a Claude-written recap from the day's tagged articles. You bring an Anthropic key for the one generation call — it is never stored — and the result is cached for every caller until the next day:

Sundown Digest
curl -H 'X-API-Key: YOUR_KEY' -H 'X-Anthropic-Key: sk-ant-...' \
  'https://api.heliusone.com/v1/sundown-digest'

Questions

Why not just give the agent a generic news API?
Because the agent then has to do the finance work itself: figure out which company a story is about, whether it is good or bad, whether it is a filing or an opinion piece, and whether it has seen the same story from three syndicators. Ticker tags, sentiment, type, category and cross-source dedupe are computed at ingest, so the tool result is already structured and the model spends its context on reasoning.
How many tokens does a tool call cost?
The MCP server and the LangChain tools return compact rows — id, title, source, time, tickers, sentiment label, category, url — around 60 tokens each. Ten results fit in roughly 600 tokens; the full summary is one article call away when the model wants it.
Which plan do agents need?
Basic is enough for most agents: every REST endpoint, one ticker per call. An agent that asks about a five-name portfolio makes five calls, which is fine at 20,000 a month. Pro adds multi-ticker calls and the stream for agents that need to react rather than answer.
Does it work with Claude, GPT, Gemini and open models?
The MCP server works with any MCP client — Claude Desktop, Claude Code, Cursor, Windsurf. The LangChain tools and LlamaIndex ToolSpec work with any model those frameworks support. The raw tool definition on this page works with any function-calling API.

Publisher and product names on this page are trademarks of their respective owners and are used only to identify sources and compared services; no affiliation, sponsorship or endorsement is implied.

Try it on your own keys

Basic is $19.99/mo, Pro $49.99/mo; both start with a 5-day, 100-call free trial. Card required, cancel anytime.