oraios/serena
Powerful capabilities — review before trusting.
View source ↗AI review
The extension contains several patterns that could be risky in an AI agent context, but they are all standard development/build operations or legitimate functionality that matches the stated purpose of an MCP-based IDE tool. No hidden instructions, prompt injection vectors, or data exfiltration mechanisms were found beyond benign usage reporting that can be disabled via environment variable.
- low Usage reporting telemetry — src/serena/agent.py:731 sends a GET request to oraios-software.de with usage parameters. This is opt-out via SERENA_USAGE_REPORTING=false and only fires outside CI/GitHub Actions. No credentials or secrets are transmitted.
- low Remote code execution in build scripts — .github/workflows/pytest.yml and Dockerfile download and execute shell scripts from external URLs (astral.sh, raw.githubusercontent.com). These are standard CI/Docker build steps, not runtime agent behavior.
- low SCP file transfer in build script — scripts/build_news_json.py uses SCP to copy a news JSON file to a remote server using an environment variable for the username. This is a deployment script, not part of the agent runtime.
- low Environment variable access patterns — Multiple files read environment variables (EDITOR, SERENA_HOME, HADES_USER, CI, GITHUB_ACTIONS, DISPLAY) for legitimate configuration purposes. No evidence of secret exfiltration.
Model: deepseek-chat
Static findings
Remote code execution · Downloads and executes remote code
.github/workflows/pytest.yml:58
run: curl -LsSf https://astral.sh/uv/install.sh | sh
Dockerfile:30
RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v${NVM_VERSION}/install.sh | bash
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
docs/autogen_docs.py:73
shutil.rmtree(rst_root)
repo_dir_sync.py:163
shutil.rmtree(self.libRepo.libDirectory)
scripts/demo_diagnostics.py:175
shutil.rmtree(temp_dir, ignore_errors=True)
src/serena/cli.py:591
os.remove(path)
src/serena/config/serena_config.py:866
shutil.move(old_config_path, config_path)
src/serena/hooks.py:520
shutil.rmtree(self.session_persistence_dir, ignore_errors=True)
src/serena/memories/memory_manager.py:311
shutil.move(old_path, new_path)
src/solidlsp/language_servers/elixir_tools/elixir_tools.py:191
os.remove(executable_path)
src/solidlsp/language_servers/haxe_language_server.py:155
os.remove(vsix_path)
src/solidlsp/language_servers/pascal_server.py:396
os.remove(file_path)
Shell / command execution · Executes shell / system commands
docs/create_toc.py:9
os.system(cmd)
repo_dir_sync.py:12
def popen(cmd):
scripts/build_news_json.py:55
os.system(f"scp news/news.json {user}@hades:/var/www/html/oraios-software/serena_news.json")
scripts/bump_version.py:56
os.system("uv lock")
src/serena/cli.py:111
subprocess.run([editor, path], check=False, **run_kwargs)
src/serena/dashboard.py:816
p = subprocess.Popen(
src/serena/util/dotnet.py:30
result = subprocess.run([self._system_dotnet, "--list-runtimes"], capture_output=True, text=True, check=True)
src/serena/util/shell.py:28
process = subprocess.Popen(
src/solidlsp/language_servers/bsl_language_server.py:55
result = subprocess.run(
src/solidlsp/language_servers/clojure_lsp.py:62
return subprocess.run(
src/solidlsp/language_servers/common.py:113
completed_process = subprocess.run(
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)
scripts/build_news_json.py:53
user = os.getenv("HADES_USER")
src/serena/agent.py:721
if os.getenv("CI") == "true" or os.getenv("GITHUB_ACTIONS") == "true" or os.getenv("SERENA_USAGE_REPORTING") == "false":
src/serena/cli.py:107
editor = os.environ.get("EDITOR")
src/serena/config/serena_config.py:61
home_dir = os.getenv("SERENA_HOME")
src/serena/hooks.py:18
serena_home_dir = os.getenv("SERENA_HOME", "").strip() or str(Path.home() / ".serena")
src/serena/util/exception.py:22
if not os.environ.get("DISPLAY"): # type: ignore
src/serena/util/gui.py:16
display = os.environ.get("DISPLAY", "")
src/serena/util/shell.py:49
args, stdin=subprocess.DEVNULL, stderr=subprocess.PIPE, timeout=timeout, env=os.environ.copy(), cwd=cwd, **subprocess_kwargs()
src/solidlsp/language_servers/al_language_server.py:236
env_path = os.environ.get("AL_EXTENSION_PATH")
src/solidlsp/language_servers/bash_language_server.py:195
"PATH": managed_bin_dir + os.pathsep + os.environ.get("PATH", ""),
src/solidlsp/language_servers/common.py:178
uvx_path = os.environ.get("UVX") or shutil.which("uvx")
src/solidlsp/language_servers/eclipse_jdtls.py:682
elif env_home := os.environ.get("JAVA_HOME"):
+ 12 more
Outbound network · Makes outbound network requests
src/serena/agent.py:731
requests.get("https://oraios-software.de/serena_usage.php", params=params, timeout=1)
src/serena/dashboard.py:10
import urllib.request
src/serena/util/dotnet.py:103
urllib.request.urlretrieve(script_url, script_path)
src/solidlsp/language_servers/haxe_language_server.py:11
import urllib.request
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.