spice-mcp 0.1.0__tar.gz → 0.1.2__tar.gz

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.

Files changed (118) hide show
  1. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/.gitignore +6 -0
  2. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/PKG-INFO +75 -15
  3. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/README.md +74 -14
  4. spice_mcp-0.1.2/debug_mcp_tool.py +147 -0
  5. spice_mcp-0.1.2/debug_template_query.py +147 -0
  6. spice_mcp-0.1.2/issue_diagnostics.py +76 -0
  7. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/pyproject.toml +18 -1
  8. spice_mcp-0.1.2/scripts/bridgez/make_circle_comparison.py +114 -0
  9. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/src/spice_mcp/adapters/dune/extract.py +12 -7
  10. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/src/spice_mcp/adapters/dune/typing_utils.py +10 -1
  11. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/src/spice_mcp/mcp/server.py +1 -20
  12. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/src/spice_mcp/mcp/tools/execute_query.py +23 -1
  13. spice_mcp-0.1.2/test_semaphore_fix.py +101 -0
  14. spice_mcp-0.1.2/test_sync_fix.py +55 -0
  15. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/tests/fastmcp/test_server_fastmcp.py +2 -3
  16. spice_mcp-0.1.2/tests/mcp/test_tool_contracts.py +55 -0
  17. spice_mcp-0.1.2/tests/offline/test_typing_utils.py +62 -0
  18. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/uv.lock +409 -3
  19. spice_mcp-0.1.0/.factory/droids/agentic-documentation-systems-droid.md +0 -16
  20. spice_mcp-0.1.0/.factory/droids/development-workflow-optimization-droid.md +0 -16
  21. spice_mcp-0.1.0/.factory/droids/production-python-development-droid.md +0 -18
  22. spice_mcp-0.1.0/.factory/droids/temp-smoke-droid.md +0 -8
  23. spice_mcp-0.1.0/.github/workflows/ci.yml +0 -144
  24. spice_mcp-0.1.0/bin/bat +0 -18
  25. spice_mcp-0.1.0/bin/fd +0 -18
  26. spice_mcp-0.1.0/debug_api.py +0 -97
  27. spice_mcp-0.1.0/tests/mcp/test_tool_contracts.py +0 -58
  28. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/.python-version +0 -0
  29. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/CONTRIBUTING.md +0 -0
  30. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/LICENSE +0 -0
  31. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/docs/architecture.md +0 -0
  32. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/docs/codex_cli.md +0 -0
  33. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/docs/codex_cli_tools.md +0 -0
  34. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/docs/commands.md +0 -0
  35. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/docs/config.md +0 -0
  36. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/docs/development.md +0 -0
  37. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/docs/discovery.md +0 -0
  38. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/docs/dune_api.md +0 -0
  39. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/docs/index.md +0 -0
  40. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/docs/installation.md +0 -0
  41. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/docs/tools.md +0 -0
  42. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/pytest.ini +0 -0
  43. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/scripts/codex_tools_doctor.sh +0 -0
  44. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/src/spice_mcp/__init__.py +0 -0
  45. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/src/spice_mcp/adapters/__init__.py +0 -0
  46. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/src/spice_mcp/adapters/dune/__init__.py +0 -0
  47. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/src/spice_mcp/adapters/dune/admin.py +0 -0
  48. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/src/spice_mcp/adapters/dune/cache.py +0 -0
  49. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/src/spice_mcp/adapters/dune/client.py +0 -0
  50. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/src/spice_mcp/adapters/dune/helpers.py +0 -0
  51. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/src/spice_mcp/adapters/dune/transport.py +0 -0
  52. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/src/spice_mcp/adapters/dune/types.py +0 -0
  53. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/src/spice_mcp/adapters/dune/urls.py +0 -0
  54. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/src/spice_mcp/adapters/http_client.py +0 -0
  55. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/src/spice_mcp/config.py +0 -0
  56. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/src/spice_mcp/core/__init__.py +0 -0
  57. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/src/spice_mcp/core/errors.py +0 -0
  58. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/src/spice_mcp/core/models.py +0 -0
  59. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/src/spice_mcp/core/ports.py +0 -0
  60. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/src/spice_mcp/logging/query_history.py +0 -0
  61. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/src/spice_mcp/mcp/__init__.py +0 -0
  62. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/src/spice_mcp/mcp/tools/__init__.py +0 -0
  63. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/src/spice_mcp/mcp/tools/base.py +0 -0
  64. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/src/spice_mcp/mcp/tools/sui_package_overview.py +0 -0
  65. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/src/spice_mcp/observability/__init__.py +0 -0
  66. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/src/spice_mcp/observability/logging.py +0 -0
  67. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/src/spice_mcp/polars_utils.py +0 -0
  68. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/src/spice_mcp/py.typed +0 -0
  69. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/src/spice_mcp/service_layer/__init__.py +0 -0
  70. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/src/spice_mcp/service_layer/discovery_service.py +0 -0
  71. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/src/spice_mcp/service_layer/query_admin_service.py +0 -0
  72. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/src/spice_mcp/service_layer/query_service.py +0 -0
  73. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/src/spice_mcp/service_layer/sui_service.py +0 -0
  74. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/tests/cassettes/.gitkeep +0 -0
  75. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/tests/config/environments.yaml +0 -0
  76. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/tests/config/test_queries.yaml +0 -0
  77. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/tests/conftest.py +0 -0
  78. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/tests/fastmcp/test_resources_and_validation.py +0 -0
  79. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/tests/fastmcp/test_server_mcp_extras.py +0 -0
  80. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/tests/http_stubbed/test_age.py +0 -0
  81. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/tests/http_stubbed/test_errors.py +0 -0
  82. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/tests/http_stubbed/test_pagination.py +0 -0
  83. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/tests/live/test_live_basic.py +0 -0
  84. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/tests/live/test_live_sui.py +0 -0
  85. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/tests/mcp/conftest.py +0 -0
  86. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/tests/mcp/test_resources.py +0 -0
  87. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/tests/offline/test_cache.py +0 -0
  88. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/tests/offline/test_discovery.py +0 -0
  89. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/tests/offline/test_dune_adapter.py +0 -0
  90. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/tests/offline/test_parsing.py +0 -0
  91. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/tests/offline/test_query_history.py +0 -0
  92. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/tests/offline/test_show_rewrite.py +0 -0
  93. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/tests/offline/test_timeout.py +0 -0
  94. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/tests/offline/test_urls.py +0 -0
  95. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/tests/scripts/comprehensive_test_runner.py +0 -0
  96. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/tests/scripts/run_tests.py +0 -0
  97. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/tests/scripts/test_api_health.py +0 -0
  98. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/tests/scripts/test_cache_functionality.py +0 -0
  99. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/tests/scripts/test_data_types.py +0 -0
  100. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/tests/scripts/test_dune_connectivity.py +0 -0
  101. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/tests/scripts/test_dune_query_execution.py +0 -0
  102. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/tests/scripts/test_error_handling.py +0 -0
  103. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/tests/scripts/test_mcp_simulation.py +0 -0
  104. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/tests/scripts/test_mcp_tools.py +0 -0
  105. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/tests/scripts/test_performance.py +0 -0
  106. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/tests/scripts/test_query_lifecycle.py +0 -0
  107. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/tests/scripts/test_resilience.py +0 -0
  108. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/tests/scripts/test_resource_management.py +0 -0
  109. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/tests/style/test_polars_lazy.py +0 -0
  110. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/tests/support/api_client.py +0 -0
  111. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/tests/support/helpers.py +0 -0
  112. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/tests/support/query_factory.py +0 -0
  113. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/tests/support/test_data.py +0 -0
  114. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/tests/tools/test_additional_mcp_tools.py +0 -0
  115. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/tests/tools/test_execute_query_tool.py +0 -0
  116. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/tests/tools/test_health_tool.py +0 -0
  117. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/tests/tools/test_query_service.py +0 -0
  118. {spice_mcp-0.1.0 → spice_mcp-0.1.2}/tests/tools/test_schemas.py +0 -0
