Live, verifiable data tools for AI agents — Dynamic Feed client + ready-made adapters for LangChain, CrewAI, LlamaIndex and Pydantic AI.
Project description
dynamicfeed-tools
Live, verifiable data tools for AI agents — a tiny typed client for the Dynamic Feed API plus ready-made adapters for LangChain, CrewAI, LlamaIndex and Pydantic AI.
Dynamic Feed serves 56 live-data tools across 18 verticals (weather, hazards, security/CVEs, space, sanctions, macro, shipping, ...). Every JSON response is Ed25519-signed, and every datapoint carries a provenance envelope — source, licence, timestamp and age — so your agent can cite where a number came from and you can verify it cryptographically.
pip install dynamicfeed-tools # client only (httpx is the sole dependency)
pip install 'dynamicfeed-tools[langchain]' # + LangChain adapter
pip install 'dynamicfeed-tools[crewai]' # + CrewAI adapter
pip install 'dynamicfeed-tools[llamaindex]' # + LlamaIndex adapter
pip install 'dynamicfeed-tools[pydantic-ai]' # + Pydantic AI adapter
Keyless first
You can start with no API key and no signup:
from dynamicfeed_tools import DynamicFeed
df = DynamicFeed() # keyless
df.nearby_hazards(lat=-33.86, lon=151.21, radius_km=300) # signed live-hazard scan
df.earthquakes(min_magnitude=5.0) # USGS, worldwide
df.reality_check("the latest Python is 3.12") # anti-hallucination verdict
df.attest("wind_kmh", "gte", 120, lat=25.76, lon=-80.19) # signed MET/NOT-MET attestation
df.receipt({"decision": "loan approved", "model": "gpt-4o"}) # signed compliance receipt
The rest of the curated surface (weather, forecasts, satellites, sanctions, CVE lookups) takes a free key — one POST, no card:
key = DynamicFeed.signup() # or: curl -X POST https://dynamicfeed.ai/signup
df = DynamicFeed(api_key=key) # or set the DYNAMICFEED_API_KEY env var
df.current_weather("Sydney")
df.weather_forecast("Tokyo", days=5)
df.satellites(group="stations")
df.sanctions_screen("ACME Trading Ltd")
df.check_vulnerability("lodash", version="4.17.10", ecosystem="npm")
If a key-gated method is called without a key, it raises MissingAPIKeyError
with the signup instructions — it never sends a doomed request.
Want all 56 tools keylessly? Dynamic Feed also speaks MCP (
https://dynamicfeed.ai/mcp, streamable HTTP, no key) — ideal when your framework has an MCP adapter. This package is the zero-infrastructure REST path with a curated, signed subset.
The curated tools
| Tool | What it answers | Key? |
|---|---|---|
nearby_hazards(lat, lon, radius_km) |
live hazards around a point (quakes, fires, storms, disasters), signed | keyless |
attest(metric, op, threshold, lat, lon) |
signed parametric trigger: is wind_kmh >= 120 here, right now? |
keyless |
receipt(data) |
Ed25519-signed, timestamped record of what an AI was told/asserted | keyless |
earthquakes(min_magnitude, limit) |
recent worldwide earthquakes (USGS) | keyless |
reality_check(claim) |
fact-check a claim against live data — never guesses | keyless |
current_weather(city) |
live weather anywhere | free key |
weather_forecast(city, days) |
up to 16-day forecast | free key |
satellites(group, limit) |
constellation catalog + physics latency floor | free key |
sanctions_screen(name) |
live US OFAC SDN + UK Sanctions List screen | free key |
check_vulnerability(package, version, ecosystem) |
full OSV.dev advisory lookup | free key |
LangChain / LangGraph
# pip install 'dynamicfeed-tools[langchain]'
from dynamicfeed_tools.langchain import get_tools
tools = get_tools() # keyless tools only
tools = get_tools(api_key="dyn_...") # all ten
from langgraph.prebuilt import create_react_agent
agent = create_react_agent("openai:gpt-4o", tools)
agent.invoke({"messages": "Any hazards within 200 km of Sydney right now?"})
CrewAI
# pip install 'dynamicfeed-tools[crewai]'
from crewai import Agent
from dynamicfeed_tools.crewai import get_tools
analyst = Agent(
role="Risk analyst",
goal="Ground every claim in live, signed data",
backstory="Works only from verifiable sources.",
tools=get_tools(api_key="dyn_..."),
)
LlamaIndex
# pip install 'dynamicfeed-tools[llamaindex]'
from llama_index.core.agent.workflow import FunctionAgent
from dynamicfeed_tools.llamaindex import get_tools
agent = FunctionAgent(tools=get_tools(), llm=llm)
await agent.run("Fact-check: 'the latest Node.js LTS is 20'.")
Pydantic AI
# pip install 'dynamicfeed-tools[pydantic-ai]'
from pydantic_ai import Agent
from dynamicfeed_tools.pydantic_ai import get_tools
agent = Agent("openai:gpt-4o", tools=get_tools())
result = agent.run_sync("What's shaking? Biggest earthquake in the last day.")
Which tools does an agent get?
All four get_tools() adapters behave the same way:
- no key → only the keyless tools (an agent is never handed a tool that is guaranteed to fail),
- key present (argument or
DYNAMICFEED_API_KEY) → all ten, include_key_gated=True/Falseoverrides the auto behavior.
Verifying responses
Responses are signed by default with the Dynamic Feed Ed25519 key. To verify:
- fetch the public keys from https://dynamicfeed.ai/.well-known/keys,
- remove the
signaturefield, canonicalize the rest (JSON, sorted keys, compact separators), and check the Ed25519 signature over those bytes.
The full DF-VERIFY/1 spec lives at https://dynamicfeed.ai/standard, and the
dynamicfeed-verify package
does the verification in one line. Receipts and attestations can additionally
be anchored to Bitcoin via POST /v1/anchor for independent proof of when.
Provenance envelopes
Datapoints carry their provenance — typically source, licence,
measured_at / timestamp and age_seconds — so an agent can cite the
upstream (USGS, NASA EONET, Open-Meteo, OFAC, OSV.dev, ...) rather than
asserting numbers from nowhere. The authoritative source catalog (publisher,
licence, commercial-use status, cadence) is keyless at
GET https://dynamicfeed.ai/v1/sources.
Errors
DynamicFeedError
├── MissingAPIKeyError # key-gated method, no key configured (raised client-side)
└── APIError # non-2xx from the API (status_code, detail)
├── AuthError # 401 / 403 — missing/invalid key server-side
└── RateLimitError # 429 — daily quota reached
Development
python3 -m venv .venv && . .venv/bin/activate
pip install -e . pytest
pytest
Tests run fully offline (httpx.MockTransport) and need none of the framework
extras; adapter construction tests activate automatically when a framework is
installed.
License
MIT — see LICENSE. Data licences vary per upstream source and are declared per datapoint and in the source catalog.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file dynamicfeed_tools-0.1.0.tar.gz.
File metadata
- Download URL: dynamicfeed_tools-0.1.0.tar.gz
- Upload date:
- Size: 19.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b87906d18d6ffb0681b5421ca5ddf534a76ed9b719b7af1a116bfe2ffaee8c76
|
|
| MD5 |
ab737184319304cf236eb0a35dd43e2d
|
|
| BLAKE2b-256 |
3f636584c95e85527b95557d4f449e5ad9dbaf1a380e5bc883f6eb1ae13eae69
|
File details
Details for the file dynamicfeed_tools-0.1.0-py3-none-any.whl.
File metadata
- Download URL: dynamicfeed_tools-0.1.0-py3-none-any.whl
- Upload date:
- Size: 21.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e0f5dab7bc726cb7c3206548c47bdd6bb0b7ecf4f96689f1f032c9291ca93730
|
|
| MD5 |
76f2acec375d6da68a9bb9f1190649c9
|
|
| BLAKE2b-256 |
0467bd6a180b13e683a1a23f35cbaec207c978a08bcf0631e00d28c80191750a
|