nulvec 0.1.0__tar.gz
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.
- nulvec-0.1.0/PKG-INFO +215 -0
- nulvec-0.1.0/README.md +186 -0
- nulvec-0.1.0/nulvec/__init__.py +8 -0
- nulvec-0.1.0/nulvec/cli.py +918 -0
- nulvec-0.1.0/nulvec/machine.py +624 -0
- nulvec-0.1.0/nulvec/mcp_proxy/__init__.py +1 -0
- nulvec-0.1.0/nulvec/mcp_proxy/stdio.py +185 -0
- nulvec-0.1.0/nulvec/models.py +90 -0
- nulvec-0.1.0/nulvec/report.py +129 -0
- nulvec-0.1.0/nulvec/scanner.py +129 -0
- nulvec-0.1.0/nulvec/scanners/__init__.py +0 -0
- nulvec-0.1.0/nulvec/scanners/code.py +127 -0
- nulvec-0.1.0/nulvec/scanners/image.py +155 -0
- nulvec-0.1.0/nulvec/scanners/mcp.py +129 -0
- nulvec-0.1.0/nulvec/scanners/pdf.py +167 -0
- nulvec-0.1.0/nulvec/scanners/skill.py +239 -0
- nulvec-0.1.0/nulvec/stage1/__init__.py +0 -0
- nulvec-0.1.0/nulvec/stage1/triage.py +307 -0
- nulvec-0.1.0/nulvec/stage2/__init__.py +0 -0
- nulvec-0.1.0/nulvec/stage2/deep.py +127 -0
- nulvec-0.1.0/nulvec/utils.py +159 -0
- nulvec-0.1.0/nulvec/wrapper.py +98 -0
- nulvec-0.1.0/nulvec.egg-info/PKG-INFO +215 -0
- nulvec-0.1.0/nulvec.egg-info/SOURCES.txt +41 -0
- nulvec-0.1.0/nulvec.egg-info/dependency_links.txt +1 -0
- nulvec-0.1.0/nulvec.egg-info/entry_points.txt +2 -0
- nulvec-0.1.0/nulvec.egg-info/requires.txt +11 -0
- nulvec-0.1.0/nulvec.egg-info/top_level.txt +1 -0
- nulvec-0.1.0/pyproject.toml +54 -0
- nulvec-0.1.0/setup.cfg +4 -0
- nulvec-0.1.0/tests/test_cli.py +69 -0
- nulvec-0.1.0/tests/test_code.py +49 -0
- nulvec-0.1.0/tests/test_git_shim.py +151 -0
- nulvec-0.1.0/tests/test_image.py +84 -0
- nulvec-0.1.0/tests/test_install_hook.py +38 -0
- nulvec-0.1.0/tests/test_machine_cli.py +133 -0
- nulvec-0.1.0/tests/test_mcp.py +50 -0
- nulvec-0.1.0/tests/test_mcp_proxy.py +79 -0
- nulvec-0.1.0/tests/test_pdf.py +67 -0
- nulvec-0.1.0/tests/test_runtime_cli.py +54 -0
- nulvec-0.1.0/tests/test_skill.py +70 -0
- nulvec-0.1.0/tests/test_skill_install_shim.py +94 -0
- nulvec-0.1.0/tests/test_wrapper.py +53 -0
nulvec-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: nulvec
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Perceptual AI security — scan images, PDFs, and web content for adversarial injections
|
|
5
|
+
Author: Nulvec
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://nulvec.dev
|
|
8
|
+
Project-URL: Repository, https://github.com/aryan5v/nulvec
|
|
9
|
+
Project-URL: Issues, https://github.com/aryan5v/nulvec/issues
|
|
10
|
+
Keywords: ai security,adversarial,prompt injection,multimodal,image scaling attack
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Topic :: Security
|
|
19
|
+
Requires-Python: >=3.9
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
Requires-Dist: Pillow>=10.0.0
|
|
22
|
+
Requires-Dist: pytesseract>=0.3.10
|
|
23
|
+
Requires-Dist: PyMuPDF>=1.23.0
|
|
24
|
+
Requires-Dist: reportlab>=4.0.0
|
|
25
|
+
Requires-Dist: typing-extensions>=4.0.0; python_version < "3.11"
|
|
26
|
+
Provides-Extra: dev
|
|
27
|
+
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
28
|
+
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
|
|
29
|
+
|
|
30
|
+
# Nulvec
|
|
31
|
+
|
|
32
|
+
Nulvec is a local-first security scanner for agent inputs.
|
|
33
|
+
|
|
34
|
+
It scans files and repositories for high-signal attack patterns before they
|
|
35
|
+
reach an LLM or agent runtime:
|
|
36
|
+
|
|
37
|
+
- SKILL.md supply-chain attacks
|
|
38
|
+
- prompt injection in MCP payloads and code comments
|
|
39
|
+
- credential exfiltration patterns
|
|
40
|
+
- hidden PDF and image payloads
|
|
41
|
+
- image scaling and steganography attacks
|
|
42
|
+
|
|
43
|
+
## Install
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
pip install nulvec
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
For image scanning, install Tesseract on the host:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
brew install tesseract
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Quick Start
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
nulvec scan suspicious-skill.md
|
|
59
|
+
nulvec scan . --block-on critical
|
|
60
|
+
nulvec install
|
|
61
|
+
nulvec skill install ./skills/my-skill
|
|
62
|
+
nulvec mcp-proxy -- python my_server.py
|
|
63
|
+
nulvec logs
|
|
64
|
+
nulvec config show
|
|
65
|
+
nulvec status
|
|
66
|
+
nulvec doctor
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Python API
|
|
70
|
+
|
|
71
|
+
```python
|
|
72
|
+
import nulvec
|
|
73
|
+
|
|
74
|
+
result = nulvec.scan("document.pdf")
|
|
75
|
+
print(result.decision)
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Machine-Level Install
|
|
79
|
+
|
|
80
|
+
`nulvec install` creates a local policy file, event log, and Git protection
|
|
81
|
+
layer. It installs a Git shim earlier in `PATH`, configures Git template hooks
|
|
82
|
+
for future clones, and adds managed hooks to the current repository when run
|
|
83
|
+
inside one.
|
|
84
|
+
|
|
85
|
+
Current support matrix:
|
|
86
|
+
|
|
87
|
+
- Git clone scanning via temp clone + pre-finalize repo scan
|
|
88
|
+
- Git pull scanning for simple `git pull` flows via fetch + temp worktree scan
|
|
89
|
+
- Git post-checkout/post-merge hooks as a fallback repo scan layer
|
|
90
|
+
- Skill install protection via `nulvec skill install <path-or-url>`
|
|
91
|
+
- Approved skill artifact hash cache under the local Nulvec runtime
|
|
92
|
+
- Stdio MCP proxy via `nulvec mcp-proxy -- <server command>`
|
|
93
|
+
- Local audit events via `nulvec logs`
|
|
94
|
+
- Local policy inspection via `nulvec config show`
|
|
95
|
+
|
|
96
|
+
## Skill Protection Boundary
|
|
97
|
+
|
|
98
|
+
Nulvec does not automatically intercept arbitrary third-party skill installers.
|
|
99
|
+
|
|
100
|
+
The protected v1 path is:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
nulvec skill install <path-or-url>
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
If you install a skill through some other CLI, Nulvec does not own that
|
|
107
|
+
execution path and cannot honestly claim automatic pre-install protection there.
|
|
108
|
+
|
|
109
|
+
## MCP Proxy Setup
|
|
110
|
+
|
|
111
|
+
The MCP proxy is manual in v1. You must point the supported client or server
|
|
112
|
+
launch command at:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
nulvec mcp-proxy -- <real server command>
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
This is the right current story for local developer tools such as Codex CLI,
|
|
119
|
+
Claude Code, and OpenCode: configure each MCP server entry to launch through
|
|
120
|
+
the proxy so Nulvec can scan server responses before they reach the client.
|
|
121
|
+
|
|
122
|
+
### Codex CLI Example
|
|
123
|
+
|
|
124
|
+
Codex CLI supports MCP server configuration in TOML via:
|
|
125
|
+
|
|
126
|
+
- global config: `~/.codex/config.toml`
|
|
127
|
+
- per-project config: `.codex/config.toml` for trusted projects
|
|
128
|
+
|
|
129
|
+
Example stdio wrapper configuration:
|
|
130
|
+
|
|
131
|
+
```toml
|
|
132
|
+
[mcp_servers.context7]
|
|
133
|
+
command = "nulvec"
|
|
134
|
+
args = ["mcp-proxy", "--", "npx", "-y", "@upstash/context7-mcp"]
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Notes:
|
|
138
|
+
|
|
139
|
+
- Codex uses an argv model, not a shell snippet, so wrapper commands must be
|
|
140
|
+
tokenized correctly.
|
|
141
|
+
- In controlled environments, MCP allowlist or identity rules may need to be
|
|
142
|
+
updated when the command changes from the original server launcher to
|
|
143
|
+
`nulvec`.
|
|
144
|
+
|
|
145
|
+
### Claude Code Example
|
|
146
|
+
|
|
147
|
+
Claude Code supports stdio MCP servers through JSON config or the `claude mcp`
|
|
148
|
+
CLI.
|
|
149
|
+
|
|
150
|
+
Common MCP config locations:
|
|
151
|
+
|
|
152
|
+
- user/local scope MCP servers: `~/.claude.json`
|
|
153
|
+
- project scope MCP servers: `.mcp.json`
|
|
154
|
+
|
|
155
|
+
Example project config:
|
|
156
|
+
|
|
157
|
+
```json
|
|
158
|
+
{
|
|
159
|
+
"mcpServers": {
|
|
160
|
+
"airtable": {
|
|
161
|
+
"type": "stdio",
|
|
162
|
+
"command": "nulvec",
|
|
163
|
+
"args": ["mcp-proxy", "--", "npx", "-y", "airtable-mcp-server"],
|
|
164
|
+
"env": {}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
Equivalent CLI shape:
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
claude mcp add --transport stdio airtable -- nulvec mcp-proxy -- npx -y airtable-mcp-server
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Notes:
|
|
177
|
+
|
|
178
|
+
- Claude CLI flag ordering matters. Claude flags must come before the server
|
|
179
|
+
name, and the wrapped server command must come after `--`.
|
|
180
|
+
- MCP scope storage is separate from general Claude settings. Do not assume MCP
|
|
181
|
+
local scope lives under `.claude/settings.local.json`.
|
|
182
|
+
- In managed environments, exact command-array allowlists can block wrapped
|
|
183
|
+
commands unless the allowlist is updated for the new `nulvec` launcher.
|
|
184
|
+
|
|
185
|
+
### OpenCode Example
|
|
186
|
+
|
|
187
|
+
OpenCode stores MCP servers in JSON config and uses a command-array model for
|
|
188
|
+
local servers.
|
|
189
|
+
|
|
190
|
+
Common config locations:
|
|
191
|
+
|
|
192
|
+
- global config: `~/.config/opencode/opencode.json`
|
|
193
|
+
- project config: `opencode.json`
|
|
194
|
+
|
|
195
|
+
Example local MCP config:
|
|
196
|
+
|
|
197
|
+
```json
|
|
198
|
+
{
|
|
199
|
+
"$schema": "https://opencode.ai/config.json",
|
|
200
|
+
"mcp": {
|
|
201
|
+
"server-everything": {
|
|
202
|
+
"type": "local",
|
|
203
|
+
"command": ["nulvec", "mcp-proxy", "--", "npx", "-y", "@modelcontextprotocol/server-everything"],
|
|
204
|
+
"enabled": true
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
Notes:
|
|
211
|
+
|
|
212
|
+
- OpenCode’s local MCP command is already an argv array, which makes wrapper
|
|
213
|
+
insertion straightforward.
|
|
214
|
+
- If you later automate rewiring, be careful with config-path detection for
|
|
215
|
+
`.json`, `.jsonc`, and older install-path variants documented by OpenCode.
|
nulvec-0.1.0/README.md
ADDED
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
# Nulvec
|
|
2
|
+
|
|
3
|
+
Nulvec is a local-first security scanner for agent inputs.
|
|
4
|
+
|
|
5
|
+
It scans files and repositories for high-signal attack patterns before they
|
|
6
|
+
reach an LLM or agent runtime:
|
|
7
|
+
|
|
8
|
+
- SKILL.md supply-chain attacks
|
|
9
|
+
- prompt injection in MCP payloads and code comments
|
|
10
|
+
- credential exfiltration patterns
|
|
11
|
+
- hidden PDF and image payloads
|
|
12
|
+
- image scaling and steganography attacks
|
|
13
|
+
|
|
14
|
+
## Install
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
pip install nulvec
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
For image scanning, install Tesseract on the host:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
brew install tesseract
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Quick Start
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
nulvec scan suspicious-skill.md
|
|
30
|
+
nulvec scan . --block-on critical
|
|
31
|
+
nulvec install
|
|
32
|
+
nulvec skill install ./skills/my-skill
|
|
33
|
+
nulvec mcp-proxy -- python my_server.py
|
|
34
|
+
nulvec logs
|
|
35
|
+
nulvec config show
|
|
36
|
+
nulvec status
|
|
37
|
+
nulvec doctor
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Python API
|
|
41
|
+
|
|
42
|
+
```python
|
|
43
|
+
import nulvec
|
|
44
|
+
|
|
45
|
+
result = nulvec.scan("document.pdf")
|
|
46
|
+
print(result.decision)
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Machine-Level Install
|
|
50
|
+
|
|
51
|
+
`nulvec install` creates a local policy file, event log, and Git protection
|
|
52
|
+
layer. It installs a Git shim earlier in `PATH`, configures Git template hooks
|
|
53
|
+
for future clones, and adds managed hooks to the current repository when run
|
|
54
|
+
inside one.
|
|
55
|
+
|
|
56
|
+
Current support matrix:
|
|
57
|
+
|
|
58
|
+
- Git clone scanning via temp clone + pre-finalize repo scan
|
|
59
|
+
- Git pull scanning for simple `git pull` flows via fetch + temp worktree scan
|
|
60
|
+
- Git post-checkout/post-merge hooks as a fallback repo scan layer
|
|
61
|
+
- Skill install protection via `nulvec skill install <path-or-url>`
|
|
62
|
+
- Approved skill artifact hash cache under the local Nulvec runtime
|
|
63
|
+
- Stdio MCP proxy via `nulvec mcp-proxy -- <server command>`
|
|
64
|
+
- Local audit events via `nulvec logs`
|
|
65
|
+
- Local policy inspection via `nulvec config show`
|
|
66
|
+
|
|
67
|
+
## Skill Protection Boundary
|
|
68
|
+
|
|
69
|
+
Nulvec does not automatically intercept arbitrary third-party skill installers.
|
|
70
|
+
|
|
71
|
+
The protected v1 path is:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
nulvec skill install <path-or-url>
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
If you install a skill through some other CLI, Nulvec does not own that
|
|
78
|
+
execution path and cannot honestly claim automatic pre-install protection there.
|
|
79
|
+
|
|
80
|
+
## MCP Proxy Setup
|
|
81
|
+
|
|
82
|
+
The MCP proxy is manual in v1. You must point the supported client or server
|
|
83
|
+
launch command at:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
nulvec mcp-proxy -- <real server command>
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
This is the right current story for local developer tools such as Codex CLI,
|
|
90
|
+
Claude Code, and OpenCode: configure each MCP server entry to launch through
|
|
91
|
+
the proxy so Nulvec can scan server responses before they reach the client.
|
|
92
|
+
|
|
93
|
+
### Codex CLI Example
|
|
94
|
+
|
|
95
|
+
Codex CLI supports MCP server configuration in TOML via:
|
|
96
|
+
|
|
97
|
+
- global config: `~/.codex/config.toml`
|
|
98
|
+
- per-project config: `.codex/config.toml` for trusted projects
|
|
99
|
+
|
|
100
|
+
Example stdio wrapper configuration:
|
|
101
|
+
|
|
102
|
+
```toml
|
|
103
|
+
[mcp_servers.context7]
|
|
104
|
+
command = "nulvec"
|
|
105
|
+
args = ["mcp-proxy", "--", "npx", "-y", "@upstash/context7-mcp"]
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Notes:
|
|
109
|
+
|
|
110
|
+
- Codex uses an argv model, not a shell snippet, so wrapper commands must be
|
|
111
|
+
tokenized correctly.
|
|
112
|
+
- In controlled environments, MCP allowlist or identity rules may need to be
|
|
113
|
+
updated when the command changes from the original server launcher to
|
|
114
|
+
`nulvec`.
|
|
115
|
+
|
|
116
|
+
### Claude Code Example
|
|
117
|
+
|
|
118
|
+
Claude Code supports stdio MCP servers through JSON config or the `claude mcp`
|
|
119
|
+
CLI.
|
|
120
|
+
|
|
121
|
+
Common MCP config locations:
|
|
122
|
+
|
|
123
|
+
- user/local scope MCP servers: `~/.claude.json`
|
|
124
|
+
- project scope MCP servers: `.mcp.json`
|
|
125
|
+
|
|
126
|
+
Example project config:
|
|
127
|
+
|
|
128
|
+
```json
|
|
129
|
+
{
|
|
130
|
+
"mcpServers": {
|
|
131
|
+
"airtable": {
|
|
132
|
+
"type": "stdio",
|
|
133
|
+
"command": "nulvec",
|
|
134
|
+
"args": ["mcp-proxy", "--", "npx", "-y", "airtable-mcp-server"],
|
|
135
|
+
"env": {}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Equivalent CLI shape:
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
claude mcp add --transport stdio airtable -- nulvec mcp-proxy -- npx -y airtable-mcp-server
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
Notes:
|
|
148
|
+
|
|
149
|
+
- Claude CLI flag ordering matters. Claude flags must come before the server
|
|
150
|
+
name, and the wrapped server command must come after `--`.
|
|
151
|
+
- MCP scope storage is separate from general Claude settings. Do not assume MCP
|
|
152
|
+
local scope lives under `.claude/settings.local.json`.
|
|
153
|
+
- In managed environments, exact command-array allowlists can block wrapped
|
|
154
|
+
commands unless the allowlist is updated for the new `nulvec` launcher.
|
|
155
|
+
|
|
156
|
+
### OpenCode Example
|
|
157
|
+
|
|
158
|
+
OpenCode stores MCP servers in JSON config and uses a command-array model for
|
|
159
|
+
local servers.
|
|
160
|
+
|
|
161
|
+
Common config locations:
|
|
162
|
+
|
|
163
|
+
- global config: `~/.config/opencode/opencode.json`
|
|
164
|
+
- project config: `opencode.json`
|
|
165
|
+
|
|
166
|
+
Example local MCP config:
|
|
167
|
+
|
|
168
|
+
```json
|
|
169
|
+
{
|
|
170
|
+
"$schema": "https://opencode.ai/config.json",
|
|
171
|
+
"mcp": {
|
|
172
|
+
"server-everything": {
|
|
173
|
+
"type": "local",
|
|
174
|
+
"command": ["nulvec", "mcp-proxy", "--", "npx", "-y", "@modelcontextprotocol/server-everything"],
|
|
175
|
+
"enabled": true
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
Notes:
|
|
182
|
+
|
|
183
|
+
- OpenCode’s local MCP command is already an argv array, which makes wrapper
|
|
184
|
+
insertion straightforward.
|
|
185
|
+
- If you later automate rewiring, be careful with config-path detection for
|
|
186
|
+
`.json`, `.jsonc`, and older install-path variants documented by OpenCode.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"""Nulvec — Perceptual AI Security."""
|
|
2
|
+
|
|
3
|
+
from nulvec.scanner import scan, scan_content
|
|
4
|
+
from nulvec.wrapper import wrap
|
|
5
|
+
from nulvec.models import ScanResult, Threat, ThreatType, Severity
|
|
6
|
+
|
|
7
|
+
__version__ = "0.1.0"
|
|
8
|
+
__all__ = ["scan", "scan_content", "wrap", "ScanResult", "Threat", "ThreatType", "Severity"]
|