SkillTotal

Is smolagents safe?

No malicious indicators - review capabilities before installing
Notable — review in context (capabilities are not malware):
  • Python shell/command execution
  • Unsafe deserialization
  • Python dynamic code execution

smolagents is an AI python_package analyzed by SkillTotal's deterministic static scanner. The scan found no malicious indicators, though 7 risky constructs are reported for review. It can: dynamic code execution, filesystem read, filesystem write, mcp tools detected, network egress and shell execution — capabilities are what the code can do, not a verdict on intent. Risk score 20/100 (low).

smolagents 1.26.0

python_package · pypi:smolagents
LOW
20
/ 100 risk score
Snapshot · scanned Jul 7, 2026 · smolagents@1.26.0 · engine 0.34.2 / ruleset 34

Automated static-analysis result. It can contain false positives and false negatives, and is not a claim about the intent of smolagents's authors. Report a false positive.

Capabilities — what this component can do (not a risk score):
dynamic code executionfilesystem readfilesystem writemcp tools detectednetwork egressshell execution

Findings (7)

HIGHUnsafe deserializationST-DESERIALIZE-PY

It loads data with a format that can rebuild arbitrary objects (e.g. pickle, or unsafe YAML).

return pickle.loads(base64.b64decode(encoded_value[7:]))
return pickle.loads(base64.b64decode(data[7:]))
return pickle.loads(base64.b64decode(data))

Why it matters: Feeding such a loader untrusted data can execute code hidden inside that data.

Fix: Deserialize untrusted data with a safe format/loader: JSON, or yaml.safe_load / Loader=SafeLoader. Reserve pickle/marshal for data you fully control.

HIGHPython dynamic code executionST-DYN-PY

The code turns strings into live code at runtime (eval / new Function / exec).

exec(tool_code, module.__dict__)

Why it matters: If those strings aren't fixed and trusted, they become a way to run arbitrary code.

Fix: Avoid evaluating dynamically constructed code; if unavoidable, ensure the input is a trusted constant and never derived from external data.

HIGHPython shell/command executionST-SHELL-PY

The component can run operating-system commands or spawn processes.

subprocess.run([deno_path, "--version"], capture_output=True, check=True)
self.server_process = subprocess.Popen(
            cmd,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            text=True,
        )

Why it matters: Powerful and often legitimate — confirm the commands aren't built from untrusted input.

Fix: Confirm the command and its arguments are fully controlled and not derived from untrusted input; avoid shell=True.

MEDIUMPython filesystem readST-FS-PY-READ

The component reads files from disk.

agent_dict = json.loads((folder / "agent.json").read_text())
tool_code = (folder / "tools" / f"{tool_name}.py").read_text()
importlib.resources.files("smolagents.prompts").joinpath("toolcalling_agent.yaml").read_text()
importlib.resources.files("smolagents.prompts").joinpath("structured_code_agent.yaml").read_text()
importlib.resources.files("smolagents.prompts").joinpath("code_agent.yaml").read_text()
tool_code = Path(tool_file).read_text()

Why it matters: Usually legitimate, but worth confirming it can't be steered into reading sensitive files.

Fix: Confirm which files are read and that paths cannot be influenced by untrusted input to reach sensitive locations.

MEDIUMPython filesystem write/deleteST-FS-PY-WRITE

The component writes or deletes files on disk.

with open(os.path.join(output_dir, "prompts.yaml"), "w", encoding="utf-8") as f:
with open(os.path.join(output_dir, "agent.json"), "w", encoding="utf-8") as f:
with open(os.path.join(output_dir, "requirements.txt"), "w", encoding="utf-8") as f:
with open(os.path.join(output_dir, "app.py"), "w", encoding="utf-8") as f:
shutil.copy(file_path, dest_path)
with open(self.runner_path, "w") as f:
file_path.write_text(content, encoding="utf-8")
with open(os.path.join(folder, "__init__.py"), "w"):

Why it matters: Usually legitimate, but worth confirming the paths can't be controlled by untrusted input.

Fix: Confirm which files are written/deleted and that paths cannot be influenced by untrusted input.

MEDIUMPython network egressST-NET-PY

The component makes outbound network requests.

response = requests.get(self._path)
response = requests.get(base_url, params=params)
response = requests.get(self.endpoint, headers=self.headers, params=params)
response = requests.get(
            "https://lite.duckduckgo.com/lite/",
            params={"q": query},
            headers={"User-Agent": "Mozilla/5.0"},
        )
response = requests.get(
            "https://www.bing.com/search",
            params={"q": query, "format": "rss"},
        )
response = requests.post(
            "https://api.exa.ai/search",
            headers={
                "x-api-key": api_key,
                "Content-Type": "application/json",
                "x-exa-integration": "smolagents", …
from requests.exceptions import RequestException
response = requests.get(url, timeout=20)
response = requests.get(self.server_url)
response = requests.post(self.server_url, json=payload, timeout=self.timeout)
from requests.exceptions import RequestException
r = requests.post(crate_kernel_endpoint, headers=headers)
if requests.get(f"{self.base_url}/api/kernelspecs?token={token}", timeout=2).status_code == 200:
resp = requests.get(f"https://{host}/api/kernelspecs?token={token}")

Why it matters: Usually legitimate, but confirm the destinations are expected and no sensitive data leaves.

Fix: Confirm the destination hosts are expected and that no sensitive data is sent off-host.

LOWMCP tool surface detectedST-MCP-DETECTED

An MCP tool surface (manifest or tool definitions) was found.

source_code = get_source(self.forward).replace("@tool", "")
# If tool was created using '@tool' decorator, it has only a forward pass, so it's simpler to just get its code
forward_source_code = forward_source_code.replace("@tool", "").strip()
else:  # If the tool was not created by the @tool decorator, it was made by subclassing Tool
f"Multiple @tool decorators found on function '{func_node.name}'. Only one @tool decorator is allowed."
f"Multiple @tool decorators found on function '{func_node.name}'. Only one @tool decorator is allowed."
f"Function '{func_node.name}' has decorators other than @tool. "

Why it matters: Just context — review which tools it offers and their permissions.

Fix: Review the declared MCP tools and their permissions.

Check your own component

Run the same evidence-backed scan on any MCP server, agent skill, or package.

Scan your own component

Or get notified if this component's risk changes:

How we determine this: deterministic static analysis (regex + AST), evidence-anchored, no code execution. Methodology →