Skip to main content

TicoRates 🇨🇷

Test & Publish PyPI Docker Pulls License: MIT

Free, open exchange rate API for Costa Rica — powered by BCCR. No sign-up, no token, ready to use.

Live server → https://ticorates.dev — free for everyone, no API key required.

How it works

  1. Request — you call any endpoint with a date and currency code.
  2. Cache check — if the rate is already in the database, it's returned instantly.
  3. BCCR fetch — on a cache miss, rates are fetched from Banco Central de Costa Rica in real time.
  4. Store & serve — the result is cached in SQLite for all future requests to the same date.

Historical dates are served from cache after the first request. Concurrent requests for the same date are deduplicated — only one BCCR call is made regardless of how many clients ask simultaneously.

Try it now

No installation. No registration. Paste and run:

# Today's USD rate
curl "https://ticorates.dev/rates/latest?currency=USD"

# Rate on a specific date
curl "https://ticorates.dev/rates?date=2025-01-15&currency=USD"

# Last 30 days
curl "https://ticorates.dev/rates?from=2025-04-01&to=2025-04-30&currency=USD"

# All supported currencies
curl https://ticorates.dev/currencies

Interactive docs → ticorates.dev/docs

Features

  • REST API — simple HTTP endpoints, no authentication required
  • 43 currencies — USD, EUR, GBP, JPY, CAD, AUD, CHF, and more
  • On-demand caching — rates are fetched from BCCR on first request and served instantly after
  • Historical rates — query any date or date range going back years
  • MCP server — native integration with Claude, Cursor, Windsurf, and other AI tools
  • Self-hosted — Docker image available for linux/amd64 and linux/arm64

Table of Contents


API Reference

Base URL: https://ticorates.dev
Interactive docs: https://ticorates.dev/docs

GET /currencies

Returns all supported currency codes and their full names.

GET /currencies

Response

{
  "USD": "United States Dollar",
  "EUR": "Euro (European Union)",
  "GBP": "British Pound Sterling (United Kingdom)",
  "JPY": "Japanese Yen (Japan)"
}

GET /rates/latest

Returns today's exchange rate from BCCR for a specific currency.

Parameter Type Required Description
currency string Yes Currency code (e.g. USD, EUR)
GET /rates/latest?currency=USD

Response

{
  "date": "2025-05-27",
  "rates": {
    "USD": {
      "purchase": 512.50,
      "sale": 519.75,
      "description": "United States Dollar"
    }
  }
}

GET /rates

Returns rates for a specific date or date range. Provide either date or both from + to.

Parameter Type Required Description
currency string Yes Currency code (e.g. USD, EUR)
date string No* Single date in YYYY-MM-DD format
from string No* Start of range in YYYY-MM-DD format
to string No* End of range in YYYY-MM-DD format

*Either date or both from + to must be provided.

GET /rates?date=2025-01-15&currency=EUR
GET /rates?from=2025-01-01&to=2025-01-31&currency=USD

A single-date request returns an object. A date-range request returns an array sorted by date.

Response — single date

{
  "date": "2025-01-15",
  "rates": {
    "USD": { "purchase": 510.25, "sale": 517.50, "description": "United States Dollar" }
  }
}

Response — date range

[
  {
    "date": "2025-01-01",
    "rates": { "USD": { "purchase": 508.00, "sale": 515.00, "description": "United States Dollar" } }
  },
  {
    "date": "2025-01-02",
    "rates": { "USD": { "purchase": 509.50, "sale": 516.75, "description": "United States Dollar" } }
  }
]

Weekends & holidays

BCCR only publishes rates on business days. TicoRates handles this transparently:

  • Single date — if you request a weekend or holiday, the API returns the most recent business day's rate (looking back up to a week). The date field in the response reflects the actual date returned, not the one requested. Requesting ?date=2025-05-25 (Sunday) returns { "date": "2025-05-23", ... }.
  • Date range — days with no published data are simply omitted from the array, so a 14-day range may return fewer than 14 entries.

GET /health

Health check endpoint. Returns 200 OK when the service is running.

{ "status": "ok" }

Error responses

Status Condition
400 Unsupported currency, or date / from+to not provided
404 No BCCR data published for the requested date
422 Missing required currency parameter, or invalid date format
502 BCCR upstream error (rate limit or service unavailable)

MCP Server

No API key required. The MCP server connects to https://ticorates.dev by default — install it and it just works.

TicoRates includes an MCP server that gives AI assistants direct access to Costa Rican exchange rates. Ask your AI questions like:

  • "What's today's dollar rate in Costa Rica?"
  • "How much has the euro changed this month?"
  • "Convert 500 USD to colones using today's rate."
  • "What was the average dollar rate in Q1 2025?"

Available tools

Tool Description
get_supported_currencies List all available currency codes and names
get_latest_rates Today's rate for a specific currency
get_rates_for_date Historical rate for a specific date
get_rates_for_date_range Rates for a date range, one entry per day
convert_amount Convert between any two currencies
get_rate_change Absolute and percentage change between two dates
get_historical_average Average purchase/sale rate over a period

Setup

The same config block works across all MCP-compatible clients. Pick yours below.

Claude Desktop

Edit claude_desktop_config.json and restart Claude Desktop.

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json
{
  "mcpServers": {
    "ticorates": {
      "command": "uvx",
      "args": ["ticorates-mcp"]
    }
  }
}

Claude Code

Run once in your terminal:

claude mcp add ticorates -- uvx ticorates-mcp

Cursor

Add to ~/.cursor/mcp.json:

