visus-mcp 0.6.0 → 0.6.2

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 (147) hide show
  1. package/.claude/settings.local.json +42 -1
  2. package/.github/ISSUE_TEMPLATE/bug_report.md +47 -0
  3. package/.github/ISSUE_TEMPLATE/false_positive.md +43 -0
  4. package/.github/ISSUE_TEMPLATE/new_pattern.md +49 -0
  5. package/.github/ISSUE_TEMPLATE/security_report.md +31 -0
  6. package/.github/PULL_REQUEST_TEMPLATE.md +39 -0
  7. package/.mcpregistry_github_token +1 -0
  8. package/.mcpregistry_registry_token +1 -0
  9. package/CLAUDE.md +197 -0
  10. package/CONTRIBUTING.md +329 -0
  11. package/README.md +111 -45
  12. package/STATUS.md +167 -29
  13. package/SUBMISSION.md +66 -0
  14. package/TROUBLESHOOT-COGNITO-AUTH-20260324-2029.md +415 -0
  15. package/TROUBLESHOOT-COGNITO-JWT-20260324.md +592 -0
  16. package/dist/browser/playwright-renderer.d.ts.map +1 -1
  17. package/dist/browser/playwright-renderer.js +71 -51
  18. package/dist/browser/playwright-renderer.js.map +1 -1
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +49 -6
  21. package/dist/index.js.map +1 -1
  22. package/dist/sanitizer/elicit-runner.d.ts +48 -0
  23. package/dist/sanitizer/elicit-runner.d.ts.map +1 -0
  24. package/dist/sanitizer/elicit-runner.js +100 -0
  25. package/dist/sanitizer/elicit-runner.js.map +1 -0
  26. package/dist/sanitizer/framework-mapper.d.ts +2 -0
  27. package/dist/sanitizer/framework-mapper.d.ts.map +1 -1
  28. package/dist/sanitizer/framework-mapper.js +91 -45
  29. package/dist/sanitizer/framework-mapper.js.map +1 -1
  30. package/dist/sanitizer/hitl-gate.d.ts +69 -0
  31. package/dist/sanitizer/hitl-gate.d.ts.map +1 -0
  32. package/dist/sanitizer/hitl-gate.js +101 -0
  33. package/dist/sanitizer/hitl-gate.js.map +1 -0
  34. package/dist/sanitizer/threat-reporter.d.ts +1 -0
  35. package/dist/sanitizer/threat-reporter.d.ts.map +1 -1
  36. package/dist/sanitizer/threat-reporter.js +10 -7
  37. package/dist/sanitizer/threat-reporter.js.map +1 -1
  38. package/infrastructure/stack.ts +1 -0
  39. package/lambda-deploy/index.js +81512 -0
  40. package/lambda-deploy/index.js.map +7 -0
  41. package/lambda-package/browser/__mocks__/playwright-renderer.d.ts +25 -0
  42. package/lambda-package/browser/__mocks__/playwright-renderer.d.ts.map +1 -0
  43. package/lambda-package/browser/__mocks__/playwright-renderer.js +119 -0
  44. package/lambda-package/browser/__mocks__/playwright-renderer.js.map +1 -0
  45. package/lambda-package/browser/playwright-renderer.d.ts +40 -0
  46. package/lambda-package/browser/playwright-renderer.d.ts.map +1 -0
  47. package/lambda-package/browser/playwright-renderer.js +214 -0
  48. package/lambda-package/browser/playwright-renderer.js.map +1 -0
  49. package/lambda-package/browser/reader.d.ts +31 -0
  50. package/lambda-package/browser/reader.d.ts.map +1 -0
  51. package/lambda-package/browser/reader.js +98 -0
  52. package/lambda-package/browser/reader.js.map +1 -0
  53. package/lambda-package/index.d.ts +18 -0
  54. package/lambda-package/index.d.ts.map +1 -0
  55. package/lambda-package/index.js +238 -0
  56. package/lambda-package/index.js.map +1 -0
  57. package/lambda-package/lambda-handler.d.ts +28 -0
  58. package/lambda-package/lambda-handler.d.ts.map +1 -0
  59. package/lambda-package/lambda-handler.js +257 -0
  60. package/lambda-package/lambda-handler.js.map +1 -0
  61. package/lambda-package/package-lock.json +7435 -0
  62. package/lambda-package/package.json +74 -0
  63. package/lambda-package/runtime.d.ts +50 -0
  64. package/lambda-package/runtime.d.ts.map +1 -0
  65. package/lambda-package/runtime.js +86 -0
  66. package/lambda-package/runtime.js.map +1 -0
  67. package/lambda-package/sanitizer/elicit-runner.d.ts +48 -0
  68. package/lambda-package/sanitizer/elicit-runner.d.ts.map +1 -0
  69. package/lambda-package/sanitizer/elicit-runner.js +100 -0
  70. package/lambda-package/sanitizer/elicit-runner.js.map +1 -0
  71. package/lambda-package/sanitizer/framework-mapper.d.ts +24 -0
  72. package/lambda-package/sanitizer/framework-mapper.d.ts.map +1 -0
  73. package/lambda-package/sanitizer/framework-mapper.js +342 -0
  74. package/lambda-package/sanitizer/framework-mapper.js.map +1 -0
  75. package/lambda-package/sanitizer/hitl-gate.d.ts +69 -0
  76. package/lambda-package/sanitizer/hitl-gate.d.ts.map +1 -0
  77. package/lambda-package/sanitizer/hitl-gate.js +101 -0
  78. package/lambda-package/sanitizer/hitl-gate.js.map +1 -0
  79. package/lambda-package/sanitizer/index.d.ts +63 -0
  80. package/lambda-package/sanitizer/index.d.ts.map +1 -0
  81. package/lambda-package/sanitizer/index.js +105 -0
  82. package/lambda-package/sanitizer/index.js.map +1 -0
  83. package/lambda-package/sanitizer/injection-detector.d.ts +34 -0
  84. package/lambda-package/sanitizer/injection-detector.d.ts.map +1 -0
  85. package/lambda-package/sanitizer/injection-detector.js +89 -0
  86. package/lambda-package/sanitizer/injection-detector.js.map +1 -0
  87. package/lambda-package/sanitizer/patterns.d.ts +30 -0
  88. package/lambda-package/sanitizer/patterns.d.ts.map +1 -0
  89. package/lambda-package/sanitizer/patterns.js +372 -0
  90. package/lambda-package/sanitizer/patterns.js.map +1 -0
  91. package/lambda-package/sanitizer/pii-allowlist.d.ts +49 -0
  92. package/lambda-package/sanitizer/pii-allowlist.d.ts.map +1 -0
  93. package/lambda-package/sanitizer/pii-allowlist.js +231 -0
  94. package/lambda-package/sanitizer/pii-allowlist.js.map +1 -0
  95. package/lambda-package/sanitizer/pii-redactor.d.ts +41 -0
  96. package/lambda-package/sanitizer/pii-redactor.d.ts.map +1 -0
  97. package/lambda-package/sanitizer/pii-redactor.js +213 -0
  98. package/lambda-package/sanitizer/pii-redactor.js.map +1 -0
  99. package/lambda-package/sanitizer/severity-classifier.d.ts +33 -0
  100. package/lambda-package/sanitizer/severity-classifier.d.ts.map +1 -0
  101. package/lambda-package/sanitizer/severity-classifier.js +113 -0
  102. package/lambda-package/sanitizer/severity-classifier.js.map +1 -0
  103. package/lambda-package/sanitizer/threat-reporter.d.ts +66 -0
  104. package/lambda-package/sanitizer/threat-reporter.d.ts.map +1 -0
  105. package/lambda-package/sanitizer/threat-reporter.js +163 -0
  106. package/lambda-package/sanitizer/threat-reporter.js.map +1 -0
  107. package/lambda-package/tools/fetch-structured.d.ts +51 -0
  108. package/lambda-package/tools/fetch-structured.d.ts.map +1 -0
  109. package/lambda-package/tools/fetch-structured.js +237 -0
  110. package/lambda-package/tools/fetch-structured.js.map +1 -0
  111. package/lambda-package/tools/fetch.d.ts +49 -0
  112. package/lambda-package/tools/fetch.d.ts.map +1 -0
  113. package/lambda-package/tools/fetch.js +131 -0
  114. package/lambda-package/tools/fetch.js.map +1 -0
  115. package/lambda-package/tools/read.d.ts +51 -0
  116. package/lambda-package/tools/read.d.ts.map +1 -0
  117. package/lambda-package/tools/read.js +127 -0
  118. package/lambda-package/tools/read.js.map +1 -0
  119. package/lambda-package/tools/search.d.ts +45 -0
  120. package/lambda-package/tools/search.d.ts.map +1 -0
  121. package/lambda-package/tools/search.js +220 -0
  122. package/lambda-package/tools/search.js.map +1 -0
  123. package/lambda-package/types.d.ts +167 -0
  124. package/lambda-package/types.d.ts.map +1 -0
  125. package/lambda-package/types.js +16 -0
  126. package/lambda-package/types.js.map +1 -0
  127. package/lambda-package/utils/format-converter.d.ts +39 -0
  128. package/lambda-package/utils/format-converter.d.ts.map +1 -0
  129. package/lambda-package/utils/format-converter.js +191 -0
  130. package/lambda-package/utils/format-converter.js.map +1 -0
  131. package/lambda-package/utils/truncate.d.ts +26 -0
  132. package/lambda-package/utils/truncate.d.ts.map +1 -0
  133. package/lambda-package/utils/truncate.js +54 -0
  134. package/lambda-package/utils/truncate.js.map +1 -0
  135. package/lambda.zip +0 -0
  136. package/mcp.json +44 -0
  137. package/package.json +9 -8
  138. package/server.json +43 -0
  139. package/src/browser/playwright-renderer.ts +74 -51
  140. package/src/index.ts +78 -6
  141. package/src/sanitizer/elicit-runner.ts +125 -0
  142. package/src/sanitizer/framework-mapper.ts +92 -45
  143. package/src/sanitizer/hitl-gate.ts +111 -0
  144. package/src/sanitizer/threat-reporter.ts +11 -7
  145. package/tests/elicit-runner.test.ts +232 -0
  146. package/tests/hitl-gate.test.ts +267 -0
  147. package/tests/threat-reporter.test.ts +69 -1
