@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.
- package/README.md +148 -89
- package/dist/index.js +238 -38
- package/dist/index.js.map +1 -1
- package/dist/tools/definitions.d.ts +6 -0
- package/dist/tools/definitions.d.ts.map +1 -1
- package/dist/tools/definitions.js +23 -106
- package/dist/tools/definitions.js.map +1 -1
- package/dist/ui/resources.d.ts +110 -0
- package/dist/ui/resources.d.ts.map +1 -0
- package/dist/ui/resources.js +263 -0
- package/dist/ui/resources.js.map +1 -0
- package/package.json +5 -3
- package/skills/quarri-chart/SKILL.md +151 -216
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Generate interactive Plotly charts
|
|
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
|
|
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
|
|
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:
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
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
|
-
|
|
72
|
-
|
|
73
|
-
|
|
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
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
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: [
|
|
122
|
-
textposition:
|
|
123
|
-
}]
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
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
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
title:
|
|
144
|
-
xaxis: { title:
|
|
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
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
title:
|
|
162
|
-
xaxis: { title:
|
|
163
|
-
yaxis: { title:
|
|
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
|
-
|
|
146
|
+
{
|
|
147
|
+
"data": [
|
|
170
148
|
{
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
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
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
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
|
-
|
|
187
|
-
title:
|
|
188
|
-
|
|
189
|
-
|
|
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
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
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:
|
|
204
|
-
}]
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
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
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
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
|
-
|
|
226
|
-
title:
|
|
227
|
-
|
|
228
|
-
|
|
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
|
-
|
|
214
|
+
{
|
|
215
|
+
"data": [
|
|
235
216
|
{
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
217
|
+
"x": ["Q1", "Q2", "Q3", "Q4"],
|
|
218
|
+
"y": [120, 150, 180, 200],
|
|
219
|
+
"name": "2023",
|
|
220
|
+
"type": "bar"
|
|
240
221
|
},
|
|
241
222
|
{
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
223
|
+
"x": ["Q1", "Q2", "Q3", "Q4"],
|
|
224
|
+
"y": [140, 165, 195, 220],
|
|
225
|
+
"name": "2024",
|
|
226
|
+
"type": "bar"
|
|
246
227
|
}
|
|
247
|
-
]
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
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
|
-
##
|
|
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
|
-
|
|
346
|
-
|
|
347
|
-
|
|
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)
|