visus-mcp 0.6.1 → 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 (111) hide show
  1. package/.claude/settings.local.json +28 -1
  2. package/.mcpregistry_github_token +1 -1
  3. package/.mcpregistry_registry_token +1 -1
  4. package/CLAUDE.md +197 -0
  5. package/TROUBLESHOOT-COGNITO-AUTH-20260324-2029.md +415 -0
  6. package/TROUBLESHOOT-COGNITO-JWT-20260324.md +592 -0
  7. package/dist/browser/playwright-renderer.d.ts.map +1 -1
  8. package/dist/browser/playwright-renderer.js +71 -51
  9. package/dist/browser/playwright-renderer.js.map +1 -1
  10. package/dist/index.js +0 -0
  11. package/infrastructure/stack.ts +1 -0
  12. package/lambda-deploy/index.js +81512 -0
  13. package/lambda-deploy/index.js.map +7 -0
  14. package/lambda-package/browser/__mocks__/playwright-renderer.d.ts +25 -0
  15. package/lambda-package/browser/__mocks__/playwright-renderer.d.ts.map +1 -0
  16. package/lambda-package/browser/__mocks__/playwright-renderer.js +119 -0
  17. package/lambda-package/browser/__mocks__/playwright-renderer.js.map +1 -0
  18. package/lambda-package/browser/playwright-renderer.d.ts +40 -0
  19. package/lambda-package/browser/playwright-renderer.d.ts.map +1 -0
  20. package/lambda-package/browser/playwright-renderer.js +214 -0
  21. package/lambda-package/browser/playwright-renderer.js.map +1 -0
  22. package/lambda-package/browser/reader.d.ts +31 -0
  23. package/lambda-package/browser/reader.d.ts.map +1 -0
  24. package/lambda-package/browser/reader.js +98 -0
  25. package/lambda-package/browser/reader.js.map +1 -0
  26. package/lambda-package/index.d.ts +18 -0
  27. package/lambda-package/index.d.ts.map +1 -0
  28. package/lambda-package/index.js +238 -0
  29. package/lambda-package/index.js.map +1 -0
  30. package/lambda-package/lambda-handler.d.ts +28 -0
  31. package/lambda-package/lambda-handler.d.ts.map +1 -0
  32. package/lambda-package/lambda-handler.js +257 -0
  33. package/lambda-package/lambda-handler.js.map +1 -0
  34. package/lambda-package/package-lock.json +7435 -0
  35. package/lambda-package/package.json +74 -0
  36. package/lambda-package/runtime.d.ts +50 -0
  37. package/lambda-package/runtime.d.ts.map +1 -0
  38. package/lambda-package/runtime.js +86 -0
  39. package/lambda-package/runtime.js.map +1 -0
  40. package/lambda-package/sanitizer/elicit-runner.d.ts +48 -0
  41. package/lambda-package/sanitizer/elicit-runner.d.ts.map +1 -0
  42. package/lambda-package/sanitizer/elicit-runner.js +100 -0
  43. package/lambda-package/sanitizer/elicit-runner.js.map +1 -0
  44. package/lambda-package/sanitizer/framework-mapper.d.ts +24 -0
  45. package/lambda-package/sanitizer/framework-mapper.d.ts.map +1 -0
  46. package/lambda-package/sanitizer/framework-mapper.js +342 -0
  47. package/lambda-package/sanitizer/framework-mapper.js.map +1 -0
  48. package/lambda-package/sanitizer/hitl-gate.d.ts +69 -0
  49. package/lambda-package/sanitizer/hitl-gate.d.ts.map +1 -0
  50. package/lambda-package/sanitizer/hitl-gate.js +101 -0
  51. package/lambda-package/sanitizer/hitl-gate.js.map +1 -0
  52. package/lambda-package/sanitizer/index.d.ts +63 -0
  53. package/lambda-package/sanitizer/index.d.ts.map +1 -0
  54. package/lambda-package/sanitizer/index.js +105 -0
  55. package/lambda-package/sanitizer/index.js.map +1 -0
  56. package/lambda-package/sanitizer/injection-detector.d.ts +34 -0
  57. package/lambda-package/sanitizer/injection-detector.d.ts.map +1 -0
  58. package/lambda-package/sanitizer/injection-detector.js +89 -0
  59. package/lambda-package/sanitizer/injection-detector.js.map +1 -0
  60. package/lambda-package/sanitizer/patterns.d.ts +30 -0
  61. package/lambda-package/sanitizer/patterns.d.ts.map +1 -0
  62. package/lambda-package/sanitizer/patterns.js +372 -0
  63. package/lambda-package/sanitizer/patterns.js.map +1 -0
  64. package/lambda-package/sanitizer/pii-allowlist.d.ts +49 -0
  65. package/lambda-package/sanitizer/pii-allowlist.d.ts.map +1 -0
  66. package/lambda-package/sanitizer/pii-allowlist.js +231 -0
  67. package/lambda-package/sanitizer/pii-allowlist.js.map +1 -0
  68. package/lambda-package/sanitizer/pii-redactor.d.ts +41 -0
  69. package/lambda-package/sanitizer/pii-redactor.d.ts.map +1 -0
  70. package/lambda-package/sanitizer/pii-redactor.js +213 -0
  71. package/lambda-package/sanitizer/pii-redactor.js.map +1 -0
  72. package/lambda-package/sanitizer/severity-classifier.d.ts +33 -0
  73. package/lambda-package/sanitizer/severity-classifier.d.ts.map +1 -0
  74. package/lambda-package/sanitizer/severity-classifier.js +113 -0
  75. package/lambda-package/sanitizer/severity-classifier.js.map +1 -0
  76. package/lambda-package/sanitizer/threat-reporter.d.ts +66 -0
  77. package/lambda-package/sanitizer/threat-reporter.d.ts.map +1 -0
  78. package/lambda-package/sanitizer/threat-reporter.js +163 -0
  79. package/lambda-package/sanitizer/threat-reporter.js.map +1 -0
  80. package/lambda-package/tools/fetch-structured.d.ts +51 -0
  81. package/lambda-package/tools/fetch-structured.d.ts.map +1 -0
  82. package/lambda-package/tools/fetch-structured.js +237 -0
  83. package/lambda-package/tools/fetch-structured.js.map +1 -0
  84. package/lambda-package/tools/fetch.d.ts +49 -0
  85. package/lambda-package/tools/fetch.d.ts.map +1 -0
  86. package/lambda-package/tools/fetch.js +131 -0
  87. package/lambda-package/tools/fetch.js.map +1 -0
  88. package/lambda-package/tools/read.d.ts +51 -0
  89. package/lambda-package/tools/read.d.ts.map +1 -0
  90. package/lambda-package/tools/read.js +127 -0
  91. package/lambda-package/tools/read.js.map +1 -0
  92. package/lambda-package/tools/search.d.ts +45 -0
  93. package/lambda-package/tools/search.d.ts.map +1 -0
  94. package/lambda-package/tools/search.js +220 -0
  95. package/lambda-package/tools/search.js.map +1 -0
  96. package/lambda-package/types.d.ts +167 -0
  97. package/lambda-package/types.d.ts.map +1 -0
  98. package/lambda-package/types.js +16 -0
  99. package/lambda-package/types.js.map +1 -0
  100. package/lambda-package/utils/format-converter.d.ts +39 -0
  101. package/lambda-package/utils/format-converter.d.ts.map +1 -0
  102. package/lambda-package/utils/format-converter.js +191 -0
  103. package/lambda-package/utils/format-converter.js.map +1 -0
  104. package/lambda-package/utils/truncate.d.ts +26 -0
  105. package/lambda-package/utils/truncate.d.ts.map +1 -0
  106. package/lambda-package/utils/truncate.js +54 -0
  107. package/lambda-package/utils/truncate.js.map +1 -0
  108. package/lambda.zip +0 -0
  109. package/package.json +3 -2
  110. package/server.json +3 -3
  111. package/src/browser/playwright-renderer.ts +74 -51
