argusqa-os 9.2.7 → 9.2.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/mcp-server.js +72 -3
package/package.json
CHANGED
package/src/mcp-server.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
* Argus MCP Server (v9.2.
|
|
3
|
+
* Argus MCP Server (v9.2.9)
|
|
4
4
|
*
|
|
5
5
|
* Exposes Argus as an MCP server so Claude (or any MCP client) can call
|
|
6
6
|
* argus_audit, argus_audit_full, argus_compare, and argus_last_report
|
|
@@ -28,6 +28,8 @@ import path from 'path';
|
|
|
28
28
|
import { createMcpClient } from './utils/mcp-client.js';
|
|
29
29
|
import { crawlRouteCheap, runCrawl } from './orchestration/crawl-and-report.js';
|
|
30
30
|
import { runComparison } from './orchestration/env-comparison.js';
|
|
31
|
+
import { WatchSession } from './orchestration/watch-mode.js';
|
|
32
|
+
import { CdpBrowserAdapter } from './adapters/browser.js';
|
|
31
33
|
|
|
32
34
|
const REPORTS_DIR = path.resolve(process.cwd(), 'reports');
|
|
33
35
|
|
|
@@ -68,6 +70,26 @@ const TOOLS = [
|
|
|
68
70
|
description: 'Returns the most recent Argus JSON report from the reports/ directory. Report includes a findings array and severity summary (critical/warning/info counts). Returns { "error": "No reports found in reports/" } when no audits have been run yet. Use to retrieve prior results without re-running a scan, or to pipe findings into another analysis tool.',
|
|
69
71
|
inputSchema: { type: 'object', properties: {} },
|
|
70
72
|
},
|
|
73
|
+
{
|
|
74
|
+
name: 'argus_watch_snapshot',
|
|
75
|
+
description: 'Snapshots the currently open Chrome tab without navigating — captures console errors, network failures (4xx/5xx), CORS blocks, and auth failures in one poll. Returns { findings: [{severity, type, message, url}], newConsole, newNetwork }. Use during active development to inspect what is happening on the current page without running a full audit. Requires Chrome on --remote-debugging-port=9222 with a page already open.',
|
|
76
|
+
inputSchema: {
|
|
77
|
+
type: 'object',
|
|
78
|
+
properties: {
|
|
79
|
+
url: { type: 'string', description: 'Optional base URL to attribute findings to (default: TARGET_DEV_URL env var). Does not navigate — reads the currently open Chrome tab.' },
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
name: 'argus_get_context',
|
|
85
|
+
description: 'Captures everything currently broken on the open Chrome tab and formats it as a diagnostic context for Claude to read and suggest fixes. Does NOT navigate — reads the live tab state after user interactions, in authenticated sessions, or mid-flow. Returns { summary, url, timestamp, critical_issues, warnings, js_errors, network_failures, console_errors, recent_requests } where summary is a plain-English description of what is broken. Use when the app is stuck, throwing errors, or behaving unexpectedly — run this, then paste the output to Claude and ask for fixes. Requires Chrome on --remote-debugging-port=9222.',
|
|
86
|
+
inputSchema: {
|
|
87
|
+
type: 'object',
|
|
88
|
+
properties: {
|
|
89
|
+
url: { type: 'string', description: 'Optional base URL to attribute findings to (default: TARGET_DEV_URL env var). Does not navigate — inspects the currently open Chrome tab.' },
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
},
|
|
71
93
|
];
|
|
72
94
|
|
|
73
95
|
// ── Helpers ───────────────────────────────────────────────────────────────────
|
|
@@ -111,6 +133,51 @@ async function handleCompare() {
|
|
|
111
133
|
});
|
|
112
134
|
}
|
|
113
135
|
|
|
136
|
+
async function handleWatchSnapshot({ url } = {}) {
|
|
137
|
+
return withMcp(async (mcp) => {
|
|
138
|
+
const browser = new CdpBrowserAdapter(mcp);
|
|
139
|
+
const baseUrl = url ?? process.env.TARGET_DEV_URL ?? 'http://localhost:3000';
|
|
140
|
+
const session = new WatchSession(browser, baseUrl);
|
|
141
|
+
const result = await session.poll();
|
|
142
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
async function handleGetContext({ url } = {}) {
|
|
147
|
+
return withMcp(async (mcp) => {
|
|
148
|
+
const browser = new CdpBrowserAdapter(mcp);
|
|
149
|
+
const baseUrl = url ?? process.env.TARGET_DEV_URL ?? 'http://localhost:3000';
|
|
150
|
+
const session = new WatchSession(browser, baseUrl);
|
|
151
|
+
const { findings, newConsole, newNetwork } = await session.poll();
|
|
152
|
+
|
|
153
|
+
const critical = findings.filter(f => f.severity === 'critical');
|
|
154
|
+
const warnings = findings.filter(f => f.severity === 'warning');
|
|
155
|
+
|
|
156
|
+
let summary;
|
|
157
|
+
if (critical.length === 0 && warnings.length === 0) {
|
|
158
|
+
summary = `No issues detected on ${baseUrl} — console and network are clean.`;
|
|
159
|
+
} else if (critical.length > 0) {
|
|
160
|
+
summary = `${critical.length} critical issue${critical.length > 1 ? 's' : ''} + ${warnings.length} warning${warnings.length !== 1 ? 's' : ''} detected on ${baseUrl}. Focus on critical issues first.`;
|
|
161
|
+
} else {
|
|
162
|
+
summary = `${warnings.length} warning${warnings.length !== 1 ? 's' : ''} detected on ${baseUrl}. No critical errors.`;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
const context = {
|
|
166
|
+
summary,
|
|
167
|
+
url: baseUrl,
|
|
168
|
+
timestamp: new Date().toISOString(),
|
|
169
|
+
critical_issues: critical,
|
|
170
|
+
warnings,
|
|
171
|
+
js_errors: findings.filter(f => f.type === 'js-error' || f.type === 'unhandled-rejection'),
|
|
172
|
+
network_failures: findings.filter(f => f.type === 'network-error' || f.type === 'cors-error' || f.type === 'auth-error'),
|
|
173
|
+
console_errors: newConsole.filter(m => m.level === 'error' || m.level === 'warning'),
|
|
174
|
+
recent_requests: newNetwork.slice(-20),
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
return { content: [{ type: 'text', text: JSON.stringify(context, null, 2) }] };
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
|
|
114
181
|
async function handleLastReport() {
|
|
115
182
|
if (!fs.existsSync(REPORTS_DIR)) {
|
|
116
183
|
return { content: [{ type: 'text', text: '{"error":"No reports found in reports/"}' }] };
|
|
@@ -129,7 +196,7 @@ async function handleLastReport() {
|
|
|
129
196
|
// ── Server bootstrap ──────────────────────────────────────────────────────────
|
|
130
197
|
|
|
131
198
|
const server = new Server(
|
|
132
|
-
{ name: 'argus', version: '9.2.
|
|
199
|
+
{ name: 'argus', version: '9.2.9' },
|
|
133
200
|
{ capabilities: { tools: {} } },
|
|
134
201
|
);
|
|
135
202
|
|
|
@@ -141,7 +208,9 @@ server.setRequestHandler(CallToolRequestSchema, async (req) => {
|
|
|
141
208
|
case 'argus_audit': return await handleAudit(req.params.arguments ?? {});
|
|
142
209
|
case 'argus_audit_full': return await handleAuditFull(req.params.arguments ?? {});
|
|
143
210
|
case 'argus_compare': return await handleCompare();
|
|
144
|
-
case 'argus_last_report':
|
|
211
|
+
case 'argus_last_report': return await handleLastReport();
|
|
212
|
+
case 'argus_watch_snapshot': return await handleWatchSnapshot(req.params.arguments ?? {});
|
|
213
|
+
case 'argus_get_context': return await handleGetContext(req.params.arguments ?? {});
|
|
145
214
|
default: throw new Error(`Unknown tool: ${req.params.name}`);
|
|
146
215
|
}
|
|
147
216
|
} catch (err) {
|