@quarri/claude-data-tools 1.1.1 → 1.2.1

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.
@@ -1,12 +1,12 @@
1
1
  ---
2
- description: Generate interactive Plotly charts and open them in the browser
2
+ description: Generate interactive Plotly charts rendered as MCP UI resources
3
3
  globs:
4
4
  alwaysApply: false
5
5
  ---
6
6
 
7
7
  # /quarri-chart - Interactive Chart Generation
8
8
 
9
- Generate data visualizations as interactive HTML files and open them in the default browser.
9
+ Generate data visualizations as interactive Plotly charts using MCP UI resources.
10
10
 
11
11
  ## When to Use
12
12
 
@@ -16,7 +16,7 @@ Use `/quarri-chart` when users want visualizations:
16
16
  - "Show me a graph of this data"
17
17
  - "Chart sales by category"
18
18
 
19
- ## Primary Workflow (DEFAULT)
19
+ ## Primary Workflow
20
20
 
21
21
  ### Step 1: Query the data
22
22
  ```sql
@@ -26,57 +26,31 @@ GROUP BY category
26
26
  ORDER BY total_sales DESC
27
27
  ```
28
28
 
29
- ### Step 2: Generate HTML with Plotly
30
- Write an HTML file to `/tmp/quarri_chart.html`:
31
-
32
- ```html
33
- <!DOCTYPE html>
34
- <html>
35
- <head>
36
- <title>[Chart Title]</title>
37
- <script src="https://cdn.plot.ly/plotly-2.27.0.min.js"></script>
38
- <style>
39
- body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; margin: 40px; background: #f5f5f5; }
40
- h1 { color: #1a1a2e; text-align: center; margin-bottom: 10px; }
41
- .subtitle { color: #666; text-align: center; margin-bottom: 30px; }
42
- #chart { width: 100%; max-width: 900px; margin: 0 auto; background: white; border-radius: 12px; box-shadow: 0 4px 12px rgba(0,0,0,0.1); padding: 20px; }
43
- </style>
44
- </head>
45
- <body>
46
- <h1>[Chart Title]</h1>
47
- <p class="subtitle">Data from [database_name]</p>
48
- <div id="chart"></div>
49
- <script>
50
- var data = [{
51
- x: [/* labels */],
52
- y: [/* values */],
53
- type: 'bar',
54
- marker: { color: '#4F46E5' }
55
- }];
56
-
57
- var layout = {
58
- title: '',
59
- xaxis: { title: '[X Label]' },
60
- yaxis: { title: '[Y Label]', tickformat: '$,.0f' },
61
- margin: { t: 40, b: 60, l: 80, r: 40 }
62
- };
63
-
64
- var config = { responsive: true, displayModeBar: true };
65
- Plotly.newPlot('chart', data, layout, config);
66
- </script>
67
- </body>
68
- </html>
29
+ ### Step 2: Return chart as MCP UI resource
30
+
31
+ After getting the data, construct a Plotly configuration and include it in your response. The chart will be rendered as an interactive UI component.
32
+
33
+ **Example Plotly config for bar chart:**
34
+ ```json
35
+ {
36
+ "data": [{
37
+ "x": ["Category A", "Category B", "Category C"],
38
+ "y": [450000, 380000, 290000],
39
+ "type": "bar",
40
+ "marker": { "color": "#4F46E5" }
41
+ }],
42
+ "layout": {
43
+ "title": "Sales by Category",
44
+ "xaxis": { "title": "Category" },
45
+ "yaxis": { "title": "Sales ($)", "tickformat": "$,.0f" }
46
+ }
47
+ }
69
48
  ```
70
49
 
71
- ### Step 3: Open in browser
72
- ```bash
73
- open /tmp/quarri_chart.html
74
- ```
75
-
76
- On different platforms:
77
- - **macOS**: `open /tmp/quarri_chart.html`
78
- - **Linux**: `xdg-open /tmp/quarri_chart.html`
79
- - **Windows**: `start /tmp/quarri_chart.html`
50
+ The response should include this as a resource block with:
51
+ - URI: `ui://quarri/chart`
52
+ - MIME type: `application/vnd.quarri.chart+json`
53
+ - Content: JSON with `type: "chart"` and `plotly: { data, layout }`
80
54
 
