MCP, MCP server
aegisarchive
Zero-install, server-preserving web archiver and ISO 28500 (WARC/1.1) forensic engine for offline replication and digital preservation.
Compatibility: Not stated.
Grade C
One Medium finding. Read the report before installing.
Not a guarantee. A hygiene check of the source at the commit shown, not a security audit.
NETWORK_HOST_FROM_INPUT
Why this grade
- NETWORK_HOST_FROM_INPUT Medium
A file takes a URL or endpoint as input and has no fixed host list.
cli/capture_bridge.py, line 205
def fetch(self, sid, url, options=None):
Any High, or two or more Medium findings, give D. One Medium gives C. Low findings or a security Note give B. Each code names a finding behind the letter.
Grades are a hygiene check of the source at the commit shown, on the date checked, not a security audit or a guarantee. The free directory grades are automated. Before release, a PlugVet engineer reviews every paid report and any grade we hold back, including all F grades, against the source code and the evidence we quote.
What was checked
Plain notes from the hygiene checks.
Permissions
Note
requests shell access. The manifest names this permission.
PERMISSION_SHELL_DECLARED
.github/workflows/ci.yml, line 53
proc = subprocess.Popen(['python3', 'mcp/server.py'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, text=True)
conductor/archive/cli_parity_20260905/plan.md, line 454
r = subprocess.run([sys.executable, 'cli/aegis_cli.py', '--profile', pp, '--output-dir', tmp], capture_output=True, text=True, timeout=120)
conductor/archive/cli_parity_20260905/plan.md, line 475
- `tests/test_cli.py` - `unittest.TestCase` with a class-level fixture like the C5 Verify server (`ThreadingHTTPServer(("127.0.0.1", 0), Handler)`, 3 HTML pages sent with `Content-
Show more
conductor/archive/repo_standards_alignment_20260905/plan.md, line 410
proc = subprocess.run(
conductor/archive/security_gates_and_fuzzing_20260905/plan.md, line 752
return subprocess.call(cmd, cwd=ROOT, **kw)
conductor/reviews/crawl-controls-final-20261016.md, line 94
raw = subprocess.check_output(['git', 'show', ref['resolved_commit'] + ':' + ref['path']])
optional/document_processing/ocr.py, line 57
with subprocess.Popen(command, cwd=cwd, env=env, stdin=subprocess.DEVNULL,
optional/document_processing/runner.py, line 83
with subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL,
Install and update
Pass
No install-time script found, and dependencies are pinned or absent.
Network
Concern
accepts a host from input, with no fixed list in this file. can reach a host that is not written as a fixed address. can reach raw.githubusercontent.com. The description does not name that host.
NETWORK_HOST_FROM_INPUT NETWORK_NO_FIXED_HOST NETWORK_UNNAMED_HOST
cli/capture_bridge.py, line 205
def fetch(self, sid, url, options=None):
cli/capture_bridge.py, line 391
result = bridge.fetch(payload['id'], payload['url'], payload.get('options'))
cli/launch.py, line 192
with urllib.request.urlopen(
Show more
.bandit-baseline.json, line 7
"code": "171 try:\n172 with urllib.request.urlopen(\n173 f\"http://127.0.0.1:{port}/__station/status\", timeout=timeout\n174 ) as resp:\n175
conductor/archive/cli_parity_20260905/plan.md, line 405
5. Inside the `with urllib.request.urlopen(...) as resp:` block, after `status = resp.status` add ` politeness.record_success(url, elapsed_ms)`, and change the write
conductor/archive/engine_correctness_20260905/evidence.legacy.jsonl, line 2
{"ts": "2026-09-05T05:40:00Z", "kind": "phase_completed", "phase": "Phase 2", "summary": "Tasks T1-T5 implemented and verified: EWMA baseline warm-up (T1, AC1), 0/429/5xx countable
conductor/archive/engine_correctness_20260905/plan.md, line 475
const resp = await fetch(robotsUrl, { method: 'GET', headers: { 'X-Preservation-Agent': 'AegisArchive/1.0' }, cache: 'no-store' });
conductor/archive/engine_correctness_20260905/spec.md, line 16
- **D1** `recordSuccess` sets `baselineLatencyMs` from the first sample. With `fetch(..., {cache:'default'})` the first response is often served from the HTTP cache (~5 ms), so `st
conductor/archive/security_gates_and_fuzzing_20260905/handoff.md, line 7
`with urllib.request.urlopen(f"http://127.0.0.1:{port}/__station/status", timeout=timeout)`
conductor/archive/security_gates_and_fuzzing_20260905/plan.md, line 270
with urllib.request.urlopen(req, timeout=15) as resp:
conductor/archive/security_gates_and_fuzzing_20260905/plan.md, line 687
"code": "169 try:\n170 with urllib.request.urlopen(\n171 f\"http://127.0.0.1:{port}/__station/status\", timeout=timeout\n172 ) as resp:\n173
Secrets
Pass
No read of a credential file or secret environment variable found.
Agent instructions
Pass
No instruction to ignore earlier instructions or to hide a step.
Obfuscation
Concern
contains an encoded blob in a file that should be readable.
OBFUSCATION_ENCODED_BLOB
optional/document_processing/README-OCR.md, line 1
# Optional local OCR (T5)
.github/workflows/ci.yml, line 75
FORBIDDEN_PATTERN=$(echo "Y2hoaHN8Y2Fpcm5zfHFoZXBzfHF1ZWVuc2xhbmR8aGVhbHRoXC5xbGR8Z2xjfHBzcXN8bnNxaHN8XGIoc3F1aXp8c2hhcmVwb2ludHxjb25mbHVlbmNlfGh0dHJhY2t8d2F5YmFja3xwb3J0YWJsZWFwcH
Licence
Pass
A licence file is present (LICENSE).
Maintainer activity
Pass
The latest commit is within the last 365 days.
Note
Hygiene check of commit d66f3c861ebb. requests shell access. The manifest names this permission. accepts a host from input, with no fixed list in this file. can reach a host that is not written as a fixed address. can reach raw.githubusercontent.com. The description does not name that host. contains an encoded blob in a file that should be readable.
Date and source
Date checked:
github.com
Commit graded: d66f3c861ebbf1c162611880d9ff8eba8b67fa5f
This link goes to the original host. PlugVet does not host or check what you download from there, and installing it is your own decision and risk.