visus-mcp 0.6.2 → 0.9.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 +15 -1
- package/.env.status +7 -0
- package/CHANGELOG.md +110 -0
- package/CLAUDE.md +3 -0
- package/README.md +29 -19
- package/SECURITY.md +2 -0
- package/STATUS.md +320 -12
- package/dist/browser/playwright-renderer.d.ts.map +1 -1
- package/dist/browser/playwright-renderer.js +27 -5
- package/dist/browser/playwright-renderer.js.map +1 -1
- package/dist/content-handlers/index.d.ts +36 -0
- package/dist/content-handlers/index.d.ts.map +1 -0
- package/dist/content-handlers/index.js +59 -0
- package/dist/content-handlers/index.js.map +1 -0
- package/dist/content-handlers/json-handler.d.ts +28 -0
- package/dist/content-handlers/json-handler.d.ts.map +1 -0
- package/dist/content-handlers/json-handler.js +116 -0
- package/dist/content-handlers/json-handler.js.map +1 -0
- package/dist/content-handlers/pdf-handler.d.ts +29 -0
- package/dist/content-handlers/pdf-handler.d.ts.map +1 -0
- package/dist/content-handlers/pdf-handler.js +77 -0
- package/dist/content-handlers/pdf-handler.js.map +1 -0
- package/dist/content-handlers/svg-handler.d.ts +35 -0
- package/dist/content-handlers/svg-handler.d.ts.map +1 -0
- package/dist/content-handlers/svg-handler.js +206 -0
- package/dist/content-handlers/svg-handler.js.map +1 -0
- package/dist/content-handlers/types.d.ts +42 -0
- package/dist/content-handlers/types.d.ts.map +1 -0
- package/dist/content-handlers/types.js +7 -0
- package/dist/content-handlers/types.js.map +1 -0
- package/dist/sanitizer/framework-mapper.d.ts +4 -0
- package/dist/sanitizer/framework-mapper.d.ts.map +1 -1
- package/dist/sanitizer/framework-mapper.js +92 -0
- package/dist/sanitizer/framework-mapper.js.map +1 -1
- package/dist/sanitizer/threat-reporter.d.ts +5 -0
- package/dist/sanitizer/threat-reporter.d.ts.map +1 -1
- package/dist/sanitizer/threat-reporter.js +15 -6
- package/dist/sanitizer/threat-reporter.js.map +1 -1
- package/dist/tools/fetch-structured.d.ts.map +1 -1
- package/dist/tools/fetch-structured.js +4 -0
- package/dist/tools/fetch-structured.js.map +1 -1
- package/dist/tools/fetch.d.ts.map +1 -1
- package/dist/tools/fetch.js +68 -4
- package/dist/tools/fetch.js.map +1 -1
- package/dist/tools/read.d.ts.map +1 -1
- package/dist/tools/read.js +4 -0
- package/dist/tools/read.js.map +1 -1
- package/dist/types.d.ts +9 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +2 -1
- package/server.json +25 -14
- package/src/browser/playwright-renderer.ts +29 -6
- package/src/content-handlers/index.ts +72 -0
- package/src/content-handlers/json-handler.ts +137 -0
- package/src/content-handlers/pdf-handler.ts +91 -0
- package/src/content-handlers/svg-handler.ts +243 -0
- package/src/content-handlers/types.ts +44 -0
- package/src/sanitizer/framework-mapper.ts +94 -0
- package/src/sanitizer/threat-reporter.ts +17 -6
- package/src/tools/fetch-structured.ts +5 -0
- package/src/tools/fetch.ts +76 -4
- package/src/tools/read.ts +5 -0
- package/src/types.ts +9 -1
- package/.github/ISSUE_TEMPLATE/bug_report.md +0 -47
- package/.github/ISSUE_TEMPLATE/false_positive.md +0 -43
- package/.github/ISSUE_TEMPLATE/new_pattern.md +0 -49
- package/.github/ISSUE_TEMPLATE/security_report.md +0 -31
- package/.github/PULL_REQUEST_TEMPLATE.md +0 -39
- package/.mcpregistry_github_token +0 -1
- package/.mcpregistry_registry_token +0 -1
- package/CONTRIBUTING.md +0 -329
- package/LINKEDIN-STRATEGY.md +0 -367
- package/ROADMAP.md +0 -221
- package/SECURITY-AUDIT-v1.md +0 -277
- package/SUBMISSION.md +0 -66
- package/TROUBLESHOOT-AUTH-20260322-2019.md +0 -291
- package/TROUBLESHOOT-BUILD-20260319-1450.md +0 -546
- package/TROUBLESHOOT-COGNITO-AUTH-20260324-2029.md +0 -415
- package/TROUBLESHOOT-COGNITO-JWT-20260324.md +0 -592
- package/TROUBLESHOOT-FETCH-20260320-1150.md +0 -168
- package/TROUBLESHOOT-JEST-20260323-1357.md +0 -139
- package/TROUBLESHOOT-LAMBDA-20260322-1945.md +0 -183
- package/TROUBLESHOOT-PLAYWRIGHT-20260321-1549.md +0 -217
- package/TROUBLESHOOT-SSL-20260320-1138.md +0 -171
- package/TROUBLESHOOT-STRUCTURED-20260320-1200.md +0 -246
- package/TROUBLESHOOT-TEST-20260320-0942.md +0 -281
- package/VISUS-CLAUDE-CODE-PROMPT.md +0 -324
- package/VISUS-PROJECT-PLAN.md +0 -205
- package/cdk.json +0 -73
- package/infrastructure/app.ts +0 -39
- package/infrastructure/stack.ts +0 -298
- package/jest.config.js +0 -33
- package/jest.setup.js +0 -9
- package/lambda-deploy/index.js +0 -81512
- package/lambda-deploy/index.js.map +0 -7
- package/lambda-package/browser/__mocks__/playwright-renderer.d.ts +0 -25
- package/lambda-package/browser/__mocks__/playwright-renderer.d.ts.map +0 -1
- package/lambda-package/browser/__mocks__/playwright-renderer.js +0 -119
- package/lambda-package/browser/__mocks__/playwright-renderer.js.map +0 -1
- package/lambda-package/browser/playwright-renderer.d.ts +0 -40
- package/lambda-package/browser/playwright-renderer.d.ts.map +0 -1
- package/lambda-package/browser/playwright-renderer.js +0 -214
- package/lambda-package/browser/playwright-renderer.js.map +0 -1
- package/lambda-package/browser/reader.d.ts +0 -31
- package/lambda-package/browser/reader.d.ts.map +0 -1
- package/lambda-package/browser/reader.js +0 -98
- package/lambda-package/browser/reader.js.map +0 -1
- package/lambda-package/index.d.ts +0 -18
- package/lambda-package/index.d.ts.map +0 -1
- package/lambda-package/index.js +0 -238
- package/lambda-package/index.js.map +0 -1
- package/lambda-package/lambda-handler.d.ts +0 -28
- package/lambda-package/lambda-handler.d.ts.map +0 -1
- package/lambda-package/lambda-handler.js +0 -257
- package/lambda-package/lambda-handler.js.map +0 -1
- package/lambda-package/package-lock.json +0 -7435
- package/lambda-package/package.json +0 -74
- package/lambda-package/runtime.d.ts +0 -50
- package/lambda-package/runtime.d.ts.map +0 -1
- package/lambda-package/runtime.js +0 -86
- package/lambda-package/runtime.js.map +0 -1
- package/lambda-package/sanitizer/elicit-runner.d.ts +0 -48
- package/lambda-package/sanitizer/elicit-runner.d.ts.map +0 -1
- package/lambda-package/sanitizer/elicit-runner.js +0 -100
- package/lambda-package/sanitizer/elicit-runner.js.map +0 -1
- package/lambda-package/sanitizer/framework-mapper.d.ts +0 -24
- package/lambda-package/sanitizer/framework-mapper.d.ts.map +0 -1
- package/lambda-package/sanitizer/framework-mapper.js +0 -342
- package/lambda-package/sanitizer/framework-mapper.js.map +0 -1
- package/lambda-package/sanitizer/hitl-gate.d.ts +0 -69
- package/lambda-package/sanitizer/hitl-gate.d.ts.map +0 -1
- package/lambda-package/sanitizer/hitl-gate.js +0 -101
- package/lambda-package/sanitizer/hitl-gate.js.map +0 -1
- package/lambda-package/sanitizer/index.d.ts +0 -63
- package/lambda-package/sanitizer/index.d.ts.map +0 -1
- package/lambda-package/sanitizer/index.js +0 -105
- package/lambda-package/sanitizer/index.js.map +0 -1
- package/lambda-package/sanitizer/injection-detector.d.ts +0 -34
- package/lambda-package/sanitizer/injection-detector.d.ts.map +0 -1
- package/lambda-package/sanitizer/injection-detector.js +0 -89
- package/lambda-package/sanitizer/injection-detector.js.map +0 -1
- package/lambda-package/sanitizer/patterns.d.ts +0 -30
- package/lambda-package/sanitizer/patterns.d.ts.map +0 -1
- package/lambda-package/sanitizer/patterns.js +0 -372
- package/lambda-package/sanitizer/patterns.js.map +0 -1
- package/lambda-package/sanitizer/pii-allowlist.d.ts +0 -49
- package/lambda-package/sanitizer/pii-allowlist.d.ts.map +0 -1
- package/lambda-package/sanitizer/pii-allowlist.js +0 -231
- package/lambda-package/sanitizer/pii-allowlist.js.map +0 -1
- package/lambda-package/sanitizer/pii-redactor.d.ts +0 -41
- package/lambda-package/sanitizer/pii-redactor.d.ts.map +0 -1
- package/lambda-package/sanitizer/pii-redactor.js +0 -213
- package/lambda-package/sanitizer/pii-redactor.js.map +0 -1
- package/lambda-package/sanitizer/severity-classifier.d.ts +0 -33
- package/lambda-package/sanitizer/severity-classifier.d.ts.map +0 -1
- package/lambda-package/sanitizer/severity-classifier.js +0 -113
- package/lambda-package/sanitizer/severity-classifier.js.map +0 -1
- package/lambda-package/sanitizer/threat-reporter.d.ts +0 -66
- package/lambda-package/sanitizer/threat-reporter.d.ts.map +0 -1
- package/lambda-package/sanitizer/threat-reporter.js +0 -163
- package/lambda-package/sanitizer/threat-reporter.js.map +0 -1
- package/lambda-package/tools/fetch-structured.d.ts +0 -51
- package/lambda-package/tools/fetch-structured.d.ts.map +0 -1
- package/lambda-package/tools/fetch-structured.js +0 -237
- package/lambda-package/tools/fetch-structured.js.map +0 -1
- package/lambda-package/tools/fetch.d.ts +0 -49
- package/lambda-package/tools/fetch.d.ts.map +0 -1
- package/lambda-package/tools/fetch.js +0 -131
- package/lambda-package/tools/fetch.js.map +0 -1
- package/lambda-package/tools/read.d.ts +0 -51
- package/lambda-package/tools/read.d.ts.map +0 -1
- package/lambda-package/tools/read.js +0 -127
- package/lambda-package/tools/read.js.map +0 -1
- package/lambda-package/tools/search.d.ts +0 -45
- package/lambda-package/tools/search.d.ts.map +0 -1
- package/lambda-package/tools/search.js +0 -220
- package/lambda-package/tools/search.js.map +0 -1
- package/lambda-package/types.d.ts +0 -167
- package/lambda-package/types.d.ts.map +0 -1
- package/lambda-package/types.js +0 -16
- package/lambda-package/types.js.map +0 -1
- package/lambda-package/utils/format-converter.d.ts +0 -39
- package/lambda-package/utils/format-converter.d.ts.map +0 -1
- package/lambda-package/utils/format-converter.js +0 -191
- package/lambda-package/utils/format-converter.js.map +0 -1
- package/lambda-package/utils/truncate.d.ts +0 -26
- package/lambda-package/utils/truncate.d.ts.map +0 -1
- package/lambda-package/utils/truncate.js +0 -54
- package/lambda-package/utils/truncate.js.map +0 -1
- package/lambda.zip +0 -0
- package/test-output.txt +0 -4
- package/tests/auth-smoke.test.ts +0 -480
- package/tests/elicit-runner.test.ts +0 -232
- package/tests/fetch-tool.test.ts +0 -922
- package/tests/hitl-gate.test.ts +0 -267
- package/tests/injection-corpus.ts +0 -338
- package/tests/pii-allowlist.test.ts +0 -282
- package/tests/reader.test.ts +0 -353
- package/tests/sanitizer.test.ts +0 -358
- package/tests/search.test.ts +0 -456
- package/tests/threat-reporter.test.ts +0 -334
- package/tsconfig.cdk.json +0 -35
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"fetch-structured.js","sourceRoot":"","sources":["../../src/tools/fetch-structured.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* visus_fetch MCP Tool
|
|
3
|
-
*
|
|
4
|
-
* Fetches a web page and returns sanitized content in markdown or text format.
|
|
5
|
-
*
|
|
6
|
-
* CRITICAL: ALL content MUST pass through the sanitizer. This cannot be bypassed.
|
|
7
|
-
*/
|
|
8
|
-
import type { VisusFetchInput, VisusFetchOutput, Result } from '../types.js';
|
|
9
|
-
/**
|
|
10
|
-
* visus_fetch tool implementation
|
|
11
|
-
*
|
|
12
|
-
* @param input Tool input parameters
|
|
13
|
-
* @returns Sanitized page content with metadata
|
|
14
|
-
*/
|
|
15
|
-
export declare function visusFetch(input: VisusFetchInput): Promise<Result<VisusFetchOutput, Error>>;
|
|
16
|
-
/**
|
|
17
|
-
* MCP tool definition for registration
|
|
18
|
-
*/
|
|
19
|
-
export declare const visusFetchToolDefinition: {
|
|
20
|
-
name: string;
|
|
21
|
-
title: string;
|
|
22
|
-
description: string;
|
|
23
|
-
inputSchema: {
|
|
24
|
-
type: string;
|
|
25
|
-
properties: {
|
|
26
|
-
url: {
|
|
27
|
-
type: string;
|
|
28
|
-
description: string;
|
|
29
|
-
};
|
|
30
|
-
format: {
|
|
31
|
-
type: string;
|
|
32
|
-
enum: string[];
|
|
33
|
-
description: string;
|
|
34
|
-
default: string;
|
|
35
|
-
};
|
|
36
|
-
timeout_ms: {
|
|
37
|
-
type: string;
|
|
38
|
-
description: string;
|
|
39
|
-
default: number;
|
|
40
|
-
};
|
|
41
|
-
};
|
|
42
|
-
required: string[];
|
|
43
|
-
};
|
|
44
|
-
readOnlyHint: boolean;
|
|
45
|
-
destructiveHint: boolean;
|
|
46
|
-
idempotentHint: boolean;
|
|
47
|
-
openWorldHint: boolean;
|
|
48
|
-
};
|
|
49
|
-
//# sourceMappingURL=fetch.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
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"}
|
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* visus_fetch MCP Tool
|
|
3
|
-
*
|
|
4
|
-
* Fetches a web page and returns sanitized content in markdown or text format.
|
|
5
|
-
*
|
|
6
|
-
* CRITICAL: ALL content MUST pass through the sanitizer. This cannot be bypassed.
|
|
7
|
-
*/
|
|
8
|
-
import { renderPage } from '../browser/playwright-renderer.js';
|
|
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';
|
|
12
|
-
import { Err } from '../types.js';
|
|
13
|
-
/**
|
|
14
|
-
* visus_fetch tool implementation
|
|
15
|
-
*
|
|
16
|
-
* @param input Tool input parameters
|
|
17
|
-
* @returns Sanitized page content with metadata
|
|
18
|
-
*/
|
|
19
|
-
export async function visusFetch(input) {
|
|
20
|
-
const { url, format = 'markdown', timeout_ms = 10000 } = input;
|
|
21
|
-
// Validate inputs
|
|
22
|
-
if (!url || typeof url !== 'string') {
|
|
23
|
-
return Err(new Error('Invalid input: url must be a non-empty string'));
|
|
24
|
-
}
|
|
25
|
-
try {
|
|
26
|
-
// Step 1: Render the page using Playwright
|
|
27
|
-
const renderResult = await renderPage(url, {
|
|
28
|
-
timeout_ms,
|
|
29
|
-
format: format === 'text' ? 'text' : 'markdown'
|
|
30
|
-
});
|
|
31
|
-
if (!renderResult.ok) {
|
|
32
|
-
return Err(renderResult.error);
|
|
33
|
-
}
|
|
34
|
-
const { html, title, contentType } = renderResult.value;
|
|
35
|
-
const rawContent = html || '';
|
|
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)
|
|
52
|
-
// This step CANNOT be skipped or bypassed
|
|
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
|
|
58
|
-
const output = {
|
|
59
|
-
url,
|
|
60
|
-
content: truncationResult.content,
|
|
61
|
-
sanitization: {
|
|
62
|
-
patterns_detected: sanitizationResult.sanitization.patterns_detected,
|
|
63
|
-
pii_types_redacted: sanitizationResult.sanitization.pii_types_redacted,
|
|
64
|
-
pii_allowlisted: sanitizationResult.sanitization.pii_allowlisted,
|
|
65
|
-
content_modified: sanitizationResult.sanitization.content_modified
|
|
66
|
-
},
|
|
67
|
-
metadata: {
|
|
68
|
-
title: title || 'Untitled',
|
|
69
|
-
fetched_at: new Date().toISOString(),
|
|
70
|
-
content_length_original: sanitizationResult.metadata.original_length,
|
|
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 })
|
|
81
|
-
};
|
|
82
|
-
// Log to stderr if critical threats detected
|
|
83
|
-
if (sanitizationResult.metadata.has_critical_threats) {
|
|
84
|
-
console.error(JSON.stringify({
|
|
85
|
-
timestamp: new Date().toISOString(),
|
|
86
|
-
event: 'critical_threat_detected',
|
|
87
|
-
url,
|
|
88
|
-
patterns: sanitizationResult.sanitization.patterns_detected,
|
|
89
|
-
severity_score: sanitizationResult.metadata.severity_score
|
|
90
|
-
}));
|
|
91
|
-
}
|
|
92
|
-
return { ok: true, value: output };
|
|
93
|
-
}
|
|
94
|
-
catch (error) {
|
|
95
|
-
return Err(error instanceof Error ? error : new Error(String(error)));
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
/**
|
|
99
|
-
* MCP tool definition for registration
|
|
100
|
-
*/
|
|
101
|
-
export const visusFetchToolDefinition = {
|
|
102
|
-
name: 'visus_fetch',
|
|
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.',
|
|
105
|
-
inputSchema: {
|
|
106
|
-
type: 'object',
|
|
107
|
-
properties: {
|
|
108
|
-
url: {
|
|
109
|
-
type: 'string',
|
|
110
|
-
description: 'The URL to fetch (must be http:// or https://)'
|
|
111
|
-
},
|
|
112
|
-
format: {
|
|
113
|
-
type: 'string',
|
|
114
|
-
enum: ['markdown', 'text'],
|
|
115
|
-
description: 'Output format: markdown (default) or plain text',
|
|
116
|
-
default: 'markdown'
|
|
117
|
-
},
|
|
118
|
-
timeout_ms: {
|
|
119
|
-
type: 'number',
|
|
120
|
-
description: 'Request timeout in milliseconds (default: 10000)',
|
|
121
|
-
default: 10000
|
|
122
|
-
}
|
|
123
|
-
},
|
|
124
|
-
required: ['url']
|
|
125
|
-
},
|
|
126
|
-
readOnlyHint: true,
|
|
127
|
-
destructiveHint: false,
|
|
128
|
-
idempotentHint: true,
|
|
129
|
-
openWorldHint: true
|
|
130
|
-
};
|
|
131
|
-
//# sourceMappingURL=fetch.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"fetch.js","sourceRoot":"","sources":["../../src/tools/fetch.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,51 +0,0 @@
|
|
|
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
|
|
@@ -1 +0,0 @@
|
|
|
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"}
|
|
@@ -1,127 +0,0 @@
|
|
|
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
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"read.js","sourceRoot":"","sources":["../../src/tools/read.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Visus Search Tool - Safe Web Search
|
|
3
|
-
*
|
|
4
|
-
* Queries DuckDuckGo's Instant Answer API and sanitizes all results
|
|
5
|
-
* before returning them to the LLM.
|
|
6
|
-
*
|
|
7
|
-
* SECURITY: Every search result snippet and title passes through the
|
|
8
|
-
* sanitization pipeline. This prevents prompt injection via search results.
|
|
9
|
-
*/
|
|
10
|
-
import type { VisusSearchInput, VisusSearchOutput, Result } from '../types.js';
|
|
11
|
-
/**
|
|
12
|
-
* Search the web via DuckDuckGo and return sanitized results
|
|
13
|
-
*
|
|
14
|
-
* @param input Search query and options
|
|
15
|
-
* @returns Sanitized search results with injection detection metadata
|
|
16
|
-
*/
|
|
17
|
-
export declare function visusSearch(input: VisusSearchInput): Promise<Result<VisusSearchOutput, Error>>;
|
|
18
|
-
/**
|
|
19
|
-
* Tool definition for MCP registration
|
|
20
|
-
*/
|
|
21
|
-
export declare const visusSearchToolDefinition: {
|
|
22
|
-
name: string;
|
|
23
|
-
title: string;
|
|
24
|
-
description: string;
|
|
25
|
-
inputSchema: {
|
|
26
|
-
type: string;
|
|
27
|
-
properties: {
|
|
28
|
-
query: {
|
|
29
|
-
type: string;
|
|
30
|
-
description: string;
|
|
31
|
-
};
|
|
32
|
-
max_results: {
|
|
33
|
-
type: string;
|
|
34
|
-
description: string;
|
|
35
|
-
default: number;
|
|
36
|
-
};
|
|
37
|
-
};
|
|
38
|
-
required: string[];
|
|
39
|
-
};
|
|
40
|
-
readOnlyHint: boolean;
|
|
41
|
-
destructiveHint: boolean;
|
|
42
|
-
idempotentHint: boolean;
|
|
43
|
-
openWorldHint: boolean;
|
|
44
|
-
};
|
|
45
|
-
//# sourceMappingURL=search.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/tools/search.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAiB/E;;;;;GAKG;AACH,wBAAsB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,iBAAiB,EAAE,KAAK,CAAC,CAAC,CAkLpG;AAuBD;;GAEG;AACH,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;CAuBrC,CAAC"}
|
|
@@ -1,220 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Visus Search Tool - Safe Web Search
|
|
3
|
-
*
|
|
4
|
-
* Queries DuckDuckGo's Instant Answer API and sanitizes all results
|
|
5
|
-
* before returning them to the LLM.
|
|
6
|
-
*
|
|
7
|
-
* SECURITY: Every search result snippet and title passes through the
|
|
8
|
-
* sanitization pipeline. This prevents prompt injection via search results.
|
|
9
|
-
*/
|
|
10
|
-
import { sanitize } from '../sanitizer/index.js';
|
|
11
|
-
import { generateThreatReport } from '../sanitizer/threat-reporter.js';
|
|
12
|
-
import { Ok, Err } from '../types.js';
|
|
13
|
-
/**
|
|
14
|
-
* Search the web via DuckDuckGo and return sanitized results
|
|
15
|
-
*
|
|
16
|
-
* @param input Search query and options
|
|
17
|
-
* @returns Sanitized search results with injection detection metadata
|
|
18
|
-
*/
|
|
19
|
-
export async function visusSearch(input) {
|
|
20
|
-
// Validate input
|
|
21
|
-
if (!input.query || typeof input.query !== 'string' || input.query.trim().length === 0) {
|
|
22
|
-
return Err(new Error('query must be a non-empty string'));
|
|
23
|
-
}
|
|
24
|
-
// Enforce max_results cap
|
|
25
|
-
const maxResults = Math.min(input.max_results ?? 5, 10);
|
|
26
|
-
try {
|
|
27
|
-
// Call DuckDuckGo Instant Answer API
|
|
28
|
-
const query = encodeURIComponent(input.query.trim());
|
|
29
|
-
const apiUrl = `https://api.duckduckgo.com/?q=${query}&format=json&no_redirect=1&no_html=1`;
|
|
30
|
-
const controller = new AbortController();
|
|
31
|
-
const timeout = setTimeout(() => controller.abort(), 8000);
|
|
32
|
-
let response;
|
|
33
|
-
try {
|
|
34
|
-
response = await fetch(apiUrl, {
|
|
35
|
-
signal: controller.signal,
|
|
36
|
-
headers: {
|
|
37
|
-
'User-Agent': 'visus-mcp/0.3.0 (https://github.com/lateos/visus-mcp)'
|
|
38
|
-
}
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
finally {
|
|
42
|
-
clearTimeout(timeout);
|
|
43
|
-
}
|
|
44
|
-
if (!response.ok) {
|
|
45
|
-
return Ok({
|
|
46
|
-
query: input.query,
|
|
47
|
-
result_count: 0,
|
|
48
|
-
sanitized: true,
|
|
49
|
-
results: [],
|
|
50
|
-
total_injections_removed: 0,
|
|
51
|
-
message: `Search unavailable (HTTP ${response.status})`
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
const data = await response.json();
|
|
55
|
-
// Extract results from DuckDuckGo response
|
|
56
|
-
const rawResults = [];
|
|
57
|
-
// Add AbstractText as first result if present
|
|
58
|
-
if (data.AbstractText && data.AbstractURL) {
|
|
59
|
-
rawResults.push({
|
|
60
|
-
title: extractTitle(data.AbstractText),
|
|
61
|
-
url: data.AbstractURL,
|
|
62
|
-
snippet: data.AbstractText
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
// Extract from RelatedTopics
|
|
66
|
-
if (data.RelatedTopics) {
|
|
67
|
-
for (const topic of data.RelatedTopics) {
|
|
68
|
-
// Handle both direct topics and nested topic groups
|
|
69
|
-
if ('Topics' in topic && Array.isArray(topic.Topics)) {
|
|
70
|
-
// Nested topics group
|
|
71
|
-
for (const nestedTopic of topic.Topics) {
|
|
72
|
-
if (nestedTopic.Text && nestedTopic.FirstURL) {
|
|
73
|
-
rawResults.push({
|
|
74
|
-
title: extractTitle(nestedTopic.Text),
|
|
75
|
-
url: nestedTopic.FirstURL,
|
|
76
|
-
snippet: nestedTopic.Text
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
else if ('Text' in topic && topic.Text && topic.FirstURL) {
|
|
82
|
-
// Direct topic
|
|
83
|
-
rawResults.push({
|
|
84
|
-
title: extractTitle(topic.Text),
|
|
85
|
-
url: topic.FirstURL,
|
|
86
|
-
snippet: topic.Text
|
|
87
|
-
});
|
|
88
|
-
}
|
|
89
|
-
// Stop if we've collected enough results
|
|
90
|
-
if (rawResults.length >= maxResults) {
|
|
91
|
-
break;
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
// Filter out results with empty URLs and limit to max_results
|
|
96
|
-
const validResults = rawResults
|
|
97
|
-
.filter(r => r.url && r.url.trim().length > 0)
|
|
98
|
-
.slice(0, maxResults);
|
|
99
|
-
// If no results found, return empty array with message
|
|
100
|
-
if (validResults.length === 0) {
|
|
101
|
-
return Ok({
|
|
102
|
-
query: input.query,
|
|
103
|
-
result_count: 0,
|
|
104
|
-
sanitized: true,
|
|
105
|
-
results: [],
|
|
106
|
-
total_injections_removed: 0,
|
|
107
|
-
message: 'No results found'
|
|
108
|
-
});
|
|
109
|
-
}
|
|
110
|
-
// Sanitize each result independently
|
|
111
|
-
const sanitizedResults = [];
|
|
112
|
-
const allPatternsDetected = new Set();
|
|
113
|
-
let totalInjectionsRemoved = 0;
|
|
114
|
-
let totalPIIRedacted = 0;
|
|
115
|
-
for (const result of validResults) {
|
|
116
|
-
// Sanitize title
|
|
117
|
-
const titleSanitization = sanitize(result.title);
|
|
118
|
-
// Sanitize snippet
|
|
119
|
-
const snippetSanitization = sanitize(result.snippet);
|
|
120
|
-
const injectionsRemoved = titleSanitization.sanitization.patterns_detected.length +
|
|
121
|
-
snippetSanitization.sanitization.patterns_detected.length;
|
|
122
|
-
const piiRedacted = titleSanitization.sanitization.pii_types_redacted.length +
|
|
123
|
-
snippetSanitization.sanitization.pii_types_redacted.length;
|
|
124
|
-
totalInjectionsRemoved += injectionsRemoved;
|
|
125
|
-
totalPIIRedacted += piiRedacted;
|
|
126
|
-
// Collect all patterns detected across all results
|
|
127
|
-
titleSanitization.sanitization.patterns_detected.forEach(p => allPatternsDetected.add(p));
|
|
128
|
-
snippetSanitization.sanitization.patterns_detected.forEach(p => allPatternsDetected.add(p));
|
|
129
|
-
sanitizedResults.push({
|
|
130
|
-
title: titleSanitization.content,
|
|
131
|
-
url: result.url,
|
|
132
|
-
snippet: snippetSanitization.content,
|
|
133
|
-
injections_removed: injectionsRemoved,
|
|
134
|
-
pii_redacted: piiRedacted
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
|
-
// Generate aggregated threat report for all search results
|
|
138
|
-
const threatReport = generateThreatReport({
|
|
139
|
-
patterns_detected: Array.from(allPatternsDetected),
|
|
140
|
-
pii_redacted: totalPIIRedacted,
|
|
141
|
-
source_url: `DuckDuckGo Search: ${input.query}`
|
|
142
|
-
});
|
|
143
|
-
return Ok({
|
|
144
|
-
query: input.query,
|
|
145
|
-
result_count: sanitizedResults.length,
|
|
146
|
-
sanitized: true,
|
|
147
|
-
results: sanitizedResults,
|
|
148
|
-
total_injections_removed: totalInjectionsRemoved,
|
|
149
|
-
// Include threat_report only if findings exist
|
|
150
|
-
...(threatReport && { threat_report: threatReport })
|
|
151
|
-
});
|
|
152
|
-
}
|
|
153
|
-
catch (error) {
|
|
154
|
-
// Handle timeout or network errors
|
|
155
|
-
if (error instanceof Error && error.name === 'AbortError') {
|
|
156
|
-
return Ok({
|
|
157
|
-
query: input.query,
|
|
158
|
-
result_count: 0,
|
|
159
|
-
sanitized: true,
|
|
160
|
-
results: [],
|
|
161
|
-
total_injections_removed: 0,
|
|
162
|
-
message: 'Search unavailable (timeout)'
|
|
163
|
-
});
|
|
164
|
-
}
|
|
165
|
-
return Ok({
|
|
166
|
-
query: input.query,
|
|
167
|
-
result_count: 0,
|
|
168
|
-
sanitized: true,
|
|
169
|
-
results: [],
|
|
170
|
-
total_injections_removed: 0,
|
|
171
|
-
message: `Search unavailable: ${error instanceof Error ? error.message : String(error)}`
|
|
172
|
-
});
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
/**
|
|
176
|
-
* Extract title from text (first sentence or up to 80 chars)
|
|
177
|
-
*/
|
|
178
|
-
function extractTitle(text) {
|
|
179
|
-
// Try to find first sentence
|
|
180
|
-
const firstSentenceMatch = text.match(/^[^.!?]+[.!?]/);
|
|
181
|
-
if (firstSentenceMatch) {
|
|
182
|
-
const sentence = firstSentenceMatch[0].trim();
|
|
183
|
-
if (sentence.length <= 80) {
|
|
184
|
-
return sentence;
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
// Fallback to first 80 chars
|
|
188
|
-
if (text.length <= 80) {
|
|
189
|
-
return text.trim();
|
|
190
|
-
}
|
|
191
|
-
return text.substring(0, 77).trim() + '...';
|
|
192
|
-
}
|
|
193
|
-
/**
|
|
194
|
-
* Tool definition for MCP registration
|
|
195
|
-
*/
|
|
196
|
-
export const visusSearchToolDefinition = {
|
|
197
|
-
name: 'visus_search',
|
|
198
|
-
title: 'Search the Web (Sanitized)',
|
|
199
|
-
description: 'Searches the web via DuckDuckGo and returns sanitized results with prompt injection and PII removed before reaching the LLM. Use before visus_fetch or visus_read to safely discover and then read pages.',
|
|
200
|
-
inputSchema: {
|
|
201
|
-
type: 'object',
|
|
202
|
-
properties: {
|
|
203
|
-
query: {
|
|
204
|
-
type: 'string',
|
|
205
|
-
description: 'Search query'
|
|
206
|
-
},
|
|
207
|
-
max_results: {
|
|
208
|
-
type: 'number',
|
|
209
|
-
description: 'Maximum number of results to return (default: 5, max: 10)',
|
|
210
|
-
default: 5
|
|
211
|
-
}
|
|
212
|
-
},
|
|
213
|
-
required: ['query']
|
|
214
|
-
},
|
|
215
|
-
readOnlyHint: true,
|
|
216
|
-
destructiveHint: false,
|
|
217
|
-
idempotentHint: true,
|
|
218
|
-
openWorldHint: true
|
|
219
|
-
};
|
|
220
|
-
//# sourceMappingURL=search.js.map
|