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,,
|