visus-mcp 0.3.0 → 0.6.0

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.
Files changed (96) hide show
  1. package/.claude/settings.local.json +22 -0
  2. package/LINKEDIN-STRATEGY.md +367 -0
  3. package/README.md +491 -16
  4. package/ROADMAP.md +167 -30
  5. package/SECURITY-AUDIT-v1.md +277 -0
  6. package/STATUS.md +801 -42
  7. package/TROUBLESHOOT-AUTH-20260322-2019.md +291 -0
  8. package/TROUBLESHOOT-JEST-20260323-1357.md +139 -0
  9. package/TROUBLESHOOT-LAMBDA-20260322-1945.md +183 -0
  10. package/VISUS-CLAUDE-CODE-PROMPT.md +1 -1
  11. package/VISUS-PROJECT-PLAN.md +7 -0
  12. package/dist/browser/playwright-renderer.d.ts.map +1 -1
  13. package/dist/browser/playwright-renderer.js +7 -0
  14. package/dist/browser/playwright-renderer.js.map +1 -1
  15. package/dist/browser/reader.d.ts +31 -0
  16. package/dist/browser/reader.d.ts.map +1 -0
  17. package/dist/browser/reader.js +98 -0
  18. package/dist/browser/reader.js.map +1 -0
  19. package/dist/index.d.ts +1 -1
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.js +37 -5
  22. package/dist/index.js.map +1 -1
  23. package/dist/lambda-handler.d.ts +0 -6
  24. package/dist/lambda-handler.d.ts.map +1 -1
  25. package/dist/lambda-handler.js +97 -25
  26. package/dist/lambda-handler.js.map +1 -1
  27. package/dist/sanitizer/framework-mapper.d.ts +22 -0
  28. package/dist/sanitizer/framework-mapper.d.ts.map +1 -0
  29. package/dist/sanitizer/framework-mapper.js +296 -0
  30. package/dist/sanitizer/framework-mapper.js.map +1 -0
  31. package/dist/sanitizer/index.d.ts +2 -0
  32. package/dist/sanitizer/index.d.ts.map +1 -1
  33. package/dist/sanitizer/index.js +14 -1
  34. package/dist/sanitizer/index.js.map +1 -1
  35. package/dist/sanitizer/patterns.js +1 -1
  36. package/dist/sanitizer/patterns.js.map +1 -1
  37. package/dist/sanitizer/severity-classifier.d.ts +33 -0
  38. package/dist/sanitizer/severity-classifier.d.ts.map +1 -0
  39. package/dist/sanitizer/severity-classifier.js +113 -0
  40. package/dist/sanitizer/severity-classifier.js.map +1 -0
  41. package/dist/sanitizer/threat-reporter.d.ts +65 -0
  42. package/dist/sanitizer/threat-reporter.d.ts.map +1 -0
  43. package/dist/sanitizer/threat-reporter.js +160 -0
  44. package/dist/sanitizer/threat-reporter.js.map +1 -0
  45. package/dist/tools/fetch-structured.d.ts +5 -0
  46. package/dist/tools/fetch-structured.d.ts.map +1 -1
  47. package/dist/tools/fetch-structured.js +54 -6
  48. package/dist/tools/fetch-structured.js.map +1 -1
  49. package/dist/tools/fetch.d.ts +5 -0
  50. package/dist/tools/fetch.d.ts.map +1 -1
  51. package/dist/tools/fetch.js +42 -9
  52. package/dist/tools/fetch.js.map +1 -1
  53. package/dist/tools/read.d.ts +51 -0
  54. package/dist/tools/read.d.ts.map +1 -0
  55. package/dist/tools/read.js +127 -0
  56. package/dist/tools/read.js.map +1 -0
  57. package/dist/tools/search.d.ts +45 -0
  58. package/dist/tools/search.d.ts.map +1 -0
  59. package/dist/tools/search.js +220 -0
  60. package/dist/tools/search.js.map +1 -0
  61. package/dist/types.d.ts +64 -0
  62. package/dist/types.d.ts.map +1 -1
  63. package/dist/types.js.map +1 -1
  64. package/dist/utils/format-converter.d.ts +39 -0
  65. package/dist/utils/format-converter.d.ts.map +1 -0
  66. package/dist/utils/format-converter.js +191 -0
  67. package/dist/utils/format-converter.js.map +1 -0
  68. package/dist/utils/truncate.d.ts +26 -0
  69. package/dist/utils/truncate.d.ts.map +1 -0
  70. package/dist/utils/truncate.js +54 -0
  71. package/dist/utils/truncate.js.map +1 -0
  72. package/infrastructure/stack.ts +55 -6
  73. package/jest.config.js +3 -0
  74. package/package.json +9 -2
  75. package/src/browser/playwright-renderer.ts +8 -0
  76. package/src/browser/reader.ts +129 -0
  77. package/src/index.ts +49 -5
  78. package/src/lambda-handler.ts +131 -26
  79. package/src/sanitizer/framework-mapper.ts +347 -0
  80. package/src/sanitizer/index.ts +18 -1
  81. package/src/sanitizer/patterns.ts +1 -1
  82. package/src/sanitizer/severity-classifier.ts +132 -0
  83. package/src/sanitizer/threat-reporter.ts +261 -0
  84. package/src/tools/fetch-structured.ts +58 -6
  85. package/src/tools/fetch.ts +44 -9
  86. package/src/tools/read.ts +143 -0
  87. package/src/tools/search.ts +263 -0
  88. package/src/types.ts +69 -0
  89. package/src/utils/format-converter.ts +236 -0
  90. package/src/utils/truncate.ts +64 -0
  91. package/tests/auth-smoke.test.ts +480 -0
  92. package/tests/fetch-tool.test.ts +595 -2
  93. package/tests/reader.test.ts +353 -0
  94. package/tests/sanitizer.test.ts +52 -0
  95. package/tests/search.test.ts +456 -0
  96. package/tests/threat-reporter.test.ts +266 -0