81
55
  ## Chart Type Selection
82
56
 
@@ -111,145 +85,152 @@ START: What is the primary analysis goal?
111
85
 
112
86
  ### Bar Chart
113
87
  ```javascript
114
- var data = [{
115
- x: ['Category A', 'Category B', 'Category C'],
116
- y: [450000, 380000, 290000],
117
- type: 'bar',
118
- marker: {
119
- color: ['#4F46E5', '#7C3AED', '#A78BFA']
88
+ {
89
+ "data": [{
90
+ "x": ["Category A", "Category B", "Category C"],
91
+ "y": [450000, 380000, 290000],
92
+ "type": "bar",
93
+ "marker": {
94
+ "color": ["#4F46E5", "#7C3AED", "#A78BFA"]
120
95
  },
121
- text: ['$450K', '$380K', '$290K'],
122
- textposition: 'auto'
123
- }];
124
-
125
- var layout = {
126
- title: 'Sales by Category',
127
- xaxis: { title: 'Category' },
128
- yaxis: { title: 'Sales ($)', tickformat: '$,.0f' }
129
- };
96
+ "text": ["$450K", "$380K", "$290K"],
97
+ "textposition": "auto"
98
+ }],
99
+ "layout": {
100
+ "title": "Sales by Category",
101
+ "xaxis": { "title": "Category" },
102
+ "yaxis": { "title": "Sales ($)", "tickformat": "$,.0f" }
103
+ }
104
+ }
130
105
  ```
131
106
 
132
107
  ### Horizontal Bar (many categories)
133
108
  ```javascript
134
- var data = [{
135
- y: ['Product A', 'Product B', 'Product C', 'Product D', 'Product E'],
136
- x: [85000, 72000, 65000, 58000, 45000],
137
- type: 'bar',
138
- orientation: 'h',
139
- marker: { color: '#4F46E5' }
140
- }];
141
-
142
- var layout = {
143
- title: 'Top Products by Revenue',
144
- xaxis: { title: 'Revenue ($)', tickformat: '$,.0f' },
145
- margin: { l: 120 }
146
- };
109
+ {
110
+ "data": [{
111
+ "y": ["Product A", "Product B", "Product C", "Product D", "Product E"],
112
+ "x": [85000, 72000, 65000, 58000, 45000],
113
+ "type": "bar",
114
+ "orientation": "h",
115
+ "marker": { "color": "#4F46E5" }
116
+ }],
117
+ "layout": {
118
+ "title": "Top Products by Revenue",
119
+ "xaxis": { "title": "Revenue ($)", "tickformat": "$,.0f" },
120
+ "margin": { "l": 120 }
121
+ }
122
+ }
147
123
  ```
148
124
 
149
125
  ### Line Chart (time series)
150
126
  ```javascript
151
- var data = [{
152
- x: ['2024-01', '2024-02', '2024-03', '2024-04', '2024-05', '2024-06'],
153
- y: [120000, 135000, 128000, 145000, 160000, 175000],
154
- type: 'scatter',
155
- mode: 'lines+markers',
156
- line: { color: '#4F46E5', width: 3 },
157
- marker: { size: 8 }
158
- }];
159
-
160
- var layout = {
161
- title: 'Monthly Revenue Trend',
162
- xaxis: { title: 'Month' },
163
- yaxis: { title: 'Revenue ($)', tickformat: '$,.0f' }
164
- };
127
+ {
128
+ "data": [{
129
+ "x": ["2024-01", "2024-02", "2024-03", "2024-04", "2024-05", "2024-06"],
130
+ "y": [120000, 135000, 128000, 145000, 160000, 175000],
131
+ "type": "scatter",
132
+ "mode": "lines+markers",
133
+ "line": { "color": "#4F46E5", "width": 3 },
134
+ "marker": { "size": 8 }
135
+ }],
136
+ "layout": {
137
+ "title": "Monthly Revenue Trend",
138
+ "xaxis": { "title": "Month" },
139
+ "yaxis": { "title": "Revenue ($)", "tickformat": "$,.0f" }
140
+ }
141
+ }
165
142
  ```
