@qe-mcp/server-ena 0.1.6 → 0.1.7
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/package.json +2 -2
- package/server.js +32 -1
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qe-mcp/server-ena",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "MCP server for Epistemic Network Analysis
|
|
3
|
+
"version": "0.1.7",
|
|
4
|
+
"description": "MCP server for Epistemic Network Analysis \u2014 WASM backend, zero Python dependency",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "server.js",
|
|
7
7
|
"bin": {
|
package/server.js
CHANGED
|
@@ -506,10 +506,35 @@ function toolInspect({ data_path, data_csv }) {
|
|
|
506
506
|
recommended = true;
|
|
507
507
|
confidence = 'low';
|
|
508
508
|
reason = `Found ${nCodes} binary code columns but no clear unit/conversation columns by name.`;
|
|
509
|
+
} else if (nCodes === 1) {
|
|
510
|
+
recommended = false;
|
|
511
|
+
confidence = 'low';
|
|
512
|
+
reason = `Only 1 binary code column was detected. ENA models co-occurrence ` +
|
|
513
|
+
`*between* codes, so it needs at least 2 (ideally 4+) binary presence/absence columns.`;
|
|
509
514
|
} else {
|
|
510
515
|
recommended = false;
|
|
511
516
|
confidence = 'low';
|
|
512
|
-
reason = `
|
|
517
|
+
reason = `No binary (0/1) code columns were detected in this dataset. ENA models the ` +
|
|
518
|
+
`co-occurrence of *codes* — columns that mark, for each row, whether a concept, ` +
|
|
519
|
+
`behavior, or feature is present (1) or absent (0). This dataset has none, so ENA ` +
|
|
520
|
+
`cannot be run on it as-is.`;
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
// Actionable guidance for the not-applicable cases, so Claude can explain
|
|
524
|
+
// to the user *why* ENA doesn't fit and what would be needed.
|
|
525
|
+
let guidance = null;
|
|
526
|
+
if (!recommended) {
|
|
527
|
+
const needs =
|
|
528
|
+
'For a dataset to be analyzable with ENA it needs:\n' +
|
|
529
|
+
' • 2+ binary (0/1) CODE columns — each marking presence/absence of a concept or behavior per row\n' +
|
|
530
|
+
' • a UNIT column identifying who or what each row belongs to\n' +
|
|
531
|
+
' • a CONVERSATION column grouping rows into episodes';
|
|
532
|
+
guidance = nCodes === 0
|
|
533
|
+
? `${needs}\n\nThis dataset appears to contain no coded columns. If it is uncoded text or ` +
|
|
534
|
+
`raw events, each concept of interest must first be turned into a 0/1 column (a ` +
|
|
535
|
+
`qualitative-coding step) before ENA can be applied. If you expected coded columns, ` +
|
|
536
|
+
`check that they use 0/1 values rather than text labels.`
|
|
537
|
+
: `${needs}\n\nAdd more binary code columns, or use a standard statistical analysis instead.`;
|
|
513
538
|
}
|
|
514
539
|
|
|
515
540
|
let nextStep = {};
|
|
@@ -554,6 +579,8 @@ function toolInspect({ data_path, data_csv }) {
|
|
|
554
579
|
suggestedConvos.slice(0,3).map(c => `${c.column} (n=${c.n_unique}, score=${c.score})`).join(', '));
|
|
555
580
|
for (const [col, vals] of Object.entries(suggestedGroups))
|
|
556
581
|
summaryLines.push(`Likely group column: '${col}' → ${JSON.stringify(vals)}`);
|
|
582
|
+
if (guidance)
|
|
583
|
+
summaryLines.push('', guidance);
|
|
557
584
|
|
|
558
585
|
const privacyNote = isPrivacySafe
|
|
559
586
|
? 'PRIVACY SAFE — data was read from a local file path. No raw row data was sent to Claude; only this analysis result was transmitted.'
|
|
@@ -564,6 +591,7 @@ function toolInspect({ data_path, data_csv }) {
|
|
|
564
591
|
ena_recommended: recommended,
|
|
565
592
|
confidence,
|
|
566
593
|
reason,
|
|
594
|
+
guidance,
|
|
567
595
|
n_rows: nRows,
|
|
568
596
|
n_cols: headers.length,
|
|
569
597
|
suggested_codes: codeCols,
|
|
@@ -1078,6 +1106,9 @@ const TOOLS = [
|
|
|
1078
1106
|
'Inspect a dataset and recommend whether ENA is an appropriate analysis. ' +
|
|
1079
1107
|
'Call this FIRST whenever a user provides tabular data and asks for analysis. ' +
|
|
1080
1108
|
'Returns ena_recommended, confidence, suggested codes/units/conversations, and a ready-to-use next_step call. ' +
|
|
1109
|
+
'When ena_recommended is false, the result includes a "guidance" field explaining why the data is not ENA-shaped ' +
|
|
1110
|
+
'(e.g. no binary code columns) and what would be needed — relay this to the user rather than silently failing or ' +
|
|
1111
|
+
'claiming the connector is unavailable. ' +
|
|
1081
1112
|
'PRIVACY: prefer data_path over data_csv so raw data stays local. ' +
|
|
1082
1113
|
'If the user has not yet indicated whether their data is sensitive, ask before using data_csv. ' +
|
|
1083
1114
|
'If they indicate sensitivity, use ena_profile instead (no raw data transmitted).',
|