@@ -0,0 +1,160 @@
1
+ /**
2
+ * Threat Reporter
3
+ *
4
+ * Generates structured threat reports when prompt injection or PII is detected.
5
+ * Two output layers:
6
+ * 1. TOON-formatted findings array (token-efficient, machine-readable)
7
+ * 2. Markdown compliance report block (human-readable, renders in Claude Desktop)
8
+ *
9
+ * Aligned with:
10
+ * - OWASP LLM Top 10 (2025)
11
+ * - NIST AI 600-1 (Generative AI Profile)
12
+ * - MITRE ATLAS (Adversarial Threat Landscape)
13
+ */
14
+ import { classifySeverity, aggregateSeverity, countBySeverity, getSeverityEmoji } from './severity-classifier.js';
15
+ import { getFrameworkMappings } from './framework-mapper.js';
16
+ /**
17
+ * Generate pattern ID from category name
18
+ * Format: PI-XXX where XXX is a zero-padded number based on hash
19
+ */
20
+ function generatePatternId(category) {
21
+ // Simple hash to generate consistent IDs
22
+ let hash = 0;
23
+ for (let i = 0; i < category.length; i++) {
24
+ hash = ((hash << 5) - hash) + category.charCodeAt(i);
25
+ hash = hash & hash;
26
+ }
27
+ const id = Math.abs(hash) % 1000;
28
+ return `PI-${String(id).padStart(3, '0')}`;
29
+ }
30
+ /**
31
+ * Build findings data structure from pattern detections
32
+ */
33
+ function buildFindings(patternsDetected) {
34
+ return patternsDetected.map((category, index) => {
35
+ const severity = classifySeverity(category);
36
+ const frameworks = getFrameworkMappings(category);
37
+ const patternId = generatePatternId(category);
38
+ return {
39
+ id: index + 1,
40
+ pattern_id: patternId,
41
+ category,
42
+ severity,
43
+ confidence: 0.95, // Default confidence; can be enhanced later
44
+ owasp_llm: frameworks.owasp_llm,
45
+ nist_ai_600_1: frameworks.nist_ai_600_1,
46
+ mitre_atlas: frameworks.mitre_atlas,
47
+ remediation: `Content sanitized. ${category.replace(/_/g, ' ')} removed.`
48
+ };
49
+ });
50
+ }
51
+ /**
52
+ * Generate TOON-encoded findings string
53
+ * Using manual TOON format to avoid Jest ESM compatibility issues
54
+ */
55
+ function generateToonFindings(findings) {
56
+ if (findings.length === 0) {
57
+ return '';
58
+ }
59
+ return generateManualToonFormat(findings);
60
+ }
61
+ /**
62
+ * Fallback manual TOON format generation
63
+ */
64
+ function generateManualToonFormat(findings) {
65
+ const header = `findings[${findings.length}]{id,pattern_id,category,severity,confidence,owasp_llm,nist_ai_600_1,mitre_atlas,remediation}:`;
66
+ const rows = findings.map(f => `${f.id},${f.pattern_id},${f.category},${f.severity},${f.confidence},${f.owasp_llm},${f.nist_ai_600_1},${f.mitre_atlas},${f.remediation}`);
67
+ return `${header}\n${rows.join('\n')}`;
68
+ }
69
+ /**
70
+ * Generate Markdown report block
71
+ */
72
+ function generateMarkdownReport(findings, overallSeverity, bySeverity, piiRedacted, sourceUrl, timestamp) {
73
+ const emoji = getSeverityEmoji(overallSeverity);
74
+ let markdown = '---\n';
75
+ markdown += `## ${emoji} Visus Threat Report\n`;
76
+ markdown += `**Generated:** ${timestamp}\n`;
77
+ markdown += `**Source:** ${sourceUrl}\n`;
78
+ markdown += `**Overall Severity:** ${overallSeverity}\n`;
79
+ markdown += `**Framework:** OWASP LLM Top 10 | NIST AI 600-1 | MITRE ATLAS\n\n`;
80
+ // Findings Summary
81
+ markdown += '### Findings Summary\n';
82
+ markdown += '| Severity | Count |\n';
83
+ markdown += '|---|---|\n';
84
+ markdown += `| ${getSeverityEmoji('CRITICAL')} CRITICAL | ${bySeverity.CRITICAL} |\n`;
85
+ markdown += `| ${getSeverityEmoji('HIGH')} HIGH | ${bySeverity.HIGH} |\n`;
86
+ markdown += `| ${getSeverityEmoji('MEDIUM')} MEDIUM | ${bySeverity.MEDIUM} |\n`;
87
+ markdown += `| ${getSeverityEmoji('LOW')} LOW | ${bySeverity.LOW} |\n\n`;
88
+ // Findings Detail (only if we have findings)
89
+ if (findings.length > 0) {
90
+ markdown += '### Findings Detail\n';
91
+ markdown += '| # | Category | Severity | Confidence | OWASP | MITRE |\n';
92
+ markdown += '|---|---|---|---|---|---|\n';
93
+ for (const finding of findings.slice(0, 10)) { // Limit to first 10 for readability
94
+ const confidencePct = Math.round(finding.confidence * 100);
95
+ const owaspShort = finding.owasp_llm.split(' - ')[0]; // e.g., "LLM01:2025"
96
+ const mitreShort = finding.mitre_atlas.split(' - ')[0]; // e.g., "AML.T0051.000"
97
+ markdown += `| ${finding.id} | ${finding.category} | ${finding.severity} | ${confidencePct}% | ${owaspShort} | ${mitreShort} |\n`;
98
+ }
99
+ if (findings.length > 10) {
100
+ markdown += `\n*...and ${findings.length - 10} more findings*\n`;
101
+ }
102
+ markdown += '\n';
103
+ }
104
+ // PII Redaction
105
+ if (piiRedacted > 0) {
106
+ markdown += '### PII Redaction\n';
107
+ markdown += `- **Items Redacted:** ${piiRedacted}\n`;
108
+ markdown += `- **Standard:** NIST AI 600-1 MS-2.6\n\n`;
109
+ }
110
+ // Remediation Status
111
+ markdown += '### Remediation Status\n';
112
+ markdown += '✅ All findings sanitized. Content delivered clean.\n\n';
113
+ // TODO: PDF export hook for future visus_report tool
114
+ // This is where the PDF generation would be triggered in Phase 3
115
+ markdown += '*Report generated by Visus MCP — Security-first web access for Claude*\n';
116
+ markdown += '---\n';
117
+ return markdown;
118
+ }
119
+ /**
120
+ * Generate threat report (main entry point)
121
+ *
122
+ * Returns null if no findings (injections_removed === 0 AND pii_redacted === 0)
123
+ */
124
+ export function generateThreatReport(input) {
125
+ const { patterns_detected, pii_redacted, source_url, timestamp = new Date().toISOString() } = input;
126
+ // Omit threat report if nothing was found
127
+ if (patterns_detected.length === 0 && pii_redacted === 0) {
128
+ return null;
129
+ }
130
+ // Build findings from detected patterns
131
+ const findings = buildFindings(patterns_detected);
132
+ // Calculate severity
133
+ const severityFindings = findings.map(f => ({
134
+ pattern_category: f.category,
135
+ severity: f.severity
136
+ }));
137
+ const overallSeverity = aggregateSeverity(severityFindings);
138
+ const bySeverity = countBySeverity(severityFindings);
139
+ // Generate TOON findings
140
+ const toonFindings = generateToonFindings(findings);
141
+ // Generate Markdown report
142
+ const markdownReport = generateMarkdownReport(findings, overallSeverity, bySeverity, pii_redacted, source_url, timestamp);
143
+ return {
144
+ generated: timestamp,
145
+ source_url,
146
+ overall_severity: overallSeverity,
147
+ total_findings: findings.length,
148
+ by_severity: bySeverity,
149
+ pii_redacted,
150
+ sanitization_applied: true,
151
+ frameworks: [
152
+ 'OWASP LLM Top 10',
153
+ 'NIST AI 600-1',
154
+ 'MITRE ATLAS'
155
+ ],
156
+ findings_toon: toonFindings,
157
+ report_markdown: markdownReport
158
+ };
159
+ }
160
+ //# sourceMappingURL=threat-reporter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"threat-reporter.js","sourceRoot":"","sources":["../../src/sanitizer/threat-reporter.ts"],"names":[],"mappings":"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"}
@@ -19,6 +19,7 @@ export declare function visusFetchStructured(input: VisusFetchStructuredInput):
19
19
  */
