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.
Release files for dynamicfeed-tools 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| dynamicfeed_tools-0.1.0.tar.gz | 19.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| dynamicfeed_tools-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 40.5 kB
Release files / dynamicfeed_tools-0.1.0.tar.gz
| Download URL | dynamicfeed_tools-0.1.0.tar.gz |
|---|---|
| Size | 19.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
b87906d18d6ffb0681b5421ca5ddf534a76ed9b719b7af1a116bfe2ffaee8c76
|
|
BLAKE2b-256 checksum How to use checksums |
3f636584c95e85527b95557d4f449e5ad9dbaf1a380e5bc883f6eb1ae13eae69
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.6
|
Release files / dynamicfeed_tools-0.1.0-py3-none-any.whl
| Download URL | dynamicfeed_tools-0.1.0-py3-none-any.whl |
|---|---|
| Size | 21.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
e0f5dab7bc726cb7c3206548c47bdd6bb0b7ecf4f96689f1f032c9291ca93730
|
|
BLAKE2b-256 checksum How to use checksums |
0467bd6a180b13e683a1a23f35cbaec207c978a08bcf0631e00d28c80191750a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.6
|