Skip to main content

Reusable SQLite-backed cache for MCP servers — TTL and incremental time series strategies

Project description

mcp-cache

A reusable SQLite-backed cache for MCP (Model Context Protocol) servers. Zero dependencies — pure Python stdlib.

Two caching strategies:

  • TTL cache — store any JSON-serializable value for N seconds
  • Time series cache — store date-keyed observations and automatically fetch only missing date ranges

Installation

pip install mcp-cache

Or from source:

git clone https://github.com/cmaurer/mcp-cache
cd mcp-cache
pip install -e .

Requires Python 3.10+.

Quick start

TTL cache

from mcp_cache import MCPCache

cache = MCPCache("~/.cache/myserver.db", default_ttl=300)

async def get_quote(symbol: str) -> dict:
    return await cache.get_or_fetch(
        key=f"quote:{symbol}",
        fetch_fn=lambda: api.fetch_quote(symbol),
        ttl=60,  # override default; omit to use default_ttl
    )

fetch_fn is called only on a cache miss or after the TTL expires. The result is stored as JSON and returned on subsequent calls within the TTL window.

Time series cache

observations = await cache.get_timeseries(
    series_id="T10YIE",
    start_date="2020-01-01",
    end_date="2024-12-31",
    fetch_fn=lambda s, e: fred_api.get_series("T10YIE", s, e),
)
# Returns list of {"date": "YYYY-MM-DD", "value": float} dicts, newest first

On the first call the full range is fetched. On subsequent calls only gaps are fetched — requesting a wider range re-uses the already-cached portion and fetches only the missing edges.

Custom key names are supported for APIs that don't use "date" / "value":

observations = await cache.get_timeseries(
    series_id="prices",
    start_date="2024-01-01",
    end_date="2024-06-30",
    fetch_fn=my_fetch,
    date_key="timestamp",
    value_key="close",
)

API reference

MCPCache(db_path, default_ttl)

Parameter Type Default Description
db_path str | Path "mcp_cache.db" Path to SQLite file. ~ is expanded. Parent dirs are created automatically.
default_ttl int 300 Default TTL in seconds for get_or_fetch.

TTL cache methods

await cache.get_or_fetch(key, fetch_fn, ttl=None)

Return the cached value for key if it exists and is still fresh. Otherwise call fetch_fn(), store the result, and return it.

  • key — cache key string
  • fetch_fn — async callable that returns a JSON-serializable value
  • ttl — per-call TTL override in seconds; uses default_ttl if omitted

await cache.invalidate(key)

Remove a specific entry from the TTL cache. No-op if the key does not exist.

await cache.clear_expired()

Delete all expired TTL entries. Returns the number of entries removed.

await cache.list_keys(prefix=None, include_expired=False)

Return TTL cache keys as a sorted list of strings.

  • prefix — only return keys starting with this string; None (default) returns all keys
  • include_expired — include expired entries; defaults to False (fresh keys only)

Time series methods

await cache.get_timeseries(series_id, start_date, end_date, fetch_fn, date_key="date", value_key="value")

Return cached observations for series_id in [start_date, end_date].

  • series_id — identifier for the series
  • start_date, end_datedate objects or ISO strings ("YYYY-MM-DD")
  • fetch_fn(start, end) — async callable receiving ISO date strings; must return a list of dicts containing date_key and optionally value_key
  • date_key, value_key — key names in the returned dicts (default "date", "value")

Returns a list of {date_key: str, value_key: float | None} dicts sorted newest first. None values are preserved — they represent real data points (e.g. non-trading days).

await cache.invalidate_series(series_id)

Remove all cached observations and range records for a series.

await cache.list_series(prefix=None)

Return distinct time series IDs as a sorted list of strings.

  • prefix — only return series IDs starting with this string; None (default) returns all series

Diagnostics

await cache.stats()

Returns a dict with cache counts:

{
    "ttl_cache":  {"total": 12, "fresh": 10, "expired": 2},
    "timeseries": {"series": 3, "observations": 1500, "fetched_ranges": 6},
    "db_path":    "/home/user/.cache/myserver.db",
}

Using with an MCP server

from mcp_cache import MCPCache

_cache = MCPCache("~/.cache/myserver.db")

@server.tool()
async def get_price_history(symbol: str, start: str, end: str) -> list[dict]:
    return await _cache.get_timeseries(
        series_id=symbol,
        start_date=start,
        end_date=end,
        fetch_fn=lambda s, e: data_provider.fetch(symbol, s, e),
    )

Using with Claude Desktop

Install the package:

pip install mcp-cache

Add the server to ~/Library/Application Support/Claude/claude_desktop_config.json:

{
  "mcpServers": {
    "cache": {
      "command": "mcp-cache"
    }
  }
}

Restart Claude Desktop. The following tools will be available:

Tool Description
cache_get(key) Return a cached value, or null if missing/expired
cache_set(key, value, ttl) Store a JSON value for ttl seconds (default 300)
cache_invalidate(key) Remove a specific entry
cache_clear_expired() Delete all expired entries
cache_list_keys(prefix, include_expired) List TTL cache keys, optionally filtered by prefix
timeseries_store(series_id, observations, range_start, range_end) Store date-keyed observations
timeseries_get(series_id, start_date, end_date) Query cached observations
timeseries_invalidate(series_id) Clear all data for a series
timeseries_list_series(prefix) List time series IDs, optionally filtered by prefix
cache_stats() Return entry counts and db path

The cache database is stored at ~/.cache/mcp_cache.db.

Development

pip install -e ".[dev]"
pytest

License

MIT

Project details


Download files

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

Source Distribution

mcp_cache-0.2.1.tar.gz (18.3 kB view details)

Uploaded Source

Built Distribution

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

mcp_cache-0.2.1-py3-none-any.whl (3.6 kB view details)

Uploaded Python 3

File details

Details for the file mcp_cache-0.2.1.tar.gz.

File metadata

  • Download URL: mcp_cache-0.2.1.tar.gz
  • Upload date:
  • Size: 18.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for mcp_cache-0.2.1.tar.gz
Algorithm Hash digest
SHA256 d8079737c98bf0cd48f6c4ba373468d2db98d4b8925d42018dd4d73e76d20ac3
MD5 b62eaeb4e27a37b4902e73540866c15b
BLAKE2b-256 acb9c631675cbdea3d9c0b21edc6dee363f4961974e3898a217528baf9fead7a

See more details on using hashes here.

File details

Details for the file mcp_cache-0.2.1-py3-none-any.whl.

File metadata

  • Download URL: mcp_cache-0.2.1-py3-none-any.whl
  • Upload date:
  • Size: 3.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for mcp_cache-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 029c770110040e4603e9ff5f59760f2c85904cc54096a285cc2842de57ee779d
MD5 06e551cee77aedea24a83c912b218c88
BLAKE2b-256 0aa6982cfcc272c83529e15931e7d095a2a2c9b1b6e7d5c4e0dca053c448d8f8

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page