20
20
  export declare const visusFetchStructuredToolDefinition: {
21
21
  name: string;
22
+ title: string;
22
23
  description: string;
23
24
  inputSchema: {
24
25
  type: string;
@@ -42,5 +43,9 @@ export declare const visusFetchStructuredToolDefinition: {
42
43
  };
43
44
  required: string[];
44
45
  };
46
+ readOnlyHint: boolean;
47
+ destructiveHint: boolean;
48
+ idempotentHint: boolean;
49
+ openWorldHint: boolean;
45
50
  };
46
51
  //# sourceMappingURL=fetch-structured.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fetch-structured.d.ts","sourceRoot":"","sources":["../../src/tools/fetch-structured.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,KAAK,EAAE,yBAAyB,EAAE,0BAA0B,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AA2EjG;;;;;GAKG;AACH,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,yBAAyB,GAC/B,OAAO,CAAC,MAAM,CAAC,0BAA0B,EAAE,KAAK,CAAC,CAAC,CA+FpD;AAED;;GAEG;AACH,eAAO,MAAM,kCAAkC;;;;;;;;;;;;;;;;;;;;;;;;;CAyB9C,CAAC"}
1
+ {"version":3,"file":"fetch-structured.d.ts","sourceRoot":"","sources":["../../src/tools/fetch-structured.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAOH,OAAO,KAAK,EAAE,yBAAyB,EAAE,0BAA0B,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AA2EjG;;;;;GAKG;AACH,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,yBAAyB,GAC/B,OAAO,CAAC,MAAM,CAAC,0BAA0B,EAAE,KAAK,CAAC,CAAC,CA4IpD;AAED;;GAEG;AACH,eAAO,MAAM,kCAAkC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8B9C,CAAC"}
@@ -9,6 +9,8 @@
9
9
  import * as cheerio from 'cheerio';
10
10
  import { renderPage } from '../browser/playwright-renderer.js';
11
11
  import { sanitize } from '../sanitizer/index.js';
12
+ import { truncateContent } from '../utils/truncate.js';
13
+ import { generateThreatReport } from '../sanitizer/threat-reporter.js';
12
14
  import { Err } from '../types.js';
13
15
  /**
14
16
  * Extract structured data from HTML using cheerio
@@ -121,10 +123,45 @@ export async function visusFetchStructured(input) {
121
123
  anyContentModified = true;
122
124
  }
123
125
  }
124
- // Step 4: Build output
126
+ // Step 4: Apply token ceiling truncation to combined data (AFTER sanitization)
127
+ // Combine all field values to check total content size
128
+ const combinedData = Object.entries(sanitizedData)
129
+ .map(([key, value]) => `${key}: ${value || 'null'}`)
130
+ .join('\n');
131
+ const truncationResult = truncateContent(combinedData);
132
+ // If truncated, we need to reconstruct sanitizedData from truncated content
133
+ let finalData = sanitizedData;
134
+ if (truncationResult.truncated) {
135
+ // Parse truncated content back into fields
136
+ // This is a simple approach - in production you might want more sophisticated handling
137
+ const lines = truncationResult.content.split('\n');
138
+ finalData = {};
139
+ for (const line of lines) {
140
+ if (line.includes(':')) {
141
+ const [key, ...valueParts] = line.split(':');
142
+ const value = valueParts.join(':').trim();
143
+ if (key.trim() in sanitizedData) {
144
+ finalData[key.trim()] = value === 'null' ? null : value;
145
+ }
146
+ }
147
+ }
148
+ // Preserve any missing fields as null
149
+ for (const key of Object.keys(sanitizedData)) {
150
+ if (!(key in finalData)) {
151
+ finalData[key] = null;
152
+ }
153
+ }
154
+ }
155
+ // Step 5: Generate aggregated threat report
156
+ const threatReport = generateThreatReport({
157
+ patterns_detected: Array.from(allPatternsDetected),
158
+ pii_redacted: Array.from(allPIITypesRedacted).length,
159
+ source_url: url
160
+ });
161
+ // Step 6: Build output
125
162
  const output = {
126
163
  url,
127
- data: sanitizedData,
164
+ data: finalData,
128
165
  sanitization: {
129
166
  patterns_detected: Array.from(allPatternsDetected),
130
167
  pii_types_redacted: Array.from(allPIITypesRedacted),
@@ -138,8 +175,14 @@ export async function visusFetchStructured(input) {
138
175
  content_length_sanitized: Object.values(sanitizedData)
139
176
  .filter(v => v !== null)
140
177
  .join(' ')
141
- .length
142
- }
178
+ .length,
179
+ ...(truncationResult.truncated && {
180
+ truncated: true,
181
+ truncated_at_chars: truncationResult.truncated_at_chars
182
+ })
183
+ },
184
+ // Include threat_report only if findings exist
185
+ ...(threatReport && { threat_report: threatReport })
143
186
  };
144
187
  // Log to stderr if threats detected
145
188
  if (allPatternsDetected.size > 0) {
@@ -162,7 +205,8 @@ export async function visusFetchStructured(input) {
162
205
  */
163
206
  export const visusFetchStructuredToolDefinition = {
164
207
  name: 'visus_fetch_structured',
165
- description: 'Fetch a web page and extract structured data according to a schema. All extracted fields are automatically sanitized for prompt injection and PII before being returned.',
208
+ title: 'Fetch Structured Data (Sanitized)',
209
+ description: 'Fetch a web page and extract structured data according to a schema. SECURITY: All extracted fields pass through prompt injection sanitization (43 pattern categories) and PII redaction BEFORE being returned to the LLM. Each field is independently sanitized to ensure safe consumption of untrusted web content.',
166
210
  inputSchema: {
167
211
  type: 'object',
168
212
  properties: {
@@ -184,6 +228,10 @@ export const visusFetchStructuredToolDefinition = {
184
228
  }
185
229
  },
186
230
  required: ['url', 'schema']
187
- }
231
+ },
232
+ readOnlyHint: true,
233
+ destructiveHint: false,
234
+ idempotentHint: true,
235
+ openWorldHint: true
188
236
  };
