Frankfurter is an open-source API that provides daily currency exchange rates collected from institutional sources. Developers use it to retrieve currency data, convert amounts, or run their own instance with Docker. The catalogue entries are add-ons for working with the API.
Getting it into your agent
One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.
npx agentmods add instructions/lineofflight/frankfurter/agents-mdgit clone --depth 1 https://github.com/lineofflight/frankfurterWrote this? Show the measurements
A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.
[](https://agentmods.dev/instructions/lineofflight/frankfurter/agents-md)<a href="https://agentmods.dev/instructions/lineofflight/frankfurter/agents-md"><img src="https://agentmods.dev/badge/instructions/lineofflight/frankfurter/agents-md.svg" alt="Measured on agentmods" height="20"></a>What it costs to keep this loaded
Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.
| Model | Per session | Once invoked |
|---|---|---|
| Fable 5 | $0.04392 | $0.04392 |
| Opus 5 | $0.02196 | $0.02196 |
| Sonnet 5 | $0.00878 | $0.00878 |
| Haiku 4.5 | $0.00439 | $0.00439 |
Grade A, and why
frankfurter AGENTS.md scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 5d ago.
A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.
Nothing flagged
None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.
How it starts
The opening of the file, as written. The whole thing — 334 lines — stays where its author put it; the contents beside it link to each section on GitHub.
Frankfurter
Frankfurter is a free and open-source currency data API built with Ruby that tracks reference exchange rates from 50+ institutional sources (central banks, the IMF, the Federal Reserve, etc.).
Before You Write Code
Several agents work in this repo at once. Assume you are not alone.
Do your work in a git worktree, not in the primary checkout. The primary checkout is shared ground. Two agents editing it at the same time lose each other's work: one stages the other's files, or checks the branch out from under them mid-task. This has happened repeatedly.
Check before your first edit. The branch reported at session start is a snapshot and goes stale:
git rev-parse --abbrev-ref HEAD # the live branch
git status --short # files you never touched mean someone else is here
for p in $(pgrep -x claude); do lsof -a -p $p -d cwd -Fn 2>/dev/null | sed -n 's/^n//p'; done | sort | uniq -c
Then take a worktree. Use the native EnterWorktree tool if your harness has one,
otherwise:
git fetch origin
git worktree add .claude/worktrees/<slug> -b <branch> origin/main
cp -R .zed .claude/worktrees/<slug>/.zed # gitignored, so a fresh worktree comes up bare
Worktrees live under .claude/worktrees/ (gitignored), never as siblings of the
checkout. Branch off origin/main, not local main, which may be stale or may
belong to another agent. A stacked local branch is often already upstream as a
squash merge, so origin/main is the right base even when local commits look
unmerged.
Exceptions. Read-only work needs no worktree. Neither does a single edit you
will commit within the minute, provided git status is clean and no other agent
is live here. Everything else gets a worktree.
Architecture
- Roda
- SQLite with Sequel
- Puma
- Rufus scheduler
- Foreman
- Cloudflare CDN
Project Structure
lib/
├── app.rb # Main Roda app — mounts v1 and v2
├── base_conversion.rb # Rebases rates from any base to a common base
├── blend_parity.rb # Parity harness: replays query shapes through table and live paths
├── blended_rate.rb # BlendedRate model: materialized pivot-frame blend, refresh/rebuild
├── blender.rb # Blends multi-provider rates: rebase → consensus → weighted average
├── bucket.rb # Shared SQL bucket expressions for weekly/monthly aggregation
├── cache.rb # Cloudflare cache purge, debounced with a trailing edge
├── carry_forward.rb # Carries forward most recent provider rate within a lookback window
├── consensus.rb # Cross-provider outlier detection (MAD-based)
├── currency.rb # Currency model (materialized from rates)
├── currency_coverage.rb # CurrencyCoverage model (provider-currency join)
├── defunct_currency.rb # Defunct-currency registry: terminal dates for retired/redenominated ISO codes
├── db.rb # Database configuration
├── currency_patches.rb # Patches Money::Currency: registers historical codes, fixes mangled names
├── log.rb # Shared logger
├── monthly_rate.rb # MonthlyRate model on monthly_rates rollup table
├── no_store_on_error.rb # Rack middleware: stops CDNs/caches from holding error responses
├── peg.rb # Currency peg definitions (from db/seeds/pegs/*.json)
├── peg_anchor.rb # Peg-aware post-processing: substitutes peg rates, synthesises uncovered pegged quotes
├── provider.rb # Provider model: identity, backfill
├── provider/
│ ├── adapters/
│ │ ├── adapter.rb # Abstract adapter: fetch interface, chunked iteration
│ │ └── <key>.rb # One adapter per provider (auto-discovered)
│ └── adapters.rb # Auto-requires all adapters
├── rate.rb # Rate model on rates table
├── rate_precision.rb # Ingest-precision policy: strips binary float noise from synthesized rates
├── rate_scopes.rb # Shared dataset scopes for rate tables (rates, weekly, monthly)
├── rate_validation.rb # Ingest-validation policy: drops invalid rows on ingest, purges stored ones
├── roundable.rb # Currency-aware decimal rounding
├── weekly_rate.rb # WeeklyRate model on weekly_rates rollup table
├── weighted_average.rb # Recency-weighted averaging with exponential decay
├── versions/
│ ├── v1.rb # Legacy API (ECB-only, frozen)
│ ├── v1/ # V1 internals (quotes, query, currency names)
│ ├── v2.rb # Multi-provider API
│ └── v2/
│ └── rate_query.rb # V2 rate query builder (blending, filtering)
├── public/
│ ├── favicon.ico # Served as a static file
│ ├── robots.txt # Served as a static file
│ ├── v1/openapi.json # V1 OpenAPI spec
│ └── v2/openapi.json # V2 OpenAPI spec
└── tasks/
├── blend.rake # Rebuild/verify the materialized blend
├── cache.rake # Manual CDN purge
├── consensus.rake # Consensus scan across providers
├── db.rake # Database migrations and setup
├── default.rake # Default task (lint + test)
├── providers.rake # Dynamic backfill task for all providers
├── rollups.rake # Rebuild weekly/monthly rollup tables
├── rubocop.rake # Linter task
└── test.rake # Test suite task
spec/ # Minitest test suite
db/migrate/ # Sequel migrations
db/seeds/
├── currency_patches.json # Money::Currency patches (historical codes, name fixes)
├── defunct_currencies.json # Defunct currencies: terminal dates for retired/redenominated ISO codes
├── pegs/ # One JSON file per peg (e.g. aed.json, bam.json)
└── providers/ # One JSON file per provider (e.g. ecb.json, boi.json)
What this file has done since we first saw it
Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.
- 5d ago First seen · 334 lines · 4,392 tokens per session scan A fa3526e8e40a
frankfurter AGENTS.md is an instructions file published in the GitHub repository lineofflight/frankfurter (1,832 stars, last pushed 3d ago), licensed MIT. It adds 4,392 tokens to every session, about $0.0220 per session on Opus 5. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-30.
Other instructions, from other repositories
dinero.js CLAUDE.md
Claude Code instructions for dinerojs/dinero.js, covering claude.md, commands, key conventions, path aliases and references.
pochem CLAUDE.md
Instructions for baradusov/pochem, covering claude instructions, philosophy, architecture, rules and directory structure.
cambio-uruguay AGENTS.md
AGENTS.md instructions for eduair94/cambio-uruguay, covering cambio-uruguay — agents, pm2 jobs (ecosystem.config.js → script → cron utc), top-level dirs, build / run / test / lint and deploy (push to main → .github/workflows/deploy.yml).
cambio-uruguay CLAUDE.md
Claude Code instructions for eduair94/cambio-uruguay: This repo's agent instructions live in AGENTS.md (the cross-tool standard). Read it.
gorest AGENTS.md
AGENTS.md instructions for pilinux/gorest, covering agents.md, project overview, build and run commands, build and tidy dependencies.
gmgn-skills CLAUDE.md
Claude Code instructions for GMGNAI/gmgn-skills, covering claude.md, critical rule — read this first, project overview, available skills and quick decision guide.