@@ -9,7 +9,6 @@
9
9
  * Lambda to the local process before Claude sees it. PHI never touches Lateos infrastructure.
10
10
  */
11
11
 
12
- import { request } from 'undici';
13
12
  import type { BrowserRenderResult, Result } from '../types.js';
14
13
  import { Ok, Err } from '../types.js';
15
14
 
@@ -99,22 +98,28 @@ async function renderWithLambda(
99
98
  try {
100
99
  // Retry Lambda calls with exponential backoff (3 attempts)
101
100
  const response = await retryWithBackoff(async () => {
102
- return await request(`${RENDERER_URL}/render`, {
103
- method: 'POST',
104
- headers: {
105
- 'Content-Type': 'application/json',
106
- },
107
- body: JSON.stringify({
108
- url,
109
- timeout_ms,
110
- content_limit_bytes: 512000, // 500KB default
111
- }),
112
- bodyTimeout: timeout_ms + 5000, // Add 5s buffer for network overhead
113
- headersTimeout: timeout_ms + 5000,
114
- });
101
+ const controller = new AbortController();
102
+ const timeoutId = setTimeout(() => controller.abort(), timeout_ms + 5000);
103
+
104
+ try {
105
+ return await fetch(`${RENDERER_URL}/render`, {
106
+ method: 'POST',
107
+ headers: {
108
+ 'Content-Type': 'application/json',
109
+ },
110
+ body: JSON.stringify({
111
+ url,
112
+ timeout_ms,
113
+ content_limit_bytes: 512000, // 500KB default
114
+ }),
115
+ signal: controller.signal,
116
+ });
117
+ } finally {
118
+ clearTimeout(timeoutId);
119
+ }
115
120
  }, 3, 1000); // 3 retries, starting with 1s delay
116
121
 
117
- const body = await response.body.json() as LambdaRenderSuccess | LambdaRenderError;
122
+ const body = await response.json() as LambdaRenderSuccess | LambdaRenderError;
118
123
 
119
124
  // Check if response is an error
120
125
  if ('error' in body) {
@@ -145,7 +150,7 @@ async function renderWithLambda(
145
150
  }
146
151
 
147
152
  /**
148
- * Render a page using undici fetch (fallback)
153
+ * Render a page using native fetch (fallback)
149
154
  */
150
155
  async function renderWithFetch(
151
156
  url: string,
@@ -154,39 +159,51 @@ async function renderWithFetch(
154
159
  logRenderer('fetch', url);
155
160
 
156
161
  try {
157
- const response = await request(url, {
158
- method: 'GET',
159
- headers: {
160
- 'User-Agent': 'Visus-MCP/0.2.0 (Security-focused web content fetcher; +https://github.com/visus-mcp/visus-mcp)',
161
- },
162
- bodyTimeout: timeout_ms,
163
- headersTimeout: timeout_ms,
164
- });
162
+ // Use AbortController for timeout
163
+ const controller = new AbortController();
164
+ const timeoutId = setTimeout(() => controller.abort(), timeout_ms);
165
165
 
166
- const html = await response.body.text();
166
+ try {
167
+ const response = await fetch(url, {
168
+ method: 'GET',
169
+ headers: {
170
+ 'User-Agent': 'Visus-MCP/0.3.1 (Security-focused web content fetcher; +https://github.com/lateos/visus-mcp)',
171
+ },
172
+ signal: controller.signal,
173
+ });
167
174
 
168
- // Capture Content-Type header
169
- const contentTypeHeader = response.headers['content-type'];
170
- const contentType = typeof contentTypeHeader === 'string'
171
- ? contentTypeHeader.split(';')[0].trim() // Remove charset and other params
172
- : 'text/html'; // Default to HTML if missing
175
+ if (!response.ok) {
176
+ return Err(new Error(`HTTP ${response.status}: ${response.statusText}`));
177
+ }
173
178
 
174
- // Extract title using regex (simple fallback)
175
- const titleMatch = html.match(/<title[^>]*>(.*?)<\/title>/i);
176
- const title = titleMatch ? titleMatch[1].trim() : '';
179
+ const html = await response.text();
177
180
 
178
- return Ok({
179
- html,
180
- title,
181
- url,
182
- contentType,
183
- text: undefined,
184
- });
181
+ // Capture Content-Type header
182
+ const contentTypeHeader = response.headers.get('content-type');
183
+ const contentType = contentTypeHeader
184
+ ? contentTypeHeader.split(';')[0].trim() // Remove charset and other params
185
+ : 'text/html'; // Default to HTML if missing
186
+
187
+ // Extract title using regex (simple fallback)
188
+ const titleMatch = html.match(/<title[^>]*>(.*?)<\/title>/i);
189
+ const title = titleMatch ? titleMatch[1].trim() : '';
190
+
191
+ return Ok({
192
+ html,
193
+ title,
194
+ url,
195
+ contentType,
196
+ text: undefined,
197
+ });
198
+
199
+ } finally {
200
+ clearTimeout(timeoutId);
201
+ }
185
202
 
186
203
  } catch (error) {
187
204
  if (error instanceof Error) {
188
- // Handle timeout errors
189
- if (error.message.includes('timeout') || error.message.includes('UND_ERR')) {
205
+ // Handle abort/timeout errors
206
+ if (error.name === 'AbortError') {
190
207
  return Err(new Error(`Navigation timeout after ${timeout_ms}ms`));
191
208
  }
192
209
 
@@ -256,17 +273,23 @@ export async function checkUrl(
256
273
  timeout_ms = 5000
257
274
  ): Promise<Result<boolean, Error>> {
258
275
  try {
259
- const response = await request(url, {
260
- method: 'HEAD',
261
- headersTimeout: timeout_ms,
262
- bodyTimeout: timeout_ms,
263
- });
276
+ const controller = new AbortController();
277
+ const timeoutId = setTimeout(() => controller.abort(), timeout_ms);
278
+
279
+ try {
280
+ const response = await fetch(url, {
281
+ method: 'HEAD',
282
+ signal: controller.signal,
283
+ });
284
+
285
+ // Consider 2xx and 3xx status codes as accessible
286
+ const isAccessible = (response.status >= 200 && response.status < 400);
264
287
 
265
- // Consider 2xx and 3xx status codes as accessible
266
- const statusCode = response.statusCode;
267
- const isAccessible = (statusCode >= 200 && statusCode < 400);
288
+ return Ok(isAccessible);
268
289
 
269
- return Ok(isAccessible);
290
+ } finally {
291
+ clearTimeout(timeoutId);
292
+ }
270
293
 
271
294
  } catch (error) {
272
295
  // URL is not accessible