> ## Documentation Index
> Fetch the complete documentation index at: https://developers.meshapi.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# CrewAI

> Power a CrewAI crew with Mesh — one LLM object, and every agent in the crew routes through Mesh including the auto-router.

CrewAI routes model calls through [LiteLLM](https://docs.litellm.ai), so Mesh is reached with LiteLLM's OpenAI-dialect transport and an explicit `base_url`. One `LLM` object serves any number of agents in the crew.

## Install

```bash theme={null}
pip install crewai
```

## Connect

```python theme={null}
import os

from crewai import LLM

llm = LLM(
    model="openai/auto",                       # openai/ = LiteLLM transport selector
    base_url="https://api.meshapi.ai/v1",
    api_key=os.environ["MESH_API_KEY"],        # rsk_...
)
```

> [!NOTE]
>
> The `openai/` prefix selects LiteLLM's OpenAI-dialect transport; LiteLLM strips it before sending, so Mesh receives `auto` and routes it. To pin a Mesh catalog id that already contains a slash, the prefix reads as doubled: `openai/openai/gpt-4o-mini`.

## A crew with a tool

```python theme={null}
from crewai import Agent, Crew, Task
from crewai.tools import tool


@tool("get_shipment_status")
def get_shipment_status(order_id: str) -> str:
    """Look up the shipment status of an order by its id."""
    book = {"A-1042": {"state": "in transit", "eta_days": 2}}
    return str({"status": "success", "order_id": order_id, **book.get(order_id, {})})


agent = Agent(
    role="Support agent",
    goal="Answer order shipment questions",
    backstory="You look up orders with the provided tool.",
    llm=llm,
    tools=[get_shipment_status],
)

task = Task(
    description="What is the shipment status of order A-1042?",
    expected_output="One sentence with the state and the ETA.",
    agent=agent,
)

print(Crew(agents=[agent], tasks=[task]).kickoff())
```

## Caveats

### Token counting against `auto`

CrewAI counts input tokens locally and cannot look up a context window for the literal name `auto`, so it logs:

```text theme={null}
Using an approximate input token count for model 'auto': assuming one token
per four characters because a native token count is unavailable.
```

This is CrewAI's own bookkeeping only — Mesh bills and logs usage against the real served model. Pin a catalog id if you need CrewAI's own counts to be exact.

### Routing varies with prompt size

CrewAI prompts are large: it wraps agent role, goal, backstory, and tool schemas into every call. With `auto` that changes which model Mesh selects, so a crew may be served a different model than a bare chat call from the same key. Check the served model rather than assuming.

Everything in [Caveats that apply to every framework](https://developers.meshapi.ai/agent/frameworks.md#caveats-that-apply-to-every-framework) also applies.

## Related

* [Agent frameworks](https://developers.meshapi.ai/agent/frameworks.md) — the shared pattern and compatibility matrix
* [Auto-routing](https://developers.meshapi.ai/docs/capabilities/auto-routing.md) — how `auto` picks a model
* [Google ADK](https://developers.meshapi.ai/agent/adk.md) — the other LiteLLM-based framework


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.