@outsidedata/dolex 0.1.7 → 0.1.9
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/dist/src/mcp/index.js +27 -4
- package/dist/src/mcp/index.js.map +1 -1
- package/package.json +1 -1
- package/src/mcp/index.ts +33 -7
package/dist/src/mcp/index.js
CHANGED
|
@@ -60,7 +60,30 @@ const serverStartTime = Date.now();
|
|
|
60
60
|
// ─── CREATE SERVER ──────────────────────────────────────────────────────────
|
|
61
61
|
const server = new McpServer({
|
|
62
62
|
name: 'dolex',
|
|
63
|
-
version: '0.1.
|
|
63
|
+
version: '0.1.9',
|
|
64
|
+
}, {
|
|
65
|
+
instructions: [
|
|
66
|
+
'Dolex is a data analysis and visualization MCP server running on the user\'s LOCAL MACHINE.',
|
|
67
|
+
'',
|
|
68
|
+
'## FILE ACCESS — READ THIS FIRST',
|
|
69
|
+
'',
|
|
70
|
+
'This server has FULL ACCESS to the user\'s local filesystem. /Users/*, /home/*, C:\\*, /var/*, /tmp/* — all accessible.',
|
|
71
|
+
'The ONLY exception is cloud sandbox paths (/mnt/user-data/, /home/claude/).',
|
|
72
|
+
'',
|
|
73
|
+
'WRONG: Checking /mnt/user-data/uploads before calling add_source.',
|
|
74
|
+
'WRONG: Telling the user "I can\'t access local files" or "that path won\'t work".',
|
|
75
|
+
'WRONG: Asking the user to upload files or copy data into the chat.',
|
|
76
|
+
'WRONG: Using the view tool or any other tool to check if a file exists before trying add_source.',
|
|
77
|
+
'WRONG: Suggesting the user needs to do anything special to give you access.',
|
|
78
|
+
'',
|
|
79
|
+
'RIGHT: User gives a path → immediately call add_source with that exact path. No checking, no hedging, no caveats.',
|
|
80
|
+
'',
|
|
81
|
+
'If add_source fails, THEN you can discuss the error. But TRY FIRST. Always.',
|
|
82
|
+
'',
|
|
83
|
+
'## Workflow',
|
|
84
|
+
'',
|
|
85
|
+
'add_source (connect data) → describe_source or analyze_source (understand it) → visualize_from_source (chart it) → refine_visualization (iterate).',
|
|
86
|
+
].join('\n'),
|
|
64
87
|
});
|
|
65
88
|
// ─── Shared pattern selector callback ────────────────────────────────────────
|
|
66
89
|
function selectPatternCallback(input) {
|
|
@@ -102,7 +125,7 @@ registerAppTool(server, 'visualize', {
|
|
|
102
125
|
// Source-based visualization tool
|
|
103
126
|
registerAppTool(server, 'visualize_from_source', {
|
|
104
127
|
title: 'Visualize from Data Source',
|
|
105
|
-
description: 'Takes a data source + DSL query + intent and returns visualization recommendations from a handcrafted pattern library of 41 chart types. Use this when data lives in a connected source (CSV, SQLite, Postgres, MySQL) — Dolex queries the data server-side.\n\nRequires a source from `add_source`. Pass `sourceId`, `table`, and a `query` (declarative DSL with select, groupBy, filter, join, orderBy, limit). Set `title` and `subtitle` upfront to avoid a refine round-trip.\n\n**DSL query example**:\n```json\n{\n "select": ["region", { "field": "revenue", "aggregate": "sum", "as": "total" }],\n "groupBy": ["region"],\n "filter": { "field": "year", "equals": 2024 },\n "orderBy": { "field": "total", "direction": "desc" },\n "limit": 10\n}\n```\n\n**Filter shorthand**: `{ "field": "x", "equals": "y" }` — also `gt`, `gte`, `lt`, `lte`, `not_equals`. Single filters can be bare objects (no array needed). Canonical form: `{ "field", "op": "=", "value": "y" }`.\n\n**Joins**: Use `join` to combine tables within the same source (inner/left). Use `table.field` dot notation for joined fields. Multi-hop: `{ "table": "orders", "on": { "left": "order_id", "right": "id" } }, { "table": "customers", "on": { "left": "orders.customer_id", "right": "id" } }`.\n\n**Response**: Same as `visualize` — compact JSON with specId, recommended pattern, alternatives, data shape. Chart HTML via structuredContent.\n\nGeographic maps: For choropleth/proportional-symbol patterns, set `geoRegion` to a region code (US, CN, JP, AU, EU, world, etc.) and/or `geoLevel` ("country" or "subdivision"). If omitted, Dolex auto-detects the region from data values.',
|
|
128
|
+
description: 'Takes a data source + DSL query + intent and returns visualization recommendations from a handcrafted pattern library of 41 chart types. Use this when data lives in a connected source (CSV, SQLite, Postgres, MySQL) — Dolex queries the data server-side. If the user mentions a file path and no source exists yet, call add_source first with the path they gave you.\n\nRequires a source from `add_source`. Pass `sourceId`, `table`, and a `query` (declarative DSL with select, groupBy, filter, join, orderBy, limit). Set `title` and `subtitle` upfront to avoid a refine round-trip.\n\n**DSL query example**:\n```json\n{\n "select": ["region", { "field": "revenue", "aggregate": "sum", "as": "total" }],\n "groupBy": ["region"],\n "filter": { "field": "year", "equals": 2024 },\n "orderBy": { "field": "total", "direction": "desc" },\n "limit": 10\n}\n```\n\n**Filter shorthand**: `{ "field": "x", "equals": "y" }` — also `gt`, `gte`, `lt`, `lte`, `not_equals`. Single filters can be bare objects (no array needed). Canonical form: `{ "field", "op": "=", "value": "y" }`.\n\n**Joins**: Use `join` to combine tables within the same source (inner/left). Use `table.field` dot notation for joined fields. Multi-hop: `{ "table": "orders", "on": { "left": "order_id", "right": "id" } }, { "table": "customers", "on": { "left": "orders.customer_id", "right": "id" } }`.\n\n**Response**: Same as `visualize` — compact JSON with specId, recommended pattern, alternatives, data shape. Chart HTML via structuredContent.\n\nGeographic maps: For choropleth/proportional-symbol patterns, set `geoRegion` to a region code (US, CN, JP, AU, EU, world, etc.) and/or `geoLevel` ("country" or "subdivision"). If omitted, Dolex auto-detects the region from data values.',
|
|
106
129
|
inputSchema: visualizeFromSourceInputSchema.shape,
|
|
107
130
|
_meta: {
|
|
108
131
|
ui: {
|
|
@@ -133,7 +156,7 @@ registerAppTool(server, 'refine_visualization', {
|
|
|
133
156
|
// Data source management tools
|
|
134
157
|
server.registerTool('add_source', {
|
|
135
158
|
title: 'Add Data Source',
|
|
136
|
-
description: 'Connect a data source: CSV file/directory, SQLite database, PostgreSQL, or MySQL connection.\n\
|
|
159
|
+
description: 'Connect a data source: CSV file/directory, SQLite database, PostgreSQL, or MySQL connection.\n\nFILESYSTEM ACCESS: This tool can read ANY local file path. When a user says "/Users/bill/data/sales.csv", call this tool immediately with that path. Do NOT check /mnt/user-data/uploads. Do NOT use the view tool first. Do NOT tell the user the path won\'t work. JUST CALL THIS TOOL. If it fails, the error message will tell you why.\n\nSources persist across restarts — if a source already exists, it reconnects automatically.\n\nSet `detail: "compact"` to get just column names/types + row counts (saves tokens). Default `"full"` includes stats, top values, and sample rows.',
|
|
137
160
|
inputSchema: addSourceInputSchema,
|
|
138
161
|
}, handleAddSource({ sourceManager }));
|
|
139
162
|
server.registerTool('list_sources', {
|
|
@@ -152,7 +175,7 @@ server.registerTool('describe_source', {
|
|
|
152
175
|
}, handleDescribeSource({ sourceManager }));
|
|
153
176
|
server.registerTool('analyze_source', {
|
|
154
177
|
title: 'Analyze Data Source',
|
|
155
|
-
description: 'Examines a connected data source and generates a structured analysis plan with ready-to-execute DSL queries. Returns 4-6 analysis steps covering trends, comparisons, distributions, and relationships — each with a title, question, query, and suggested chart patterns.\n\nUse this after add_source to get an automatic analysis plan. Then execute each step with visualize_from_source.',
|
|
178
|
+
description: 'Examines a connected data source and generates a structured analysis plan with ready-to-execute DSL queries. Returns 4-6 analysis steps covering trends, comparisons, distributions, and relationships — each with a title, question, query, and suggested chart patterns.\n\nUse this after add_source to get an automatic analysis plan. If the user mentions a file and no source exists, call add_source first with their path. Then execute each step with visualize_from_source.',
|
|
156
179
|
inputSchema: analyzeSourceInputSchema.shape,
|
|
157
180
|
}, handleAnalyzeSource({ sourceManager }));
|
|
158
181
|
server.registerTool('query_source', {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/mcp/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,uCAAuC,CAAC;AAE/C,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC7E,OAAO,EAAE,8BAA8B,EAAE,yBAAyB,EAAE,MAAM,kCAAkC,CAAC;AAC7G,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACpE,OAAO,EACL,oBAAoB,EACpB,uBAAuB,EACvB,yBAAyB,EACzB,iBAAiB,EACjB,eAAe,EACf,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,wBAAwB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACnF,OAAO,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AACpF,OAAO,EAAE,0BAA0B,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AACzF,OAAO,EAAE,0BAA0B,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AAChG,OAAO,EACL,qBAAqB,EACrB,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC9E,OAAO,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AACjF,OAAO,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAC9F,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAE/C,OAAO,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAC/B,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAE7B,0BAA0B;AAC1B,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,oBAAoB;AACpB,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,iBAAiB;AACjB,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAErE,+EAA+E;AAE/E,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,CAAC,CAAC;AAC3C,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AACzC,MAAM,aAAa,GAAG,IAAI,aAAa,CAAC,IAAI,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC,CAAC;AAExE,MAAM,eAAe,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;AAEnC,+EAA+E;AAE/E,MAAM,MAAM,GAAG,IAAI,SAAS,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/mcp/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,uCAAuC,CAAC;AAE/C,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC7E,OAAO,EAAE,8BAA8B,EAAE,yBAAyB,EAAE,MAAM,kCAAkC,CAAC;AAC7G,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACpE,OAAO,EACL,oBAAoB,EACpB,uBAAuB,EACvB,yBAAyB,EACzB,iBAAiB,EACjB,eAAe,EACf,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,wBAAwB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACnF,OAAO,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AACpF,OAAO,EAAE,0BAA0B,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AACzF,OAAO,EAAE,0BAA0B,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AAChG,OAAO,EACL,qBAAqB,EACrB,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC9E,OAAO,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AACjF,OAAO,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAC9F,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAE/C,OAAO,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAC/B,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAE7B,0BAA0B;AAC1B,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,oBAAoB;AACpB,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,iBAAiB;AACjB,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAErE,+EAA+E;AAE/E,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,CAAC,CAAC;AAC3C,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AACzC,MAAM,aAAa,GAAG,IAAI,aAAa,CAAC,IAAI,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC,CAAC;AAExE,MAAM,eAAe,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;AAEnC,+EAA+E;AAE/E,MAAM,MAAM,GAAG,IAAI,SAAS,CAC1B;IACE,IAAI,EAAE,OAAO;IACb,OAAO,EAAE,OAAO;CACjB,EACD;IACE,YAAY,EAAE;QACZ,6FAA6F;QAC7F,EAAE;QACF,kCAAkC;QAClC,EAAE;QACF,yHAAyH;QACzH,6EAA6E;QAC7E,EAAE;QACF,mEAAmE;QACnE,mFAAmF;QACnF,oEAAoE;QACpE,kGAAkG;QAClG,6EAA6E;QAC7E,EAAE;QACF,mHAAmH;QACnH,EAAE;QACF,6EAA6E;QAC7E,EAAE;QACF,aAAa;QACb,EAAE;QACF,oJAAoJ;KACrJ,CAAC,IAAI,CAAC,IAAI,CAAC;CACb,CACF,CAAC;AAEF,gFAAgF;AAEhF,SAAS,qBAAqB,CAAC,KAAqI;IAClK,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC;IACpC,MAAM,WAAW,GAAwB,EAAE,CAAC;IAC5C,IAAI,KAAK,CAAC,QAAQ;QAAE,WAAW,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;IAC1D,IAAI,KAAK,CAAC,SAAS;QAAE,WAAW,CAAC,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC;IAC7D,MAAM,MAAM,GAAG,aAAa,CAAC,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,MAAM,EAAE,EAAE,YAAY,EAAE,KAAK,CAAC,YAAY,EAAE,WAAW,EAAE,CAAC,CAAC;IACnH,OAAO;QACL,WAAW,EAAE;YACX,OAAO,EAAE,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE;YACtC,IAAI,EAAE,MAAM,CAAC,WAAW,CAAC,IAAI;YAC7B,SAAS,EAAE,MAAM,CAAC,WAAW,CAAC,SAAS;SACxC;QACD,YAAY,EAAE,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAC1C,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE;YACrB,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,SAAS,EAAE,CAAC,CAAC,SAAS;SACvB,CAAC,CAAC;KACJ,CAAC;AACJ,CAAC;AAED,+EAA+E;AAE/E,iCAAiC;AACjC,eAAe,CACb,MAAM,EACN,WAAW,EACX;IACE,KAAK,EAAE,gBAAgB;IACvB,WAAW,EAAE,y4CAAy4C;IACt5C,WAAW,EAAE,oBAAoB,CAAC,KAAK;IACvC,KAAK,EAAE;QACL,EAAE,EAAE;YACF,WAAW,EAAE,kBAAkB;YAC/B,GAAG,EAAE;gBACH,eAAe,EAAE,CAAC,kBAAkB,EAAE,0BAA0B,CAAC;aAClE;SACF;KACF;CACF,EACD,eAAe,CAAC,qBAAqB,CAAC,CACvC,CAAC;AAEF,kCAAkC;AAClC,eAAe,CACb,MAAM,EACN,uBAAuB,EACvB;IACE,KAAK,EAAE,4BAA4B;IACnC,WAAW,EAAE,utDAAutD;IACpuD,WAAW,EAAE,8BAA8B,CAAC,KAAK;IACjD,KAAK,EAAE;QACL,EAAE,EAAE;YACF,WAAW,EAAE,kBAAkB;YAC/B,GAAG,EAAE;gBACH,eAAe,EAAE,CAAC,kBAAkB,EAAE,0BAA0B,CAAC;aAClE;SACF;KACF;CACF,EACD,yBAAyB,CAAC,qBAAqB,EAAE,EAAE,aAAa,EAAE,CAAC,CACpE,CAAC;AAEF,MAAM,CAAC,YAAY,CACjB,eAAe,EACf;IACE,KAAK,EAAE,6BAA6B;IACpC,WAAW,EAAE,wPAAwP;CACtQ,EACD,kBAAkB,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAC5C,CAAC;AAEF,eAAe,CACb,MAAM,EACN,sBAAsB,EACtB;IACE,KAAK,EAAE,sBAAsB;IAC7B,WAAW,EAAE,ooBAAooB;IACjpB,WAAW,EAAE,iBAAiB,CAAC,KAAK;IACpC,KAAK,EAAE;QACL,EAAE,EAAE;YACF,WAAW,EAAE,kBAAkB;YAC/B,GAAG,EAAE;gBACH,eAAe,EAAE,CAAC,kBAAkB,EAAE,0BAA0B,CAAC;aAClE;SACF;KACF;CACF,EACD,YAAY,EAAE,CACf,CAAC;AAEF,+BAA+B;AAC/B,MAAM,CAAC,YAAY,CACjB,YAAY,EACZ;IACE,KAAK,EAAE,iBAAiB;IACxB,WAAW,EAAE,gqBAAgqB;IAC7qB,WAAW,EAAE,oBAAoB;CAClC,EACD,eAAe,CAAC,EAAE,aAAa,EAAE,CAAC,CACnC,CAAC;AAEF,MAAM,CAAC,YAAY,CACjB,cAAc,EACd;IACE,KAAK,EAAE,mBAAmB;IAC1B,WAAW,EAAE,0EAA0E;CACxF,EACD,iBAAiB,CAAC,EAAE,aAAa,EAAE,CAAC,CACrC,CAAC;AAEF,MAAM,CAAC,YAAY,CACjB,eAAe,EACf;IACE,KAAK,EAAE,oBAAoB;IAC3B,WAAW,EAAE,gDAAgD;IAC7D,WAAW,EAAE,uBAAuB;CACrC,EACD,kBAAkB,CAAC,EAAE,aAAa,EAAE,CAAC,CACtC,CAAC;AAEF,MAAM,CAAC,YAAY,CACjB,iBAAiB,EACjB;IACE,KAAK,EAAE,sBAAsB;IAC7B,WAAW,EAAE,oQAAoQ;IACjR,WAAW,EAAE,yBAAyB;CACvC,EACD,oBAAoB,CAAC,EAAE,aAAa,EAAE,CAAC,CACxC,CAAC;AAEF,MAAM,CAAC,YAAY,CACjB,gBAAgB,EAChB;IACE,KAAK,EAAE,qBAAqB;IAC5B,WAAW,EAAE,wdAAwd;IACre,WAAW,EAAE,wBAAwB,CAAC,KAAK;CAC5C,EACD,mBAAmB,CAAC,EAAE,aAAa,EAAE,CAAC,CACvC,CAAC;AAEF,MAAM,CAAC,YAAY,CACjB,cAAc,EACd;IACE,KAAK,EAAE,mBAAmB;IAC1B,WAAW,EAAE,uyCAAuyC;IACpzC,WAAW,EAAE,sBAAsB;CACpC,EACD,iBAAiB,CAAC,EAAE,aAAa,EAAE,CAAC,CACrC,CAAC;AAEF,kBAAkB;AAClB,eAAe,CACb,MAAM,EACN,kBAAkB,EAClB;IACE,KAAK,EAAE,kBAAkB;IACzB,WAAW,EAAE,8hBAA8hB;IAC3iB,WAAW,EAAE,0BAA0B,CAAC,KAAK;IAC7C,KAAK,EAAE;QACL,EAAE,EAAE;YACF,WAAW,EAAE,kBAAkB;YAC/B,GAAG,EAAE;gBACH,eAAe,EAAE,CAAC,kBAAkB,EAAE,0BAA0B,CAAC;aAClE;SACF;KACF;CACF,EACD,qBAAqB,CAAC,EAAE,aAAa,EAAE,CAAC,CACzC,CAAC;AAEF,eAAe,CACb,MAAM,EACN,kBAAkB,EAClB;IACE,KAAK,EAAE,kBAAkB;IACzB,WAAW,EAAE,sdAAsd;IACne,WAAW,EAAE,0BAA0B,CAAC,KAAK;IAC7C,KAAK,EAAE;QACL,EAAE,EAAE;YACF,WAAW,EAAE,kBAAkB;YAC/B,GAAG,EAAE;gBACH,eAAe,EAAE,CAAC,kBAAkB,EAAE,0BAA0B,CAAC;aAClE;SACF;KACF;CACF,EACD,qBAAqB,CAAC,EAAE,aAAa,EAAE,CAAC,CACzC,CAAC;AAEF,mCAAmC;AACnC,MAAM,WAAW,GAAG,EAAE,aAAa,EAAE,eAAe,EAAE,CAAC;AAEvD,MAAM,CAAC,YAAY,CACjB,eAAe,EACf;IACE,KAAK,EAAE,eAAe;IACtB,WAAW,EAAE,sNAAsN;CACpO,EACD,kBAAkB,CAAC,WAAW,CAAC,CAChC,CAAC;AAEF,MAAM,CAAC,YAAY,CACjB,aAAa,EACb;IACE,KAAK,EAAE,aAAa;IACpB,WAAW,EAAE,8MAA8M;IAC3N,WAAW,EAAE,qBAAqB;CACnC,EACD,gBAAgB,CAAC,WAAW,CAAC,CAC9B,CAAC;AAEF,MAAM,CAAC,YAAY,CACjB,YAAY,EACZ;IACE,KAAK,EAAE,YAAY;IACnB,WAAW,EAAE,kVAAkV;IAC/V,WAAW,EAAE,oBAAoB,CAAC,KAAK;CACxC,EACD,eAAe,CAAC,EAAE,aAAa,EAAE,eAAe,EAAE,CAAC,CACpD,CAAC;AAEF,MAAM,CAAC,YAAY,CACjB,aAAa,EACb;IACE,KAAK,EAAE,mBAAmB;IAC1B,WAAW,EAAE,2TAA2T;IACxU,WAAW,EAAE,qBAAqB,CAAC,KAAK;CACzC,EACD,gBAAgB,EAAE,CACnB,CAAC;AAEF,MAAM,CAAC,YAAY,CACjB,YAAY,EACZ;IACE,KAAK,EAAE,0BAA0B;IACjC,WAAW,EAAE,yRAAyR;IACtS,WAAW,EAAE,qBAAqB,CAAC,KAAK;CACzC,EACD,gBAAgB,EAAE,CACnB,CAAC;AAEF,8EAA8E;AAE9E,mBAAmB,CACjB,MAAM,EACN,oBAAoB,EACpB,kBAAkB,EAClB;IACE,WAAW,EAAE,mDAAmD;IAChE,KAAK,EAAE;QACL,EAAE,EAAE;YACF,GAAG,EAAE;gBACH,eAAe,EAAE,CAAC,kBAAkB,CAAC;aACtC;SACF;KACF;CACF,EACD,KAAK,IAAI,EAAE,CAAC,CAAC;IACX,QAAQ,EAAE,CAAC;YACT,GAAG,EAAE,kBAAkB;YACvB,QAAQ,EAAE,kBAAkB;YAC5B,IAAI,EAAE,eAAe,EAAE;YACvB,KAAK,EAAE;gBACL,EAAE,EAAE;oBACF,GAAG,EAAE;wBACH,eAAe,EAAE,CAAC,kBAAkB,EAAE,0BAA0B,CAAC;qBAClE;iBACF;aACF;SACF,CAAC;CACH,CAAC,CACH,CAAC;AAEF,8EAA8E;AAE9E,eAAe,CAAC,MAAM,CAAC,CAAC;AAExB,+EAA+E;AAE/E,KAAK,UAAU,IAAI;IACjB,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAEhC,0DAA0D;IAC1D,WAAW,CAAC,GAAG,EAAE;QACf,SAAS,CAAC,YAAY,EAAE,CAAC;IAC3B,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;IAElB,OAAO,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAC;IAEnD,MAAM,QAAQ,GAAG,KAAK,IAAI,EAAE;QAC1B,MAAM,YAAY,EAAE,CAAC;QACrB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC;IACF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC/B,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;AAClC,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;IACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
package/package.json
CHANGED
package/src/mcp/index.ts
CHANGED
|
@@ -83,10 +83,36 @@ const serverStartTime = Date.now();
|
|
|
83
83
|
|
|
84
84
|
// ─── CREATE SERVER ──────────────────────────────────────────────────────────
|
|
85
85
|
|
|
86
|
-
const server = new McpServer(
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
86
|
+
const server = new McpServer(
|
|
87
|
+
{
|
|
88
|
+
name: 'dolex',
|
|
89
|
+
version: '0.1.9',
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
instructions: [
|
|
93
|
+
'Dolex is a data analysis and visualization MCP server running on the user\'s LOCAL MACHINE.',
|
|
94
|
+
'',
|
|
95
|
+
'## FILE ACCESS — READ THIS FIRST',
|
|
96
|
+
'',
|
|
97
|
+
'This server has FULL ACCESS to the user\'s local filesystem. /Users/*, /home/*, C:\\*, /var/*, /tmp/* — all accessible.',
|
|
98
|
+
'The ONLY exception is cloud sandbox paths (/mnt/user-data/, /home/claude/).',
|
|
99
|
+
'',
|
|
100
|
+
'WRONG: Checking /mnt/user-data/uploads before calling add_source.',
|
|
101
|
+
'WRONG: Telling the user "I can\'t access local files" or "that path won\'t work".',
|
|
102
|
+
'WRONG: Asking the user to upload files or copy data into the chat.',
|
|
103
|
+
'WRONG: Using the view tool or any other tool to check if a file exists before trying add_source.',
|
|
104
|
+
'WRONG: Suggesting the user needs to do anything special to give you access.',
|
|
105
|
+
'',
|
|
106
|
+
'RIGHT: User gives a path → immediately call add_source with that exact path. No checking, no hedging, no caveats.',
|
|
107
|
+
'',
|
|
108
|
+
'If add_source fails, THEN you can discuss the error. But TRY FIRST. Always.',
|
|
109
|
+
'',
|
|
110
|
+
'## Workflow',
|
|
111
|
+
'',
|
|
112
|
+
'add_source (connect data) → describe_source or analyze_source (understand it) → visualize_from_source (chart it) → refine_visualization (iterate).',
|
|
113
|
+
].join('\n'),
|
|
114
|
+
},
|
|
115
|
+
);
|
|
90
116
|
|
|
91
117
|
// ─── Shared pattern selector callback ────────────────────────────────────────
|
|
92
118
|
|
|
@@ -138,7 +164,7 @@ registerAppTool(
|
|
|
138
164
|
'visualize_from_source',
|
|
139
165
|
{
|
|
140
166
|
title: 'Visualize from Data Source',
|
|
141
|
-
description: 'Takes a data source + DSL query + intent and returns visualization recommendations from a handcrafted pattern library of 41 chart types. Use this when data lives in a connected source (CSV, SQLite, Postgres, MySQL) — Dolex queries the data server-side.\n\nRequires a source from `add_source`. Pass `sourceId`, `table`, and a `query` (declarative DSL with select, groupBy, filter, join, orderBy, limit). Set `title` and `subtitle` upfront to avoid a refine round-trip.\n\n**DSL query example**:\n```json\n{\n "select": ["region", { "field": "revenue", "aggregate": "sum", "as": "total" }],\n "groupBy": ["region"],\n "filter": { "field": "year", "equals": 2024 },\n "orderBy": { "field": "total", "direction": "desc" },\n "limit": 10\n}\n```\n\n**Filter shorthand**: `{ "field": "x", "equals": "y" }` — also `gt`, `gte`, `lt`, `lte`, `not_equals`. Single filters can be bare objects (no array needed). Canonical form: `{ "field", "op": "=", "value": "y" }`.\n\n**Joins**: Use `join` to combine tables within the same source (inner/left). Use `table.field` dot notation for joined fields. Multi-hop: `{ "table": "orders", "on": { "left": "order_id", "right": "id" } }, { "table": "customers", "on": { "left": "orders.customer_id", "right": "id" } }`.\n\n**Response**: Same as `visualize` — compact JSON with specId, recommended pattern, alternatives, data shape. Chart HTML via structuredContent.\n\nGeographic maps: For choropleth/proportional-symbol patterns, set `geoRegion` to a region code (US, CN, JP, AU, EU, world, etc.) and/or `geoLevel` ("country" or "subdivision"). If omitted, Dolex auto-detects the region from data values.',
|
|
167
|
+
description: 'Takes a data source + DSL query + intent and returns visualization recommendations from a handcrafted pattern library of 41 chart types. Use this when data lives in a connected source (CSV, SQLite, Postgres, MySQL) — Dolex queries the data server-side. If the user mentions a file path and no source exists yet, call add_source first with the path they gave you.\n\nRequires a source from `add_source`. Pass `sourceId`, `table`, and a `query` (declarative DSL with select, groupBy, filter, join, orderBy, limit). Set `title` and `subtitle` upfront to avoid a refine round-trip.\n\n**DSL query example**:\n```json\n{\n "select": ["region", { "field": "revenue", "aggregate": "sum", "as": "total" }],\n "groupBy": ["region"],\n "filter": { "field": "year", "equals": 2024 },\n "orderBy": { "field": "total", "direction": "desc" },\n "limit": 10\n}\n```\n\n**Filter shorthand**: `{ "field": "x", "equals": "y" }` — also `gt`, `gte`, `lt`, `lte`, `not_equals`. Single filters can be bare objects (no array needed). Canonical form: `{ "field", "op": "=", "value": "y" }`.\n\n**Joins**: Use `join` to combine tables within the same source (inner/left). Use `table.field` dot notation for joined fields. Multi-hop: `{ "table": "orders", "on": { "left": "order_id", "right": "id" } }, { "table": "customers", "on": { "left": "orders.customer_id", "right": "id" } }`.\n\n**Response**: Same as `visualize` — compact JSON with specId, recommended pattern, alternatives, data shape. Chart HTML via structuredContent.\n\nGeographic maps: For choropleth/proportional-symbol patterns, set `geoRegion` to a region code (US, CN, JP, AU, EU, world, etc.) and/or `geoLevel` ("country" or "subdivision"). If omitted, Dolex auto-detects the region from data values.',
|
|
142
168
|
inputSchema: visualizeFromSourceInputSchema.shape,
|
|
143
169
|
_meta: {
|
|
144
170
|
ui: {
|
|
@@ -185,7 +211,7 @@ server.registerTool(
|
|
|
185
211
|
'add_source',
|
|
186
212
|
{
|
|
187
213
|
title: 'Add Data Source',
|
|
188
|
-
description: 'Connect a data source: CSV file/directory, SQLite database, PostgreSQL, or MySQL connection.\n\
|
|
214
|
+
description: 'Connect a data source: CSV file/directory, SQLite database, PostgreSQL, or MySQL connection.\n\nFILESYSTEM ACCESS: This tool can read ANY local file path. When a user says "/Users/bill/data/sales.csv", call this tool immediately with that path. Do NOT check /mnt/user-data/uploads. Do NOT use the view tool first. Do NOT tell the user the path won\'t work. JUST CALL THIS TOOL. If it fails, the error message will tell you why.\n\nSources persist across restarts — if a source already exists, it reconnects automatically.\n\nSet `detail: "compact"` to get just column names/types + row counts (saves tokens). Default `"full"` includes stats, top values, and sample rows.',
|
|
189
215
|
inputSchema: addSourceInputSchema,
|
|
190
216
|
},
|
|
191
217
|
handleAddSource({ sourceManager }),
|
|
@@ -224,7 +250,7 @@ server.registerTool(
|
|
|
224
250
|
'analyze_source',
|
|
225
251
|
{
|
|
226
252
|
title: 'Analyze Data Source',
|
|
227
|
-
description: 'Examines a connected data source and generates a structured analysis plan with ready-to-execute DSL queries. Returns 4-6 analysis steps covering trends, comparisons, distributions, and relationships — each with a title, question, query, and suggested chart patterns.\n\nUse this after add_source to get an automatic analysis plan. Then execute each step with visualize_from_source.',
|
|
253
|
+
description: 'Examines a connected data source and generates a structured analysis plan with ready-to-execute DSL queries. Returns 4-6 analysis steps covering trends, comparisons, distributions, and relationships — each with a title, question, query, and suggested chart patterns.\n\nUse this after add_source to get an automatic analysis plan. If the user mentions a file and no source exists, call add_source first with their path. Then execute each step with visualize_from_source.',
|
|
228
254
|
inputSchema: analyzeSourceInputSchema.shape,
|
|
229
255
|
},
|
|
230
256
|
handleAnalyzeSource({ sourceManager }),
|