@@ -15,3 +15,9 @@ notes/*
15
15
  .pytest_cache/*
16
16
  tests/scripts/test_report.txt
17
17
  coverage*
18
+
19
+ # Development tools and directories
20
+ bin/
21
+ .github/
22
+ .factory/
23
+ debug_api.py
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: spice-mcp
3
- Version: 0.1.0
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 (`docs/architecture.md`)
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
- Quick Start
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 `docs/index.md` for full documentation:
119
- - Dune API structure and capabilities: `docs/dune_api.md`
120
- - Discovery patterns and examples: `docs/discovery.md`
121
- - Sui package workflows: `docs/sui_packages.md`
122
- - Tool reference and schemas: `docs/tools.md`
123
- - Codex CLI + tooling integration: `docs/codex_cli.md`, `docs/codex_cli_tools.md`
124
- - Architecture overview: `docs/architecture.md`
125
- - Installation and configuration: `docs/installation.md`, `docs/config.md`
126
- - Development and linting: `docs/development.md`
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).
@@ -1,26 +1,86 @@
1
1
  # spice-mcp
2
2
 
3
- 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.
3
+ 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.
4
4
 
5
5
  Requirements: Python 3.13+
6
6
 
7
7
  This project uses FastMCP for typed, decorator-registered tools and resources.
8
8
 
9
- Highlights
9
+ ## Highlights
10
10
  - Polars LazyFrame-first pipeline: results stay lazy until explicitly materialized
11
- - Ports/adapters layering for maintainable integrations (`docs/architecture.md`)
11
+ - Ports/adapters layering for maintainable integrations ([docs/architecture.md](docs/architecture.md))
12
12
  - Discovery utilities (find schemas/tables, describe columns)
13
13
  - Sui package workflows (events/transactions/objects) with safe defaults
14
14
  - JSONL query history + SQL artifacts (SHA-256) for reproducibility
15
15
  - Rich MCP surface: query info/run, discovery, health, Sui, and Dune admin (create/update/fork)
16
16
 
17
- Quick Start
17
+ ## What is Dune?
18
+ [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.
19
+
20
+ ## Quick Start
18
21
  - 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).
19
22
  - Install dependencies (`uv sync` or `pip install -e .`).
20
23
  - Start the FastMCP stdio server:
21
24
  - `python -m spice_mcp.mcp.server --env PYTHONPATH=$(pwd)/src`
22
25
  - or install the console script via `uv tool install .` and run `spice-mcp`.
23
26
 
27
+ ## Cursor IDE Setup
28
+
29
+ To use spice-mcp with Cursor IDE:
30
+
31
+ 1. **Install the MCP Server**:
32
+ ```bash
33
+ # Install dependencies and package
34
+ uv sync
35
+ pip install -e .
36
+
37
+ # Or install via uv tool (creates console script)
38
+ uv tool install .
39
+ ```
40
+
41
+ 2. **Configure Cursor**:
42
+ - Open Cursor Settings → MCP Servers
43
+ - Add new MCP server configuration:
44
+ ```json
45
+ {
46
+ "name": "spice-mcp",
47
+ "command": "spice-mcp",
48
+ "env": {
49
+ "DUNE_API_KEY": "your-dune-api-key-here"
50
+ },
51
+ "disabled": false
52
+ }
53
+ ```
54
+ Alternatively, if you prefer running from source:
55
+ ```json
56
+ {
57
+ "name": "spice-mcp",
58
+ "command": "python",
59
+ "args": ["-m", "spice_mcp.mcp.server"],
60
+ "env": {
61
+ "PYTHONPATH": "/path/to/your/spice-mcp/src",
62
+ "DUNE_API_KEY": "your-dune-api-key-here"
63
+ },
64
+ "disabled": false
65
+ }
66
+ ```
67
+
68
+ 3. **Restart Cursor** to load the MCP server
69
+
70
+ 4. **Verify Connection**:
71
+ - Open Cursor and use the command palette (Cmd/Ctrl + Shift + P)
72
+ - Search for "MCP" or "spice" commands
73
+ - Test with `dune_health_check` to verify the connection
74
+
75
+ 5. **Available Tools in Cursor**:
76
+ - `dune_query`: Run Dune queries by ID, URL, or raw SQL
77
+ - `dune_find_tables`: Search schemas and list tables
78
+ - `dune_describe_table`: Get column metadata
79
+ - `sui_package_overview`: Analyze Sui packages
80
+ - `dune_health_check`: Verify API connection
81
+
82
+ **Tip**: Create a `.env` file in your project root with `DUNE_API_KEY=your-key-here` for easier configuration.
83
+
24
84
  ## MCP Tools and Features
25
85
 
26
86
  All tools expose typed parameters, titles, and tags; failures return a consistent error envelope.
@@ -93,16 +153,16 @@ Core Tools (with parameters)
93
153
  - Use: Verify API key presence and logging paths
94
154
  - Output: `api_key_present`, `query_history_path`, `logging_enabled`, `status`
95
155
 
96
- Docs
97
- - See `docs/index.md` for full documentation:
98
- - Dune API structure and capabilities: `docs/dune_api.md`
99
- - Discovery patterns and examples: `docs/discovery.md`
100
- - Sui package workflows: `docs/sui_packages.md`
101
- - Tool reference and schemas: `docs/tools.md`
102
- - Codex CLI + tooling integration: `docs/codex_cli.md`, `docs/codex_cli_tools.md`
103
- - Architecture overview: `docs/architecture.md`
104
- - Installation and configuration: `docs/installation.md`, `docs/config.md`
105
- - Development and linting: `docs/development.md`
156
+ ## Docs
157
+ - See [docs/index.md](docs/index.md) for full documentation:
158
+ - Dune API structure and capabilities: [docs/dune_api.md](docs/dune_api.md)
159
+ - Discovery patterns and examples: [docs/discovery.md](docs/discovery.md)
160
+ - Sui package workflows: [docs/sui_packages.md](docs/sui_packages.md)
161
+ - Tool reference and schemas: [docs/tools.md](docs/tools.md)
162
+ - Codex CLI + tooling integration: [docs/codex_cli.md](docs/codex_cli.md), [docs/codex_cli_tools.md](docs/codex_cli_tools.md)
163
+ - Architecture overview: [docs/architecture.md](docs/architecture.md)
164
+ - Installation and configuration: [docs/installation.md](docs/installation.md), [docs/config.md](docs/config.md)
165
+ - Development and linting: [docs/development.md](docs/development.md)
106
166
 
107
167
  Notes
108
168
  - Legacy Spice code now lives under `src/spice_mcp/adapters/dune` (extract, cache, urls, types).
@@ -0,0 +1,147 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Debug script to test the MCP tool layer directly.
4
+ """
5
+
6
+ import os
7
+ import sys
8
+ import json
9
+ from pathlib import Path
10
+
11
+ # Add src to path
12
+ sys.path.insert(0, '/Users/evandekim/Documents/spice_mcp/src')
13
+
14
+ from spice_mcp.config import Config
15
+ from spice_mcp.logging.query_history import QueryHistory
16
+ from spice_mcp.mcp.tools.execute_query import ExecuteQueryTool
17
+ from spice_mcp.service_layer.query_service import QueryService
18
+ from spice_mcp.adapters.dune.client import DuneAdapter
19
+
20
+ def test_mcp_tool_directly():
21
+ """Test the MCP tool directly"""
22
+
23
+ # Ensure API key is available
24
+ api_key = os.getenv('DUNE_API_KEY')
25
+ if not api_key:
26
+ print("❌ DUNE_API_KEY not set")
27
+ return False
28
+
29
+ print("🔍 Testing MCP tool directly...")
30
+
31
+ try:
32
+ # Setup the components
33
+ from spice_mcp.config import DuneConfig, CacheConfig, HttpClientConfig
34
+ config = Config(
35
+ dune=DuneConfig(api_key=api_key),
36
+ cache=CacheConfig(),
37
+ http=HttpClientConfig()
38
+ )
39
+ adapter = DuneAdapter(config)
40
+ query_service = QueryService(adapter)
41
+ query_history = QueryHistory(Path("/tmp/query_history.jsonl"), Path("/tmp/sql_artifacts"))
42
+
43
+ # Create the tool
44
+ tool = ExecuteQueryTool(config, query_service, query_history)
45
+
46
+ # Test simple raw SQL
47
+ print("\n📝 Testing MCP tool with 'SELECT 1 as test'")
48
+
49
+ # This should work via the MCP tool interface
50
+ import asyncio
51
+ result = asyncio.run(tool.execute(
52
+ query="SELECT 1 as test",
53
+ refresh=True,
54
+ format="preview"
55
+ ))
56
+
57
+ print(f"✅ Tool result type: {type(result)}")
58
+ print(f"✅ Tool result keys: {list(result.keys()) if isinstance(result, dict) else 'not dict'}")
59
+
60
+ if isinstance(result, dict):
61
+ print(f"✅ Response type: {result.get('type')}")
62
+ print(f"✅ Row count: {result.get('rowcount')}")
63
+ print(f"✅ Execution ID: {result.get('execution_id')}")
64
+ if 'error' in result:
65
+ print(f"❌ Error: {result['error']}")
66
+ return False
67
+ else:
68
+ print("✅ Success! MCP tool executed raw SQL correctly")
69
+
70
+ except Exception as e:
71
+ print(f"❌ MCP tool test failed: {e}")
72
+ print(f" Error type: {type(e)}")
73
+ import traceback
74
+ traceback.print_exc()
75
+ return False
76
+
77
+ return True
78
+
79
+ def test_service_layer_directly():
80
+ """Test the service layer directly"""
81
+
82
+ # Ensure API key is available
83
+ api_key = os.getenv('DUNE_API_KEY')
84
+ if not api_key:
85
+ print("❌ DUNE_API_KEY not set")
86
+ return False
87
+
88
+ print("🔍 Testing service layer directly...")
89
+
90
+ try:
91
+ # Setup the components
92
+ from spice_mcp.config import DuneConfig, CacheConfig, HttpClientConfig
93
+ config = Config(
94
+ dune=DuneConfig(api_key=api_key),
95
+ cache=CacheConfig(),
96
+ http=HttpClientConfig()
97
+ )
98
+ adapter = DuneAdapter(config)
99
+ query_service = QueryService(adapter)
100
+
101
+ # Test service layer directly
102
+ print("\n📝 Testing service layer with 'SELECT 1 as test'")
103
+
104
+ result = query_service.execute(
105
+ query="SELECT 1 as test",
106
+ refresh=True,
107
+ include_execution=True
108
+ )
109
+
110
+ print(f"✅ Service result type: {type(result)}")
111
+ print(f"✅ Service result keys: {list(result.keys()) if isinstance(result, dict) else 'not dict'}")
112
+
113
+ if isinstance(result, dict):
114
+ print(f"✅ Row count: {result.get('rowcount')}")
115
+ print(f"✅ Execution: {result.get('execution')}")
116
+ if 'execution' in result and result['execution'].get('execution_id'):
117
+ print("✅ Service layer executed successfully!")
118
+ return True
119
+ else:
120
+ print("❌ Service layer failed - no execution ID")
121
+ return False
122
+
123
+ except Exception as e:
124
+ print(f"❌ Service layer test failed: {e}")
125
+ import traceback
126
+ traceback.print_exc()
127
+ return False
128
+
129
+ return False
130
+
131
+ if __name__ == "__main__":
132
+ print("🐛 Debugging spice-mcp MCP tool layer...")
133
+
134
+ success = True
135
+
136
+ # Test 1: Service layer
137
+ success &= test_service_layer_directly()
138
+
139
+ # Test 2: MCP tool
140
+ success &= test_mcp_tool_directly()
141
+
142
+ if success:
143
+ print("\n✅ All tests passed!")
144
+ sys.exit(0)
145
+ else:
146
+ print("\n❌ Some tests failed!")
147
+ sys.exit(1)
@@ -0,0 +1,147 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Debug script to test template query 4060379 execution directly.
4
+ """
5
+
6
+ import os
7
+ import sys
8
+ import json
9
+
10
+ # Add src to path
11
+ sys.path.insert(0, '/Users/evandekim/Documents/spice_mcp/src')
12
+
13
+ from spice_mcp.adapters.dune import extract, urls
14
+
15
+ def test_template_query_directly():
16
+ """Test the template query directly via extract.query()"""
17
+
18
+ # Ensure API key is available
19
+ api_key = os.getenv('DUNE_API_KEY')
20
+ if not api_key:
21
+ print("❌ DUNE_API_KEY not set")
22
+ return False
23
+
24
+ template_id = int(os.getenv("SPICE_RAW_SQL_QUERY_ID", "4060379"))
25
+ print(f"🔍 Testing template query {template_id} directly...")
26
+
27
+ try:
28
+ # Test 1: Execute simple raw SQL
29
+ print("\n📝 Test 1: Simple SELECT 1")
30
+ result = extract.query(
31
+ query_or_execution="SELECT 1 as test",
32
+ verbose=True,
33
+ refresh=True,
34
+ poll=True,
35
+ api_key=api_key,
36
+ timeout_seconds=30
37
+ )
38
+
39
+ print(f"✅ Result type: {type(result)}")
40
+ if hasattr(result, 'shape'):
41
+ print(f"✅ Result shape: {result.shape}")
42
+ print(f"✅ Result columns: {list(result.columns) if hasattr(result, 'columns') else 'N/A'}")
43
+
44
+ except Exception as e:
45
+ print(f"❌ Test 1 failed: {e}")
46
+ print(f" Error type: {type(e)}")
47
+ return False
48
+
49
+ try:
50
+ # Test 2: Test with parameters explicitly
51
+ print("\n📝 Test 2: Raw SQL with explicit parameters")
52
+ result = extract.query(
53
+ query_or_execution="SELECT 1 as test",
54
+ verbose=True,
55
+ refresh=True,
56
+ poll=True,
57
+ api_key=api_key,
58
+ parameters={'query': 'SELECT 1 as test'},
59
+ timeout_seconds=30
60
+ )
61
+
62
+ print(f"✅ Result type: {type(result)}")
63
+ if hasattr(result, 'shape'):
64
+ print(f"✅ Result shape: {result.shape}")
65
+
66
+ except Exception as e:
67
+ print(f"❌ Test 2 failed: {e}")
68
+ return False
69
+
70
+ return True
71
+
72
+ def test_determine_input_type():
73
+ """Test the determine_input_type function"""
74
+ print("\n🔍 Testing determine_input_type...")
75
+
76
+ query_id, execution, parameters = extract.determine_input_type("SELECT 1 as test")
77
+
78
+ print(f"✅ Query ID: {query_id}")
79
+ print(f"✅ Execution: {execution}")
80
+ print(f"✅ Parameters: {parameters}")
81
+
82
+ return True
83
+
84
+ def test_template_query_api_check():
85
+ """Check if the template query actually exists and is accessible"""
86
+ template_id = int(os.getenv("SPICE_RAW_SQL_QUERY_ID", "4060379"))
87
+ api_key = os.getenv('DUNE_API_KEY')
88
+
89
+ if not api_key:
90
+ print("❌ DUNE_API_KEY not set")
91
+ return False
92
+
93
+ print(f"\n🔍 Checking template query {template_id} metadata...")
94
+
95
+ try:
96
+ # Check if the query exists by trying to get its info
97
+ url = urls.get_query_execute_url(template_id)
98
+ headers = {'X-Dune-API-Key': api_key, 'User-Agent': extract.get_user_agent()}
99
+
100
+ print(f"🌐 Query execute URL: {url}")
101
+
102
+ # Try to execute with empty parameters first
103
+ import requests
104
+
105
+ response = requests.post(
106
+ url,
107
+ headers=headers,
108
+ json={'query_parameters': {}, 'performance': 'medium'},
109
+ timeout=30
110
+ )
111
+
112
+ print(f"📊 Status code: {response.status_code}")
113
+
114
+ if response.status_code == 200:
115
+ result = response.json()
116
+ print(f"✅ Execution result: {json.dumps(result, indent=2)}")
117
+ else:
118
+ print(f"❌ API Response: {response.text}")
119
+ return False
120
+
121
+ except Exception as e:
122
+ print(f"❌ Template query check failed: {e}")
123
+ return False
124
+
125
+ return True
126
+
127
+ if __name__ == "__main__":
128
+ print("🐛 Debugging spice-mcp raw SQL execution issues...")
129
+
130
+ success = True
131
+
132
+ # Test 1: Determine input type
133
+ success &= test_determine_input_type()
134
+
135
+ # Test 2: Check template query API
136
+ success &= test_template_query_api_check()
137
+
138
+ # Test 3: Direct execution
139
+ print(f"\n🚀 About to test raw SQL execution...")
140
+ success &= test_template_query_directly()
141
+
142
+ if success:
143
+ print("\n✅ All tests passed!")
144
+ sys.exit(0)
145
+ else:
146
+ print("\n❌ Some tests failed!")
147
+ sys.exit(1)
@@ -0,0 +1,76 @@
1
+ # Raw SQL Execution Issue Analysis
2
+
3
+ ## ✅ GOOD NEWS: Core Code is Working Correctly!
4
+
5
+ After extensive debugging, I've determined that the core spice-mcp code is **working perfectly**. Both the Dune adapter layer and MCP tool layer successfully execute raw SQL queries when properly configured.
6
+
7
+ ## 🐛 Root Cause: Environmental/Configuration Issue
8
+
9
+ The issue reported in #6 is **not in the code itself** but rather in how users are running the MCP server. The symptoms suggest:
10
+
11
+ 1. **Environment variable issue**: `SPICE_RAW_SQL_QUERY_ID` may not be set in the MCP server context
12
+ 2. **MCP server setup issue**: The FastMCP server may not be properly configured
13
+ 3. **Path/import issues**: The MCP server may be running in a different environment
14
+
15
+ ## 🔧 Proposed Solutions
16
+
17
+ ### Option 1: Hard-code fallback (Recommended)
18
+ Make the template ID resolution more robust by providing a fallback:
19
+
20
+ ```python
21
+ def resolve_raw_sql_template_id() -> int:
22
+ """Return a stable template ID used for executing raw SQL text."""
23
+ # Try environment variable first, fallback to hardcoded value
24
+ env_value = os.getenv("SPICE_RAW_SQL_QUERY_ID")
25
+ if env_value and env_value.strip():
26
+ try:
27
+ return int(env_value.strip())
28
+ except ValueError:
29
+ pass
30
+ # Fallback to known working template ID
31
+ return 4060379
32
+ ```
33
+
34
+ ### Option 2: Enhanced Diagnostics
35
+ Add better error reporting in the MCP tool to help users debug their setup:
36
+
37
+ ```python
38
+ # Add environment variable check at tool startup
39
+ if not os.getenv("SPICE_RAW_SQL_QUERY_ID"):
40
+ print("Warning: SPICE_RAW_SQL_QUERY_ID not set, using default template ID")
41
+ ```
42
+
43
+ ### Option 3: Verify Tool
44
+ Create a verification tool that tests the raw SQL path:
45
+
46
+ ```python
47
+ def verify_raw_sql_config(self) -> dict:
48
+ """Verify that raw SQL configuration is working."""
49
+ try:
50
+ template_id = resolve_raw_sql_template_id()
51
+ return {
52
+ "status": "ok",
53
+ "template_id": template_id,
54
+ "env_var_set": bool(os.getenv("SPICE_RAW_SQL_QUERY_ID"))
55
+ }
56
+ except Exception as e:
57
+ return {"status": "error", "error": str(e)}
58
+ ```
59
+
60
+ ## 🎯 User Action Required
61
+
62
+ For users experiencing this issue:
63
+
64
+ 1. **Set environment variable properly in MCP server context**
65
+ 2. **Verify MCP server startup logs** for any authentication or import errors
66
+ 3. **Use the enhanced diagnostics** (once implemented)
67
+
68
+ ## 📋 Test Results Summary
69
+
70
+ - ✅ Template ID resolution: Working
71
+ - ✅ Dune adapter raw SQL: Working
72
+ - ✅ MCP tool raw SQL: Working
73
+ - ✅ Service layer: Working
74
+ - ❌ User environment: Needs investigation
75
+
76
+ The fix in 0.1.1 addressed the core issue. The remaining problem is likely user environment specific.
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "spice-mcp"
3
- version = "0.1.0"
3
+ version = "0.1.2"
4
4
  description = "MCP server for Dune Analytics data access"
5
5
  authors = [
6
6
  { name = "Evan-Kim2028", email = "ekcopersonal@gmail.com" }
@@ -36,6 +36,23 @@ managed = true
36
36
  dev-dependencies = [
37
37
  "pytest>=8.0.0",
38
38
  "pytest-asyncio>=0.23.0",
39
+ "pytest-cov>=5.0.0",
40
+ "freezegun>=1.4.0",
41
+ "jsonschema>=4.21.1",
42
+ "responses>=0.25.0",
43
+ "aioresponses>=0.7.6",
44
+ "vcrpy>=6.0.1",
45
+ "hypothesis>=6.100.0",
46
+ "ruff>=0.6.9",
47
+ "mypy>=1.11.2",
48
+ ]
49
+
50
+ # uv dependency groups for CI and local dev
51
+ [dependency-groups]
52
+ dev = [
53
+ "pytest>=8.0.0",
54
+ "pytest-asyncio>=0.23.0",
55
+ "pytest-cov>=5.0.0",
39
56
  "freezegun>=1.4.0",
40
57
  "jsonschema>=4.21.1",
41
58
  "responses>=0.25.0",