spice-mcp 0.1.0__py3-none-any.whl → 0.1.2__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.
Potentially problematic release.
This version of spice-mcp might be problematic. Click here for more details.
- spice_mcp/adapters/dune/extract.py +12 -7
- spice_mcp/adapters/dune/typing_utils.py +10 -1
- spice_mcp/mcp/server.py +1 -20
- spice_mcp/mcp/tools/execute_query.py +23 -1
- {spice_mcp-0.1.0.dist-info → spice_mcp-0.1.2.dist-info}/METADATA +75 -15
- {spice_mcp-0.1.0.dist-info → spice_mcp-0.1.2.dist-info}/RECORD +9 -9
- {spice_mcp-0.1.0.dist-info → spice_mcp-0.1.2.dist-info}/WHEEL +0 -0
- {spice_mcp-0.1.0.dist-info → spice_mcp-0.1.2.dist-info}/entry_points.txt +0 -0
- {spice_mcp-0.1.0.dist-info → spice_mcp-0.1.2.dist-info}/licenses/LICENSE +0 -0
|
@@ -3,6 +3,7 @@ from __future__ import annotations
|
|
|
3
3
|
import io
|
|
4
4
|
import time
|
|
5
5
|
from typing import TYPE_CHECKING, overload
|
|
6
|
+
import os
|
|
6
7
|
|
|
7
8
|
from ..http_client import HttpClient
|
|
8
9
|
from . import cache as _cache
|
|
@@ -32,6 +33,10 @@ from .typing_utils import resolve_raw_sql_template_id
|
|
|
32
33
|
|
|
33
34
|
ADAPTER_VERSION = "spice-mcp-adapter"
|
|
34
35
|
|
|
36
|
+
# Runtime-configurable HTTP timeouts (helps avoid host-level timeouts)
|
|
37
|
+
_GET_TIMEOUT: float = float(os.getenv("SPICE_DUNE_GET_TIMEOUT", os.getenv("SPICE_HTTP_TIMEOUT", "30")))
|
|
38
|
+
_POST_TIMEOUT: float = float(os.getenv("SPICE_DUNE_POST_TIMEOUT", os.getenv("SPICE_HTTP_TIMEOUT", "30")))
|
|
39
|
+
|
|
35
40
|
if TYPE_CHECKING:
|
|
36
41
|
from collections.abc import Mapping, Sequence
|
|
37
42
|
from typing import Any, Literal
|
|
@@ -749,7 +754,7 @@ def _execute(
|
|
|
749
754
|
print('executing query, query_id = ' + str(query_id))
|
|
750
755
|
|
|
751
756
|
# perform request
|
|
752
|
-
response = _transport_post(url, headers=headers, json=data, timeout=
|
|
757
|
+
response = _transport_post(url, headers=headers, json=data, timeout=_POST_TIMEOUT)
|
|
753
758
|
result: Mapping[str, Any] = response.json()
|
|
754
759
|
|
|
755
760
|
# check for errors
|
|
@@ -786,7 +791,7 @@ async def _async_execute(
|
|
|
786
791
|
print('executing query, query_id = ' + str(query_id))
|
|
787
792
|
|
|
788
793
|
# perform request
|
|
789
|
-
timeout = aiohttp.ClientTimeout(total=
|
|
794
|
+
timeout = aiohttp.ClientTimeout(total=_POST_TIMEOUT)
|
|
790
795
|
async with aiohttp.ClientSession(timeout=timeout) as session:
|
|
791
796
|
async with session.post(url, headers=headers, json=data) as response:
|
|
792
797
|
result: Mapping[str, Any] = await response.json()
|
|
@@ -862,12 +867,12 @@ def _get_results(
|
|
|
862
867
|
def _get_with_retries(u: str):
|
|
863
868
|
client = current_http_client()
|
|
864
869
|
if client is not None:
|
|
865
|
-
return client.request("GET", u, headers=headers, timeout=
|
|
870
|
+
return client.request("GET", u, headers=headers, timeout=_GET_TIMEOUT)
|
|
866
871
|
|
|
867
872
|
attempts = 0
|
|
868
873
|
backoff = 0.5
|
|
869
874
|
while True:
|
|
870
|
-
resp = _transport_get(u, headers=headers, timeout=
|
|
875
|
+
resp = _transport_get(u, headers=headers, timeout=_GET_TIMEOUT)
|
|
871
876
|
if resp.status_code in (429, 502):
|
|
872
877
|
attempts += 1
|
|
873
878
|
if attempts >= 3:
|
|
@@ -963,7 +968,7 @@ async def _async_get_results(
|
|
|
963
968
|
print('getting results, execution_id = ' + str(execution['execution_id']))
|
|
964
969
|
|
|
965
970
|
# perform request
|
|
966
|
-
timeout = aiohttp.ClientTimeout(total=
|
|
971
|
+
timeout = aiohttp.ClientTimeout(total=_GET_TIMEOUT)
|
|
967
972
|
async with aiohttp.ClientSession(timeout=timeout) as session:
|
|
968
973
|
# GET with simple retry/backoff for 429/502
|
|
969
974
|
attempts = 0
|
|
@@ -1169,7 +1174,7 @@ def _poll_execution(
|
|
|
1169
1174
|
)
|
|
1170
1175
|
|
|
1171
1176
|
# poll
|
|
1172
|
-
response = _http_get(url, headers=headers, timeout=
|
|
1177
|
+
response = _http_get(url, headers=headers, timeout=_GET_TIMEOUT)
|
|
1173
1178
|
result = response.json()
|
|
1174
1179
|
if (
|
|
1175
1180
|
'is_execution_finished' not in result
|
|
@@ -1243,7 +1248,7 @@ async def _async_poll_execution(
|
|
|
1243
1248
|
t_start = time.time()
|
|
1244
1249
|
|
|
1245
1250
|
# poll until completion
|
|
1246
|
-
timeout = aiohttp.ClientTimeout(total=
|
|
1251
|
+
timeout = aiohttp.ClientTimeout(total=_GET_TIMEOUT)
|
|
1247
1252
|
async with aiohttp.ClientSession(timeout=timeout) as session:
|
|
1248
1253
|
sleep_amount = poll_interval
|
|
1249
1254
|
while True:
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import os
|
|
4
|
+
|
|
3
5
|
|
|
4
6
|
def resolve_raw_sql_template_id() -> int:
|
|
5
7
|
"""Return a stable template ID used for executing raw SQL text.
|
|
@@ -7,4 +9,11 @@ def resolve_raw_sql_template_id() -> int:
|
|
|
7
9
|
Tests stub HTTP boundaries and only require a consistent integer. This
|
|
8
10
|
placeholder can be adjusted if upstream semantics change.
|
|
9
11
|
"""
|
|
10
|
-
|
|
12
|
+
env_value = os.getenv("SPICE_RAW_SQL_QUERY_ID")
|
|
13
|
+
if env_value:
|
|
14
|
+
try:
|
|
15
|
+
return int(env_value.strip())
|
|
16
|
+
except (ValueError, AttributeError):
|
|
17
|
+
# Invalid environment variable, fallback to default
|
|
18
|
+
pass
|
|
19
|
+
return 4060379
|
spice_mcp/mcp/server.py
CHANGED
|
@@ -229,26 +229,7 @@ async def dune_query(
|
|
|
229
229
|
_ensure_initialized()
|
|
230
230
|
assert EXECUTE_QUERY_TOOL is not None
|
|
231
231
|
try:
|
|
232
|
-
#
|
|
233
|
-
if 'asyncio' not in globals():
|
|
234
|
-
pass # type: ignore
|
|
235
|
-
if SEMAPHORE is not None:
|
|
236
|
-
async with SEMAPHORE: # type: ignore
|
|
237
|
-
return await EXECUTE_QUERY_TOOL.execute(
|
|
238
|
-
query=query,
|
|
239
|
-
parameters=parameters,
|
|
240
|
-
refresh=refresh,
|
|
241
|
-
max_age=max_age,
|
|
242
|
-
limit=limit,
|
|
243
|
-
offset=offset,
|
|
244
|
-
sample_count=sample_count,
|
|
245
|
-
sort_by=sort_by,
|
|
246
|
-
columns=columns,
|
|
247
|
-
format=format,
|
|
248
|
-
extras=extras,
|
|
249
|
-
timeout_seconds=timeout_seconds,
|
|
250
|
-
)
|
|
251
|
-
# Fallback without semaphore
|
|
232
|
+
# Execute query directly without semaphore concurrency control
|
|
252
233
|
return await EXECUTE_QUERY_TOOL.execute(
|
|
253
234
|
query=query,
|
|
254
235
|
parameters=parameters,
|
|
@@ -313,6 +313,15 @@ class ExecuteQueryTool(MCPTool):
|
|
|
313
313
|
if template_id_value is not None:
|
|
314
314
|
extra_fields["template_query_id"] = template_id_value
|
|
315
315
|
|
|
316
|
+
# Compute query SHA256 for better debugging
|
|
317
|
+
q_sha = None
|
|
318
|
+
try:
|
|
319
|
+
q_sha = self._persist_query_sql(q_use, q_type)
|
|
320
|
+
if q_sha:
|
|
321
|
+
extra_fields["query_sha256"] = q_sha
|
|
322
|
+
except Exception:
|
|
323
|
+
pass
|
|
324
|
+
|
|
316
325
|
self.query_history.record(
|
|
317
326
|
execution_id="unknown",
|
|
318
327
|
query_type=_categorize_query(query),
|
|
@@ -324,9 +333,22 @@ class ExecuteQueryTool(MCPTool):
|
|
|
324
333
|
)
|
|
325
334
|
|
|
326
335
|
enriched = self._enrich_error(exc)
|
|
327
|
-
context = {"tool": "dune_query", "query": q_use}
|
|
336
|
+
context = {"tool": "dune_query", "query": q_use, "query_type": _categorize_query(q_use)}
|
|
328
337
|
if enriched:
|
|
329
338
|
context.update(enriched)
|
|
339
|
+
|
|
340
|
+
# Add debugging information for raw SQL failures
|
|
341
|
+
if q_type == "raw_sql" and "could not determine execution" in str(exc):
|
|
342
|
+
context.update({
|
|
343
|
+
"debug_info": "Raw SQL execution failed - this may be related to FastMCP async/concurrency handling",
|
|
344
|
+
"template_query_id": template_id_value,
|
|
345
|
+
"environment_vars": {
|
|
346
|
+
"SPICE_RAW_SQL_QUERY_ID": os.getenv("SPICE_RAW_SQL_QUERY_ID"),
|
|
347
|
+
"DUNE_API_KEY_present": bool(os.getenv("DUNE_API_KEY"))
|
|
348
|
+
},
|
|
349
|
+
"suggested_action": "Retry or check if the template query (4060379) is accessible"
|
|
350
|
+
})
|
|
351
|
+
|
|
330
352
|
return error_response(exc, context=context)
|
|
331
353
|
|
|
332
354
|
def _persist_query_sql(self, query: str, q_type: str) -> str | None:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: spice-mcp
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.2
|
|
4
4
|
Summary: MCP server for Dune Analytics data access
|
|
5
5
|
Author-email: Evan-Kim2028 <ekcopersonal@gmail.com>
|
|
6
6
|
License-File: LICENSE
|
|
@@ -21,27 +21,87 @@ Description-Content-Type: text/markdown
|
|
|
21
21
|
|
|
22
22
|
# spice-mcp
|
|
23
23
|
|
|
24
|
-
spice-mcp is an MCP server for Dune Analytics. It wraps a curated subset of the original Spice client inside a clean architecture (`core` models/ports → `adapters.dune` → service layer → FastMCP tools) and adds agent-friendly workflows for discovery and Sui package exploration. Results are Polars-first in Python and compact, token-efficient in MCP responses.
|
|
24
|
+
spice-mcp is an MCP server for [Dune](https://dune.com/) Analytics. It wraps a curated subset of the original Spice client inside a clean architecture (`core` models/ports → `adapters.dune` → service layer → FastMCP tools) and adds agent-friendly workflows for discovery and Sui package exploration. Results are Polars-first in Python and compact, token-efficient in MCP responses.
|
|
25
25
|
|
|
26
26
|
Requirements: Python 3.13+
|
|
27
27
|
|
|
28
28
|
This project uses FastMCP for typed, decorator-registered tools and resources.
|
|
29
29
|
|
|
30
|
-
Highlights
|
|
30
|
+
## Highlights
|
|
31
31
|
- Polars LazyFrame-first pipeline: results stay lazy until explicitly materialized
|
|
32
|
-
- Ports/adapters layering for maintainable integrations (
|
|
32
|
+
- Ports/adapters layering for maintainable integrations ([docs/architecture.md](docs/architecture.md))
|
|
33
33
|
- Discovery utilities (find schemas/tables, describe columns)
|
|
34
34
|
- Sui package workflows (events/transactions/objects) with safe defaults
|
|
35
35
|
- JSONL query history + SQL artifacts (SHA-256) for reproducibility
|
|
36
36
|
- Rich MCP surface: query info/run, discovery, health, Sui, and Dune admin (create/update/fork)
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
## What is Dune?
|
|
39
|
+
[Dune](https://dune.com/) is a crypto data platform providing curated blockchain datasets and a public API to run and fetch query results. See the [Dune Docs](https://dune.com/docs) and [Dune API](https://dune.com/docs/api/) for full details.
|
|
40
|
+
|
|
41
|
+
## Quick Start
|
|
39
42
|
- Export `DUNE_API_KEY` in your shell (the server can also load a local `.env`; set `SPICE_MCP_SKIP_DOTENV=1` to skip during tests).
|
|
40
43
|
- Install dependencies (`uv sync` or `pip install -e .`).
|
|
41
44
|
- Start the FastMCP stdio server:
|
|
42
45
|
- `python -m spice_mcp.mcp.server --env PYTHONPATH=$(pwd)/src`
|
|
43
46
|
- or install the console script via `uv tool install .` and run `spice-mcp`.
|
|
44
47
|
|
|
48
|
+
## Cursor IDE Setup
|
|
49
|
+
|
|
50
|
+
To use spice-mcp with Cursor IDE:
|
|
51
|
+
|
|
52
|
+
1. **Install the MCP Server**:
|
|
53
|
+
```bash
|
|
54
|
+
# Install dependencies and package
|
|
55
|
+
uv sync
|
|
56
|
+
pip install -e .
|
|
57
|
+
|
|
58
|
+
# Or install via uv tool (creates console script)
|
|
59
|
+
uv tool install .
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
2. **Configure Cursor**:
|
|
63
|
+
- Open Cursor Settings → MCP Servers
|
|
64
|
+
- Add new MCP server configuration:
|
|
65
|
+
```json
|
|
66
|
+
{
|
|
67
|
+
"name": "spice-mcp",
|
|
68
|
+
"command": "spice-mcp",
|
|
69
|
+
"env": {
|
|
70
|
+
"DUNE_API_KEY": "your-dune-api-key-here"
|
|
71
|
+
},
|
|
72
|
+
"disabled": false
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
Alternatively, if you prefer running from source:
|
|
76
|
+
```json
|
|
77
|
+
{
|
|
78
|
+
"name": "spice-mcp",
|
|
79
|
+
"command": "python",
|
|
80
|
+
"args": ["-m", "spice_mcp.mcp.server"],
|
|
81
|
+
"env": {
|
|
82
|
+
"PYTHONPATH": "/path/to/your/spice-mcp/src",
|
|
83
|
+
"DUNE_API_KEY": "your-dune-api-key-here"
|
|
84
|
+
},
|
|
85
|
+
"disabled": false
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
3. **Restart Cursor** to load the MCP server
|
|
90
|
+
|
|
91
|
+
4. **Verify Connection**:
|
|
92
|
+
- Open Cursor and use the command palette (Cmd/Ctrl + Shift + P)
|
|
93
|
+
- Search for "MCP" or "spice" commands
|
|
94
|
+
- Test with `dune_health_check` to verify the connection
|
|
95
|
+
|
|
96
|
+
5. **Available Tools in Cursor**:
|
|
97
|
+
- `dune_query`: Run Dune queries by ID, URL, or raw SQL
|
|
98
|
+
- `dune_find_tables`: Search schemas and list tables
|
|
99
|
+
- `dune_describe_table`: Get column metadata
|
|
100
|
+
- `sui_package_overview`: Analyze Sui packages
|
|
101
|
+
- `dune_health_check`: Verify API connection
|
|
102
|
+
|
|
103
|
+
**Tip**: Create a `.env` file in your project root with `DUNE_API_KEY=your-key-here` for easier configuration.
|
|
104
|
+
|
|
45
105
|
## MCP Tools and Features
|
|
46
106
|
|
|
47
107
|
All tools expose typed parameters, titles, and tags; failures return a consistent error envelope.
|
|
@@ -114,16 +174,16 @@ Core Tools (with parameters)
|
|
|
114
174
|
- Use: Verify API key presence and logging paths
|
|
115
175
|
- Output: `api_key_present`, `query_history_path`, `logging_enabled`, `status`
|
|
116
176
|
|
|
117
|
-
Docs
|
|
118
|
-
- See
|
|
119
|
-
- Dune API structure and capabilities:
|
|
120
|
-
- Discovery patterns and examples:
|
|
121
|
-
- Sui package workflows:
|
|
122
|
-
- Tool reference and schemas:
|
|
123
|
-
- Codex CLI + tooling integration:
|
|
124
|
-
- Architecture overview:
|
|
125
|
-
- Installation and configuration:
|
|
126
|
-
- Development and linting:
|
|
177
|
+
## Docs
|
|
178
|
+
- See [docs/index.md](docs/index.md) for full documentation:
|
|
179
|
+
- Dune API structure and capabilities: [docs/dune_api.md](docs/dune_api.md)
|
|
180
|
+
- Discovery patterns and examples: [docs/discovery.md](docs/discovery.md)
|
|
181
|
+
- Sui package workflows: [docs/sui_packages.md](docs/sui_packages.md)
|
|
182
|
+
- Tool reference and schemas: [docs/tools.md](docs/tools.md)
|
|
183
|
+
- Codex CLI + tooling integration: [docs/codex_cli.md](docs/codex_cli.md), [docs/codex_cli_tools.md](docs/codex_cli_tools.md)
|
|
184
|
+
- Architecture overview: [docs/architecture.md](docs/architecture.md)
|
|
185
|
+
- Installation and configuration: [docs/installation.md](docs/installation.md), [docs/config.md](docs/config.md)
|
|
186
|
+
- Development and linting: [docs/development.md](docs/development.md)
|
|
127
187
|
|
|
128
188
|
Notes
|
|
129
189
|
- Legacy Spice code now lives under `src/spice_mcp/adapters/dune` (extract, cache, urls, types).
|
|
@@ -8,11 +8,11 @@ spice_mcp/adapters/dune/__init__.py,sha256=8HRHPxkz0y2cyHSs4oCkHq_LQaUW5MBevbeNx
|
|
|
8
8
|
spice_mcp/adapters/dune/admin.py,sha256=yxOueVz-rmgC-ZFbT06k59G24yRgYjiEkZlall5hXNQ,3157
|
|
9
9
|
spice_mcp/adapters/dune/cache.py,sha256=7UmmxpBNeSGPH3KYBBSPHlVXCpiZUi4-X300U2FsSBs,5252
|
|
10
10
|
spice_mcp/adapters/dune/client.py,sha256=JPrQZ_dtaPcGf6lYUguDxGweOtxG-8qMqOiXuhWL9QA,9122
|
|
11
|
-
spice_mcp/adapters/dune/extract.py,sha256=
|
|
11
|
+
spice_mcp/adapters/dune/extract.py,sha256=frIFRUNJ99UlP26N9F-p1psX-e_TVq9vJTQxh0MBCr8,48510
|
|
12
12
|
spice_mcp/adapters/dune/helpers.py,sha256=BgDKr_g-UqmU2hoMb0ejQZHta_NbKwR1eDJp33sJYNk,227
|
|
13
13
|
spice_mcp/adapters/dune/transport.py,sha256=eRP-jPY2ZXxvTX9HSjIFqFUlbIzXspgH95jBFoTlpaQ,1436
|
|
14
14
|
spice_mcp/adapters/dune/types.py,sha256=57TMX07u-Gq4BYwRAuZV0xI81nVXgtpp7KBID9YbKyQ,1195
|
|
15
|
-
spice_mcp/adapters/dune/typing_utils.py,sha256=
|
|
15
|
+
spice_mcp/adapters/dune/typing_utils.py,sha256=EpWneGDn-eQdo6lkLuESR09KXkDj9OqGz8bEF3JaFkM,574
|
|
16
16
|
spice_mcp/adapters/dune/urls.py,sha256=bcuPERkFQduRTT2BrgzVhoFrMn-Lkvw9NmktcBZYEig,3902
|
|
17
17
|
spice_mcp/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
18
18
|
spice_mcp/core/errors.py,sha256=jlfTuyRaAaA_oU07KUk-1pDAAa43KG0BbZc5CINXtoE,3256
|
|
@@ -20,10 +20,10 @@ spice_mcp/core/models.py,sha256=2AgAPcaDPEXLdka1E6-0cXN_QNsN2rnDoBnDTDDsO6I,2121
|
|
|
20
20
|
spice_mcp/core/ports.py,sha256=-wtWjpYSjL-qugUtsm0MTngtJZWzr7QNDbAUCj4BTS0,2028
|
|
21
21
|
spice_mcp/logging/query_history.py,sha256=doE9lod64uzJxlA2XzHH2-VAmC6WstYAkQ0taEAxiIM,4315
|
|
22
22
|
spice_mcp/mcp/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
23
|
-
spice_mcp/mcp/server.py,sha256=
|
|
23
|
+
spice_mcp/mcp/server.py,sha256=RtvK0u9Q3dp3JMALrVFL43Li1lKdaQwLvtZuoo0pkbY,18082
|
|
24
24
|
spice_mcp/mcp/tools/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
25
25
|
spice_mcp/mcp/tools/base.py,sha256=Xw8k5WAXotCdZRd-cVJIFPH87JH8DH0sh1zKu-KmW3w,1047
|
|
26
|
-
spice_mcp/mcp/tools/execute_query.py,sha256=
|
|
26
|
+
spice_mcp/mcp/tools/execute_query.py,sha256=y2HU3Cv6T7QBXBDMea0TlXcf8_ERkq2sJeaexR6kBXE,17556
|
|
27
27
|
spice_mcp/mcp/tools/sui_package_overview.py,sha256=a1CcpfBzEFzScjXgxLu9urxdtSbXjF98ugWPOX167rc,1736
|
|
28
28
|
spice_mcp/observability/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
29
29
|
spice_mcp/observability/logging.py,sha256=ceJUEpKGpf5PAgPBmpB49zjqhdGCAESfLemFUhDSmI8,529
|
|
@@ -32,8 +32,8 @@ spice_mcp/service_layer/discovery_service.py,sha256=202O0SzCZGQukd9kb2JYfarLygZH
|
|
|
32
32
|
spice_mcp/service_layer/query_admin_service.py,sha256=4q1NAAuTui7cm83Aq2rFDLIzKTHX17yzbSoSJyCmLbI,1356
|
|
33
33
|
spice_mcp/service_layer/query_service.py,sha256=q0eAVW5I3sUxm29DgzPN_cH3rZEzmKwmdE3Xj4qP9lI,3878
|
|
34
34
|
spice_mcp/service_layer/sui_service.py,sha256=G-LOsl-z-ldMxAYAetnG17IQlpVtLchGUjN6opU-PF0,4712
|
|
35
|
-
spice_mcp-0.1.
|
|
36
|
-
spice_mcp-0.1.
|
|
37
|
-
spice_mcp-0.1.
|
|
38
|
-
spice_mcp-0.1.
|
|
39
|
-
spice_mcp-0.1.
|
|
35
|
+
spice_mcp-0.1.2.dist-info/METADATA,sha256=TB63rlJQOinwNKj3XvevK0OLLF2Ic0xYmeLU_kaiuas,9316
|
|
36
|
+
spice_mcp-0.1.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
37
|
+
spice_mcp-0.1.2.dist-info/entry_points.txt,sha256=4XiXX13Vy-oiUJwlcO_82OltBaxFnEnkJ-76sZGm5os,56
|
|
38
|
+
spice_mcp-0.1.2.dist-info/licenses/LICENSE,sha256=r0GNDnDY1RSkVQp7kEEf6MQU21OrNGJkxUHIsv6eyLk,1079
|
|
39
|
+
spice_mcp-0.1.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|