@@ -0,0 +1,329 @@
1
+ # Contributing to Visus
2
+
3
+ Thank you for considering contributing to Visus! This project is security-first — all contributions must maintain the sanitization guarantees that protect users. Visus is engineered, not vibe-coded. We expect rigorous testing, clear documentation, and adherence to security best practices.
4
+
5
+ ---
6
+
7
+ ## What We're Looking For
8
+
9
+ The most valuable contributions to Visus are:
10
+
11
+ - **New injection pattern categories** (most wanted) — Validated detection patterns for emerging prompt injection techniques
12
+ - **False positive reports** — Cases where Visus incorrectly flags or redacts legitimate content
13
+ - **New PII redaction types** — Additional personally identifiable information patterns (passports, driver's licenses, medical IDs, etc.)
14
+ - **Performance improvements** — Optimizations to the sanitizer pipeline that maintain coverage
15
+ - **Documentation improvements** — Clearer explanations, better examples, tutorial content
16
+ - **Bug reports with reproduction steps** — Detailed reports that help us quickly identify and fix issues
17
+
18
+ ### What is OUT OF SCOPE
19
+
20
+ To avoid wasted effort, please **do not submit PRs** for:
21
+
22
+ - Changes that reduce sanitization coverage or allow bypassing the pipeline
23
+ - New tools that don't run content through the sanitizer
24
+ - Dependencies that require Python runtime (Visus is TypeScript-only)
25
+ - Modifications to the security rules defined in CLAUDE.md
26
+ - Changes that introduce `any` types or violate TypeScript strict mode
27
+
28
+ ---
29
+
30
+ ## How to Add a New Injection Pattern
31
+
32
+ This is the most important contribution type. Follow these steps carefully:
33
+
34
+ ### Step 1: Add the pattern definition
35
+
36
+ Open `src/sanitizer/patterns.ts` and add your pattern to the `INJECTION_PATTERNS` array. Each pattern requires:
37
+
38
+ ```typescript
39
+ {
40
+ name: 'your_pattern_name', // snake_case identifier
41
+ description: 'What this detects', // Brief explanation
42
+ regex: /pattern_here/gi, // Detection regex (case-insensitive)
43
+ severity: 'critical', // critical | high | medium | low
44
+ action: 'redact' // strip | redact | escape
45
+ }
46
+ ```
47
+
48
+ **Example pattern:**
49
+ ```typescript
50
+ {
51
+ name: 'unicode_normalization_attack',
52
+ description: 'Uses Unicode normalization to hide instructions',
53
+ regex: /\u0041\u0301.*\b(ignore|admin)\b/gi, // Á (decomposed) hiding text
54
+ severity: 'high',
55
+ action: 'strip'
56
+ }
57
+ ```
58
+
59
+ ### Step 2: Add severity classification
60
+
61
+ Open `src/sanitizer/severity-classifier.ts` and add your pattern category to the correct severity level:
62
+
63
+ ```typescript
64
+ case 'your_pattern_name':
65
+ return 'CRITICAL'; // or HIGH, MEDIUM, LOW
66
+ ```
67
+
68
+ ### Step 3: Add framework mappings
69
+
70
+ Open `src/sanitizer/framework-mapper.ts` and add mappings for all four compliance frameworks:
71
+
72
+ ```typescript
73
+ your_pattern_name: {
74
+ owasp_llm: 'LLM01:2025 - Prompt Injection',
75
+ nist_ai_600_1: 'MS-2.5 - Prompt Injection',
76
+ mitre_atlas: 'AML.T0051.000 - LLM Prompt Injection',
77
+ iso_42001: 'A.6.1.5 - AI System Security (Adversarial Input)'
78
+ },
79
+ ```
80
+
81
+ **How to choose mappings:**
82
+ - **OWASP LLM Top 10**: See [OWASP LLM Top 10 (2025)](https://owasp.org/www-project-top-10-for-large-language-model-applications/)
83
+ - **NIST AI 600-1**: See [NIST AI 600-1 Controls](https://csrc.nist.gov/pubs/ai/600/1/final)
84
+ - **MITRE ATLAS**: See [MITRE ATLAS Tactics](https://atlas.mitre.org/)
85
+ - **ISO/IEC 42001**: Use Annex A controls (A.X.X format)
86
+
87
+ ### Step 4: Add test cases
88
+
89
+ Open `tests/sanitizer.test.ts` and add at least two test cases:
90
+
91
+ **Positive case** (content that SHOULD be caught):
92
+ ```typescript
93
+ it('should detect your_pattern_name', () => {
94
+ const result = sanitize('Malicious content here that triggers pattern');
95
+ expect(result.patterns_detected).toContain('your_pattern_name');
96
+ expect(result.content_modified).toBe(true);
97
+ });
98
+ ```
99
+
100
+ **Negative case** (legitimate content that should NOT be caught):
101
+ ```typescript
102
+ it('should NOT flag legitimate content as your_pattern_name', () => {
103
+ const result = sanitize('Legitimate content that looks similar but is safe');
104
+ expect(result.patterns_detected).not.toContain('your_pattern_name');
105
+ expect(result.content_modified).toBe(false);
106
+ });
107
+ ```
108
+
109
+ **Why negative cases matter:** False positives erode trust. Always test that your pattern doesn't fire on legitimate content.
110
+
111
+ ### Step 5: Run tests
112
+
113
+ ```bash
114
+ npm test
115
+ ```
116
+
117
+ All tests must pass (100% pass rate). If any tests fail, fix them before submitting.
118
+
119
+ ### Step 6: Update SECURITY.md
120
+
121
+ Add your pattern to the appropriate severity section in `SECURITY.md` with an example:
122
+
123
+ ```markdown
124
+ **XX. Your Pattern Name**
125
+ - **Example**: "Text that triggers the pattern"
126
+ - **Action**: Redact/Strip/Escape
127
+ ```
128
+
129
+ ---
130
+
131
+ ## How to Report a False Positive
132
+
133
+ A **false positive** occurs when Visus incorrectly flags or redacts legitimate, non-malicious content. These are **high priority bugs** because they impact usability.
134
+
135
+ **To report a false positive:**
136
+
137
+ 1. Open a **"False Positive Report"** issue using the GitHub issue template
138
+ 2. Include:
139
+ - The URL or content that triggered the false positive (sanitize if sensitive)
140
+ - Which pattern category fired (visible in `patterns_detected` field)
141
+ - What the expected behavior should be
142
+ - Domain context (news site, documentation, health info, government, etc.)
143
+ 3. **Do NOT include:**
144
+ - Sensitive URLs or private content in public issues
145
+ - Personally identifiable information
146
+
147
+ We take false positives seriously and will prioritize fixes.
148
+
149
+ ---
150
+
151
+ ## Development Setup
152
+
153
+ ### Prerequisites
154
+
155
+ - **Node.js** 18+ and npm
156
+ - **Git** for version control
157
+ - **macOS / Windows**: No additional setup required
158
+ - **Linux**: Playwright requires system libraries (see README.md)
159
+
160
+ ### Clone and Install
161
+
162
+ ```bash
163
+ git clone https://github.com/visus-mcp/visus-mcp.git
164
+ cd visus-mcp
165
+ npm install
166
+ npm run build
167
+ npm test
168
+ ```
169
+
170
+ **Note about Playwright:** The first run will download Chromium (~170MB). This is normal.
171
+
172
+ **Note about macOS iCloud:** If you use iCloud Drive, develop in `~/Projects`, NOT `~/Documents`. iCloud sync can interfere with node_modules.
173
+
174
+ ---
175
+
176
+ ## Running Tests
177
+
178
+ ```bash
179
+ npm test # Full test suite (all 274+ tests)
180
+ npm test -- --watch # Watch mode for active development
181
+ npm test sanitizer # Run sanitizer tests only
182
+ npm test -- --coverage # Generate coverage report
183
+ ```
184
+
185
+ **Test requirements:**
186
+ - All PRs must pass 100% of existing tests
187
+ - New functionality must include new tests
188
+ - Test count should never decrease
189
+ - Minimum 80% code coverage
190
+
191
+ ---
192
+
193
+ ## Security Vulnerability Reporting
194
+
195
+ **DO NOT open public issues for security vulnerabilities.**
196
+
197
+ If you discover a security vulnerability in Visus (e.g., a way to bypass the sanitizer, extract PII, or compromise the system):
198
+
199
+ 📧 **Email:** security@lateos.ai
200
+
201
+ Include in your report:
202
+ - Description of the vulnerability
203
+ - Steps to reproduce
204
+ - Potential impact assessment
205
+ - Suggested fix (optional)
206
+
207
+ We aim to respond within 48 hours and will work with you on a coordinated disclosure timeline (typically 90 days).
208
+
209
+ See [SECURITY.md](./SECURITY.md) for the full disclosure policy.
210
+
211
+ ---
212
+
213
+ ## Pull Request Process
214
+
215
+ ### Before Opening a PR
216
+
217
+ 1. **Fork the repo** and create a feature branch:
218
+ ```bash
219
+ git checkout -b feature/your-feature-name
220
+ ```
221
+
222
+ 2. **Make your changes** with tests:
223
+ - Write code following TypeScript strict mode
224
+ - Add test cases for new functionality
225
+ - Update documentation if needed
226
+
227
+ 3. **Run the test suite**:
228
+ ```bash
229
+ npm test
230
+ ```
231
+ All tests must pass (100% success rate).
232
+
233
+ 4. **Run the build**:
234
+ ```bash
235
+ npm run build
236
+ ```
237
+ TypeScript must compile cleanly with zero errors.
238
+
239
+ 5. **Update STATUS.md** if adding a new feature:
240
+ - Add your feature to the current version section
241
+ - Use consistent formatting with existing entries
242
+
243
+ ### Opening the PR
244
+
245
+ 1. Push your branch to your fork
246
+ 2. Open a PR against the `main` branch
247
+ 3. Use the PR template and fill out all sections
248
+ 4. Include a clear description of **what** changed and **why**
249
+ 5. Reference any related issues (e.g., "Closes #123")
250
+
251
+ ### PR Review Criteria
252
+
253
+ Your PR will be reviewed for:
254
+
255
+ - ✅ **Test coverage** — All existing tests pass, new tests added
256
+ - ✅ **TypeScript compliance** — No `any` types, strict mode passes
257
+ - ✅ **Security** — Sanitizer pipeline not bypassed
258
+ - ✅ **Documentation** — Code is well-commented and clear
259
+ - ✅ **Performance** — No significant latency regressions
260
+
261
+ **PRs that will NOT be merged:**
262
+ - ❌ Reduce test count or coverage
263
+ - ❌ Bypass the sanitizer pipeline
264
+ - ❌ Introduce `any` types or disable strict mode
265
+ - ❌ Break existing functionality
266
+
267
+ ---
268
+
269
+ ## Code Style
270
+
271
+ ### TypeScript Conventions
272
+
273
+ - **TypeScript strict mode** — No `any` types allowed (use `unknown` if necessary)
274
+ - **Explicit return types** — All functions must declare return types
275
+ - **JSDoc comments** — All public functions must have JSDoc documentation
276
+ - **Error handling** — Never throw raw errors; return typed Result objects
277
+
278
+ ### MCP Tool Registration
279
+
280
+ All new tools must register with proper MCP annotations:
281
+
282
+ ```typescript
283
+ {
284
+ name: 'tool_name',
285
+ description: 'What this tool does',
286
+ readOnlyHint: true, // If tool doesn't modify state
287
+ destructiveHint: false, // If tool could cause data loss
288
+ idempotentHint: true, // If repeated calls have same effect
289
+ openWorldHint: false // If tool accesses external resources
290
+ }
291
+ ```
292
+
293
+ ### Logging
294
+
295
+ - **Structured JSON** to stderr only (never `console.log`)
296
+ - **Never log PII** — Use field redaction for sensitive data
297
+ - **Use timestamps** in ISO 8601 format
298
+
299
+ **Example:**
300
+ ```typescript
301
+ console.error(JSON.stringify({
302
+ timestamp: new Date().toISOString(),
303
+ event: 'sanitization_completed',
304
+ patterns_detected: ['role_hijacking'],
305
+ content_modified: true
306
+ }));
307
+ ```
308
+
309
+ ---
310
+
311
+ ## Recognition
312
+
313
+ Contributors who add validated injection patterns that are merged into the main branch will be credited in:
314
+
315
+ - **SECURITY.md** under "Community Patterns"
316
+ - **Release notes** for the version that includes their pattern
317
+ - **GitHub Contributors** page
318
+
319
+ We deeply appreciate the security research community's contributions to making Visus more robust.
320
+
321
+ ---
322
+
323
+ ## Questions?
324
+
325
+ - **General questions**: Open a [GitHub Discussion](https://github.com/visus-mcp/visus-mcp/discussions)
326
+ - **Bug reports**: Use the [Bug Report issue template](https://github.com/visus-mcp/visus-mcp/issues/new?template=bug_report.md)
327
+ - **Security issues**: Email security@lateos.ai (do NOT open public issues)
328
+
329
+ **Built with by Lateos**
package/README.md CHANGED
@@ -1,30 +1,55 @@
1
1
  # Visus — Secure Web Access for Claude
2
2
 
3
- > **Every MCP browser tool passes raw web content to your LLM. Visus doesn't.**
3
+ [![npm version](https://img.shields.io/npm/v/visus-mcp?color=crimson&label=npm)](https://www.npmjs.com/package/visus-mcp)
4
+ [![tests](https://img.shields.io/badge/tests-246%20passing-brightgreen)](https://github.com/visus-mcp/visus-mcp)
5
+ [![tools](https://img.shields.io/badge/MCP%20tools-4-blue)](https://github.com/visus-mcp/visus-mcp)
6
+ [![mcp](https://img.shields.io/badge/MCP-compatible-brightgreen)](https://modelcontextprotocol.io)
7
+ [![license](https://img.shields.io/badge/license-MIT-blue)](https://github.com/visus-mcp/visus-mcp/blob/main/LICENSE)
8
+ [![security](https://img.shields.io/badge/frameworks-NIST%20%7C%20OWASP%20%7C%20MITRE%20%7C%20ISO42001-orange)](https://github.com/visus-mcp/visus-mcp/blob/main/SECURITY.md)
9
+ [![iso42001](https://img.shields.io/badge/ISO%2FIEC-42001%3A2023-blueviolet)](https://www.iso.org/standard/81230.html)
4
10
 
5
- Visus is an MCP (Model Context Protocol) tool that provides Claude with secure, sanitized access to web pages. Built by [Lateos](https://lateos.ai), Visus runs **all** fetched content through a comprehensive injection sanitization pipeline before the LLM reads a single character.
11
+ > **Your AI agent shouldn't have to read garbage.**
12
+ > **visus-mcp makes sure it doesn't.**
6
13
 
7
- **Tagline:** *"What the web shows you, Lateos reads safely."*
14
+ When your agent fetches a webpage it reads everything — nav bars, cookie banners, tracking scripts, ads, SEO spam. Every token costs money. Some pages also embed hidden instructions designed to manipulate your agent's behaviour.
15
+
16
+ Claude handles most of it. But it still has to read all of it first. You still pay for every token.
17
+
18
+ **visus-mcp is a pre-filter.** It strips the noise before a single character enters Claude's context window — reducing token consumption on bloated pages by up to 70%, redacting PII before it enters conversation history, and producing a compliance-grade audit log when it finds something worth flagging.
19
+
20
+ Built as infrastructure, not a replacement for Claude's own safety training. The two layers together are stronger than either alone.
21
+ ```bash
22
+ npx visus-mcp@0.6.0
23
+ ```
24
+
25
+ *"What the web shows you, Lateos reads safely."*
8
26
 
9
27
  ---
10
28
 
11
- ## The Problem with Other Tools
29
+ ## Why Your Agent Is Reading Too Much
12
30
 
13
- Popular MCP browser tools like Firecrawl, Playwright MCP, and ScrapeGraphAI pass untrusted web content directly to your LLM without sanitization. This creates a **critical security vulnerability**:
31
+ A typical news article: **12,000 tokens** of raw HTML.
32
+ The actual article content: **~800 tokens**.
14
33
 
15
- - **Prompt injection attacks** can manipulate AI behavior
16
- - **Personal identifiable information (PII)** can leak into conversation logs
17
- - **Malicious instructions** hidden in web pages can compromise your AI agent
34
+ You're paying for the nav bar. The footer. The cookie banner. The analytics scripts. The related articles sidebar. The ads.
18
35
 
19
- Visus solves this by treating **every web page as untrusted input** and sanitizing it before your LLM sees it.
36
+ visus-mcp fetches the same page and delivers:
37
+ - **visus_read** — article content only via Mozilla Readability (~70% token reduction on content-heavy pages)
38
+ - **visus_fetch** — full page with noise stripped and format-converted (JSON/XML/RSS auto-detected)
39
+ - **visus_search** — sanitized DuckDuckGo results, SEO spam removed before it hits context
40
+
41
+ **Real example from today:** fetching npmjs.com/package/visus-mcp returned 149,589 bytes raw. visus-mcp delivered 44,129 bytes to Claude. Same information. 70% fewer tokens.
42
+
43
+ **And when a page is actively trying to manipulate your agent** — hidden instructions, obfuscated scripts, role hijacking attempts — visus strips those too and logs them in a structured compliance report. Not because Claude can't handle them. Because your agent shouldn't have to spend tokens reading attack attempts in the first place.
20
44
 
21
45
  ---
22
46
 
23
47
  ## How Visus Works
24
48
 
25
49
  ```
26
- User provides URL → Playwright FetchInjection Sanitizer (43 patterns)
27
- PII Redactor Clean Content Claude via MCP
50
+ URL → Playwright RenderFormat Detection (HTML/JSON/XML/RSS)
51
+ Reader Extraction (optional)Injection Sanitizer (43 patterns)
52
+ → PII Redactor → Token Ceiling (24k cap) → Clean Content → Claude
28
53
  ```
29
54
 
30
55
  ### Security Pipeline
@@ -32,9 +57,9 @@ PII Redactor → Clean Content → Claude via MCP
32
57
  1. **Browser Rendering**: Headless Chromium via Playwright fetches the page
33
58
  2. **Injection Detection**: 43 pattern categories scan for prompt injection attempts
34
59
  3. **PII Redaction**: Emails, phone numbers, SSNs, credit cards, and IP addresses are redacted
35
- 4. **Clean Delivery**: Only sanitized content reaches your LLM
60
+ 4. **Clean Delivery**: Stripped, formatted, token-efficient content reaches your LLM — with a compliance report attached if anything was flagged
36
61
 
37
- **This pipeline cannot be bypassed.** Every tool invocation runs content through the full sanitizer.
62
+ **This pipeline runs before content enters Claude's context window** reducing token consumption, keeping PII out of conversation history, and generating audit logs when injection patterns are detected.
38
63
 
39
64
  ---
40
65
 
@@ -80,11 +105,16 @@ npx visus-mcp
80
105
 
81
106
  ### Claude Desktop Configuration
82
107
 
83
- Visus supports three rendering backends:
108
+ > [!NOTE]
109
+ > **No API key required.** The open-source tier works out of the box with `npx visus-mcp`.
110
+ > Sanitization always runs locally — web content never reaches Lateos infrastructure
111
+ > unless you explicitly configure the managed renderer URL.
112
+
113
+ Visus supports three deployment tiers:
84
114
 
85
- **Example 1 — Phase 1 (Default, No Lambda):**
115
+ **Tier 1 — Open Source / Default (No env vars required):**
86
116
 
87
- Basic configuration using undici HTTP fetch (no JavaScript execution):
117
+ Uses Playwright locally with full JavaScript support. Works immediately, zero configuration:
88
118
 
89
119
  ```json
90
120
  {
@@ -97,9 +127,11 @@ Basic configuration using undici HTTP fetch (no JavaScript execution):
97
127
  }
98
128
  ```
99
129
 
100
- **Example 2 — Managed Tier (Lateos Endpoint):**
130
+ **Tier 2 — Managed / Lateos (Hosted renderer) — Coming Phase 2:**
101
131
 
102
- Use Lateos managed Lambda renderer with Playwright (supports JavaScript, SPAs):
132
+ > [!NOTE]
133
+ > The hosted Lateos renderer is part of Phase 2 and is not yet publicly available.
134
+ > Sign up for early access at [lateos.ai](https://lateos.ai).
103
135
 
104
136
  ```json
105
137
  {
@@ -108,15 +140,16 @@ Use Lateos managed Lambda renderer with Playwright (supports JavaScript, SPAs):
108
140
  "command": "npx",
109
141
  "args": ["visus-mcp"],
110
142
  "env": {
111
- "VISUS_RENDERER_URL": "https://renderer.lateos.ai",
112
- "NODE_EXTRA_CA_CERTS": "/path/to/system-ca-bundle.pem"
143
+ "VISUS_RENDERER_URL": "https://renderer.lateos.ai"
113
144
  }
114
145
  }
115
146
  }
116
147
  }
117
148
  ```
118
149
 
119
- **Example 3 BYOC (Your Own Lambda):**
150
+ The sanitization pipeline always runs locally. This config simply routes page rendering (JavaScript execution) through a hosted Playwright Lambda instead of local Playwright. Available Phase 2.
151
+
152
+ **Tier 3 — BYOC (Bring Your Own Cloud):**
120
153
 
121
154
  Deploy your own Lambda renderer (see [visus-mcp-renderer](https://github.com/visus-mcp/visus-mcp-renderer)):
122
155
 
@@ -127,8 +160,7 @@ Deploy your own Lambda renderer (see [visus-mcp-renderer](https://github.com/vis
127
160
  "command": "npx",
128
161
  "args": ["visus-mcp"],
129
162
  "env": {
130
- "VISUS_RENDERER_URL": "https://YOUR_API_ID.execute-api.YOUR_REGION.amazonaws.com",
131
- "NODE_EXTRA_CA_CERTS": "/path/to/system-ca-bundle.pem"
163
+ "VISUS_RENDERER_URL": "https://YOUR_API_ID.execute-api.YOUR_REGION.amazonaws.com"
132
164
  }
133
165
  }
134
166
  }
@@ -137,7 +169,7 @@ Deploy your own Lambda renderer (see [visus-mcp-renderer](https://github.com/vis
137
169
 
138
170
  Replace `YOUR_API_ID` and `YOUR_REGION` with values from your CDK deployment output.
139
171
 
140
- **CRITICAL SECURITY NOTE:** The sanitizer ALWAYS runs locally, regardless of which renderer you use. Rendered HTML is returned to your local visus-mcp process before Claude sees it. PHI never touches Lateos infrastructure (even when using the managed tier).
172
+ **CRITICAL SECURITY NOTE:** The sanitizer ALWAYS runs locally, regardless of which tier you use. Rendered HTML is returned to your local visus-mcp process before Claude sees it. Web content never touches Lateos infrastructure unless you explicitly configure the managed renderer URL.
141
173
 
142
174
  Restart Claude Desktop. Visus tools are now available to Claude.
143
175
 
@@ -147,7 +179,7 @@ Restart Claude Desktop. Visus tools are now available to Claude.
147
179
 
148
180
  ### `visus_fetch`
149
181
 
150
- Fetch and sanitize a web page with automatic format detection. Supports HTML, JSON, XML, and RSS/Atom feeds. Includes NIST AI 600-1 / OWASP LLM / MITRE ATLAS aligned threat report when injection or PII is detected.
182
+ Fetch and sanitize a web page with automatic format detection. Supports HTML, JSON, XML, and RSS/Atom feeds. Includes NIST AI 600-1 / OWASP LLM / MITRE ATLAS / ISO/IEC 42001 aligned threat report when injection or PII is detected.
151
183
 
152
184
  **Supported Formats:**
153
185
  - **HTML** (`text/html`, `application/xhtml+xml`) - Standard web pages, returned as-is
@@ -157,7 +189,7 @@ Fetch and sanitize a web page with automatic format detection. Supports HTML, JS
157
189
 
158
190
  ### `visus_read`
159
191
 
160
- Extract clean article content from a web page using Mozilla Readability (reader mode). Includes NIST AI 600-1 / OWASP LLM / MITRE ATLAS aligned threat report when injection or PII is detected.
192
+ Extract clean article content from a web page using Mozilla Readability (reader mode). Includes NIST AI 600-1 / OWASP LLM / MITRE ATLAS / ISO/IEC 42001 aligned threat report when injection or PII is detected.
161
193
 
162
194
  **Input:**
163
195
  ```json
@@ -189,7 +221,7 @@ Extract clean article content from a web page using Mozilla Readability (reader
189
221
 
190
222
  ### `visus_search`
191
223
 
192
- Search the web via DuckDuckGo and return sanitized results with prompt injection and PII removed. Use before `visus_fetch` or `visus_read` to safely discover and then read pages. Includes NIST AI 600-1 / OWASP LLM / MITRE ATLAS aligned threat report when injection or PII is detected.
224
+ Search the web via DuckDuckGo and return sanitized results with prompt injection and PII removed. Use before `visus_fetch` or `visus_read` to safely discover and then read pages. Includes NIST AI 600-1 / OWASP LLM / MITRE ATLAS / ISO/IEC 42001 aligned threat report when injection or PII is detected.
193
225
 
194
226
  **Input:**
195
227
  ```json
@@ -222,7 +254,7 @@ All search result titles and snippets are independently sanitized before reachin
222
254
 
223
255
  ### `visus_fetch_structured`
224
256
 
225
- Extract structured data from a web page according to a schema. Includes NIST AI 600-1 / OWASP LLM / MITRE ATLAS aligned threat report when injection or PII is detected.
257
+ Extract structured data from a web page according to a schema. Includes NIST AI 600-1 / OWASP LLM / MITRE ATLAS / ISO/IEC 42001 aligned threat report when injection or PII is detected.
226
258
 
227
259
  **Input:**
228
260
  ```json
@@ -275,7 +307,7 @@ Findings are encoded using [TOON format](https://toonformat.dev) for token effic
275
307
  - Pattern ID and category
276
308
  - Severity level (CRITICAL, HIGH, MEDIUM, LOW)
277
309
  - Confidence score
278
- - Framework alignments (OWASP LLM Top 10, NIST AI 600-1, MITRE ATLAS)
310
+ - Framework alignments (OWASP LLM Top 10, NIST AI 600-1, MITRE ATLAS, ISO/IEC 42001)
279
311
  - Remediation status
280
312
 
281
313
  ### 2. Markdown Compliance Report (Human-Readable)
@@ -290,11 +322,12 @@ A formatted Markdown table renders cleanly in Claude Desktop and GitHub, showing
290
322
 
291
323
  ### Framework Alignments
292
324
 
293
- Every detected threat is mapped to three compliance frameworks:
325
+ Every detected threat is mapped to four compliance frameworks:
294
326
 
295
327
  - **[OWASP LLM Top 10 (2025)](https://owasp.org/www-project-top-10-for-large-language-model-applications/)**: Industry-standard LLM security risks
296
328
  - **[NIST AI 600-1](https://csrc.nist.gov/pubs/ai/600/1/final)**: Generative AI Profile for risk management
297
329
  - **[MITRE ATLAS](https://atlas.mitre.org/)**: Adversarial Threat Landscape for AI Systems
330
+ - **[ISO/IEC 42001:2023](https://www.iso.org/standard/81230.html)**: International AI Management System standard — Annex A controls for AI system security, data quality, and responsible AI governance. Globally recognized for enterprise and regulatory procurement.
298
331
 
299
332
  ### When Reports Are Generated
300
333
 
@@ -303,6 +336,32 @@ Threat reports are included in tool responses **only when findings exist**:
303
336
  - ✅ PII redacted → Report included
304
337
  - ❌ Clean content → Report omitted (zero overhead)
305
338
 
339
+ ### Human-in-the-Loop Security
340
+
341
+ When Visus detects a **CRITICAL** severity threat, it pauses execution and surfaces a confirmation dialog before returning content:
342
+
343
+ ```
344
+ ⚠️ Visus blocked a CRITICAL threat on this page.
345
+
346
+ 2 injection attempt(s) detected on: https://malicious.example.com
347
+
348
+ Highest severity finding: role_hijacking
349
+ (LLM01:2025 | AML.T0051.000)
350
+
351
+ Content has been sanitized. Proceed with clean version?
352
+
353
+ [ ✓ Proceed with sanitized content ] [ ✓ Include threat report ]
354
+ ```
355
+
356
+ **Three outcomes:**
357
+ - **Accept** → Sanitized content delivered, threat report attached if requested
358
+ - **Decline** → Request blocked, threat details returned for review
359
+ - **No response / timeout** → Sanitized content delivered (fail-safe)
360
+
361
+ **Important:** HITL triggers only on CRITICAL findings. HIGH/MEDIUM/LOW findings are sanitized silently with threat report attached — no interruption to workflow.
362
+
363
+ **Security model:** Sanitization is the security gate. HITL is UX. Content is ALWAYS sanitized before reaching the LLM, whether or not you accept the elicitation prompt.
364
+
306
365
  ### Example Threat Report
307
366
 
308
367
  When a HIGH severity injection is detected:
@@ -313,7 +372,7 @@ When a HIGH severity injection is detected:
313
372
  **Generated:** 2026-03-23T14:30:00.000Z
314
373
  **Source:** https://malicious.example.com
315
374
  **Overall Severity:** HIGH
316
- **Framework:** OWASP LLM Top 10 | NIST AI 600-1 | MITRE ATLAS
375
+ **Framework:** OWASP LLM Top 10 | NIST AI 600-1 | MITRE ATLAS | ISO/IEC 42001
317
376
 
318
377
  ### Findings Summary
319
378
  | Severity | Count |
@@ -324,9 +383,9 @@ When a HIGH severity injection is detected:
324
383
  | 🟢 LOW | 0 |
325
384
 
326
385
  ### Findings Detail
327
- | # | Category | Severity | Confidence | OWASP | MITRE |
328
- |---|---|---|---|---|---|
329
- | 1 | role_hijacking | CRITICAL | 95% | LLM01:2025 | AML.T0051.000 |
386
+ | # | Category | Severity | Confidence | OWASP | MITRE | ISO 42001 |
387
+ |---|---|---|---|---|---|---|
388
+ | 1 | role_hijacking | CRITICAL | 95% | LLM01:2025 | AML.T0051.000 | A.6.1.5 |
330
389
 
331
390
  ### Remediation Status
332
391
  ✅ All findings sanitized. Content delivered clean.
@@ -698,7 +757,7 @@ Visus is part of the **Lateos** platform — a security-by-design AI agent frame
698
757
 
699
758
  - **AWS Serverless**: Lambda, Step Functions, API Gateway, Cognito
700
759
  - **Security**: Bedrock Guardrails, KMS encryption, Secrets Manager
701
- - **Validated Patterns**: 43 injection patterns, 122/122 passing tests
760
+ - **Validated Patterns**: 43 injection patterns, 274/274 passing tests
702
761
  - **CISSP/CEH-Informed**: Designed by security professionals
703
762
 
704
763
  Learn more: [lateos.ai](https://lateos.ai) (Phase 2)
@@ -749,17 +808,21 @@ npm start
749
808
 
750
809
  ## Project Status
751
810
 
752
- **Phase 1** (Current): Open-source MCP tool with local sanitization
811
+ | Version | Status | Highlights |
812
+ |---|---|---|
813
+ | v0.7.0 | ✅ Complete | HITL Elicitation Bridge for CRITICAL threats |
814
+ | v0.6.0 | ✅ Released | Content-Type detection (JSON/XML/RSS) |
815
+ | v0.5.0 | ✅ Released | TOON threat reports, NIST/OWASP/MITRE/ISO42001 |
816
+ | v0.4.0 | ✅ Released | Safe DuckDuckGo search |
817
+ | v0.3.2 | ✅ Released | Reader mode (Mozilla Readability) |
818
+ | v0.3.1 | ✅ Released | Security hardening, 100% compliance |
819
+ | v0.3.0 | ✅ Released | PII allowlist (health authority numbers) |
753
820
 
754
- **Phase 2** (Planned):
755
- - Lateos cloud integration for audit logging
756
- - User session relay for authenticated pages
757
- - Hosted tier with SLA guarantees
821
+ **Phase 3 — Anthropic MCP Directory submission in progress.**
758
822
 
759
- **Phase 3** (Future):
760
- - Chrome extension for session relay
761
- - Real-time threat dashboard
762
- - Custom pattern libraries
823
+ Roadmap: `visus_report` PDF export · Docker image ·
824
+ `visus-file-mcp` (document sanitization) ·
825
+ Chrome extension for authenticated pages (LinkedIn, X, dashboards)
763
826
 
764
827
  ---
765
828
 
@@ -777,7 +840,7 @@ Report vulnerabilities: **security@lateos.ai** or [GitHub Security](https://gith
777
840
 
778
841
  MIT License
779
842
 
780
- Copyright (c) 2024 Lateos (Leo Chongolnee)
843
+ Copyright (c) 2026 Lateos (Leo Chongolnee)
781
844
 
782
845
  ---
783
846
 
@@ -791,6 +854,9 @@ Inspired by the MCP ecosystem and informed by CISSP/CEH security principles.
791
854
 
792
855
  ## FAQ
793
856
 
857
+ **Q: Does visus-mcp replace Claude's own safety features?**
858
+ A: No — and it's not trying to. Claude handles most injection attempts natively through its safety training. visus-mcp is a pre-filter that runs before content enters Claude's context window. The benefit is efficiency: your agent doesn't spend tokens processing noise, ads, tracking scripts, or known injection patterns that would be stripped anyway. Think of it as a pre-processor, not a replacement for model-level safety. The two layers together are more robust than either alone.
859
+
794
860
  **Q: Does Visus slow down web fetching?**
795
861
  A: Minimal overhead. Sanitization adds ~50-200ms per page.
796
862