166
143
 
167
144
  ### Multi-Line Chart
168
145
  ```javascript
169
- var data = [
146
+ {
147
+ "data": [
170
148
  {
171
- x: ['Jan', 'Feb', 'Mar', 'Apr'],
172
- y: [100, 120, 115, 140],
173
- name: 'Product A',
174
- type: 'scatter',
175
- mode: 'lines+markers'
149
+ "x": ["Jan", "Feb", "Mar", "Apr"],
150
+ "y": [100, 120, 115, 140],
151
+ "name": "Product A",
152
+ "type": "scatter",
153
+ "mode": "lines+markers"
176
154
  },
177
155
  {
178
- x: ['Jan', 'Feb', 'Mar', 'Apr'],
179
- y: [80, 95, 110, 120],
180
- name: 'Product B',
181
- type: 'scatter',
182
- mode: 'lines+markers'
156
+ "x": ["Jan", "Feb", "Mar", "Apr"],
157
+ "y": [80, 95, 110, 120],
158
+ "name": "Product B",
159
+ "type": "scatter",
160
+ "mode": "lines+markers"
183
161
  }
184
- ];
185
-
186
- var layout = {
187
- title: 'Product Comparison',
188
- xaxis: { title: 'Month' },
189
- yaxis: { title: 'Sales' }
190
- };
162
+ ],
163
+ "layout": {
164
+ "title": "Product Comparison",
165
+ "xaxis": { "title": "Month" },
166
+ "yaxis": { "title": "Sales" }
167
+ }
168
+ }
191
169
  ```
192
170
 
193
171
  ### Pie/Donut Chart
194
172
  ```javascript
195
- var data = [{
196
- labels: ['Technology', 'Furniture', 'Office Supplies'],
197
- values: [5471124, 4730801, 4144724],
198
- type: 'pie',
199
- hole: 0.4, // Remove for regular pie
200
- marker: {
201
- colors: ['#4F46E5', '#10B981', '#F59E0B']
173
+ {
174
+ "data": [{
175
+ "labels": ["Technology", "Furniture", "Office Supplies"],
176
+ "values": [5471124, 4730801, 4144724],
177
+ "type": "pie",
178
+ "hole": 0.4,
179
+ "marker": {
180
+ "colors": ["#4F46E5", "#10B981", "#F59E0B"]
202
181
  },
203
- textinfo: 'label+percent'
204
- }];
205
-
206
- var layout = {
207
- title: 'Sales Distribution by Category'
208
- };
182
+ "textinfo": "label+percent"
183
+ }],
184
+ "layout": {
185
+ "title": "Sales Distribution by Category"
186
+ }
187
+ }
209
188
  ```
210
189
 
211
190
  ### Scatter Plot
212
191
  ```javascript
213
- var data = [{
214
- x: [/* x values */],
215
- y: [/* y values */],
216
- mode: 'markers',
217
- type: 'scatter',
218
- marker: {
219
- size: 10,
220
- color: '#4F46E5',
221
- opacity: 0.7
192
+ {
193
+ "data": [{
194
+ "x": [/* x values */],
195
+ "y": [/* y values */],
196
+ "mode": "markers",
197
+ "type": "scatter",
198
+ "marker": {
199
+ "size": 10,
200
+ "color": "#4F46E5",
201
+ "opacity": 0.7
222
202
  }
223
- }];
224
-
225
- var layout = {
226
- title: 'Correlation Analysis',
227
- xaxis: { title: 'Variable X' },
228
- yaxis: { title: 'Variable Y' }
229
- };
203
+ }],
204
+ "layout": {
205
+ "title": "Correlation Analysis",
206
+ "xaxis": { "title": "Variable X" },
207
+ "yaxis": { "title": "Variable Y" }
208
+ }
209
+ }
230
210
  ```
231
211
 
232
212
  ### Grouped Bar Chart
