Giving an AI agent tools is often a single line of configuration. You install a toolkit, hand the agent the catalogue, and it can now search the web, read files, or query a database. The line that grants these powers does not say what they are.

So we read the source. All 77 tools in crewai-tools, classified by the capability each one actually needs.

What the catalogue can do

CapabilityToolsShare
Spawns a process2633.8%
Makes outbound network requests1722.1%
Reads local files911.7%
Writes or deletes local files56.5%
No capability detected2735.1%

A third of the catalogue can start a process on your machine. A security review might flag that number, but acting on it would be a mistake. It merges two completely different kinds of activity.

The split that matters

Of those 26 process-spawning tools, 22 do it for exactly one reason: to install their own missing dependency.

The pattern is consistent. The tool tries to import a package it needs, the import fails, and it offers to fix that for you:

subprocess.run(["uv", "add", "tavily-python"], check=True)

Tavily, Weaviate, SerpAPI, the Firecrawl tools, the Oxylabs scrapers — all the same shape. Helpful, well-intentioned, and worth knowing about, because it means using one of these tools for the first time runs a package manager on your machine, fetching and installing code from a registry at agent runtime. That is a supply chain event, triggered by an agent, in the middle of a task.

The other 4 tools — 5.2% of the catalogue — can run something the caller chose:

  • code_interpreter_tool — its entire purpose; it executes code the model writes
  • selenium_scraping_tool
  • singlestore_search_tool
  • snowflake_search_tool

Those two numbers describe different risks and deserve different responses. Reporting a single "33.8% can execute" figure would let a reader conclude that a third of the catalogue runs arbitrary commands, which is wrong by a factor of six.

We know this because our first classifier did exactly that, and the error was only caught by reading what the pattern had actually matched rather than trusting the count.

Why "just give it the tools" is the wrong default

Most agent frameworks make wholesale granting easy and selective granting fiddly. The path of least resistance hands over the catalogue.

This measurement suggests three reasons to grant tools selectively.

Capabilities arrive bundled. 31 of the 77 tools carry two or more of the capabilities we measured. Adding a tool because you want its search function may also bring file reading and process spawning along with it, and nothing in the installation surfaces that.

Self-installation happens when you are not watching. A dependency install triggered by a tool during an agent run happens without a human in the loop, at a moment nobody chose, pulling whatever version the registry currently resolves. In CI, or in a container that is supposed to be immutable, that is a meaningful surprise.

The four that matter are identifiable. This is the useful half of the finding. Arbitrary execution is not spread thinly across the catalogue; it lives in four named tools. If you are reviewing an agent's permissions, that is a short list to reason about rather than a diffuse worry.

The 27 that do nothing, and why that is also a finding

Twenty-seven of the 77 tools show no detected capability at all. That is not a defect in the tools; it is what a well-behaved wrapper looks like. They call a hosted API through a client library, and the client does the network work, so the tool's own file contains no request.

This matters because it shows the limits of static analysis. A tool that reaches the internet through a vendor SDK is doing something meaningful to your security posture — it is sending your data somewhere — and it looks identical, from the source, to a tool that does nothing at all. Reading files catches direct calls. It does not catch delegation.

Which is the argument for the other half of the exercise: read what a tool is for, not only what its code does. A search tool with no detected network capability is not offline. It is using somebody else's HTTP client.

What to actually do

Nothing here argues against agent tooling. It argues for granting it the way you would grant any other permission.

  • Enumerate before you grant. List the tools the agent will actually have, not the toolkit it came from. If the list is longer than the tasks, it is too long.
  • Pre-install dependencies deliberately. If the tools you use want packages, install them yourself, at a version you chose, before the agent runs. Then the self-install path never fires.
  • Treat the execution tools as a separate decision. Four tools in this catalogue can run supplied commands. That is a decision worth making once, explicitly, rather than inheriting.
  • Run agents where a process spawn is survivable. A container that can be discarded is a better answer than a policy nobody checks.

Our guide on what a package signature actually proves covers the registry side of the same problem: the code an agent installs mid-task carries the same provenance questions as the code you install deliberately, and rather less scrutiny.

This sits inside a wider pattern. Only 12.4% of the techniques in MITRE's AI threat matrix are AI-specific; the remaining 87.6% is classical security applied to a model, which we measured in most of an AI attack is an ordinary attack. An agent that can spawn processes and write files sits squarely in that 87.6%.

How this was measured, and what it cannot see

Each tool's own Python source was read and matched against signals for process spawning, network access, and file reads and writes. The whole repository is fetched as a single archive and every file is read locally.

Every count here is a floor. Static signals catch what a tool does in its own file. A tool that spawns a process through a helper module three files away is not detected, so the real surface is at least this large and possibly larger. "At least" is the honest framing and we have used it throughout.

A capability is not a vulnerability. A tool that writes files is doing its job; a scraper that makes network requests would be useless otherwise. The finding is not that any individual tool is unsafe — it is how many capabilities arrive together from a single install, and how little of that is visible at the moment you grant them.

An earlier run of this measurement reported 35 of 77 tools because the API it used allows 60 requests an hour and the measurement needed about 155 — the missing 42 had been refused, and the harness recorded that as "no source" rather than "I was refused". The controls passed anyway, because they sampled tools fetched before the limit hit. The harness now refuses to produce a result at all unless it has read at least 90% of the directories. If you build something similar, that assertion is the part worth copying.

Figures are from 19 August 2026 against the default branch; the script is in our repository and re-runnable.