Integrations

CrewAI

Wrap a CrewAI Crew so its tool calls route through ArmorIQ

CrewAI Integration

ArmorIQCrew wraps CrewAI's Crew. On kickoff() it derives a plan from the crew's tools and tasks, mints one intent token for the run, and patches each ArmorIQ-backed tool so its execution routes through the ArmorIQ proxy instead of calling out directly.

Live in Python only. Ships in armoriq-sdk. There is no TypeScript CrewAI adapter. See Integrations for the status matrix.

This is a narrower adapter than Google ADK, LangChain or Strands. It gives you intent verification and audit, but not per-user scoping, per-call policy enforcement, holds, or approvals. Read Limitations before choosing it.

Install

pip install "armoriq-sdk[crewai]"

Usage

from armoriq_sdk import ArmorIQClient
from armoriq_sdk.integrations.crewai import ArmorIQCrew

client = ArmorIQClient(api_key=os.environ["ARMORIQ_API_KEY"])

crew = ArmorIQCrew(
    agents=[researcher, writer],
    tasks=[research_task, write_task],
    armoriq_client=client,
    llm="gpt-4o",
)

result = crew.kickoff()

Every argument other than armoriq_client, llm and token_validity_seconds is forwarded to crewai.Crew, so an existing crew definition moves over unchanged. kickoff_async() works the same way.

Parameters

ParameterTypeDefaultDescription
armoriq_clientArmorIQClientrequiredHolds your API key and endpoints
llmstrrequiredLLM identifier recorded on the plan, e.g. "gpt-4o"
token_validity_secondsfloat3600.0Intent-token validity window for the run
*args, **kwargsForwarded to crewai.Crew

Which tools get protected

The adapter only wraps tools that expose both a .mcp and an .action attribute. It walks every agent's tools list, deduplicates by object identity, and patches _run on each match.

A standard crewai tool does not have those attributes, so it is not wrapped and executes exactly as it would without ArmorIQ. Your ArmorIQ-backed tools need to carry the MCP name and action they map to.

The generated plan has one step per unique (mcp, action) pair, with the goal derived from your tasks' description (falling back to expected_output). Steps carry no parameters, so verification is at the action level rather than the argument level.

It fails open when it finds nothing to protect. If no tool on any agent has .mcp and .action, the adapter logs

No ArmorIQ tools found; crew runs without ArmorIQ verification

at WARNING level, mints no token, and runs the crew anyway. A misconfigured tool therefore looks like a successful protected run unless you are watching the logs. Assert on your logging, or check that the tools you expect to be wrapped really do carry both attributes.

Limitations

Google ADK / LangChain / StrandsCrewAI
Intent token minted from the planYesYes
Tool calls routed through the proxyYesYes
Per-user scoping (for_user(email))YesNo - the whole crew runs as one identity
Per-call policy enforcement (allow / hold / block)YesNo
Holds and approval waitingYesNo
Live enforcement eventsStrands, LangChainNo
Plan step granularityper tool call, with argsper (mcp, action), no args

Practical consequences:

  • Audit records are attributed to the client's base identity, not to an end user. If you serve multiple users, their activity is not distinguishable.
  • Policies that depend on the acting user, or that hold a call for approval, will not be evaluated on this path.
  • One token covers the whole kickoff(), so its validity has to span the entire crew run. That is why the default is an hour rather than the SDK's usual 60 seconds.

If you need any of the above on CrewAI, skip the adapter and call ArmorIQClient from inside your BaseTool._run instead. That gives you the full session surface at the cost of about ten lines per tool. See Custom frameworks.

On this page