visus-mcp 0.2.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 (107) 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 +214 -34
  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 +10 -2
  32. package/dist/sanitizer/index.d.ts.map +1 -1
  33. package/dist/sanitizer/index.js +22 -6
  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/pii-allowlist.d.ts +49 -0
  38. package/dist/sanitizer/pii-allowlist.d.ts.map +1 -0
  39. package/dist/sanitizer/pii-allowlist.js +231 -0
  40. package/dist/sanitizer/pii-allowlist.js.map +1 -0
  41. package/dist/sanitizer/pii-redactor.d.ts +13 -1
  42. package/dist/sanitizer/pii-redactor.d.ts.map +1 -1
  43. package/dist/sanitizer/pii-redactor.js +26 -2
  44. package/dist/sanitizer/pii-redactor.js.map +1 -1
  45. package/dist/sanitizer/severity-classifier.d.ts +33 -0
  46. package/dist/sanitizer/severity-classifier.d.ts.map +1 -0
  47. package/dist/sanitizer/severity-classifier.js +113 -0
  48. package/dist/sanitizer/severity-classifier.js.map +1 -0
  49. package/dist/sanitizer/threat-reporter.d.ts +65 -0
  50. package/dist/sanitizer/threat-reporter.d.ts.map +1 -0
  51. package/dist/sanitizer/threat-reporter.js +160 -0
  52. package/dist/sanitizer/threat-reporter.js.map +1 -0
  53. package/dist/tools/fetch-structured.d.ts +5 -0
  54. package/dist/tools/fetch-structured.d.ts.map +1 -1
  55. package/dist/tools/fetch-structured.js +59 -8
  56. package/dist/tools/fetch-structured.js.map +1 -1
  57. package/dist/tools/fetch.d.ts +5 -0
  58. package/dist/tools/fetch.d.ts.map +1 -1
  59. package/dist/tools/fetch.js +43 -9
  60. package/dist/tools/fetch.js.map +1 -1
  61. package/dist/tools/read.d.ts +51 -0
  62. package/dist/tools/read.d.ts.map +1 -0
  63. package/dist/tools/read.js +127 -0
  64. package/dist/tools/read.js.map +1 -0
  65. package/dist/tools/search.d.ts +45 -0
  66. package/dist/tools/search.d.ts.map +1 -0
  67. package/dist/tools/search.js +220 -0
  68. package/dist/tools/search.js.map +1 -0
  69. package/dist/types.d.ts +74 -0
  70. package/dist/types.d.ts.map +1 -1
  71. package/dist/types.js.map +1 -1
  72. package/dist/utils/format-converter.d.ts +39 -0
  73. package/dist/utils/format-converter.d.ts.map +1 -0
  74. package/dist/utils/format-converter.js +191 -0
  75. package/dist/utils/format-converter.js.map +1 -0
  76. package/dist/utils/truncate.d.ts +26 -0
  77. package/dist/utils/truncate.d.ts.map +1 -0
  78. package/dist/utils/truncate.js +54 -0
  79. package/dist/utils/truncate.js.map +1 -0
  80. package/infrastructure/stack.ts +55 -6
  81. package/jest.config.js +3 -0
  82. package/package.json +9 -2
  83. package/src/browser/playwright-renderer.ts +8 -0
  84. package/src/browser/reader.ts +129 -0
  85. package/src/index.ts +49 -5
  86. package/src/lambda-handler.ts +131 -26
  87. package/src/sanitizer/framework-mapper.ts +347 -0
  88. package/src/sanitizer/index.ts +28 -6
  89. package/src/sanitizer/patterns.ts +1 -1
  90. package/src/sanitizer/pii-allowlist.ts +273 -0
  91. package/src/sanitizer/pii-redactor.ts +43 -2
  92. package/src/sanitizer/severity-classifier.ts +132 -0
  93. package/src/sanitizer/threat-reporter.ts +261 -0
  94. package/src/tools/fetch-structured.ts +63 -8
  95. package/src/tools/fetch.ts +45 -9
  96. package/src/tools/read.ts +143 -0
  97. package/src/tools/search.ts +263 -0
  98. package/src/types.ts +71 -0
  99. package/src/utils/format-converter.ts +236 -0
  100. package/src/utils/truncate.ts +64 -0
  101. package/tests/auth-smoke.test.ts +480 -0
  102. package/tests/fetch-tool.test.ts +595 -2
  103. package/tests/pii-allowlist.test.ts +282 -0
  104. package/tests/reader.test.ts +353 -0
  105. package/tests/sanitizer.test.ts +52 -0
  106. package/tests/search.test.ts +456 -0
  107. 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,CA4FpD;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
