mcp-cache 0.1.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,212 @@
1
+ Metadata-Version: 2.4
2
+ Name: mcp-cache
3
+ Version: 0.1.1
4
+ Summary: Reusable SQLite-backed cache for MCP servers — TTL and incremental time series strategies
5
+ Project-URL: Homepage, https://github.com/cmaurer/mcp-cache
6
+ Project-URL: Issues, https://github.com/cmaurer/mcp-cache/issues
7
+ License: MIT
8
+ Keywords: cache,llm,mcp,sqlite,time-series
9
+ Requires-Python: >=3.10
10
+ Requires-Dist: mcp>=1.0
11
+ Provides-Extra: dev
12
+ Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
13
+ Requires-Dist: pytest>=8.0; extra == 'dev'
14
+ Description-Content-Type: text/markdown
15
+
16
+ # mcp-cache
17
+
18
+ A reusable SQLite-backed cache for MCP (Model Context Protocol) servers. Zero dependencies — pure Python stdlib.
19
+
20
+ Two caching strategies:
21
+
22
+ - **TTL cache** — store any JSON-serializable value for N seconds
23
+ - **Time series cache** — store date-keyed observations and automatically fetch only missing date ranges
24
+
25
+ ## Installation
26
+
27
+ ```bash
28
+ pip install mcp-cache
29
+ ```
30
+
31
+ Or from source:
32
+
33
+ ```bash
34
+ git clone https://github.com/cmaurer/mcp-cache
35
+ cd mcp-cache
36
+ pip install -e .
37
+ ```
38
+
39
+ Requires Python 3.10+.
40
+
41
+ ## Quick start
42
+
43
+ ### TTL cache
44
+
45
+ ```python
46
+ from mcp_cache import MCPCache
47
+
48
+ cache = MCPCache("~/.cache/myserver.db", default_ttl=300)
49
+
50
+ async def get_quote(symbol: str) -> dict:
51
+ return await cache.get_or_fetch(
52
+ key=f"quote:{symbol}",
53
+ fetch_fn=lambda: api.fetch_quote(symbol),
54
+ ttl=60, # override default; omit to use default_ttl
55
+ )
56
+ ```
57
+
58
+ `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.
59
+
60
+ ### Time series cache
61
+
62
+ ```python
63
+ observations = await cache.get_timeseries(
64
+ series_id="T10YIE",
65
+ start_date="2020-01-01",
66
+ end_date="2024-12-31",
67
+ fetch_fn=lambda s, e: fred_api.get_series("T10YIE", s, e),
68
+ )
69
+ # Returns list of {"date": "YYYY-MM-DD", "value": float} dicts, newest first
70
+ ```
71
+
72
+ 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.
73
+
74
+ Custom key names are supported for APIs that don't use `"date"` / `"value"`:
75
+
76
+ ```python
77
+ observations = await cache.get_timeseries(
78
+ series_id="prices",
79
+ start_date="2024-01-01",
80
+ end_date="2024-06-30",
81
+ fetch_fn=my_fetch,
82
+ date_key="timestamp",
83
+ value_key="close",
84
+ )
85
+ ```
86
+
87
+ ## API reference
88
+
89
+ ### `MCPCache(db_path, default_ttl)`
90
+
91
+ | Parameter | Type | Default | Description |
92
+ |-----------|------|---------|-------------|
93
+ | `db_path` | `str \| Path` | `"mcp_cache.db"` | Path to SQLite file. `~` is expanded. Parent dirs are created automatically. |
94
+ | `default_ttl` | `int` | `300` | Default TTL in seconds for `get_or_fetch`. |
95
+
96
+ ---
97
+
98
+ ### TTL cache methods
99
+
100
+ #### `await cache.get_or_fetch(key, fetch_fn, ttl=None)`
101
+
102
+ Return the cached value for `key` if it exists and is still fresh. Otherwise call `fetch_fn()`, store the result, and return it.
103
+
104
+ - `key` — cache key string
105
+ - `fetch_fn` — async callable that returns a JSON-serializable value
106
+ - `ttl` — per-call TTL override in seconds; uses `default_ttl` if omitted
107
+
108
+ #### `await cache.invalidate(key)`
109
+
110
+ Remove a specific entry from the TTL cache. No-op if the key does not exist.
111
+
112
+ #### `await cache.clear_expired()`
113
+
114
+ Delete all expired TTL entries. Returns the number of entries removed.
115
+
116
+ ---
117
+
118
+ ### Time series methods
119
+
120
+ #### `await cache.get_timeseries(series_id, start_date, end_date, fetch_fn, date_key="date", value_key="value")`
121
+
122
+ Return cached observations for `series_id` in `[start_date, end_date]`.
123
+
124
+ - `series_id` — identifier for the series
125
+ - `start_date`, `end_date` — `date` objects or ISO strings (`"YYYY-MM-DD"`)
126
+ - `fetch_fn(start, end)` — async callable receiving ISO date strings; must return a list of dicts containing `date_key` and optionally `value_key`
127
+ - `date_key`, `value_key` — key names in the returned dicts (default `"date"`, `"value"`)
128
+
129
+ 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).
130
+
131
+ #### `await cache.invalidate_series(series_id)`
132
+
133
+ Remove all cached observations and range records for a series.
134
+
135
+ ---
136
+
137
+ ### Diagnostics
138
+
139
+ #### `await cache.stats()`
140
+
141
+ Returns a dict with cache counts:
142
+
143
+ ```python
144
+ {
145
+ "ttl_cache": {"total": 12, "fresh": 10, "expired": 2},
146
+ "timeseries": {"series": 3, "observations": 1500, "fetched_ranges": 6},
147
+ "db_path": "/home/user/.cache/myserver.db",
148
+ }
149
+ ```
150
+
151
+ ## Using with an MCP server
152
+
153
+ ```python
154
+ from mcp_cache import MCPCache
155
+
156
+ _cache = MCPCache("~/.cache/myserver.db")
157
+
158
+ @server.tool()
159
+ async def get_price_history(symbol: str, start: str, end: str) -> list[dict]:
160
+ return await _cache.get_timeseries(
161
+ series_id=symbol,
162
+ start_date=start,
163
+ end_date=end,
164
+ fetch_fn=lambda s, e: data_provider.fetch(symbol, s, e),
165
+ )
166
+ ```
167
+
168
+ ## Using with Claude Desktop
169
+
170
+ Install the package:
171
+
172
+ ```bash
173
+ pip install mcp-cache
174
+ ```
175
+
176
+ Add the server to `~/Library/Application Support/Claude/claude_desktop_config.json`:
177
+
178
+ ```json
179
+ {
180
+ "mcpServers": {
181
+ "cache": {
182
+ "command": "mcp-cache"
183
+ }
184
+ }
185
+ }
186
+ ```
187
+
188
+ Restart Claude Desktop. The following tools will be available:
189
+
190
+ | Tool | Description |
191
+ |------|-------------|
192
+ | `cache_get(key)` | Return a cached value, or `null` if missing/expired |
193
+ | `cache_set(key, value, ttl)` | Store a JSON value for `ttl` seconds (default 300) |
194
+ | `cache_invalidate(key)` | Remove a specific entry |
195
+ | `cache_clear_expired()` | Delete all expired entries |
196
+ | `timeseries_store(series_id, observations, range_start, range_end)` | Store date-keyed observations |
197
+ | `timeseries_get(series_id, start_date, end_date)` | Query cached observations |
198
+ | `timeseries_invalidate(series_id)` | Clear all data for a series |
199
+ | `cache_stats()` | Return entry counts and db path |
200
+
201
+ The cache database is stored at `~/.cache/mcp_cache.db`.
202
+
203
+ ## Development
204
+
205
+ ```bash
206
+ pip install -e ".[dev]"
207
+ pytest
208
+ ```
209
+
210
+ ## License
211
+
212
+ MIT
@@ -0,0 +1,4 @@
1
+ mcp_cache-0.1.1.dist-info/METADATA,sha256=VS3rmss9OPckE1eQRtevt-VUs35BsjXXCokGy2gLkbU,5972
2
+ mcp_cache-0.1.1.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
3
+ mcp_cache-0.1.1.dist-info/entry_points.txt,sha256=vs3RlZUDvmPIz1n3O54zi2SN76ZsaRjTxlzdGXu9lic,52
4
+ mcp_cache-0.1.1.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.30.1
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ mcp-cache = mcp_cache.server:main