Mostly safe โ a couple of notes worth reading.
Scanned 5/3/2026, 7:06:46 PMยทCached resultยทFast Scanยท45 rulesยทHow we decide โ
AIVSS Score
Low
Severity Breakdown
0
critical
3
high
120
medium
36
low
MCP Server Information
Findings
This package presents moderate security concerns with a B grade and 53/100 safety score, driven primarily by 120 medium-severity issues concentrated in resource exhaustion (73 findings) and ANSI escape injection vulnerabilities (39 findings). The three high-severity findings and widespread readiness gaps suggest the package may lack production-hardening and could be vulnerable to denial-of-service attacks or terminal injection exploits. You should evaluate whether the functionality justifies these risks and consider implementing additional input validation and resource limits if you proceed with installation.
Scan Details
Want deeper analysis?
Fast scan found 23 findings using rule-based analysis. Upgrade for LLM consensus across 5 judges, AI-generated remediation, and cross-file taint analysis.
Building your own MCP server?
Same rules, same LLM judges, same grade. Private scans stay isolated to your account and never appear in the public registry. Required for code your team hasnโt shipped yet.
23 of 23 findings
23 findings
XML parser configured without entity expansion disabled. XXE (XML external entity) attacks can read local files, exfiltrate data, and cause SSRF when the parser resolves external entities.
Evidence
| 669 | # Use iterparse for memory efficiency on large exports |
| 670 | import xml.etree.ElementTree as ET |
| 671 | |
| 672 | tree = ET.parse(xml_path) # noqa: S314 |
| 673 | root = tree.getroot() |
| 674 | except Exception as e: |
| 675 | logger.warning("Failed to parse entities.xml: %s", e) |
Remediation
Use defusedxml in Python (drop-in replacement for stdlib XML modules). In Java, set XMLConstants.FEATURE_SECURE_PROCESSING=true and disable external-DTD features on the factory before parsing.
XML parser configured without entity expansion disabled. XXE (XML external entity) attacks can read local files, exfiltrate data, and cause SSRF when the parser resolves external entities.
Evidence
| 1312 | headers={"User-Agent": "SkillSeekers/3.4"}, |
| 1313 | ) |
| 1314 | if sub_resp.status_code == 200: |
| 1315 | sub_root = ET.fromstring(sub_resp.text) |
| 1316 | for loc in sub_root.findall(".//sm:url/sm:loc", ns): |
| 1317 | url = (loc.text or "").strip().split("#")[0] |
| 1318 | if self.is_valid_url(url): |
Remediation
Use defusedxml in Python (drop-in replacement for stdlib XML modules). In Java, set XMLConstants.FEATURE_SECURE_PROCESSING=true and disable external-DTD features on the factory before parsing.
XML parser configured without entity expansion disabled. XXE (XML external entity) attacks can read local files, exfiltrate data, and cause SSRF when the parser resolves external entities.
Evidence
| 1297 | if "xml" not in response.headers.get("content-type", ""): |
| 1298 | continue |
| 1299 | |
| 1300 | root = ET.fromstring(response.text) |
| 1301 | ns = {"sm": "http://www.sitemaps.org/schemas/sitemap/0.9"} |
| 1302 | |
| 1303 | # Handle sitemap index (nested sitemaps) |
Remediation
Use defusedxml in Python (drop-in replacement for stdlib XML modules). In Java, set XMLConstants.FEATURE_SECURE_PROCESSING=true and disable external-DTD features on the factory before parsing.
User-controlled value printed to terminal without ANSI escape sanitization. Malicious input can inject cursor-control sequences, rewrite earlier output, or hide shell commands from the operator.
Evidence
| 59 | query = "How do I create a Vue component?" |
| 60 | |
| 61 | console.print(f"\n[yellow]Query:[/yellow] {query}") |
| 62 | |
| 63 | try: |
| 64 | results = collection.query( |
Remediation
Strip C0/C1 control codes before printing user-controlled values. Python: re.sub(r"[\x00-\x08\x0b-\x1f\x7f]", "", s). Prefer a structured logger (json/logfmt) over raw print to stdout.
User-controlled value printed to terminal without ANSI escape sanitization. Malicious input can inject cursor-control sequences, rewrite earlier output, or hide shell commands from the operator.
Evidence
| 304 | field_schema=PayloadSchemaType.KEYWORD |
| 305 | ) |
| 306 | |
| 307 | print("โ
Collection created with payload indexes") |
| 308 | ``` |
| 309 | |
| 310 | ### Step 4: Batch Upload with Progress |
Remediation
Strip C0/C1 control codes before printing user-controlled values. Python: re.sub(r"[\x00-\x08\x0b-\x1f\x7f]", "", s). Prefer a structured logger (json/logfmt) over raw print to stdout.
User-controlled value printed to terminal without ANSI escape sanitization. Malicious input can inject cursor-control sequences, rewrite earlier output, or hide shell commands from the operator.
Evidence
| 257 | else: |
| 258 | print("โ Invalid choice.") |
| 259 | except ValueError: |
| 260 | print("โ Invalid input.") |
| 261 | |
| 262 | |
| 263 | def set_default_profile(): |
Remediation
Strip C0/C1 control codes before printing user-controlled values. Python: re.sub(r"[\x00-\x08\x0b-\x1f\x7f]", "", s). Prefer a structured logger (json/logfmt) over raw print to stdout.
User-controlled value printed to terminal without ANSI escape sanitization. Malicious input can inject cursor-control sequences, rewrite earlier output, or hide shell commands from the operator.
Evidence
| 351 | # Stop if we've read enough |
| 352 | if total_chars > max_chars: |
| 353 | print(f" โน Limiting input to {max_chars:,} characters") |
| 354 | break |
| 355 | |
| 356 | return references |
Remediation
Strip C0/C1 control codes before printing user-controlled values. Python: re.sub(r"[\x00-\x08\x0b-\x1f\x7f]", "", s). Prefer a structured logger (json/logfmt) over raw print to stdout.
User-controlled value printed to terminal without ANSI escape sanitization. Malicious input can inject cursor-control sequences, rewrite earlier output, or hide shell commands from the operator.
Evidence
| 106 | query = "useState Hook" |
| 107 | alpha = 0 # Pure keyword search |
| 108 | |
| 109 | console.print(f"\n[yellow]Query:[/yellow] {query}") |
| 110 | console.print(f"[yellow]Alpha:[/yellow] {alpha} (pure keyword/BM25)") |
| 111 | |
| 112 | try: |
Remediation
Strip C0/C1 control codes before printing user-controlled values. Python: re.sub(r"[\x00-\x08\x0b-\x1f\x7f]", "", s). Prefer a structured logger (json/logfmt) over raw print to stdout.
User-controlled value printed to terminal without ANSI escape sanitization. Malicious input can inject cursor-control sequences, rewrite earlier output, or hide shell commands from the operator.
Evidence
| 82 | for i, query in enumerate(queries, 1): |
| 83 | print(f"\n{'=' * 60}") |
| 84 | print(f"Query {i}: {query}") |
| 85 | print("=" * 60) |
| 86 | |
| 87 | # Run query |
Remediation
Strip C0/C1 control codes before printing user-controlled values. Python: re.sub(r"[\x00-\x08\x0b-\x1f\x7f]", "", s). Prefer a structured logger (json/logfmt) over raw print to stdout.
User-controlled value printed to terminal without ANSI escape sanitization. Malicious input can inject cursor-control sequences, rewrite earlier output, or hide shell commands from the operator.
Evidence
| 379 | print(f"\\nRank {{i}} (score={{result.score:.4f}}):") |
| 380 | print(f" Category: {{result.payload['category']}}") |
| 381 | print(f" File: {{result.payload['file']}}") |
| 382 | print(f" Text: {{result.payload['content'][:200]}}...") |
| 383 | |
| 384 | # Advanced filtering examples |
| 385 | # Filter by multiple conditions |
Remediation
Strip C0/C1 control codes before printing user-controlled values. Python: re.sub(r"[\x00-\x08\x0b-\x1f\x7f]", "", s). Prefer a structured logger (json/logfmt) over raw print to stdout.
User-controlled value printed to terminal without ANSI escape sanitization. Malicious input can inject cursor-control sequences, rewrite earlier output, or hide shell commands from the operator.
Evidence
| 452 | try: |
| 453 | config.config["resume"]["keep_progress_days"] = int(days_input) |
| 454 | except ValueError: |
| 455 | print("โ ๏ธ Invalid input, keeping current value") |
| 456 | |
| 457 | config.save_config() |
| 458 | print("\nโ Resume settings updated") |
Remediation
Strip C0/C1 control codes before printing user-controlled values. Python: re.sub(r"[\x00-\x08\x0b-\x1f\x7f]", "", s). Prefer a structured logger (json/logfmt) over raw print to stdout.
User-controlled value printed to terminal without ANSI escape sanitization. Malicious input can inject cursor-control sequences, rewrite earlier output, or hide shell commands from the operator.
Evidence
| 289 | else: |
| 290 | print("โ Invalid choice.") |
| 291 | except ValueError: |
| 292 | print("โ Invalid input.") |
| 293 | |
| 294 | |
| 295 | def open_github_token_page(): |
Remediation
Strip C0/C1 control codes before printing user-controlled values. Python: re.sub(r"[\x00-\x08\x0b-\x1f\x7f]", "", s). Prefer a structured logger (json/logfmt) over raw print to stdout.
User-controlled value printed to terminal without ANSI escape sanitization. Malicious input can inject cursor-control sequences, rewrite earlier output, or hide shell commands from the operator.
Evidence
| 76 | for i, point in enumerate(result[0], 1): |
| 77 | console.print(f"[bold]{i}. {point.payload['file']}[/bold]") |
| 78 | console.print(f" {point.payload['content'][:100]}...\n") |
| 79 | |
| 80 | console.print("โ Query examples completed!") |
| 81 | console.print("\n[yellow]๐ก Note:[/yellow] For vector search, add embeddings to points!") |
Remediation
Strip C0/C1 control codes before printing user-controlled values. Python: re.sub(r"[\x00-\x08\x0b-\x1f\x7f]", "", s). Prefer a structured logger (json/logfmt) over raw print to stdout.
User-controlled value printed to terminal without ANSI escape sanitization. Malicious input can inject cursor-control sequences, rewrite earlier output, or hide shell commands from the operator.
Evidence
| 75 | console.print(f"[green]Found {len(result[0])} points matching both conditions:[/green]\n") |
| 76 | |
| 77 | for i, point in enumerate(result[0], 1): |
| 78 | console.print(f"[bold]{i}. {point.payload['file']}[/bold]") |
| 79 | console.print(f" {point.payload['content'][:100]}...\n") |
| 80 | |
| 81 | console.print("โ Query examples completed!") |
Remediation
Strip C0/C1 control codes before printing user-controlled values. Python: re.sub(r"[\x00-\x08\x0b-\x1f\x7f]", "", s). Prefer a structured logger (json/logfmt) over raw print to stdout.
User-controlled value printed to terminal without ANSI escape sanitization. Malicious input can inject cursor-control sequences, rewrite earlier output, or hide shell commands from the operator.
Evidence
| 71 | def _send_console(self, payload: WebhookPayload): |
| 72 | """Print to console.""" |
| 73 | print(f"\n๐ข {payload.event.upper()}: {payload.skill_name}") |
| 74 | |
| 75 | if payload.changes: |
| 76 | changes = payload.changes |
Remediation
Strip C0/C1 control codes before printing user-controlled values. Python: re.sub(r"[\x00-\x08\x0b-\x1f\x7f]", "", s). Prefer a structured logger (json/logfmt) over raw print to stdout.
User-controlled value printed to terminal without ANSI escape sanitization. Malicious input can inject cursor-control sequences, rewrite earlier output, or hide shell commands from the operator.
Evidence
| 733 | if self.agent == "claude": |
| 734 | print(" ๐ก CLI agent limit: ~30,000-40,000 characters") |
| 735 | else: |
| 736 | print(" ๐ก Local CLI agents often have input limits; summarizing to be safe") |
| 737 | print() |
| 738 | print(" ๐ง Applying smart summarization to ensure success...") |
| 739 | print(" โข Keeping introductions and overviews") |
Remediation
Strip C0/C1 control codes before printing user-controlled values. Python: re.sub(r"[\x00-\x08\x0b-\x1f\x7f]", "", s). Prefer a structured logger (json/logfmt) over raw print to stdout.
User-controlled value printed to terminal without ANSI escape sanitization. Malicious input can inject cursor-control sequences, rewrite earlier output, or hide shell commands from the operator.
Evidence
| 429 | # Extract results |
| 430 | for result in results: |
| 431 | print(f"Score: {result.score:.3f}") |
| 432 | print(f"Category: {result.payload['category']}") |
| 433 | print(f"Content: {result.payload['content'][:200]}...") |
| 434 | print() |
| 435 | ``` |
Remediation
Strip C0/C1 control codes before printing user-controlled values. Python: re.sub(r"[\x00-\x08\x0b-\x1f\x7f]", "", s). Prefer a structured logger (json/logfmt) over raw print to stdout.
User-controlled value printed to terminal without ANSI escape sanitization. Malicious input can inject cursor-control sequences, rewrite earlier output, or hide shell commands from the operator.
Evidence
| 182 | query = "guide" |
| 183 | |
| 184 | console.print(f"\n[yellow]Query:[/yellow] {query}") |
| 185 | console.print(f"[yellow]Filter:[/yellow] category = 'guides' AND type = 'reference'") |
| 186 | |
| 187 | try: |
Remediation
Strip C0/C1 control codes before printing user-controlled values. Python: re.sub(r"[\x00-\x08\x0b-\x1f\x7f]", "", s). Prefer a structured logger (json/logfmt) over raw print to stdout.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 101 | if text: |
| 102 | try: |
| 103 | data = yaml.safe_load(text) |
| 104 | desc = data.get("description", "") |
| 105 | except Exception: |
| 106 | pass |
| 107 | print(f" {name:<32} {desc}") |
| 108 | |
| 109 | if user: |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 357 | if result.returncode == 0 and result.stdout.strip(): |
| 358 | return result.stdout.strip() |
| 359 | |
| 360 | except Exception: |
| 361 | pass |
| 362 | |
| 363 | # Fallback to file modification time |
| 364 | mtime = config_path.stat().st_mtime |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 633 | descr = child.get("descr") |
| 634 | if descr: |
| 635 | info["alt_text"] = descr |
| 636 | break |
| 637 | except Exception: |
| 638 | pass |
| 639 | |
| 640 | images.append(info) |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 34 | # Recreate collection if exists |
| 35 | try: |
| 36 | client.delete_collection(collection_name) |
| 37 | except: |
| 38 | pass |
| 39 | |
| 40 | client.create_collection( |
| 41 | collection_name=collection_name, |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.
Silent error swallowing detected. An except clause that does pass or ... discards the exception with no log, no metric, and no trace. This blinds incident response and hides real failures.
Evidence
| 121 | if text: |
| 122 | try: |
| 123 | data = yaml.safe_load(text) |
| 124 | desc = data.get("description", "") |
| 125 | except Exception: |
| 126 | pass |
| 127 | result.append({"name": name, "description": desc, "source": "user"}) |
| 128 | |
| 129 | output = yaml.dump(result, default_flow_style=False, sort_keys=False) |
Remediation
Log the exception at minimum (`logger.exception(e)`), emit a metric, or re-raise if the error is not recoverable. If you genuinely want to ignore an exception, say so with a comment.