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.
- package/.claude/settings.local.json +22 -0
- package/LINKEDIN-STRATEGY.md +367 -0
- package/README.md +491 -16
- package/ROADMAP.md +214 -34
- package/SECURITY-AUDIT-v1.md +277 -0
- package/STATUS.md +801 -42
- package/TROUBLESHOOT-AUTH-20260322-2019.md +291 -0
- package/TROUBLESHOOT-JEST-20260323-1357.md +139 -0
- package/TROUBLESHOOT-LAMBDA-20260322-1945.md +183 -0
- package/VISUS-CLAUDE-CODE-PROMPT.md +1 -1
- package/VISUS-PROJECT-PLAN.md +7 -0
- package/dist/browser/playwright-renderer.d.ts.map +1 -1
- package/dist/browser/playwright-renderer.js +7 -0
- package/dist/browser/playwright-renderer.js.map +1 -1
- package/dist/browser/reader.d.ts +31 -0
- package/dist/browser/reader.d.ts.map +1 -0
- package/dist/browser/reader.js +98 -0
- package/dist/browser/reader.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +37 -5
- package/dist/index.js.map +1 -1
- package/dist/lambda-handler.d.ts +0 -6
- package/dist/lambda-handler.d.ts.map +1 -1
- package/dist/lambda-handler.js +97 -25
- package/dist/lambda-handler.js.map +1 -1
- package/dist/sanitizer/framework-mapper.d.ts +22 -0
- package/dist/sanitizer/framework-mapper.d.ts.map +1 -0
- package/dist/sanitizer/framework-mapper.js +296 -0
- package/dist/sanitizer/framework-mapper.js.map +1 -0
- package/dist/sanitizer/index.d.ts +10 -2
- package/dist/sanitizer/index.d.ts.map +1 -1
- package/dist/sanitizer/index.js +22 -6
- package/dist/sanitizer/index.js.map +1 -1
- package/dist/sanitizer/patterns.js +1 -1
- package/dist/sanitizer/patterns.js.map +1 -1
- package/dist/sanitizer/pii-allowlist.d.ts +49 -0
- package/dist/sanitizer/pii-allowlist.d.ts.map +1 -0
- package/dist/sanitizer/pii-allowlist.js +231 -0
- package/dist/sanitizer/pii-allowlist.js.map +1 -0
- package/dist/sanitizer/pii-redactor.d.ts +13 -1
- package/dist/sanitizer/pii-redactor.d.ts.map +1 -1
- package/dist/sanitizer/pii-redactor.js +26 -2
- package/dist/sanitizer/pii-redactor.js.map +1 -1
- package/dist/sanitizer/severity-classifier.d.ts +33 -0
- package/dist/sanitizer/severity-classifier.d.ts.map +1 -0
- package/dist/sanitizer/severity-classifier.js +113 -0
- package/dist/sanitizer/severity-classifier.js.map +1 -0
- package/dist/sanitizer/threat-reporter.d.ts +65 -0
- package/dist/sanitizer/threat-reporter.d.ts.map +1 -0
- package/dist/sanitizer/threat-reporter.js +160 -0
- package/dist/sanitizer/threat-reporter.js.map +1 -0
- package/dist/tools/fetch-structured.d.ts +5 -0
- package/dist/tools/fetch-structured.d.ts.map +1 -1
- package/dist/tools/fetch-structured.js +59 -8
- package/dist/tools/fetch-structured.js.map +1 -1
- package/dist/tools/fetch.d.ts +5 -0
- package/dist/tools/fetch.d.ts.map +1 -1
- package/dist/tools/fetch.js +43 -9
- package/dist/tools/fetch.js.map +1 -1
- package/dist/tools/read.d.ts +51 -0
- package/dist/tools/read.d.ts.map +1 -0
- package/dist/tools/read.js +127 -0
- package/dist/tools/read.js.map +1 -0
- package/dist/tools/search.d.ts +45 -0
- package/dist/tools/search.d.ts.map +1 -0
- package/dist/tools/search.js +220 -0
- package/dist/tools/search.js.map +1 -0
- package/dist/types.d.ts +74 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/format-converter.d.ts +39 -0
- package/dist/utils/format-converter.d.ts.map +1 -0
- package/dist/utils/format-converter.js +191 -0
- package/dist/utils/format-converter.js.map +1 -0
- package/dist/utils/truncate.d.ts +26 -0
- package/dist/utils/truncate.d.ts.map +1 -0
- package/dist/utils/truncate.js +54 -0
- package/dist/utils/truncate.js.map +1 -0
- package/infrastructure/stack.ts +55 -6
- package/jest.config.js +3 -0
- package/package.json +9 -2
- package/src/browser/playwright-renderer.ts +8 -0
- package/src/browser/reader.ts +129 -0
- package/src/index.ts +49 -5
- package/src/lambda-handler.ts +131 -26
- package/src/sanitizer/framework-mapper.ts +347 -0
- package/src/sanitizer/index.ts +28 -6
- package/src/sanitizer/patterns.ts +1 -1
- package/src/sanitizer/pii-allowlist.ts +273 -0
- package/src/sanitizer/pii-redactor.ts +43 -2
- package/src/sanitizer/severity-classifier.ts +132 -0
- package/src/sanitizer/threat-reporter.ts +261 -0
- package/src/tools/fetch-structured.ts +63 -8
- package/src/tools/fetch.ts +45 -9
- package/src/tools/read.ts +143 -0
- package/src/tools/search.ts +263 -0
- package/src/types.ts +71 -0
- package/src/utils/format-converter.ts +236 -0
- package/src/utils/truncate.ts +64 -0
- package/tests/auth-smoke.test.ts +480 -0
- package/tests/fetch-tool.test.ts +595 -2
- package/tests/pii-allowlist.test.ts +282 -0
- package/tests/reader.test.ts +353 -0
- package/tests/sanitizer.test.ts +52 -0
- package/tests/search.test.ts +456 -0
- 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;
|
|
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:
|
|
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:
|
|
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
|
-
|
|
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":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,OAAO,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAC;AAC/D,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"fetch-structured.js","sourceRoot":"","sources":["../../src/tools/fetch-structured.ts"],"names":[],"mappings":"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"}
|
package/dist/tools/fetch.d.ts
CHANGED
|
@@ -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;
|
|
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"}
|
package/dist/tools/fetch.js
CHANGED
|
@@ -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:
|
|
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(
|
|
37
|
-
// Step 3:
|
|
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:
|
|
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
|
-
|
|
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
|
package/dist/tools/fetch.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch.js","sourceRoot":"","sources":["../../src/tools/fetch.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAC;AAC/D,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;
|
|
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"}
|