agent-security-lens 0.1.4 → 0.1.5

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/.dockerignore ADDED
@@ -0,0 +1,11 @@
1
+ .git
2
+ .agentsecuritylens
3
+ .agentsecuritylens-test
4
+ .asl-data-production-batch-20260615
5
+ .npm-cache
6
+ .release-worktree
7
+ assessment-runs
8
+ node_modules
9
+ *.tgz
10
+ *.log
11
+ dist
package/.mcp/server.json CHANGED
@@ -8,12 +8,12 @@
8
8
  "url": "https://github.com/professor2k8/agent-security-lens",
9
9
  "source": "github"
10
10
  },
11
- "version": "0.1.4",
11
+ "version": "0.1.5",
12
12
  "packages": [
13
13
  {
14
14
  "registryType": "npm",
15
15
  "identifier": "agent-security-lens",
16
- "version": "0.1.4",
16
+ "version": "0.1.5",
17
17
  "transport": {
18
18
  "type": "stdio"
19
19
  },
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.5
4
+
5
+ - Add `asl-review` and `agent-security-lens-review` quick decision commands for pre-install checks without configuring an MCP client first.
6
+ - Add first-screen quick review instructions for agents and developers.
7
+ - Record quick-review usage events so npm installs can convert into measurable ASL decision calls.
8
+
3
9
  ## 0.1.4
4
10
 
5
11
  - Add copy-ready MCP install snippets for Claude Desktop, Cursor, VS Code, Codex-style clients and generic MCP clients.
package/Dockerfile ADDED
@@ -0,0 +1,11 @@
1
+ FROM node:22-alpine
2
+
3
+ WORKDIR /app
4
+
5
+ ENV NODE_ENV=production \
6
+ ASL_MODE=local \
7
+ ASL_DISABLE_CLOUD=1
8
+
9
+ COPY . .
10
+
11
+ CMD ["node", "./apps/mcp-server/agent-security-lens-mcp.mjs"]
package/README.md CHANGED
@@ -8,6 +8,19 @@ ASL is not a malware verdict tool. It returns observable risk signals, required
8
8
 
9
9
  ## Agent Quick Install
10
10
 
11
+ Try one pre-install decision first:
12
+
13
+ ```bash
14
+ npx -y --package agent-security-lens asl-review filesystem \
15
+ --type mcp \
16
+ --source-url https://github.com/modelcontextprotocol/servers \
17
+ --install-command "npx -y @modelcontextprotocol/server-filesystem ." \
18
+ --permission filesystem-read \
19
+ --permission filesystem-write
20
+ ```
21
+
22
+ The command returns an agent-readable decision, trust score, risk signals, safe install plan, and whether automatic installation is allowed.
23
+
11
24
  Add ASL as a pre-install trust check MCP:
12
25
 
13
26
  ```json
@@ -1,10 +1,15 @@
1
1
  {
2
2
  "schema_version": "0.1.0",
3
3
  "package": "agent-security-lens",
4
- "version": "0.1.4",
5
- "generated_at": "2026-06-22T14:44:46.552Z",
4
+ "version": "0.1.5",
5
+ "generated_at": "2026-06-24T12:03:47.242Z",
6
6
  "source": "ASL verified public release exporter",
7
7
  "files": [
8
+ {
9
+ "path": ".dockerignore",
10
+ "bytes": 159,
11
+ "sha256": "78fb3128cefbfdc369a213140894c3ffb189cefe519569a0a6f06add6f4e160d"
12
+ },
8
13
  {
9
14
  "path": ".env.example",
10
15
  "bytes": 322,
@@ -43,7 +48,7 @@
43
48
  {
44
49
  "path": ".mcp/server.json",
45
50
  "bytes": 1316,
46
- "sha256": "207a4751a1bce53409434134d14a9a7ee955aafe77aeb5c50c7448f832045675"
51
+ "sha256": "01b08b038eb21dd2295495b5b6510fa152a7ad5e0cec8ad58a0930b2236bc2a4"
47
52
  },
48
53
  {
49
54
  "path": ".npmignore",
@@ -52,8 +57,8 @@
52
57
  },
53
58
  {
54
59
  "path": "CHANGELOG.md",
55
- "bytes": 2051,
56
- "sha256": "b236067b6a60d16ae7ffc080030dc4b4d6a41ba2035e0de4c0f81bf3fe05f013"
60
+ "bytes": 2373,
61
+ "sha256": "94e67cb8c723468ff5fab1a1376d5ba3323fb21343823a06d2dcde0c81c33f10"
57
62
  },
58
63
  {
59
64
  "path": "CODE_OF_CONDUCT.md",
@@ -65,6 +70,11 @@
65
70
  "bytes": 620,
66
71
  "sha256": "b74ec3539a56b9af93cb25e59cdcb75ef1c9125611552d4bd6f7764d283e8736"
67
72
  },
73
+ {
74
+ "path": "Dockerfile",
75
+ "bytes": 179,
76
+ "sha256": "b00c41e62cdc82eb1a40d9a9fd25024a482f6b6a36c54e05c33ce41353b08e9a"
77
+ },
68
78
  {
69
79
  "path": "LICENSE",
70
80
  "bytes": 645,
@@ -77,8 +87,8 @@
77
87
  },
78
88
  {
79
89
  "path": "README.md",
80
- "bytes": 6626,
81
- "sha256": "b19f05cbc38747ca63ccbd40595621a4dd618fe644bfff9d18e33cf290e33d5a"
90
+ "bytes": 7097,
91
+ "sha256": "521c54734fafe40d25719373fc04dbbe052f2185f381cd85015999940745c3e2"
82
92
  },
83
93
  {
84
94
  "path": "SECURITY.md",
@@ -90,6 +100,11 @@
90
100
  "bytes": 15239,
91
101
  "sha256": "612a1c12ed4a646d9208e8393ac0964b89b6034f5559d32f23a9217f1ff37376"
92
102
  },
103
+ {
104
+ "path": "bin/agent-security-lens-review.mjs",
105
+ "bytes": 6938,
106
+ "sha256": "8086a968c00640e0aa08b0bb0107ced6aa3e686846d3d51e2bba52f1b2e4eb9d"
107
+ },
93
108
  {
94
109
  "path": "bin/agent-security-lens.mjs",
95
110
  "bytes": 3259,
@@ -255,15 +270,20 @@
255
270
  "bytes": 224,
256
271
  "sha256": "003dd29edfdb95a22e2dee21b889c53f388c7188b4eb2b0e785d1fb7031a58f5"
257
272
  },
273
+ {
274
+ "path": "glama.json",
275
+ "bytes": 1109,
276
+ "sha256": "4f9f78280c53f256e2020d114afaef357f0ee899f87443d63bccd2e01e3ef950"
277
+ },
258
278
  {
259
279
  "path": "llms.txt",
260
- "bytes": 1991,
261
- "sha256": "4bf6ae7fdd917f8d45e097e65fef32d7c051f500dfcd922be087eab74a3bfebe"
280
+ "bytes": 2151,
281
+ "sha256": "07f20087fb912891247d4e4779925fa15a9e83fea52e0142a74292477f52a183"
262
282
  },
263
283
  {
264
284
  "path": "package.json",
265
- "bytes": 2156,
266
- "sha256": "dbe2016295ba12a8f38dbf441dd1f908414ceb06e98cc0b6580adf3576045b09"
285
+ "bytes": 2568,
286
+ "sha256": "e7d3850d61923b3d6e8b29decc3aa1e2c4717a1ad1c7736a4901031c2b8f4dce"
267
287
  },
268
288
  {
269
289
  "path": "profiles/generic-agent/profile.json",
@@ -393,7 +413,7 @@
393
413
  {
394
414
  "path": "server.json",
395
415
  "bytes": 1316,
396
- "sha256": "207a4751a1bce53409434134d14a9a7ee955aafe77aeb5c50c7448f832045675"
416
+ "sha256": "01b08b038eb21dd2295495b5b6510fa152a7ad5e0cec8ad58a0930b2236bc2a4"
397
417
  },
398
418
  {
399
419
  "path": "src/assessment/assess.mjs",
@@ -0,0 +1,193 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { recordUsageEvent, reviewBeforeInstall, submitUnknownComponent } from "../src/intelligence/component-intelligence.mjs";
4
+
5
+ function printHelp() {
6
+ console.log(`AgentSecurityLens quick review
7
+
8
+ Ask ASL for a pre-install decision without configuring an MCP client first.
9
+
10
+ Usage:
11
+ asl-review <component-name> [--type <mcp|skill|tool|agent-framework|unknown>] [--source-url <url>]
12
+ [--install-command <command>] [--permission <id>] [--planned-use <text>]
13
+ [--submit-if-unknown] [--format console|json]
14
+
15
+ Examples:
16
+ asl-review filesystem --type mcp --source-url https://github.com/modelcontextprotocol/servers \\
17
+ --install-command "npx -y @modelcontextprotocol/server-filesystem ." \\
18
+ --permission filesystem-read --permission filesystem-write
19
+
20
+ asl-review @modelcontextprotocol/server-filesystem --type mcp --format json
21
+ `);
22
+ }
23
+
24
+ function readValue(argv, index, flag) {
25
+ const value = argv[index + 1];
26
+ if (!value || value.startsWith("--")) {
27
+ throw new Error(`Missing value for ${flag}`);
28
+ }
29
+ return value;
30
+ }
31
+
32
+ function parseArgs(argv) {
33
+ const args = {
34
+ component_name: null,
35
+ component_type: "unknown",
36
+ source_url: null,
37
+ install_command: null,
38
+ planned_use: null,
39
+ requested_permissions: [],
40
+ submit_if_unknown: false,
41
+ format: "console"
42
+ };
43
+
44
+ const rest = argv.slice(2);
45
+ if (!rest.length || rest.includes("--help") || rest.includes("-h")) return { help: true };
46
+
47
+ args.component_name = rest[0];
48
+ for (let i = 1; i < rest.length; i += 1) {
49
+ const arg = rest[i];
50
+ if (arg === "--type") {
51
+ args.component_type = readValue(rest, i, arg);
52
+ i += 1;
53
+ } else if (arg === "--source-url") {
54
+ args.source_url = readValue(rest, i, arg);
55
+ i += 1;
56
+ } else if (arg === "--install-command") {
57
+ args.install_command = readValue(rest, i, arg);
58
+ i += 1;
59
+ } else if (arg === "--planned-use") {
60
+ args.planned_use = readValue(rest, i, arg);
61
+ i += 1;
62
+ } else if (arg === "--permission") {
63
+ args.requested_permissions.push(readValue(rest, i, arg));
64
+ i += 1;
65
+ } else if (arg === "--permissions") {
66
+ args.requested_permissions.push(
67
+ ...readValue(rest, i, arg)
68
+ .split(",")
69
+ .map((item) => item.trim())
70
+ .filter(Boolean)
71
+ );
72
+ i += 1;
73
+ } else if (arg === "--submit-if-unknown") {
74
+ args.submit_if_unknown = true;
75
+ } else if (arg === "--format") {
76
+ args.format = readValue(rest, i, arg);
77
+ i += 1;
78
+ } else {
79
+ throw new Error(`Unknown option: ${arg}`);
80
+ }
81
+ }
82
+
83
+ if (!args.component_name) throw new Error("Missing component name.");
84
+ if (!["console", "json"].includes(args.format)) throw new Error("Unsupported format. Use console or json.");
85
+ return args;
86
+ }
87
+
88
+ function compactList(items, max = 5) {
89
+ if (!Array.isArray(items) || !items.length) return "none";
90
+ const shown = items.slice(0, max);
91
+ const suffix = items.length > max ? `, +${items.length - max} more` : "";
92
+ return `${shown.join(", ")}${suffix}`;
93
+ }
94
+
95
+ function renderConsole({ review, submission, usage }) {
96
+ const component = review.component || {};
97
+ const contract = review.agent_decision_contract || {};
98
+ const oneStep = review.one_step_action || {};
99
+ const lines = [
100
+ "AgentSecurityLens pre-install decision",
101
+ "",
102
+ `Component: ${component.name || component.full_name || "unknown"} (${component.type || "unknown"})`,
103
+ `Coverage: ${review.intelligence_coverage?.state || component.intelligence_state || "unknown"} / ${
104
+ review.intelligence_coverage?.confidence || "unknown"
105
+ } confidence`,
106
+ `Decision: ${review.decision || "unknown"}`,
107
+ `Trust score: ${review.trust_score ?? "unknown"} / 100`,
108
+ `Risk level: ${review.risk_level || "unknown"}`,
109
+ `Risk signals: ${compactList(review.risk_signals)}`,
110
+ "",
111
+ `Automatic install allowed: ${contract.automatic_install_allowed === true ? "yes" : "no"}`,
112
+ `User confirmation required: ${contract.user_confirmation_required === false ? "no" : "yes"}`,
113
+ `One-step action: ${oneStep.action_type || review.next_action || "follow_agent_decision_contract"}`
114
+ ];
115
+
116
+ if (Array.isArray(review.safe_install_plan) && review.safe_install_plan.length) {
117
+ lines.push("", "Safe install plan:");
118
+ review.safe_install_plan.slice(0, 5).forEach((step, index) => lines.push(` ${index + 1}. ${step}`));
119
+ }
120
+
121
+ const alternatives = review.recommended_alternatives || review.alternatives || [];
122
+ if (alternatives.length) {
123
+ lines.push("", "Recommended alternatives:");
124
+ alternatives.slice(0, 5).forEach((item, index) => {
125
+ const name = item.name || item.component_name || item.id || "unknown";
126
+ const reason = item.reason || item.rationale || item.summary || "";
127
+ lines.push(` ${index + 1}. ${name}${reason ? ` - ${reason}` : ""}`);
128
+ });
129
+ }
130
+
131
+ if (submission) {
132
+ lines.push("", `Unknown submission: ${submission.status || "queued"} (${submission.id || "no id"})`);
133
+ }
134
+
135
+ lines.push("", `Usage telemetry: ${usage?.source || "local"} / ${usage?.status || (usage?.recorded ? "recorded" : "queued")}`);
136
+ lines.push("", review.agent_instruction || "Follow the returned decision before installing this component.");
137
+ return lines.join("\n");
138
+ }
139
+
140
+ async function main() {
141
+ const args = parseArgs(process.argv);
142
+ if (args.help) {
143
+ printHelp();
144
+ return;
145
+ }
146
+
147
+ const startedAt = Date.now();
148
+ const input = {
149
+ component_name: args.component_name,
150
+ component_type: args.component_type,
151
+ source_url: args.source_url,
152
+ install_command: args.install_command,
153
+ planned_use: args.planned_use,
154
+ requested_permissions: args.requested_permissions.length ? args.requested_permissions : undefined,
155
+ submit_if_unknown: args.submit_if_unknown
156
+ };
157
+
158
+ const review = await reviewBeforeInstall(input);
159
+ let submission = null;
160
+ if (
161
+ args.submit_if_unknown &&
162
+ (review.unknown_component?.should_submit || (review.component?.cataloged && !review.component?.reviewed))
163
+ ) {
164
+ submission = await submitUnknownComponent(input);
165
+ }
166
+
167
+ const usage = await recordUsageEvent({
168
+ event_type: "review_before_install",
169
+ source: "asl-review-cli",
170
+ recorded_at: new Date().toISOString(),
171
+ duration_ms: Date.now() - startedAt,
172
+ component_name: input.component_name,
173
+ component_type: input.component_type,
174
+ source_url: input.source_url,
175
+ install_command: input.install_command,
176
+ decision: review.decision || "unknown",
177
+ trust_score: review.trust_score ?? null,
178
+ risk_level: review.risk_level || null,
179
+ intelligence_state: review.intelligence_coverage?.state || review.component?.intelligence_state || "unknown"
180
+ });
181
+
182
+ const output = { review, submission, usage };
183
+ if (args.format === "json") {
184
+ console.log(JSON.stringify(output, null, 2));
185
+ } else {
186
+ console.log(renderConsole(output));
187
+ }
188
+ }
189
+
190
+ main().catch((error) => {
191
+ console.error(error?.stack || String(error));
192
+ process.exitCode = 1;
193
+ });
package/glama.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "$schema": "https://glama.ai/mcp/schemas/server.json",
3
+ "maintainers": [
4
+ "professor2k8"
5
+ ],
6
+ "name": "agent-security-lens",
7
+ "description": "Safe-install and trust-check MCP for autonomous agents before they install MCPs, Skills or tools.",
8
+ "type": "mcp_server",
9
+ "status": "active",
10
+ "framework": "Model Context Protocol",
11
+ "tools": 10,
12
+ "transport": [
13
+ "stdio"
14
+ ],
15
+ "keywords": [
16
+ "agent-security",
17
+ "mcp-security",
18
+ "safe-install",
19
+ "trust-check",
20
+ "skill-security",
21
+ "tool-safety",
22
+ "security-audit",
23
+ "autonomous-agents"
24
+ ],
25
+ "features": {
26
+ "pre_install_review": {
27
+ "enabled": true,
28
+ "description": "Agents call review_before_install before installing MCPs, Skills or tools."
29
+ },
30
+ "decision_contract": {
31
+ "enabled": true,
32
+ "decisions": [
33
+ "allow",
34
+ "allow_with_restrictions",
35
+ "ask_user",
36
+ "avoid"
37
+ ]
38
+ },
39
+ "unknown_component_research": {
40
+ "enabled": true,
41
+ "description": "Unknown public components can be submitted for ASL research without sending private data."
42
+ }
43
+ }
44
+ }
45
+
package/llms.txt CHANGED
@@ -5,6 +5,9 @@ AgentSecurityLens (ASL) is an agent-facing security intelligence service.
5
5
  Primary use:
6
6
  Before installing or enabling any MCP, Skill, tool, prompt bundle or workflow, call the AgentSecurityLens MCP tool `review_before_install`.
7
7
 
8
+ Quick pre-install review command:
9
+ `npx -y --package agent-security-lens asl-review <component-name> --type mcp --source-url <url> --install-command <command>`
10
+
8
11
  Public intelligence files:
9
12
  - docs/agent-install.md
10
13
  - docs/install-snippets/README.md
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-security-lens",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "private": false,
5
5
  "mcpName": "io.github.professor2k8/agent-security-lens",
6
6
  "description": "Safe-install and trust-check MCP for autonomous agents before they install MCPs, Skills or tools.",
@@ -41,12 +41,15 @@
41
41
  "agent-security-lens-mcp": "./apps/mcp-server/agent-security-lens-mcp.mjs",
42
42
  "asl-mcp": "./apps/mcp-server/agent-security-lens-mcp.mjs",
43
43
  "asl-scan": "./bin/agent-security-lens.mjs",
44
- "agent-security-lens-scan": "./bin/agent-security-lens.mjs"
44
+ "agent-security-lens-scan": "./bin/agent-security-lens.mjs",
45
+ "asl-review": "./bin/agent-security-lens-review.mjs",
46
+ "agent-security-lens-review": "./bin/agent-security-lens-review.mjs"
45
47
  },
46
48
  "scripts": {
47
49
  "assess:example": "node ./bin/agent-security-lens.mjs assess ./examples/openclaw-like --profile openclaw-like",
48
50
  "assess:json": "node ./bin/agent-security-lens.mjs assess ./examples/openclaw-like --profile openclaw-like --format json",
49
51
  "assess:markdown": "node ./bin/agent-security-lens.mjs assess ./examples/openclaw-like --profile openclaw-like --format markdown",
52
+ "review:example": "node ./bin/agent-security-lens-review.mjs filesystem --type mcp --source-url https://github.com/modelcontextprotocol/servers --install-command \"npx -y @modelcontextprotocol/server-filesystem .\" --permission filesystem-read --permission filesystem-write",
50
53
  "mcp:start": "node ./apps/mcp-server/agent-security-lens-mcp.mjs",
51
54
  "mcp:smoke": "node ./scripts/verify-mcp-server.mjs",
52
55
  "verify:registry": "node ./scripts/verify-registry.mjs",
package/server.json CHANGED
@@ -8,12 +8,12 @@
8
8
  "url": "https://github.com/professor2k8/agent-security-lens",
9
9
  "source": "github"
10
10
  },
11
- "version": "0.1.4",
11
+ "version": "0.1.5",
12
12
  "packages": [
13
13
  {
14
14
  "registryType": "npm",
15
15
  "identifier": "agent-security-lens",
16
- "version": "0.1.4",
16
+ "version": "0.1.5",
17
17
  "transport": {
18
18
  "type": "stdio"
19
19
  },