Low
Check your own MCP server
Free · no signup · instant shareable report.
Outbound network 5
Environment variables (config / keys) 24
Filesystem writes 10
Remote code execution 3
Shell / command execution 29
AI review
The extension contains several patterns that could be risky in an AI agent context, but none appear to be intentionally malicious or deceptive. The primary concerns are a telemetry endpoint that sends usage data, and some CI/CD scripts that download remote code, but these are standard development practices and not hidden instructions targeting the agent itself.
- low Telemetry endpoint sends usage data — src/serena/agent.py:731 sends a GET request to https://oraios-software.de/serena_usage.php with environment and timing parameters. This is opt-out via SERENA_USAGE_REPORTING env var and only fires outside CI, but it's an external data exfiltration point that should be documented and consent-based.
- low CI/CD downloads remote scripts — .github/workflows/pytest.yml:58 and Dockerfile:30 execute curl-piped-to-shell commands to install uv and nvm. While common in CI, these patterns could be exploited if the remote URLs are compromised, and they execute arbitrary code during build.
- low SCP command with env var for credentials — scripts/build_news_json.py:55 uses os.system(f"scp news/news.json {user}@hades:/var/www/html/...") where user comes from HADES_USER env var. This is a deployment script, not agent-facing, but shows credentials in environment variables used in shell commands.
Model: deepseek-chat
Static findings
Remote code execution · Downloads and executes remote code
info
.github/workflows/pytest.yml:58
run: curl -LsSf https://astral.sh/uv/install.sh | sh
info
Dockerfile:30
RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v${NVM_VERSION}/install.sh | bash
info
src/solidlsp/language_servers/lean4_language_server.py:41
" curl https://raw.githubusercontent.com/leanprover/elan/master/elan-init.sh -sSf | sh\n"
Filesystem writes · Reads or writes the filesystem
info
docs/autogen_docs.py:73
shutil.rmtree(rst_root)
low
repo_dir_sync.py:163
shutil.rmtree(self.libRepo.libDirectory)
low
scripts/demo_diagnostics.py:175
shutil.rmtree(temp_dir, ignore_errors=True)
low
src/serena/cli.py:591
os.remove(path)
low
src/serena/config/serena_config.py:866
shutil.move(old_config_path, config_path)
low
src/serena/hooks.py:520
shutil.rmtree(self.session_persistence_dir, ignore_errors=True)
low
src/serena/memories/memory_manager.py:311
shutil.move(old_path, new_path)
low
src/solidlsp/language_servers/elixir_tools/elixir_tools.py:191
os.remove(executable_path)
low
src/solidlsp/language_servers/haxe_language_server.py:155
os.remove(vsix_path)
low
src/solidlsp/language_servers/pascal_server.py:396
os.remove(file_path)
Shell / command execution · Executes shell / system commands
info
docs/create_toc.py:9
os.system(cmd)
medium
repo_dir_sync.py:12
def popen(cmd):
medium
scripts/build_news_json.py:55
os.system(f"scp news/news.json {user}@hades:/var/www/html/oraios-software/serena_news.json")
medium
scripts/bump_version.py:56
os.system("uv lock")
medium
src/serena/cli.py:111
subprocess.run([editor, path], check=False, **run_kwargs)
medium
src/serena/dashboard.py:816
p = subprocess.Popen(
medium
src/serena/util/dotnet.py:30
result = subprocess.run([self._system_dotnet, "--list-runtimes"], capture_output=True, text=True, check=True)
medium
src/serena/util/shell.py:28
process = subprocess.Popen(
medium
src/solidlsp/language_servers/bsl_language_server.py:55
result = subprocess.run(
medium
src/solidlsp/language_servers/clojure_lsp.py:62
return subprocess.run(
medium
src/solidlsp/language_servers/common.py:113
completed_process = subprocess.run(
medium
src/solidlsp/language_servers/elixir_tools/elixir_tools.py:68
result = subprocess.run(["elixir", "--version"], capture_output=True, text=True, check=False)
+ 17 more
Environment variables (config / keys) · Reads environment variables (config / API keys)
low
scripts/build_news_json.py:53
user = os.getenv("HADES_USER")
low
src/serena/agent.py:721
if os.getenv("CI") == "true" or os.getenv("GITHUB_ACTIONS") == "true" or os.getenv("SERENA_USAGE_REPORTING") == "false":
low
src/serena/cli.py:107
editor = os.environ.get("EDITOR")
low
src/serena/config/serena_config.py:61
home_dir = os.getenv("SERENA_HOME")
low
src/serena/hooks.py:18
serena_home_dir = os.getenv("SERENA_HOME", "").strip() or str(Path.home() / ".serena")
low
src/serena/util/exception.py:22
if not os.environ.get("DISPLAY"): # type: ignore
low
src/serena/util/gui.py:16
display = os.environ.get("DISPLAY", "")
low
src/serena/util/shell.py:49
args, stdin=subprocess.DEVNULL, stderr=subprocess.PIPE, timeout=timeout, env=os.environ.copy(), cwd=cwd, **subprocess_kwargs()
low
src/solidlsp/language_servers/al_language_server.py:236
env_path = os.environ.get("AL_EXTENSION_PATH")
low
src/solidlsp/language_servers/bash_language_server.py:195
"PATH": managed_bin_dir + os.pathsep + os.environ.get("PATH", ""),
low
src/solidlsp/language_servers/common.py:178
uvx_path = os.environ.get("UVX") or shutil.which("uvx")
low
src/solidlsp/language_servers/eclipse_jdtls.py:682
elif env_home := os.environ.get("JAVA_HOME"):
+ 12 more
Outbound network · Makes outbound network requests
low
src/serena/agent.py:731
requests.get("https://oraios-software.de/serena_usage.php", params=params, timeout=1)
low
src/serena/dashboard.py:10
import urllib.request
low
src/serena/util/dotnet.py:103
urllib.request.urlretrieve(script_url, script_path)
low
src/solidlsp/language_servers/haxe_language_server.py:11
import urllib.request
low
src/solidlsp/language_servers/pascal_server.py:60
import urllib.request
Scanning every extension your team installs?
Pro & Team add monitoring, private scans, and a CI gate for unsafe extensions.
MCPVet is a heuristic aid, not a security guarantee. A clean grade does not prove an extension is safe; always review code and instructions you don't trust.