spice-mcp 0.1.5__py3-none-any.whl → 0.1.7__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.

@@ -349,13 +349,17 @@ class SpellbookExplorer(CatalogExplorer):
349
349
  return {}
350
350
 
351
351
  def _parse_sql_columns(self, sql_file: Path) -> list[TableColumn]:
352
- """Parse SQL file to extract column names from SELECT statements."""
352
+ """
353
+ Parse SQL file to extract column names from SELECT statements.
354
+
355
+ Note: This is a best-effort heuristic and may not be perfect for complex SQL.
356
+ For accurate column information, use Dune's DESCRIBE TABLE or query the actual table.
357
+ """
353
358
  try:
354
359
  with open(sql_file, encoding="utf-8") as f:
355
360
  sql = f.read()
356
361
 
357
- # Look for SELECT ... FROM patterns
358
- # Match: SELECT col1, col2, col3 FROM ...
362
+ # Look for SELECT ... FROM patterns (simple heuristic)
359
363
  select_match = re.search(
360
364
  r"SELECT\s+(.+?)\s+FROM",
361
365
  sql,
@@ -364,27 +368,20 @@ class SpellbookExplorer(CatalogExplorer):
364
368
 
365
369
  if select_match:
366
370
  cols_str = select_match.group(1)
367
- # Split by comma, but handle function calls and aliases
371
+ # Simple split - may not handle all nested cases perfectly
372
+ # This is OK since column info is optional and best-effort
368
373
  cols = []
369
374
  for col in cols_str.split(","):
370
375
  col = col.strip()
371
- # Extract column name (handle aliases: col AS alias -> col)
372
- if " AS " in col.upper():
373
- col = col.split(" AS ", 1)[0].strip()
374
- elif " " in col and not col.startswith("("):
375
- # Might be alias without AS
376
- parts = col.split()
377
- col = parts[0].strip()
378
-
379
- # Clean up function calls: function(col) -> col
380
- col = re.sub(r"^\w+\((.+)\)", r"\1", col)
376
+ # Basic cleanup - remove obvious SQL noise
377
+ col = col.split()[-1] if col else ""
381
378
  col = col.strip().strip('"').strip("'")
382
379
 
383
- if col and col not in ["*", "DISTINCT"]:
380
+ if col and col not in ["*", "DISTINCT", "FROM"]:
384
381
  cols.append(
385
382
  TableColumn(
386
383
  name=col,
387
- dune_type="VARCHAR", # Default, can't infer from SQL
384
+ dune_type="VARCHAR",
388
385
  polars_dtype="Utf8",
389
386
  )
390
387
  )
spice_mcp/mcp/server.py CHANGED
@@ -347,7 +347,7 @@ def _unified_discover_impl(
347
347
  schema: str | None = None,
348
348
  limit: int = 50,
349
349
  source: Literal["dune", "spellbook", "both"] = "both",
350
- include_columns: bool = True,
350
+ include_columns: bool = False,
351
351
  ) -> dict[str, Any]:
352
352
  """
353
353
  Unified discovery implementation that can search Dune API, Spellbook repo, or both.
@@ -496,7 +496,7 @@ def dune_discover(
496
496
  schema: str | None = None,
497
497
  limit: int = 50,
498
498
  source: Literal["dune", "spellbook", "both"] = "both",
499
- include_columns: bool = True,
499
+ include_columns: bool = False,
500
500
  ) -> dict[str, Any]:
501
501
  """
502
502
  PRIMARY discovery tool for finding tables in Dune.
@@ -520,7 +520,9 @@ def dune_discover(
520
520
  limit: Maximum number of tables to return
521
521
  source: Where to search - "dune" (Dune API only), "spellbook" (GitHub repo only),
522
522
  or "both" (default: searches both and merges results)
523
- include_columns: Whether to include column details for Spellbook models (default: True)
523
+ include_columns: Whether to include column details (default: False).
524
+ Note: Column info from Spellbook SQL is unreliable.
525
+ Use dune_describe_table on the actual Dune table for accurate columns.
524
526
 
525
527
  Returns:
526
528
  Dictionary with:
@@ -534,9 +536,10 @@ def dune_discover(
534
536
  - dune_alias: Actual Dune table alias (for Spellbook models)
535
537
  - dune_table: Verified, queryable Dune table name (e.g., "sui_walrus.base_table")
536
538
  - verified: True (all returned tables are verified to exist)
537
- - columns: Column details (for Spellbook models, if include_columns=True)
538
539
  - 'source': The source parameter used
539
540
  - 'message': Helpful message if no tables found
541
+
542
+ Note: To get accurate column information, use dune_describe_table on the dune_table value.
540
543
 
541
544
  Examples:
542
545
  # Search both sources for walrus - returns verified tables only
@@ -611,7 +614,7 @@ def _spellbook_find_models_impl(
611
614
  keyword: str | list[str] | None = None,
612
615
  schema: str | None = None,
613
616
  limit: int = 50,
614
- include_columns: bool = True,
617
+ include_columns: bool = False,
615
618
  ) -> dict[str, Any]:
616
619
  """
617
620
  Implementation for spellbook model discovery.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: spice-mcp
3
- Version: 0.1.5
3
+ Version: 0.1.7
4
4
  Summary: mcp server built ontop of dune api endpoint
5
5
  Author-email: Evan-Kim2028 <ekcopersonal@gmail.com>
6
6
  License-File: LICENSE
@@ -17,14 +17,14 @@ spice_mcp/adapters/dune/typing_utils.py,sha256=EpWneGDn-eQdo6lkLuESR09KXkDj9OqGz
17
17
  spice_mcp/adapters/dune/urls.py,sha256=bcuPERkFQduRTT2BrgzVhoFrMn-Lkvw9NmktcBZYEig,3902
18
18
  spice_mcp/adapters/dune/user_agent.py,sha256=c6Kt4zczbuT9mapDoh8-3sgm268MUtvyIRxDF9yJwXQ,218
19
19
  spice_mcp/adapters/spellbook/__init__.py,sha256=D2cdVtSUbmAJdbPRvAyKxYS4-wUQ3unXyX4ZFYxenuk,150
20
- spice_mcp/adapters/spellbook/explorer.py,sha256=nfecYztzxfBXp9b9IKcP4dVICCnPzhHvPfNJKFhaKxA,14856
20
+ spice_mcp/adapters/spellbook/explorer.py,sha256=PQCUJjXnaf8YSziINVNSqIXsns_y6l62JgjBId4b7jo,14654
21
21
  spice_mcp/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
22
  spice_mcp/core/errors.py,sha256=jlfTuyRaAaA_oU07KUk-1pDAAa43KG0BbZc5CINXtoE,3256
23
23
  spice_mcp/core/models.py,sha256=i0C_-UE16OWyyZo_liooEJeYvbChE5lpK80aN2OF4lk,1795
24
24
  spice_mcp/core/ports.py,sha256=nEdeA3UH7v0kB_hbguMrpDljb9EhSxUAO0SdhjpoijQ,1618
25
25
  spice_mcp/logging/query_history.py,sha256=doE9lod64uzJxlA2XzHH2-VAmC6WstYAkQ0taEAxiIM,4315
26
26
  spice_mcp/mcp/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
27
- spice_mcp/mcp/server.py,sha256=oi0RRaSithCgUt0Qt6Tb3gks32LN0dOOwN7kX-BrN7s,32263
27
+ spice_mcp/mcp/server.py,sha256=M6IPxQD--eecdNryTIL8JlkWPAXrj256P0UCEktdOt0,32438
28
28
  spice_mcp/mcp/tools/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
29
29
  spice_mcp/mcp/tools/base.py,sha256=zJkVxLgXR48iZcJeng8cZ2rXvbyicagoGlMN7BK7Img,1041
30
30
  spice_mcp/mcp/tools/execute_query.py,sha256=K1YpuQGwvVM20A4_h9zNlkeG37J7jbY7BPzLm6vPAsY,16033
@@ -35,8 +35,8 @@ spice_mcp/service_layer/discovery_service.py,sha256=202O0SzCZGQukd9kb2JYfarLygZH
35
35
  spice_mcp/service_layer/query_admin_service.py,sha256=4q1NAAuTui7cm83Aq2rFDLIzKTHX17yzbSoSJyCmLbI,1356
36
36
  spice_mcp/service_layer/query_service.py,sha256=q0eAVW5I3sUxm29DgzPN_cH3rZEzmKwmdE3Xj4qP9lI,3878
37
37
  spice_mcp/service_layer/verification_service.py,sha256=dPA88p9zKqg62bNjN_4c5QFEUBHCWjZph8pn2a5zrUI,6057
38
- spice_mcp-0.1.5.dist-info/METADATA,sha256=ag4hjEMz-qxvImxJPxpsQN_0F9BOUdbk6TF8zAXW5I4,6093
39
- spice_mcp-0.1.5.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
40
- spice_mcp-0.1.5.dist-info/entry_points.txt,sha256=4XiXX13Vy-oiUJwlcO_82OltBaxFnEnkJ-76sZGm5os,56
41
- spice_mcp-0.1.5.dist-info/licenses/LICENSE,sha256=r0GNDnDY1RSkVQp7kEEf6MQU21OrNGJkxUHIsv6eyLk,1079
42
- spice_mcp-0.1.5.dist-info/RECORD,,
38
+ spice_mcp-0.1.7.dist-info/METADATA,sha256=1nVDHRV6aJzq2ANEmfaCO5E2phc_m93kQh0P0KUBrkE,6093
39
+ spice_mcp-0.1.7.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
40
+ spice_mcp-0.1.7.dist-info/entry_points.txt,sha256=4XiXX13Vy-oiUJwlcO_82OltBaxFnEnkJ-76sZGm5os,56
41
+ spice_mcp-0.1.7.dist-info/licenses/LICENSE,sha256=r0GNDnDY1RSkVQp7kEEf6MQU21OrNGJkxUHIsv6eyLk,1079
42
+ spice_mcp-0.1.7.dist-info/RECORD,,