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.2.tar.gz (18.7 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.2-py3-none-any.whl (8.8 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: mcp_cache-0.2.2.tar.gz
  • Upload date:
  • Size: 18.7 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.2.tar.gz
Algorithm Hash digest
SHA256 6b483c42c403129ff82a3e86fa479f989894acaa2b7138f11e022dd5130e8d13
MD5 9ca0d5cf986cb47103aeef58b1a00576
BLAKE2b-256 c55b88566250716ae07301f552c5ed948a96546525e488c82dd52bffd764fc19

See more details on using hashes here.

File details

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

File metadata

  • Download URL: mcp_cache-0.2.2-py3-none-any.whl
  • Upload date:
  • Size: 8.8 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.2-py3-none-any.whl
Algorithm Hash digest
SHA256 e78f6276a9e6b349ac03d8f78a218c854e66b9aa7231a5d3977afbf475eae5a5
MD5 c1724f08ac99ff5307340ad2cf748246
BLAKE2b-256 89ef07a3eb0f4f3e14e17c2b242ea3741c9bff7d859b658269843013f1e6f323

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