189
237
  //# sourceMappingURL=fetch-structured.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"fetch-structured.js","sourceRoot":"","sources":["../../src/tools/fetch-structured.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fetch-structured.js","sourceRoot":"","sources":["../../src/tools/fetch-structured.ts"],"names":[],"mappings":"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"}
@@ -18,6 +18,7 @@ export declare function visusFetch(input: VisusFetchInput): Promise<Result<Visus
18
18
  */
19
19
  export declare const visusFetchToolDefinition: {
20
20
  name: string;
21
+ title: string;
21
22
  description: string;
22
23
  inputSchema: {
23
24
  type: string;
@@ -40,5 +41,9 @@ export declare const visusFetchToolDefinition: {
40
41
  };
41
42
  required: string[];
42
43
  };
44
+ readOnlyHint: boolean;
45
+ destructiveHint: boolean;
46
+ idempotentHint: boolean;
47
+ openWorldHint: boolean;
43
48
  };
44
49
  //# sourceMappingURL=fetch.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../src/tools/fetch.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAG7E;;;;;GAKG;AACH,wBAAsB,UAAU,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAC,CA4DjG;AAED;;GAEG;AACH,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;CAwBpC,CAAC"}
1
+ {"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../src/tools/fetch.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAG7E;;;;;GAKG;AACH,wBAAsB,UAAU,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAC,CAwFjG;AAED;;GAEG;AACH,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6BpC,CAAC"}
@@ -7,6 +7,8 @@
7
7
  */
