visus-mcp 0.6.2 → 0.8.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 (177) hide show
  1. package/.claude/settings.local.json +6 -1
  2. package/.env.status +7 -0
  3. package/CHANGELOG.md +65 -0
  4. package/CLAUDE.md +3 -0
  5. package/README.md +15 -7
  6. package/SECURITY.md +2 -0
  7. package/STATUS.md +203 -9
  8. package/dist/content-handlers/index.d.ts +36 -0
  9. package/dist/content-handlers/index.d.ts.map +1 -0
  10. package/dist/content-handlers/index.js +59 -0
  11. package/dist/content-handlers/index.js.map +1 -0
  12. package/dist/content-handlers/json-handler.d.ts +28 -0
  13. package/dist/content-handlers/json-handler.d.ts.map +1 -0
  14. package/dist/content-handlers/json-handler.js +116 -0
  15. package/dist/content-handlers/json-handler.js.map +1 -0
  16. package/dist/content-handlers/pdf-handler.d.ts +29 -0
  17. package/dist/content-handlers/pdf-handler.d.ts.map +1 -0
  18. package/dist/content-handlers/pdf-handler.js +77 -0
  19. package/dist/content-handlers/pdf-handler.js.map +1 -0
  20. package/dist/content-handlers/svg-handler.d.ts +35 -0
  21. package/dist/content-handlers/svg-handler.d.ts.map +1 -0
  22. package/dist/content-handlers/svg-handler.js +206 -0
  23. package/dist/content-handlers/svg-handler.js.map +1 -0
  24. package/dist/content-handlers/types.d.ts +42 -0
  25. package/dist/content-handlers/types.d.ts.map +1 -0
  26. package/dist/content-handlers/types.js +7 -0
  27. package/dist/content-handlers/types.js.map +1 -0
  28. package/dist/tools/fetch.d.ts.map +1 -1
  29. package/dist/tools/fetch.js +62 -4
  30. package/dist/tools/fetch.js.map +1 -1
  31. package/package.json +2 -1
  32. package/server.json +2 -2
  33. package/src/content-handlers/index.ts +72 -0
  34. package/src/content-handlers/json-handler.ts +137 -0
  35. package/src/content-handlers/pdf-handler.ts +91 -0
  36. package/src/content-handlers/svg-handler.ts +243 -0
  37. package/src/content-handlers/types.ts +44 -0
  38. package/src/tools/fetch.ts +69 -4
  39. package/.github/ISSUE_TEMPLATE/bug_report.md +0 -47
  40. package/.github/ISSUE_TEMPLATE/false_positive.md +0 -43
  41. package/.github/ISSUE_TEMPLATE/new_pattern.md +0 -49
  42. package/.github/ISSUE_TEMPLATE/security_report.md +0 -31
  43. package/.github/PULL_REQUEST_TEMPLATE.md +0 -39
  44. package/.mcpregistry_github_token +0 -1
  45. package/.mcpregistry_registry_token +0 -1
  46. package/CONTRIBUTING.md +0 -329
  47. package/LINKEDIN-STRATEGY.md +0 -367
  48. package/ROADMAP.md +0 -221
  49. package/SECURITY-AUDIT-v1.md +0 -277
  50. package/SUBMISSION.md +0 -66
  51. package/TROUBLESHOOT-AUTH-20260322-2019.md +0 -291
  52. package/TROUBLESHOOT-BUILD-20260319-1450.md +0 -546
  53. package/TROUBLESHOOT-COGNITO-AUTH-20260324-2029.md +0 -415
  54. package/TROUBLESHOOT-COGNITO-JWT-20260324.md +0 -592
  55. package/TROUBLESHOOT-FETCH-20260320-1150.md +0 -168
  56. package/TROUBLESHOOT-JEST-20260323-1357.md +0 -139
  57. package/TROUBLESHOOT-LAMBDA-20260322-1945.md +0 -183
  58. package/TROUBLESHOOT-PLAYWRIGHT-20260321-1549.md +0 -217
  59. package/TROUBLESHOOT-SSL-20260320-1138.md +0 -171
  60. package/TROUBLESHOOT-STRUCTURED-20260320-1200.md +0 -246
  61. package/TROUBLESHOOT-TEST-20260320-0942.md +0 -281
  62. package/VISUS-CLAUDE-CODE-PROMPT.md +0 -324
  63. package/VISUS-PROJECT-PLAN.md +0 -205
  64. package/cdk.json +0 -73
  65. package/infrastructure/app.ts +0 -39
  66. package/infrastructure/stack.ts +0 -298
  67. package/jest.config.js +0 -33
  68. package/jest.setup.js +0 -9
  69. package/lambda-deploy/index.js +0 -81512
  70. package/lambda-deploy/index.js.map +0 -7
  71. package/lambda-package/browser/__mocks__/playwright-renderer.d.ts +0 -25
  72. package/lambda-package/browser/__mocks__/playwright-renderer.d.ts.map +0 -1
  73. package/lambda-package/browser/__mocks__/playwright-renderer.js +0 -119
  74. package/lambda-package/browser/__mocks__/playwright-renderer.js.map +0 -1
  75. package/lambda-package/browser/playwright-renderer.d.ts +0 -40
  76. package/lambda-package/browser/playwright-renderer.d.ts.map +0 -1
  77. package/lambda-package/browser/playwright-renderer.js +0 -214
  78. package/lambda-package/browser/playwright-renderer.js.map +0 -1
  79. package/lambda-package/browser/reader.d.ts +0 -31
  80. package/lambda-package/browser/reader.d.ts.map +0 -1
  81. package/lambda-package/browser/reader.js +0 -98
  82. package/lambda-package/browser/reader.js.map +0 -1
  83. package/lambda-package/index.d.ts +0 -18
  84. package/lambda-package/index.d.ts.map +0 -1
  85. package/lambda-package/index.js +0 -238
  86. package/lambda-package/index.js.map +0 -1
  87. package/lambda-package/lambda-handler.d.ts +0 -28
  88. package/lambda-package/lambda-handler.d.ts.map +0 -1
  89. package/lambda-package/lambda-handler.js +0 -257
  90. package/lambda-package/lambda-handler.js.map +0 -1
  91. package/lambda-package/package-lock.json +0 -7435
  92. package/lambda-package/package.json +0 -74
  93. package/lambda-package/runtime.d.ts +0 -50
  94. package/lambda-package/runtime.d.ts.map +0 -1
  95. package/lambda-package/runtime.js +0 -86
  96. package/lambda-package/runtime.js.map +0 -1
  97. package/lambda-package/sanitizer/elicit-runner.d.ts +0 -48
  98. package/lambda-package/sanitizer/elicit-runner.d.ts.map +0 -1
  99. package/lambda-package/sanitizer/elicit-runner.js +0 -100
  100. package/lambda-package/sanitizer/elicit-runner.js.map +0 -1
  101. package/lambda-package/sanitizer/framework-mapper.d.ts +0 -24
  102. package/lambda-package/sanitizer/framework-mapper.d.ts.map +0 -1
  103. package/lambda-package/sanitizer/framework-mapper.js +0 -342
  104. package/lambda-package/sanitizer/framework-mapper.js.map +0 -1
  105. package/lambda-package/sanitizer/hitl-gate.d.ts +0 -69
  106. package/lambda-package/sanitizer/hitl-gate.d.ts.map +0 -1
  107. package/lambda-package/sanitizer/hitl-gate.js +0 -101
  108. package/lambda-package/sanitizer/hitl-gate.js.map +0 -1
  109. package/lambda-package/sanitizer/index.d.ts +0 -63
  110. package/lambda-package/sanitizer/index.d.ts.map +0 -1
  111. package/lambda-package/sanitizer/index.js +0 -105
  112. package/lambda-package/sanitizer/index.js.map +0 -1
  113. package/lambda-package/sanitizer/injection-detector.d.ts +0 -34
  114. package/lambda-package/sanitizer/injection-detector.d.ts.map +0 -1
  115. package/lambda-package/sanitizer/injection-detector.js +0 -89
  116. package/lambda-package/sanitizer/injection-detector.js.map +0 -1
  117. package/lambda-package/sanitizer/patterns.d.ts +0 -30
  118. package/lambda-package/sanitizer/patterns.d.ts.map +0 -1
  119. package/lambda-package/sanitizer/patterns.js +0 -372
  120. package/lambda-package/sanitizer/patterns.js.map +0 -1
  121. package/lambda-package/sanitizer/pii-allowlist.d.ts +0 -49
  122. package/lambda-package/sanitizer/pii-allowlist.d.ts.map +0 -1
  123. package/lambda-package/sanitizer/pii-allowlist.js +0 -231
  124. package/lambda-package/sanitizer/pii-allowlist.js.map +0 -1
  125. package/lambda-package/sanitizer/pii-redactor.d.ts +0 -41
  126. package/lambda-package/sanitizer/pii-redactor.d.ts.map +0 -1
  127. package/lambda-package/sanitizer/pii-redactor.js +0 -213
  128. package/lambda-package/sanitizer/pii-redactor.js.map +0 -1
  129. package/lambda-package/sanitizer/severity-classifier.d.ts +0 -33
  130. package/lambda-package/sanitizer/severity-classifier.d.ts.map +0 -1
  131. package/lambda-package/sanitizer/severity-classifier.js +0 -113
  132. package/lambda-package/sanitizer/severity-classifier.js.map +0 -1
  133. package/lambda-package/sanitizer/threat-reporter.d.ts +0 -66
  134. package/lambda-package/sanitizer/threat-reporter.d.ts.map +0 -1
  135. package/lambda-package/sanitizer/threat-reporter.js +0 -163
  136. package/lambda-package/sanitizer/threat-reporter.js.map +0 -1
  137. package/lambda-package/tools/fetch-structured.d.ts +0 -51
  138. package/lambda-package/tools/fetch-structured.d.ts.map +0 -1
  139. package/lambda-package/tools/fetch-structured.js +0 -237
  140. package/lambda-package/tools/fetch-structured.js.map +0 -1
  141. package/lambda-package/tools/fetch.d.ts +0 -49
  142. package/lambda-package/tools/fetch.d.ts.map +0 -1
  143. package/lambda-package/tools/fetch.js +0 -131
  144. package/lambda-package/tools/fetch.js.map +0 -1
  145. package/lambda-package/tools/read.d.ts +0 -51
  146. package/lambda-package/tools/read.d.ts.map +0 -1
  147. package/lambda-package/tools/read.js +0 -127
  148. package/lambda-package/tools/read.js.map +0 -1
  149. package/lambda-package/tools/search.d.ts +0 -45
  150. package/lambda-package/tools/search.d.ts.map +0 -1
  151. package/lambda-package/tools/search.js +0 -220
  152. package/lambda-package/tools/search.js.map +0 -1
  153. package/lambda-package/types.d.ts +0 -167
  154. package/lambda-package/types.d.ts.map +0 -1
  155. package/lambda-package/types.js +0 -16
  156. package/lambda-package/types.js.map +0 -1
  157. package/lambda-package/utils/format-converter.d.ts +0 -39
  158. package/lambda-package/utils/format-converter.d.ts.map +0 -1
  159. package/lambda-package/utils/format-converter.js +0 -191
  160. package/lambda-package/utils/format-converter.js.map +0 -1
  161. package/lambda-package/utils/truncate.d.ts +0 -26
  162. package/lambda-package/utils/truncate.d.ts.map +0 -1
  163. package/lambda-package/utils/truncate.js +0 -54
  164. package/lambda-package/utils/truncate.js.map +0 -1
  165. package/lambda.zip +0 -0
  166. package/test-output.txt +0 -4
  167. package/tests/auth-smoke.test.ts +0 -480
  168. package/tests/elicit-runner.test.ts +0 -232
  169. package/tests/fetch-tool.test.ts +0 -922
  170. package/tests/hitl-gate.test.ts +0 -267
  171. package/tests/injection-corpus.ts +0 -338
  172. package/tests/pii-allowlist.test.ts +0 -282
  173. package/tests/reader.test.ts +0 -353
  174. package/tests/sanitizer.test.ts +0 -358
  175. package/tests/search.test.ts +0 -456
  176. package/tests/threat-reporter.test.ts +0 -334
  177. 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