{
  "mcpServers": {
    "ticorates": {
      "command": "uvx",
      "args": ["ticorates-mcp"]
    }
  }
}

Or go to Settings → Cursor Settings → Features → MCP → Add MCP Server.

Windsurf

Open the Cascade panel → ⚙ Settings → MCP Servers → Add, then enter:

  • Command: uvx
  • Args: ticorates-mcp

OpenAI Codex CLI

codex mcp add ticorates -- uvx ticorates-mcp

Other clients

Any MCP-compatible client that supports stdio transport works with TicoRates. Use the same JSON config structure shown above.

Pointing the MCP at a self-hosted instance

By default, ticorates-mcp connects to https://ticorates.dev. To use your own instance, set TICORATES_BASE_URL in your client's config:

{
  "mcpServers": {
    "ticorates": {
      "command": "uvx",
      "args": ["ticorates-mcp"],
      "env": {
        "TICORATES_BASE_URL": "http://your-server:8000"
      }
    }
  }
}

Self-Hosting

Prerequisites

Setup

1. Create a docker-compose.yml:

services:
  ticorates:
    image: jonach1998/ticorates:latest
    ports:
      - "8000:8000"
    env_file: .env
    environment:
      - TZ=America/Costa_Rica
    volumes:
      - ticorates_data:/app/data
    restart: always
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
      interval: 30s
      timeout: 5s
      retries: 3
      start_period: 10s

volumes:
  ticorates_data:

2. Create a .env file:

BCCR_API_KEY=your_token_here
BCCR_BASE_URL=https://apim.bccr.fi.cr/SDDE/api/Bccr.GE.SDDE.Publico.Indicadores.API

# Optional — change the SQLite database path (default: /app/data/ticorates.db)
# DATABASE_URL=sqlite:////custom/path/ticorates.db

# Optional — only count requests with this header in /metrics (see Monitoring)
# METRICS_TRUSTED_HEADER=CF-Connecting-IP

# Optional — expose an MCP server at /mcp for AI assistants. Default: false.
# MCP_ENABLED=true

# Optional — only relevant when MCP_ENABLED=true. Base URL the mounted MCP
# tools call (default: https://ticorates.dev).
# TICORATES_BASE_URL=http://localhost:8000

3. Start the service:

docker compose up -d

The API will be available at http://localhost:8000.
Interactive docs at http://localhost:8000/docs.

Monitoring

The app exposes Prometheus metrics at /metrics (request counts by status, latency histograms). Scrape it from your monitoring stack — but keep /metrics off the public internet (block the path at your reverse proxy or tunnel), since it's an internal operational endpoint.

By default every request is counted. If you run behind a trusted proxy that tags real traffic with a header, set METRICS_TRUSTED_HEADER to count only those requests and keep internal traffic (scrapes, healthchecks, LAN) out of your metrics. With Cloudflare, use METRICS_TRUSTED_HEADER=CF-Connecting-IP.


Development

Requirements: Python 3.13+, uv

# Clone the repo and install dependencies
git clone https://github.com/jonach1998/ticorates
cd ticorates
uv sync --extra dev

# Copy and fill in your BCCR credentials
cp .env.example .env

# Run the API
uv run uvicorn ticorates.main:app --reload

# Run the MCP server
uv run ticorates-mcp

# Run unit tests (no credentials needed)
uv run python -m pytest

# Run the full stress test against the live BCCR API (requires .env)
uv run python tests/stress/stress_test.py

Star History

Star History Chart

License

MIT — see LICENSE.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ticorates_mcp-1.1.5.tar.gz (65.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ticorates_mcp-1.1.5-py3-none-any.whl (22.0 kB view details)

Uploaded Python 3

File details

Details for the file ticorates_mcp-1.1.5.tar.gz.

File metadata

  • Download URL: ticorates_mcp-1.1.5.tar.gz
  • Upload date:
  • Size: 65.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for ticorates_mcp-1.1.5.tar.gz
Algorithm Hash digest
SHA256 24625c7269df44b52848da2a97a5ce77156d95060151e386c7087b2b170ffe6d
MD5 970664da86e08a2c98f0d5ae3b4d06af
BLAKE2b-256 68de376a58a37732eac518a174c616ef1201f26f61948b486e25d54bcc5746a2

See more details on using hashes here.

Provenance

The following attestation bundles were made for ticorates_mcp-1.1.5.tar.gz:

Publisher: test-and-publish.yml on jonach1998/ticorates

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ticorates_mcp-1.1.5-py3-none-any.whl.

File metadata

  • Download URL: ticorates_mcp-1.1.5-py3-none-any.whl
  • Upload date:
  • Size: 22.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for ticorates_mcp-1.1.5-py3-none-any.whl
Algorithm Hash digest
SHA256 ce0a786b6a58e6d513e27d94b2a2d1b84d7d5e8e0a22227915d82b7c9a139733
MD5 f63f09e2197136fea9c58dfe224b1f2a
BLAKE2b-256 8bde065ab353b06077d8aac9a594929ceff10e318f1fbe0b3a897c2ed06ebaa9

See more details on using hashes here.

Provenance

The following attestation bundles were made for ticorates_mcp-1.1.5-py3-none-any.whl:

Publisher: test-and-publish.yml on jonach1998/ticorates

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

1.1.5 This release

2 files

1.1.3

2 files

1.1.2

2 files

1.1.1

2 files

1.1.0

2 files

1.0.5

2 files

1.0.3

2 files

1.0.2

2 files

1.0.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page