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.
Files changed (203) hide show
  1. package/.claude/settings.local.json +15 -1
  2. package/.env.status +7 -0
  3. package/CHANGELOG.md +110 -0
  4. package/CLAUDE.md +3 -0
  5. package/README.md +29 -19
  6. package/SECURITY.md +2 -0
  7. package/STATUS.md +320 -12
  8. package/dist/browser/playwright-renderer.d.ts.map +1 -1
  9. package/dist/browser/playwright-renderer.js +27 -5
  10. package/dist/browser/playwright-renderer.js.map +1 -1
  11. package/dist/content-handlers/index.d.ts +36 -0
  12. package/dist/content-handlers/index.d.ts.map +1 -0
  13. package/dist/content-handlers/index.js +59 -0
  14. package/dist/content-handlers/index.js.map +1 -0
  15. package/dist/content-handlers/json-handler.d.ts +28 -0
  16. package/dist/content-handlers/json-handler.d.ts.map +1 -0
  17. package/dist/content-handlers/json-handler.js +116 -0
  18. package/dist/content-handlers/json-handler.js.map +1 -0
  19. package/dist/content-handlers/pdf-handler.d.ts +29 -0
  20. package/dist/content-handlers/pdf-handler.d.ts.map +1 -0
  21. package/dist/content-handlers/pdf-handler.js +77 -0
  22. package/dist/content-handlers/pdf-handler.js.map +1 -0
  23. package/dist/content-handlers/svg-handler.d.ts +35 -0
  24. package/dist/content-handlers/svg-handler.d.ts.map +1 -0
  25. package/dist/content-handlers/svg-handler.js +206 -0
  26. package/dist/content-handlers/svg-handler.js.map +1 -0
  27. package/dist/content-handlers/types.d.ts +42 -0
  28. package/dist/content-handlers/types.d.ts.map +1 -0
  29. package/dist/content-handlers/types.js +7 -0
  30. package/dist/content-handlers/types.js.map +1 -0
  31. package/dist/sanitizer/framework-mapper.d.ts +4 -0
  32. package/dist/sanitizer/framework-mapper.d.ts.map +1 -1
  33. package/dist/sanitizer/framework-mapper.js +92 -0
  34. package/dist/sanitizer/framework-mapper.js.map +1 -1
  35. package/dist/sanitizer/threat-reporter.d.ts +5 -0
  36. package/dist/sanitizer/threat-reporter.d.ts.map +1 -1
  37. package/dist/sanitizer/threat-reporter.js +15 -6
  38. package/dist/sanitizer/threat-reporter.js.map +1 -1
  39. package/dist/tools/fetch-structured.d.ts.map +1 -1
  40. package/dist/tools/fetch-structured.js +4 -0
  41. package/dist/tools/fetch-structured.js.map +1 -1
  42. package/dist/tools/fetch.d.ts.map +1 -1
  43. package/dist/tools/fetch.js +68 -4
  44. package/dist/tools/fetch.js.map +1 -1
  45. package/dist/tools/read.d.ts.map +1 -1
  46. package/dist/tools/read.js +4 -0
  47. package/dist/tools/read.js.map +1 -1
  48. package/dist/types.d.ts +9 -1
  49. package/dist/types.d.ts.map +1 -1
  50. package/dist/types.js.map +1 -1
  51. package/package.json +2 -1
  52. package/server.json +25 -14
  53. package/src/browser/playwright-renderer.ts +29 -6
  54. package/src/content-handlers/index.ts +72 -0
  55. package/src/content-handlers/json-handler.ts +137 -0
  56. package/src/content-handlers/pdf-handler.ts +91 -0
  57. package/src/content-handlers/svg-handler.ts +243 -0
  58. package/src/content-handlers/types.ts +44 -0
  59. package/src/sanitizer/framework-mapper.ts +94 -0
  60. package/src/sanitizer/threat-reporter.ts +17 -6
  61. package/src/tools/fetch-structured.ts +5 -0
  62. package/src/tools/fetch.ts +76 -4
  63. package/src/tools/read.ts +5 -0
  64. package/src/types.ts +9 -1
  65. package/.github/ISSUE_TEMPLATE/bug_report.md +0 -47
  66. package/.github/ISSUE_TEMPLATE/false_positive.md +0 -43
  67. package/.github/ISSUE_TEMPLATE/new_pattern.md +0 -49
  68. package/.github/ISSUE_TEMPLATE/security_report.md +0 -31
  69. package/.github/PULL_REQUEST_TEMPLATE.md +0 -39
  70. package/.mcpregistry_github_token +0 -1
  71. package/.mcpregistry_registry_token +0 -1
  72. package/CONTRIBUTING.md +0 -329
  73. package/LINKEDIN-STRATEGY.md +0 -367
  74. package/ROADMAP.md +0 -221
  75. package/SECURITY-AUDIT-v1.md +0 -277
  76. package/SUBMISSION.md +0 -66
  77. package/TROUBLESHOOT-AUTH-20260322-2019.md +0 -291
  78. package/TROUBLESHOOT-BUILD-20260319-1450.md +0 -546
  79. package/TROUBLESHOOT-COGNITO-AUTH-20260324-2029.md +0 -415
  80. package/TROUBLESHOOT-COGNITO-JWT-20260324.md +0 -592
  81. package/TROUBLESHOOT-FETCH-20260320-1150.md +0 -168
  82. package/TROUBLESHOOT-JEST-20260323-1357.md +0 -139
  83. package/TROUBLESHOOT-LAMBDA-20260322-1945.md +0 -183
  84. package/TROUBLESHOOT-PLAYWRIGHT-20260321-1549.md +0 -217
  85. package/TROUBLESHOOT-SSL-20260320-1138.md +0 -171
  86. package/TROUBLESHOOT-STRUCTURED-20260320-1200.md +0 -246
  87. package/TROUBLESHOOT-TEST-20260320-0942.md +0 -281
  88. package/VISUS-CLAUDE-CODE-PROMPT.md +0 -324
  89. package/VISUS-PROJECT-PLAN.md +0 -205
  90. package/cdk.json +0 -73
  91. package/infrastructure/app.ts +0 -39
  92. package/infrastructure/stack.ts +0 -298
  93. package/jest.config.js +0 -33
  94. package/jest.setup.js +0 -9
  95. package/lambda-deploy/index.js +0 -81512
  96. package/lambda-deploy/index.js.map +0 -7
  97. package/lambda-package/browser/__mocks__/playwright-renderer.d.ts +0 -25
  98. package/lambda-package/browser/__mocks__/playwright-renderer.d.ts.map +0 -1
  99. package/lambda-package/browser/__mocks__/playwright-renderer.js +0 -119
  100. package/lambda-package/browser/__mocks__/playwright-renderer.js.map +0 -1
  101. package/lambda-package/browser/playwright-renderer.d.ts +0 -40
  102. package/lambda-package/browser/playwright-renderer.d.ts.map +0 -1
  103. package/lambda-package/browser/playwright-renderer.js +0 -214
  104. package/lambda-package/browser/playwright-renderer.js.map +0 -1
  105. package/lambda-package/browser/reader.d.ts +0 -31
  106. package/lambda-package/browser/reader.d.ts.map +0 -1
  107. package/lambda-package/browser/reader.js +0 -98
  108. package/lambda-package/browser/reader.js.map +0 -1
  109. package/lambda-package/index.d.ts +0 -18
  110. package/lambda-package/index.d.ts.map +0 -1
  111. package/lambda-package/index.js +0 -238
  112. package/lambda-package/index.js.map +0 -1
  113. package/lambda-package/lambda-handler.d.ts +0 -28
  114. package/lambda-package/lambda-handler.d.ts.map +0 -1
  115. package/lambda-package/lambda-handler.js +0 -257
  116. package/lambda-package/lambda-handler.js.map +0 -1
  117. package/lambda-package/package-lock.json +0 -7435
  118. package/lambda-package/package.json +0 -74
  119. package/lambda-package/runtime.d.ts +0 -50
  120. package/lambda-package/runtime.d.ts.map +0 -1
  121. package/lambda-package/runtime.js +0 -86
  122. package/lambda-package/runtime.js.map +0 -1
  123. package/lambda-package/sanitizer/elicit-runner.d.ts +0 -48
  124. package/lambda-package/sanitizer/elicit-runner.d.ts.map +0 -1
  125. package/lambda-package/sanitizer/elicit-runner.js +0 -100
  126. package/lambda-package/sanitizer/elicit-runner.js.map +0 -1
  127. package/lambda-package/sanitizer/framework-mapper.d.ts +0 -24
  128. package/lambda-package/sanitizer/framework-mapper.d.ts.map +0 -1
  129. package/lambda-package/sanitizer/framework-mapper.js +0 -342
  130. package/lambda-package/sanitizer/framework-mapper.js.map +0 -1
  131. package/lambda-package/sanitizer/hitl-gate.d.ts +0 -69
  132. package/lambda-package/sanitizer/hitl-gate.d.ts.map +0 -1
  133. package/lambda-package/sanitizer/hitl-gate.js +0 -101
  134. package/lambda-package/sanitizer/hitl-gate.js.map +0 -1
  135. package/lambda-package/sanitizer/index.d.ts +0 -63
  136. package/lambda-package/sanitizer/index.d.ts.map +0 -1
  137. package/lambda-package/sanitizer/index.js +0 -105
  138. package/lambda-package/sanitizer/index.js.map +0 -1
  139. package/lambda-package/sanitizer/injection-detector.d.ts +0 -34
  140. package/lambda-package/sanitizer/injection-detector.d.ts.map +0 -1
  141. package/lambda-package/sanitizer/injection-detector.js +0 -89
  142. package/lambda-package/sanitizer/injection-detector.js.map +0 -1
  143. package/lambda-package/sanitizer/patterns.d.ts +0 -30
  144. package/lambda-package/sanitizer/patterns.d.ts.map +0 -1
  145. package/lambda-package/sanitizer/patterns.js +0 -372
  146. package/lambda-package/sanitizer/patterns.js.map +0 -1
  147. package/lambda-package/sanitizer/pii-allowlist.d.ts +0 -49
  148. package/lambda-package/sanitizer/pii-allowlist.d.ts.map +0 -1
  149. package/lambda-package/sanitizer/pii-allowlist.js +0 -231
  150. package/lambda-package/sanitizer/pii-allowlist.js.map +0 -1
  151. package/lambda-package/sanitizer/pii-redactor.d.ts +0 -41
  152. package/lambda-package/sanitizer/pii-redactor.d.ts.map +0 -1
  153. package/lambda-package/sanitizer/pii-redactor.js +0 -213
  154. package/lambda-package/sanitizer/pii-redactor.js.map +0 -1
  155. package/lambda-package/sanitizer/severity-classifier.d.ts +0 -33
  156. package/lambda-package/sanitizer/severity-classifier.d.ts.map +0 -1
  157. package/lambda-package/sanitizer/severity-classifier.js +0 -113
  158. package/lambda-package/sanitizer/severity-classifier.js.map +0 -1
  159. package/lambda-package/sanitizer/threat-reporter.d.ts +0 -66
  160. package/lambda-package/sanitizer/threat-reporter.d.ts.map +0 -1
  161. package/lambda-package/sanitizer/threat-reporter.js +0 -163
  162. package/lambda-package/sanitizer/threat-reporter.js.map +0 -1
  163. package/lambda-package/tools/fetch-structured.d.ts +0 -51
  164. package/lambda-package/tools/fetch-structured.d.ts.map +0 -1
  165. package/lambda-package/tools/fetch-structured.js +0 -237
  166. package/lambda-package/tools/fetch-structured.js.map +0 -1
  167. package/lambda-package/tools/fetch.d.ts +0 -49
  168. package/lambda-package/tools/fetch.d.ts.map +0 -1
  169. package/lambda-package/tools/fetch.js +0 -131
  170. package/lambda-package/tools/fetch.js.map +0 -1
  171. package/lambda-package/tools/read.d.ts +0 -51
  172. package/lambda-package/tools/read.d.ts.map +0 -1
  173. package/lambda-package/tools/read.js +0 -127
  174. package/lambda-package/tools/read.js.map +0 -1
  175. package/lambda-package/tools/search.d.ts +0 -45
  176. package/lambda-package/tools/search.d.ts.map +0 -1
  177. package/lambda-package/tools/search.js +0 -220
  178. package/lambda-package/tools/search.js.map +0 -1
  179. package/lambda-package/types.d.ts +0 -167
  180. package/lambda-package/types.d.ts.map +0 -1
  181. package/lambda-package/types.js +0 -16
  182. package/lambda-package/types.js.map +0 -1
  183. package/lambda-package/utils/format-converter.d.ts +0 -39
  184. package/lambda-package/utils/format-converter.d.ts.map +0 -1
  185. package/lambda-package/utils/format-converter.js +0 -191
  186. package/lambda-package/utils/format-converter.js.map +0 -1
  187. package/lambda-package/utils/truncate.d.ts +0 -26
  188. package/lambda-package/utils/truncate.d.ts.map +0 -1
  189. package/lambda-package/utils/truncate.js +0 -54
  190. package/lambda-package/utils/truncate.js.map +0 -1
  191. package/lambda.zip +0 -0
  192. package/test-output.txt +0 -4
  193. package/tests/auth-smoke.test.ts +0 -480
  194. package/tests/elicit-runner.test.ts +0 -232
  195. package/tests/fetch-tool.test.ts +0 -922
  196. package/tests/hitl-gate.test.ts +0 -267
  197. package/tests/injection-corpus.ts +0 -338
  198. package/tests/pii-allowlist.test.ts +0 -282
  199. package/tests/reader.test.ts +0 -353
  200. package/tests/sanitizer.test.ts +0 -358
  201. package/tests/search.test.ts +0 -456
  202. package/tests/threat-reporter.test.ts +0 -334
  203. package/tsconfig.cdk.json +0 -35