@@ -99,33 +101,71 @@ export async function visusFetchStructured(input) {
99
101
  const { title, html } = renderResult.value;
100
102
  // Step 2: Extract structured data from HTML using cheerio
101
103
  const extractedData = extractStructuredData(html, schema);
102
- // Step 3: CRITICAL - Sanitize each extracted field
104
+ // Step 3: CRITICAL - Sanitize each extracted field (with allowlisting)
103
105
  // This step CANNOT be skipped or bypassed
104
106
  const sanitizedData = {};
105
107
  const allPatternsDetected = new Set();
106
108
  const allPIITypesRedacted = new Set();
109
+ const allPIIAllowlisted = [];
107
110
  let anyContentModified = false;
108
111
  for (const [fieldName, value] of Object.entries(extractedData)) {
109
112
  if (value === null) {
110
113
  sanitizedData[fieldName] = null;
111
114
  continue;
112
115
  }
113
- const sanitizationResult = sanitize(value);
116
+ const sanitizationResult = sanitize(value, url);
114
117
  sanitizedData[fieldName] = sanitizationResult.content;
115
118
  // Collect all patterns detected across fields
116
119
  sanitizationResult.sanitization.patterns_detected.forEach(p => allPatternsDetected.add(p));
117
120
  sanitizationResult.sanitization.pii_types_redacted.forEach(p => allPIITypesRedacted.add(p));
121
+ allPIIAllowlisted.push(...sanitizationResult.sanitization.pii_allowlisted);
118
122
  if (sanitizationResult.sanitization.content_modified) {
119
123
  anyContentModified = true;
120
124
  }
121
125
  }
122
- // 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
123
162
  const output = {
124
163
  url,
125
- data: sanitizedData,
164
+ data: finalData,
126
165
  sanitization: {
127
166
  patterns_detected: Array.from(allPatternsDetected),
128
167
  pii_types_redacted: Array.from(allPIITypesRedacted),
168
+ pii_allowlisted: allPIIAllowlisted,
129
169
  content_modified: anyContentModified
130
170
  },
131
171
  metadata: {
@@ -135,8 +175,14 @@ export async function visusFetchStructured(input) {
135
175
  content_length_sanitized: Object.values(sanitizedData)
136
176
  .filter(v => v !== null)
137
177
  .join(' ')
138
- .length
139
- }
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 })
140
186
  };
141
187
  // Log to stderr if threats detected
142
188
  if (allPatternsDetected.size > 0) {
@@ -159,7 +205,8 @@ export async function visusFetchStructured(input) {
159
205
  */
160
206
  export const visusFetchStructuredToolDefinition = {
161
207
  name: 'visus_fetch_structured',
162
- 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.',
163
210
  inputSchema: {
164
211
  type: 'object',
165
212
  properties: {
@@ -181,6 +228,10 @@ export const visusFetchStructuredToolDefinition = {
181
228
  }
182
229
  },
183
230
  required: ['url', 'schema']
184
- }
231
+ },
232
+ readOnlyHint: true,
233
+ destructiveHint: false,
234
+ idempotentHint: true,
235
+ openWorldHint: true
185
236
  };
186
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,CA2DjG;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,26 +31,53 @@ 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)
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);
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,
64
+ pii_allowlisted: sanitizationResult.sanitization.pii_allowlisted,
44
65
  content_modified: sanitizationResult.sanitization.content_modified
45
66
  },
46
67
  metadata: {
47
68
  title: title || 'Untitled',
48
69
  fetched_at: new Date().toISOString(),
49
70
  content_length_original: sanitizationResult.metadata.original_length,
50
- content_length_sanitized: sanitizationResult.metadata.sanitized_length
51
- }
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 })
52
81
  };
53
82
  // Log to stderr if critical threats detected
54
83
  if (sanitizationResult.metadata.has_critical_threats) {
@@ -71,7 +100,8 @@ export async function visusFetch(input) {
71
100
  */
72
101
  export const visusFetchToolDefinition = {
73
102
  name: 'visus_fetch',
74
- 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.',
75
105
  inputSchema: {
76
106
  type: 'object',
77
107
  properties: {
@@ -92,6 +122,10 @@ export const visusFetchToolDefinition = {
92
122
  }
93
123
  },
94
124
  required: ['url']
95
- }
125
+ },
126
+ readOnlyHint: true,
127
+ destructiveHint: false,
128
+ idempotentHint: true,
129
+ openWorldHint: true
96
130
  };
97
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"}