233
213
  ```javascript
234
- var data = [
214
+ {
215
+ "data": [
235
216
  {
236
- x: ['Q1', 'Q2', 'Q3', 'Q4'],
237
- y: [120, 150, 180, 200],
238
- name: '2023',
239
- type: 'bar'
217
+ "x": ["Q1", "Q2", "Q3", "Q4"],
218
+ "y": [120, 150, 180, 200],
219
+ "name": "2023",
220
+ "type": "bar"
240
221
  },
241
222
  {
242
- x: ['Q1', 'Q2', 'Q3', 'Q4'],
243
- y: [140, 165, 195, 220],
244
- name: '2024',
245
- type: 'bar'
223
+ "x": ["Q1", "Q2", "Q3", "Q4"],
224
+ "y": [140, 165, 195, 220],
225
+ "name": "2024",
226
+ "type": "bar"
246
227
  }
247
- ];
248
-
249
- var layout = {
250
- title: 'Year over Year Comparison',
251
- barmode: 'group'
252
- };
228
+ ],
229
+ "layout": {
230
+ "title": "Year over Year Comparison",
231
+ "barmode": "group"
232
+ }
233
+ }
253
234
  ```
254
235
 
255
236
  ## Color Palettes
@@ -284,69 +265,23 @@ tickformat: '.1%' // 45.2%
284
265
  tickformat: '~s' // 1.2M, 3.4K
285
266
  ```
286
267
 
287
- ## Complete Example
288
-
289
- For "Show me sales by category":
290
-
291
- ```html
292
- <!DOCTYPE html>
293
- <html>
294
- <head>
295
- <title>Sales by Category</title>
296
- <script src="https://cdn.plot.ly/plotly-2.27.0.min.js"></script>
297
- <style>
298
- body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; margin: 40px; background: #f5f5f5; }
299
- h1 { color: #1a1a2e; text-align: center; margin-bottom: 10px; }
300
- .subtitle { color: #666; text-align: center; margin-bottom: 30px; font-size: 14px; }
301
- #chart { width: 100%; max-width: 900px; margin: 0 auto; background: white; border-radius: 12px; box-shadow: 0 4px 12px rgba(0,0,0,0.1); padding: 20px; }
302
- </style>
303
- </head>
304
- <body>
305
- <h1>Superstore Sales by Category</h1>
306
- <p class="subtitle">Total: $14.3M across 51,290 orders</p>
307
- <div id="chart"></div>
308
- <script>
309
- var data = [{
310
- x: ['Technology', 'Furniture', 'Office Supplies'],
311
- y: [5471124.24, 4730801.23, 4144724.04],
312
- type: 'bar',
313
- marker: {
314
- color: ['#4F46E5', '#7C3AED', '#A78BFA']
315
- },
316
- text: ['$5.47M', '$4.73M', '$4.14M'],
317
- textposition: 'outside',
318
- textfont: { size: 14, color: '#374151' }
319
- }];
320
-
321
- var layout = {
322
- xaxis: { title: 'Category', tickfont: { size: 12 } },
323
- yaxis: {
324
- title: 'Sales ($)',
325
- tickformat: '$,.0f',
326
- tickfont: { size: 11 }
327
- },
328
- margin: { t: 40, b: 80, l: 100, r: 40 },
329
- plot_bgcolor: 'white',
330
- paper_bgcolor: 'white'
331
- };
332
-
333
- var config = {
334
- responsive: true,
335
- displayModeBar: true,
336
- modeBarButtonsToRemove: ['lasso2d', 'select2d']
337
- };
338
-
339
- Plotly.newPlot('chart', data, layout, config);
340
- </script>
341
- </body>
342
- </html>
343
- ```
268
+ ## MCP UI Resource Format
344
269
 
345
- Then run:
346
- ```bash
347
- open /tmp/quarri_chart.html
270
+ The chart should be returned as an MCP UI resource with the following structure:
271
+
272
+ ```json
273
+ {
274
+ "type": "chart",
275
+ "title": "Chart Title",
276
+ "plotly": {
277
+ "data": [/* Plotly data traces */],
278
+ "layout": {/* Plotly layout config */}
279
+ }
280
+ }
348
281
  ```
349
282
 
283
+ This is automatically rendered by Claude Code when you include the resource block in your response.
284
+
350
285
  ## Alternative Outputs
351
286
 
352
287
  ### QuickChart URL (for sharing/embedding)