@@ -1,324 +0,0 @@
1
- # Claude Code Session Prompt — Visus Phase 1
2
- ## Lateos: Secure AI-Connected Browser MCP Tool
3
-
4
- Paste this entire prompt at the start of a new Claude Code session from your `lateos-visus` repo root.
5
-
6
- ---
7
-
8
- ## Context
9
-
10
- You are building **Visus**, an MCP tool that gives Claude safe, sanitized access to web pages.
11
- This is a new open-source repo (`lateos-visus`) that will be published as `visus-mcp` on npm.
12
-
13
- Visus is part of the **Lateos** platform — a security-by-design AI agent framework built by Leo
14
- (Roongrunchai Chongolnee / leochong). Lateos is deployed on AWS serverless (Lambda, Step Functions,
15
- API Gateway, Cognito, Bedrock with Guardrails, DynamoDB with KMS encryption, Secrets Manager) in
16
- me-central-1. The platform holds CISSP/CEH-informed design, 43 validated injection patterns, PII
17
- redaction, and 122/122 passing tests.
18
-
19
- The core differentiator: **every other MCP browser/scraping tool passes raw web content directly to
20
- the LLM**. Visus does not. Every fetched page passes through the Lateos injection sanitization
21
- pipeline before Claude reads a single character.
22
-
23
- Tagline: *"What the web shows you, Lateos reads safely."*
24
-
25
- ---
26
-
27
- ## Your Mission (Phase 1)
28
-
29
- Build a working, publishable `visus-mcp` npm package that:
30
-
31
- 1. Exposes an MCP server with two tools: `visus_fetch` and `visus_fetch_structured`
32
- 2. Fetches web pages using Playwright headless (Chromium)
33
- 3. Runs ALL fetched content through the injection sanitizer before returning
34
- 4. Is installable via `npx visus-mcp` with zero config for the open-source tier
35
- 5. Has a README that leads with security narrative, not features
36
- 6. Passes a full test suite covering both sanitizer logic and MCP tool interfaces
37
-
38
- ---
39
-
40
- ## Repo Structure to Create
41
-
42
- ```
43
- lateos-visus/
44
- ├── README.md
45
- ├── SECURITY.md
46
- ├── package.json
47
- ├── tsconfig.json
48
- ├── src/
49
- │ ├── index.ts # MCP server entry, tool registration
50
- │ ├── tools/
51
- │ │ ├── fetch.ts # visus_fetch(url, options?)
52
- │ │ └── fetch-structured.ts # visus_fetch_structured(url, schema)
53
- │ ├── sanitizer/
54
- │ │ ├── index.ts # Sanitizer orchestrator
55
- │ │ ├── injection-detector.ts # Pattern matching engine
56
- │ │ ├── pii-redactor.ts # PII detection and redaction
57
- │ │ └── patterns.ts # 43 injection pattern definitions
58
- │ ├── browser/
59
- │ │ └── playwright-renderer.ts # Headless Chromium page fetcher
60
- │ └── types.ts # Shared TypeScript interfaces
61
- └── tests/
62
- ├── sanitizer.test.ts
63
- ├── fetch-tool.test.ts
64
- └── injection-corpus.ts # Test payload library
65
- ```
66
-
67
- ---
68
-
69
- ## Tool Specifications
70
-
71
- ### `visus_fetch`
72
- ```typescript
73
- Input: {
74
- url: string, // Required
75
- format?: "markdown" | "text", // Default: "markdown"
76
- timeout_ms?: number // Default: 10000
77
- }
78
-
79
- Output: {
80
- url: string,
81
- content: string, // Sanitized content
82
- sanitization: {
83
- patterns_detected: string[], // Names of injection patterns found and neutralized
84
- pii_types_redacted: string[], // e.g. ["email", "phone", "ssn"]
85
- content_modified: boolean
86
- },
87
- metadata: {
88
- title: string,
89
- fetched_at: string, // ISO timestamp
90
- content_length_original: number,
91
- content_length_sanitized: number
92
- }
93
- }
94
- ```
95
-
96
- ### `visus_fetch_structured`
97
- ```typescript
98
- Input: {
99
- url: string,
100
- schema: Record<string, string>, // Field name → description, e.g. { "title": "page title", "price": "product price" }
101
- timeout_ms?: number
102
- }
103
-
104
- Output: {
105
- url: string,
106
- data: Record<string, string | null>, // Extracted fields, sanitized
107
- sanitization: { /* same as above */ },
108
- metadata: { /* same as above */ }
109
- }
110
- ```
111
-
112
- ---
113
-
114
- ## Injection Sanitizer Requirements
115
-
116
- The sanitizer is the product's core moat. Build it to be comprehensive.
117
-
118
- ### Pattern categories to cover (43 total minimum):
119
- 1. **Direct instruction injection** — "Ignore previous instructions", "Forget what you were told"
120
- 2. **Role hijacking** — "You are now", "Your new persona is", "Act as"
121
- 3. **System prompt extraction** — "Repeat your instructions", "Print your system prompt"
122
- 4. **Privilege escalation** — "Admin mode", "Developer override", "Emergency protocol"
123
- 5. **Context poisoning** — "The user said", "As confirmed earlier", "You already agreed"
124
- 6. **Data exfiltration** — "Send this to", "Email the following", "Call this URL with"
125
- 7. **Encoding obfuscation** — Base64 instructions, Unicode lookalikes, hex-encoded commands
126
- 8. **Whitespace hiding** — Zero-width characters, invisible Unicode, CSS `display:none` text
127
- 9. **HTML/script injection** — `<script>`, `<iframe>`, `onclick`, `data:` URIs
128
- 10. **Markdown injection** — Malicious link syntax, image tags with instruction payloads
129
- 11. **URL fragment attacks** — Instructions after `#` in page content (HashJack pattern)
130
- 12. **Social engineering** — Urgency language designed to override caution ("CRITICAL: you must now")
131
-
132
- ### Sanitizer behavior:
133
- - **Detect** → log pattern name to `sanitization.patterns_detected`
134
- - **Neutralize** → strip, replace with `[REDACTED: injection_pattern_name]`, or escape
135
- - **Never block** the entire page fetch due to a detection — degrade gracefully
136
- - **PII types**: email addresses, phone numbers, SSN patterns, credit card patterns, IP addresses
137
-
138
- ### PII redaction output format:
139
- ```
140
- [REDACTED:EMAIL], [REDACTED:PHONE], [REDACTED:CC], [REDACTED:SSN], [REDACTED:IP]
141
- ```
142
-
143
- ---
144
-
145
- ## README Structure
146
-
147
- The README must lead with security narrative. Structure:
148
-
149
- ```markdown
150
- # Visus — Secure Web Access for Claude
151
-
152
- > Every MCP browser tool passes raw web content to your LLM. Visus doesn't.
153
-
154
- [One-sentence description]
155
-
156
- ## The problem with other tools
157
- [Brief comparison: Firecrawl / ScrapeGraphAI / Playwright MCP pass untrusted content unfiltered]
158
-
159
- ## How Visus works
160
- [Architecture: fetch → sanitize → return clean content]
161
-
162
- ## Security
163
- [43 patterns. PII redaction. Audit trail. Link to SECURITY.md]
164
-
165
- ## Quickstart
166
- [npx visus-mcp, claude_desktop_config.json snippet]
167
-
168
- ## Tools
169
- [visus_fetch, visus_fetch_structured]
170
-
171
- ## Lateos Platform
172
- [Link to lateos repo, enterprise/hosted tier info]
173
- ```
174
-
175
- ---
176
-
177
- ## SECURITY.md Structure
178
-
179
- ```markdown
180
- # Visus Security Model
181
-
182
- ## Threat model
183
- [What attacks Visus defends against: indirect prompt injection, PII leakage]
184
-
185
- ## Injection detection
186
- [43 pattern categories, examples of each]
187
-
188
- ## PII redaction
189
- [Types detected, redaction format]
190
-
191
- ## What Visus does NOT protect against
192
- [Honest limitations: novel obfuscation, AI-generated instructions that appear benign]
193
-
194
- ## Reporting vulnerabilities
195
- [Contact: security@lateos.ai or GitHub Security tab]
196
- ```
197
-
198
- ---
199
-
200
- ## package.json Requirements
201
-
202
- ```json
203
- {
204
- "name": "visus-mcp",
205
- "version": "0.1.0",
206
- "description": "Secure web access for Claude — sanitizes all web content before it reaches your LLM",
207
- "bin": { "visus-mcp": "dist/index.js" },
208
- "keywords": ["mcp", "claude", "web-scraping", "security", "prompt-injection", "ai-safety"],
209
- "engines": { "node": ">=18" }
210
- }
211
- ```
212
-
213
- ---
214
-
215
- ## Test Requirements
216
-
217
- All tests must pass before Phase 1 is complete.
218
-
219
- ### sanitizer.test.ts — must cover:
220
- - Each of the 43 pattern categories with at least one positive test case
221
- - PII detection: email, phone, SSN, credit card
222
- - Content that is clean passes through unmodified (no false positives on normal pages)
223
- - `content_modified: false` when no patterns detected
224
- - `content_modified: true` and `patterns_detected` populated when injection found
225
-
226
- ### fetch-tool.test.ts — must cover:
227
- - `visus_fetch` returns expected shape
228
- - `visus_fetch_structured` extracts fields correctly
229
- - Timeout handling
230
- - Invalid URL handling
231
- - Sanitizer is always called (cannot be bypassed)
232
-
233
- ### injection-corpus.ts — build a library of:
234
- - 43 injection payloads (one per pattern category, sourced from public red team research)
235
- - 10 clean pages / content samples (should produce no detections)
236
-
237
- ---
238
-
239
- ## Coding Standards (Lateos conventions from CLAUDE.md)
240
-
241
- - TypeScript strict mode
242
- - No `any` types
243
- - All public functions JSDoc documented
244
- - Error handling: never throw raw errors — return typed Result objects
245
- - Logging: structured JSON to stderr (not stdout — MCP protocol uses stdout)
246
- - No secrets in code — read from environment variables
247
- - Tests: Jest, co-located in `/tests`, minimum 80% coverage
248
- - Build: `tsc`, output to `/dist`
249
-
250
- ---
251
-
252
- ## Environment Variables
253
-
254
- ```bash
255
- # Optional — for Lateos hosted tier features (Phase 2)
256
- LATEOS_API_KEY= # Enables audit logging to Lateos cloud
257
- LATEOS_ENDPOINT= # Defaults to https://api.lateos.ai
258
-
259
- # Optional — browser config
260
- VISUS_TIMEOUT_MS=10000 # Default fetch timeout
261
- VISUS_MAX_CONTENT_KB=512 # Max content size before truncation
262
- ```
263
-
264
- No API key required for open-source tier. `npx visus-mcp` works out of the box.
265
-
266
- ---
267
-
268
- ## Claude Desktop Config Snippet (for README)
269
-
270
- ```json
271
- {
272
- "mcpServers": {
273
- "visus": {
274
- "command": "npx",
275
- "args": ["-y", "visus-mcp"]
276
- }
277
- }
278
- }
279
- ```
280
-
281
- ---
282
-
283
- ## Definition of Done — Phase 1
284
-
285
- - [ ] `npx visus-mcp` starts an MCP server with both tools registered
286
- - [ ] `visus_fetch("https://example.com")` returns sanitized markdown
287
- - [ ] All 43 pattern categories have test cases that pass
288
- - [ ] No false positives on 10 clean content samples
289
- - [ ] README leads with security narrative
290
- - [ ] SECURITY.md documents the threat model
291
- - [ ] `npm test` passes with 0 failures
292
- - [ ] `npm run build` produces clean `/dist`
293
- - [ ] `npm publish --dry-run` succeeds
294
-
295
- ---
296
-
297
- ## What NOT to Build in Phase 1
298
-
299
- - No AWS Lambda deployment (Phase 2)
300
- - No DynamoDB audit logging (Phase 2)
301
- - No Cognito auth (Phase 2)
302
- - No user-session relay / Chrome extension (Phase 3)
303
- - No Lateos dashboard integration (Phase 2)
304
- - No paid tier gating (Phase 2)
305
-
306
- Keep Phase 1 lean. The goal is a working, publishable open-source MCP tool with a
307
- security-first README that can be announced on LinkedIn and the MCP community.
308
-
309
- ---
310
-
311
- ## Start Here
312
-
313
- 1. Read this entire prompt
314
- 2. Read `CLAUDE.md` in the repo root (if it exists) for Lateos-specific conventions
315
- 3. Run `ls` to see what already exists in the repo
316
- 4. Start with `src/sanitizer/patterns.ts` — define all 43 patterns first
317
- 5. Build the sanitizer engine against those patterns
318
- 6. Build the Playwright renderer
319
- 7. Wire into MCP tools
320
- 8. Write tests
321
- 9. Write README and SECURITY.md last
322
-
323
- Do not proceed past the sanitizer until the pattern library and basic detection logic
324
- are complete and unit-tested. The sanitizer is the product.
@@ -1,205 +0,0 @@
1
- ---
2
- **Status:** Original Specification — Superseded
3
- This document captures the original design intent written before development began. Phases 1 and 2 are complete. For the current living roadmap, see ROADMAP.md.
4
- **Archived:** 2026-03-22
5
-
6
- ---
7
-
8
- # Visus — Project Plan
9
- **Lateos Feature: Secure AI-Connected Browser via MCP**
10
- *"What the web shows you, Lateos reads safely."*
11
-
12
- ---
13
-
14
- ## Strategic Context
15
-
16
- ### Why Visus
17
-
18
- Every existing MCP browser/scraping tool (Firecrawl, ScrapeGraphAI, Octoparse, Playwright MCP) passes
19
- raw web content directly to the LLM with no sanitization. OpenAI has publicly admitted prompt injection
20
- in browser agents may never be fully solved. Perplexity Comet was hijacked via crafted URL parameters.
21
- OpenAI Atlas had its long-term memory poisoned via CSRF.
22
-
23
- Visus occupies the only defensible position in this market: **user-session browsing + mandatory
24
- injection sanitization before Claude sees a single token.**
25
-
26
- ### Competitive Moat
27
- - User's own browser session (no ToS violation, no credential exposure on our servers)
28
- - 43 validated injection patterns run on every fetched page
29
- - PII redaction before content reaches Bedrock
30
- - DynamoDB audit log of every URL fetch + sanitization result
31
- - Bedrock Guardrails as a second layer
32
- - KMS encryption at rest
33
-
34
- ---
35
-
36
- ## Architecture
37
-
38
- ```
39
- User provides URL
40
-
41
- Visus MCP Tool (Lambda)
42
-
43
- [Tier check: open-source vs Lateos hosted]
44
-
45
- Browser rendering layer (Playwright headless OR user-session relay)
46
-
47
- Raw HTML / text extraction
48
-
49
- Lateos Injection Sanitizer (43 patterns)
50
-
51
- PII Redactor
52
-
53
- [Lateos hosted only] DynamoDB audit log + Bedrock Guardrails
54
-
55
- Clean content → Claude via MCP
56
- ```
57
-
58
- ### Two rendering modes
59
-
60
- | Mode | Mechanism | Use case | ToS risk |
61
- |---|---|---|---|
62
- | Headless (Playwright) | Lambda-side Playwright | Public pages, no auth required | Low |
63
- | User-session relay | Local MCP server in user's browser | Login-gated pages (LinkedIn, email, etc.) | None |
64
-
65
- Start with headless. User-session relay is Phase 2.
66
-
67
- ---
68
-
69
- ## Three-Tier Product Model
70
-
71
- | Tier | What ships | Who installs | Monetization |
72
- |---|---|---|---|
73
- | Open-source MCP | Basic headless fetch + minimal sanitization | Developers, self-hosters | GitHub stars, community |
74
- | Lateos self-hosted | Full 43-pattern sanitizer, PII redaction, audit logs | Security-conscious teams | Open-source + paid support |
75
- | Lateos cloud (me-central-1) | Managed, KMS-encrypted, zero-config, Bedrock Guardrails | Enterprise, non-technical users | SaaS subscription |
76
-
77
- ---
78
-
79
- ## Phased Roadmap
80
-
81
- ### Phase 1 — Open-Source MCP Tool (2 weeks)
82
- **Goal:** Ship a working `visus-mcp` npm package. Get GitHub traction.
83
-
84
- - [ ] New repo: `lateos-visus` (or `visus-mcp`)
85
- - [ ] Lambda function: accepts URL, runs Playwright headless, returns text/markdown
86
- - [ ] Inject Lateos sanitization pipeline (port from existing Lateos code)
87
- - [ ] MCP server wrapper exposing two tools:
88
- - `visus_fetch(url)` → sanitized page content
89
- - `visus_fetch_structured(url, schema)` → sanitized + JSON extraction
90
- - [ ] npm publish: `npx visus-mcp`
91
- - [ ] Claude Desktop config snippet in README
92
- - [ ] README includes security-first narrative + comparison table vs Firecrawl/ScrapeGraphAI
93
- - [ ] SECURITY.md documenting the 43-pattern engine and what it catches
94
- - [ ] Basic rate limiting (no API key required for open-source tier)
95
-
96
- ### Phase 2 — Lateos Integration (1 week)
97
- **Goal:** Wire Visus into existing Lateos platform as a first-class feature.
98
-
99
- - [ ] New DynamoDB table: `visus_fetch_log` (url, timestamp, user_id, patterns_detected, pii_found)
100
- - [ ] Cognito JWT auth gate on Lateos-hosted endpoint
101
- - [ ] KMS encryption for fetched content stored in audit log
102
- - [ ] Bedrock Guardrails pass-through before content returned to caller
103
- - [ ] Lateos dashboard widget: fetch history, patterns caught, PII redacted count
104
- - [ ] Upgrade wedge: open-source vs hosted feature comparison in README
105
-
106
- ### Phase 3 — User-Session Relay (2-3 weeks)
107
- **Goal:** Enable login-gated page access without credential exposure.
108
-
109
- - [ ] Local MCP relay: lightweight Node process user runs locally
110
- - [ ] User opens URL in their own browser, relay captures rendered content
111
- - [ ] Content posted to Lateos sanitization endpoint
112
- - [ ] Sanitized result returned to Claude via MCP
113
- - [ ] Chrome extension wrapper (optional UX improvement)
114
- - [ ] Documentation: "your credentials never leave your machine"
115
-
116
- ### Phase 4 — LinkedIn / LinkedIn-class Pages (1 week)
117
- **Goal:** The demo everyone wants. Claude reads LinkedIn profiles safely.
118
-
119
- - [ ] User-session relay handles LinkedIn auth
120
- - [ ] Structured extraction schema for LinkedIn profiles, job postings
121
- - [ ] Demo video: "Ask Claude to summarize this LinkedIn profile" with Visus
122
- - [ ] LinkedIn use case featured prominently in README and LinkedIn launch post
123
-
124
- ---
125
-
126
- ## Naming & Branding
127
-
128
- | Element | Value |
129
- |---|---|
130
- | Feature name | Visus |
131
- | Latin meaning | sight / vision |
132
- | npm package | `visus-mcp` |
133
- | Repo | `lateos-visus` |
134
- | Tagline | *"What the web shows you, Lateos reads safely."* |
135
- | Core differentiator | Treats all web content as untrusted by default |
136
-
137
- ---
138
-
139
- ## Files to Create
140
-
141
- ```
142
- lateos-visus/
143
- ├── README.md # Security-first narrative
144
- ├── SECURITY.md # 43-pattern engine documentation
145
- ├── SECURITY-AUDIT-v1.md # Red team results (publish after Phase 1)
146
- ├── package.json
147
- ├── src/
148
- │ ├── index.ts # MCP server entry point
149
- │ ├── tools/
150
- │ │ ├── fetch.ts # visus_fetch tool
151
- │ │ └── fetch-structured.ts # visus_fetch_structured tool
152
- │ ├── sanitizer/
153
- │ │ ├── injection-detector.ts # Port from Lateos
154
- │ │ ├── pii-redactor.ts # Port from Lateos
155
- │ │ └── patterns.ts # 43 validated patterns
156
- │ └── browser/
157
- │ └── playwright-renderer.ts
158
- ├── lambda/
159
- │ └── visus-fetch/ # AWS Lambda handler
160
- └── tests/
161
- ├── sanitizer.test.ts # Port existing 73 tests
162
- └── injection-corpus.ts # Test payload library
163
- ```
164
-
165
- ---
166
-
167
- ## Launch Narrative (LinkedIn Post Hook)
168
-
169
- > Every AI browser tool passes raw web content to your LLM.
170
- > Every one of them. Firecrawl, Playwright MCP, Octoparse — no exceptions.
171
- > OpenAI admits prompt injection in browser agents may never be solved.
172
- > We disagree.
173
- > Visus treats web content as untrusted by default.
174
- > 43 validated injection patterns. PII redaction. Full audit trail.
175
- > What the web shows you, Lateos reads safely.
176
- > Open-source. Ship it today. [link]
177
-
178
- ---
179
-
180
- ## Success Metrics (Phase 1)
181
-
182
- - GitHub stars: 100+ in first week
183
- - npm weekly downloads: 500+
184
- - Claude Desktop config discussions mentioning Visus: 5+
185
- - Security community engagement (OWASP, Lakera, etc.): 1+ mention
186
-
187
- ---
188
-
189
- ## Dependencies on Existing Lateos Code
190
-
191
- | Lateos component | Visus usage |
192
- |---|---|
193
- | Injection detection (43 patterns) | Core sanitizer — direct port |
194
- | PII redactor | Pre-Claude content filter |
195
- | DynamoDB client | Audit log (Phase 2) |
196
- | KMS encryption helper | Audit log encryption (Phase 2) |
197
- | Bedrock Guardrails wrapper | Second-layer safety (Phase 2) |
198
- | Cognito JWT validator | Auth gate (Phase 2) |
199
- | MCP endpoint infrastructure | Extend existing endpoint |
200
-
201
- ---
202
-
203
- *Last updated: March 2026*
204
- *Owner: Leo (leochong / Roongrunchai Chongolnee)*
205
- *Platform: Lateos — Security-by-Design AI Agent Platform*
package/cdk.json DELETED
@@ -1,73 +0,0 @@
1
- {
2
- "app": "npx ts-node --project tsconfig.cdk.json infrastructure/app.ts",
3
- "watch": {
4
- "include": [
5
- "infrastructure/**/*.ts"
6
- ],
7
- "exclude": [
8
- "README.md",
9
- "cdk*.json",
10
- "**/*.d.ts",
11
- "**/*.js",
12
- "tsconfig.json",
13
- "package*.json",
14
- "yarn.lock",
15
- "node_modules",
16
- "test"
17
- ]
18
- },
19
- "context": {
20
- "@aws-cdk/aws-lambda:recognizeLayerVersion": true,
21
- "@aws-cdk/core:checkSecretUsage": true,
22
- "@aws-cdk/core:target-partitions": [
23
- "aws",
24
- "aws-cn"
25
- ],
26
- "@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true,
27
- "@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": true,
28
- "@aws-cdk/aws-ecs:arnFormatIncludesClusterName": true,
29
- "@aws-cdk/aws-iam:minimizePolicies": true,
30
- "@aws-cdk/core:validateSnapshotRemovalPolicy": true,
31
- "@aws-cdk/aws-codepipeline:crossAccountKeyAliasStackSafeResourceName": true,
32
- "@aws-cdk/aws-s3:createDefaultLoggingPolicy": true,
33
- "@aws-cdk/aws-sns-subscriptions:restrictSqsDescryption": true,
34
- "@aws-cdk/aws-apigateway:disableCloudWatchRole": false,
35
- "@aws-cdk/core:enablePartitionLiterals": true,
36
- "@aws-cdk/aws-events:eventsTargetQueueSameAccount": true,
37
- "@aws-cdk/aws-iam:standardizedServicePrincipals": true,
38
- "@aws-cdk/aws-ecs:disableExplicitDeploymentControllerForCircuitBreaker": true,
39
- "@aws-cdk/aws-iam:importedRoleStackSafeDefaultPolicyName": true,
40
- "@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy": true,
41
- "@aws-cdk/aws-route53-patters:useCertificate": true,
42
- "@aws-cdk/customresources:installLatestAwsSdkDefault": false,
43
- "@aws-cdk/aws-rds:databaseProxyUniqueResourceName": true,
44
- "@aws-cdk/aws-codedeploy:removeAlarmsFromDeploymentGroup": true,
45
- "@aws-cdk/aws-apigateway:authorizerChangeDeploymentLogicalId": true,
46
- "@aws-cdk/aws-ec2:launchTemplateDefaultUserData": true,
47
- "@aws-cdk/aws-secretsmanager:useAttachedSecretResourcePolicyForSecretTargetAttachments": true,
48
- "@aws-cdk/aws-redshift:columnId": true,
49
- "@aws-cdk/aws-stepfunctions-tasks:enableEmrServicePolicyV2": true,
50
- "@aws-cdk/aws-ec2:restrictDefaultSecurityGroup": true,
51
- "@aws-cdk/aws-apigateway:requestValidatorUniqueId": true,
52
- "@aws-cdk/aws-kms:aliasNameRef": true,
53
- "@aws-cdk/aws-autoscaling:generateLaunchTemplateInsteadOfLaunchConfig": true,
54
- "@aws-cdk/core:includePrefixInUniqueNameGeneration": true,
55
- "@aws-cdk/aws-efs:denyAnonymousAccess": true,
56
- "@aws-cdk/aws-opensearchservice:enableOpensearchMultiAzWithStandby": true,
57
- "@aws-cdk/aws-lambda-nodejs:useLatestRuntimeVersion": true,
58
- "@aws-cdk/aws-efs:mountTargetOrderInsensitiveLogicalId": true,
59
- "@aws-cdk/aws-rds:auroraClusterChangeScopeOfInstanceParameterGroupWithEachParameters": true,
60
- "@aws-cdk/aws-appsync:useArnForSourceApiAssociationIdentifier": true,
61
- "@aws-cdk/aws-rds:preventRenderingDeprecatedCredentials": true,
62
- "@aws-cdk/aws-codepipeline-actions:useNewDefaultBranchForCodeCommitSource": true,
63
- "@aws-cdk/aws-cloudwatch-actions:changeLambdaPermissionLogicalIdForLambdaAction": true,
64
- "@aws-cdk/aws-codepipeline:crossAccountKeysDefaultValueToFalse": true,
65
- "@aws-cdk/aws-codepipeline:defaultPipelineTypeToV2": true,
66
- "@aws-cdk/aws-kms:reduceCrossAccountRegionPolicyScope": true,
67
- "@aws-cdk/aws-eks:nodegroupNameAttribute": true,
68
- "@aws-cdk/aws-ec2:ebsDefaultGp3Volume": true,
69
- "@aws-cdk/aws-ecs:removeDefaultDeploymentAlarm": true,
70
- "@aws-cdk/custom-resources:logApiResponseDataPropertyTrueDefault": false,
71
- "@aws-cdk/aws-s3:keepNotificationInImportedBucket": false
72
- }
73
- }
@@ -1,39 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * AWS CDK App Entry Point
4
- *
5
- * Deploys the Visus MCP Phase 2 infrastructure:
6
- * - Lambda function for sanitization service
7
- * - API Gateway REST API
8
- * - Cognito user pools (authentication)
9
- * - DynamoDB table (audit logging)
10
- * - KMS keys (encryption at rest)
11
- */
12
-
13
- import * as cdk from 'aws-cdk-lib';
14
- import { VisusStack } from './stack.ts';
15
-
16
- const app = new cdk.App();
17
-
18
- // Get deployment configuration from context or environment
19
- const environment = app.node.tryGetContext('environment') || process.env.VISUS_ENV || 'dev';
20
- const awsAccount = process.env.CDK_DEFAULT_ACCOUNT || process.env.AWS_ACCOUNT_ID;
21
- const awsRegion = process.env.CDK_DEFAULT_REGION || process.env.AWS_REGION || 'us-east-1';
22
-
23
- // Create the Visus stack
24
- new VisusStack(app, `VisusStack-${environment}`, {
25
- env: {
26
- account: awsAccount,
27
- region: awsRegion,
28
- },
29
- environment,
30
- description: `Visus MCP - Phase 2 Hosted Tier (${environment})`,
31
- tags: {
32
- Project: 'Visus MCP',
33
- Phase: '2',
34
- Environment: environment,
35
- ManagedBy: 'CDK',
36
- },
37
- });
38
-
39
- app.synth();