8
8
  import { renderPage } from '../browser/playwright-renderer.js';
9
9
  import { sanitize } from '../sanitizer/index.js';
10
+ import { truncateContent } from '../utils/truncate.js';
11
+ import { detectFormat, convertJson, convertXml, convertRss } from '../utils/format-converter.js';
10
12
  import { Err } from '../types.js';
11
13
  /**
12
14
  * visus_fetch tool implementation
@@ -29,15 +31,33 @@ export async function visusFetch(input) {
29
31
  if (!renderResult.ok) {
30
32
  return Err(renderResult.error);
31
33
  }
32
- const { html, title } = renderResult.value;
34
+ const { html, title, contentType } = renderResult.value;
33
35
  const rawContent = html || '';
34
- // Step 2: CRITICAL - Sanitize content (injection detection + PII redaction with allowlisting)
36
+ // Step 2: Detect format and apply format-appropriate conversion
37
+ const detectedContentType = contentType || 'text/html';
38
+ const formatType = detectFormat(detectedContentType);
39
+ let processedContent = rawContent;
40
+ // Apply format-specific conversion (skip Readability for non-HTML)
41
+ if (formatType === 'json') {
42
+ processedContent = convertJson(rawContent);
43
+ }
44
+ else if (formatType === 'xml') {
45
+ processedContent = convertXml(rawContent);
46
+ }
47
+ else if (formatType === 'rss') {
48
+ processedContent = convertRss(rawContent);
49
+ }
50
+ // For 'html' format, processedContent remains as rawContent
51
+ // Step 3: CRITICAL - Sanitize content (injection detection + PII redaction with allowlisting)
35
52
  // This step CANNOT be skipped or bypassed
36
- const sanitizationResult = sanitize(rawContent, url);
37
- // Step 3: Build output
53
+ const sanitizationResult = sanitize(processedContent, url);
54
+ // Step 3: Apply token ceiling truncation (AFTER sanitization)
55
+ // Anthropic MCP Directory enforces 25,000 token response limit
56
+ const truncationResult = truncateContent(sanitizationResult.content);
57
+ // Step 4: Build output
38
58
  const output = {
39
59
  url,
40
- content: sanitizationResult.content,
60
+ content: truncationResult.content,
41
61
  sanitization: {
42
62
  patterns_detected: sanitizationResult.sanitization.patterns_detected,
43
63
  pii_types_redacted: sanitizationResult.sanitization.pii_types_redacted,
@@ -48,8 +68,16 @@ export async function visusFetch(input) {
48
68
  title: title || 'Untitled',
49
69
  fetched_at: new Date().toISOString(),
50
70
  content_length_original: sanitizationResult.metadata.original_length,
51
- content_length_sanitized: sanitizationResult.metadata.sanitized_length
52
- }
71
+ content_length_sanitized: sanitizationResult.metadata.sanitized_length,
72
+ format_detected: formatType,
73
+ content_type: detectedContentType,
74
+ ...(truncationResult.truncated && {
75
+ truncated: true,
76
+ truncated_at_chars: truncationResult.truncated_at_chars
77
+ })
78
+ },
79
+ // Include threat_report only if findings exist
80
+ ...(sanitizationResult.threat_report && { threat_report: sanitizationResult.threat_report })
53
81
  };
54
82
  // Log to stderr if critical threats detected
55
83
  if (sanitizationResult.metadata.has_critical_threats) {
@@ -72,7 +100,8 @@ export async function visusFetch(input) {
72
100
  */
73
101
  export const visusFetchToolDefinition = {
74
102
  name: 'visus_fetch',
75
- description: 'Fetch and sanitize web page content. Returns clean, injection-free content in markdown or text format. All content is automatically scanned for prompt injection patterns and PII before being returned.',
103
+ title: 'Fetch Web Page (Sanitized)',
104
+ description: 'Fetch and sanitize web page content. Returns clean, injection-free content in markdown or text format. SECURITY: All content passes through prompt injection sanitization (43 pattern categories) and PII redaction BEFORE reaching the LLM. This ensures safe consumption of untrusted web content.',
76
105
  inputSchema: {
77
106
  type: 'object',
78
107
  properties: {
@@ -93,6 +122,10 @@ export const visusFetchToolDefinition = {
93
122
  }
94
123
  },
95
124
  required: ['url']
96
- }
125
+ },
126
+ readOnlyHint: true,
127
+ destructiveHint: false,
128
+ idempotentHint: true,
129
+ openWorldHint: true
97
130
  };
98
131
  //# sourceMappingURL=fetch.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"fetch.js","sourceRoot":"","sources":["../../src/tools/fetch.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fetch.js","sourceRoot":"","sources":["../../src/tools/fetch.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * visus_read MCP Tool
3
+ *
4
+ * Extracts clean article content from a web page using Mozilla Readability,
5
+ * stripping navigation, ads, and boilerplate. Full prompt injection sanitization
6
+ * and PII redaction applied before content reaches the LLM.
7
+ *
8
+ * CRITICAL: ALL content MUST pass through the sanitizer. This cannot be bypassed.
9
+ *
10
+ * Pipeline order:
11
+ * 1. Playwright renders page (full JS execution)
12
+ * 2. Reader extracts main content (reduces input size)
13
+ * 3. Sanitizer runs on clean text
14
+ * 4. Token ceiling applied (24,000 token cap)
15
+ */
16
+ import type { VisusReadInput, VisusReadOutput, Result } from '../types.js';
17
+ /**
18
+ * visus_read tool implementation
19
+ *
20
+ * @param input Tool input parameters
21
+ * @returns Sanitized article content with metadata
22
+ */
23
+ export declare function visusRead(input: VisusReadInput): Promise<Result<VisusReadOutput, Error>>;
24
+ /**
25
+ * MCP tool definition for registration
26
+ */
27
+ export declare const visusReadToolDefinition: {
28
+ name: string;
29
+ title: string;
30
+ description: string;
31
+ inputSchema: {
32
+ type: string;
33
+ properties: {
34
+ url: {
35
+ type: string;
36
+ description: string;
37
+ };
38
+ timeout_ms: {
39
+ type: string;
40
+ description: string;
41
+ default: number;
42
+ };
43
+ };
44
+ required: string[];
45
+ };
46
+ readOnlyHint: boolean;
47
+ destructiveHint: boolean;
48
+ idempotentHint: boolean;
49
+ openWorldHint: boolean;
50
+ };
51
+ //# sourceMappingURL=read.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read.d.ts","sourceRoot":"","sources":["../../src/tools/read.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAMH,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAG3E;;;;;GAKG;AACH,wBAAsB,SAAS,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC,CAqF9F;AAED;;GAEG;AACH,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;CAuBnC,CAAC"}
@@ -0,0 +1,127 @@
1
+ /**
2
+ * visus_read MCP Tool
3
+ *
4
+ * Extracts clean article content from a web page using Mozilla Readability,
5
+ * stripping navigation, ads, and boilerplate. Full prompt injection sanitization
6
+ * and PII redaction applied before content reaches the LLM.
7
+ *
8
+ * CRITICAL: ALL content MUST pass through the sanitizer. This cannot be bypassed.
9
+ *
10
+ * Pipeline order:
11
+ * 1. Playwright renders page (full JS execution)
12
+ * 2. Reader extracts main content (reduces input size)
13
+ * 3. Sanitizer runs on clean text
14
+ * 4. Token ceiling applied (24,000 token cap)
15
+ */
16
+ import { renderPage } from '../browser/playwright-renderer.js';
17
+ import { extractArticle } from '../browser/reader.js';
18
+ import { sanitize } from '../sanitizer/index.js';
19
+ import { truncateContent } from '../utils/truncate.js';
20
+ import { Err } from '../types.js';
21
+ /**
22
+ * visus_read tool implementation
23
+ *
24
+ * @param input Tool input parameters
25
+ * @returns Sanitized article content with metadata
26
+ */
27
+ export async function visusRead(input) {
28
+ const { url, timeout_ms = 10000 } = input;
29
+ // Validate inputs
30
+ if (!url || typeof url !== 'string') {
31
+ return Err(new Error('Invalid input: url must be a non-empty string'));
32
+ }
33
+ try {
34
+ // Step 1: Render the page using Playwright
35
+ const renderResult = await renderPage(url, {
36
+ timeout_ms,
37
+ format: 'html'
38
+ });
39
+ if (!renderResult.ok) {
40
+ return Err(renderResult.error);
41
+ }
42
+ const { html, title: pageTitle } = renderResult.value;
43
+ // Step 2: Extract article content using Readability
44
+ const readerResult = extractArticle(html, url);
45
+ if (!readerResult.ok) {
46
+ return Err(readerResult.error);
47
+ }
48
+ const article = readerResult.value;
49
+ // Step 3: CRITICAL - Sanitize content (injection detection + PII redaction)
50
+ // Sanitization runs AFTER Readability, not before
51
+ // This step CANNOT be skipped or bypassed
52
+ const sanitizationResult = sanitize(article.content, url);
53
+ // Step 4: Apply token ceiling truncation (AFTER sanitization)
54
+ // Anthropic MCP Directory enforces 25,000 token response limit
55
+ const truncationResult = truncateContent(sanitizationResult.content);
56
+ // Step 5: Build output
57
+ const output = {
58
+ url,
59
+ content: truncationResult.content,
60
+ metadata: {
61
+ title: article.title || pageTitle || 'Untitled',
62
+ author: article.byline,
63
+ published: article.publishedTime,
64
+ word_count: article.wordCount,
65
+ reader_mode_available: article.readerModeAvailable,
66
+ sanitized: true,
67
+ injections_removed: sanitizationResult.sanitization.patterns_detected.length,
68
+ pii_redacted: sanitizationResult.sanitization.pii_types_redacted.length,
69
+ truncated: truncationResult.truncated,
70
+ fetched_at: new Date().toISOString()
71
+ },
72
+ // Include threat_report only if findings exist
73
+ ...(sanitizationResult.threat_report && { threat_report: sanitizationResult.threat_report })
74
+ };
75
+ // Log to stderr if critical threats detected
76
+ if (sanitizationResult.metadata.has_critical_threats) {
77
+ console.error(JSON.stringify({
78
+ timestamp: new Date().toISOString(),
79
+ event: 'reader_critical_threat_detected',
80
+ url,
81
+ patterns: sanitizationResult.sanitization.patterns_detected,
82
+ severity_score: sanitizationResult.metadata.severity_score
83
+ }));
84
+ }
85
+ // Log to stderr if reader mode failed (non-article page)
86
+ if (!article.readerModeAvailable) {
87
+ console.error(JSON.stringify({
88
+ timestamp: new Date().toISOString(),
89
+ event: 'reader_mode_fallback',
90
+ url,
91
+ reason: 'Readability could not extract article structure'
92
+ }));
93
+ }
94
+ return { ok: true, value: output };
95
+ }
96
+ catch (error) {
97
+ return Err(error instanceof Error ? error : new Error(String(error)));
98
+ }
99
+ }
100
+ /**
101
+ * MCP tool definition for registration
102
+ */
103
+ export const visusReadToolDefinition = {
104
+ name: 'visus_read',
105
+ title: 'Read Web Page (Reader Mode + Sanitized)',
106
+ description: 'Extracts clean article content from a web page using Mozilla Readability, stripping navigation, ads, and boilerplate. Full prompt injection sanitization and PII redaction applied before content reaches the LLM. Optimized for context-efficient, safe web reading in Claude Desktop.',
107
+ inputSchema: {
108
+ type: 'object',
109
+ properties: {
110
+ url: {
111
+ type: 'string',
112
+ description: 'The URL to fetch (must be http:// or https://)'
113
+ },
114
+ timeout_ms: {
115
+ type: 'number',
116
+ description: 'Request timeout in milliseconds (default: 10000)',
117
+ default: 10000
118
+ }
119
+ },
120
+ required: ['url']
121
+ },
122
+ readOnlyHint: true,
123
+ destructiveHint: false,
124
+ idempotentHint: true,
125
+ openWorldHint: true
126
+ };
127
+ //# sourceMappingURL=read.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read.js","sourceRoot":"","sources":["../../src/tools/read.ts"],"names":[],"mappings":"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"}