Skip to main content
Version: 1.0.5

CrewAI Adapter for uAgents

This example shows how to expose a CrewAI trip-planning crew as a uAgent with CrewaiRegisterTool from uagents-adapter.

Use a unique agent name

CrewaiRegisterTool does not read AGENT_SEED. The mailbox seed is derived as uagent_seed_{name} and {port}. If you keep the sample name and port, every reader gets the same address. Change name (and optionally port) before you run the agent.

Prerequisites

Getting Started

1. Clone the parent example repo

The trip planner lives in a subdirectory of fetchai/innovation-lab-examples. Clone the parent repository, then cd into Crewai-agents/trip_planner (there is no crewai-example/ folder).

macOS / Linux:

clone.sh
git clone https://github.com/fetchai/innovation-lab-examples.git
cd innovation-lab-examples/Crewai-agents/trip_planner
python3.11 -m venv venv
source venv/bin/activate

Windows (PowerShell):

clone.ps1
git clone https://github.com/fetchai/innovation-lab-examples.git
cd innovation-lab-examples\Crewai-agents\trip_planner
py -3.11 -m venv venv
venv\Scripts\activate

2. Install dependencies

Install the versions this page uses. Do not run pip install -r requirements.txt from the cloned example until that file is updated: it still pins uagents-adapter==0.2.1 and uagents==0.22.3, which do not match CrewaiRegisterTool 0.6.2.

install.sh
pip install uagents==0.25.5 "uagents-adapter[crewai]==0.6.2" python-dotenv langchain-openai

The [crewai] extra pulls in crewai==0.203.1 for adapter 0.6.2.

3. Environment variables

Create a .env file in Crewai-agents/trip_planner. Canonical Agentverse variable name (same as other Innovation Lab adapter pages):

.env
OPENAI_API_KEY=your_openai_key
AGENTVERSE_API_KEY=your_agentverse_key
VariableRequired?Notes
OPENAI_API_KEYYesUsed by the crew LLM (gpt-4o in trip_agents.py) and by NL parameter extraction
AGENTVERSE_API_KEYYesMailbox / Agentverse registration. Older main_uagents.py in the example repo still reads AV_API_KEY; the sample below accepts either name
AI_AGENT_ADDRESSNoOverride the NL formatter uAgent (agent1q...). If unset, the adapter default is used
SERPER_API_KEY, BROWSERLESS_API_KEY, OPENWEATHER_API_KEY, SEARCH_API_KEYNoPresent in the example .env.example, but current trip_agents.py / trip_tasks.py are LLM-only and do not call those tools

Do not set AGENT_SEED. It is unused by CrewaiRegisterTool.

4. Run the uAgents wrapper

Replace cloned main_uagents.py with the sample in this page (or edit the clone so it matches: AGENTVERSE_API_KEY, unique name, return_dict=True, optional AI_AGENT_ADDRESS). The example repo currently uses a different name, port 8033, AV_API_KEY, and a hardcoded ai_agent_address.

run.sh
python main_uagents.py

Windows:

run.ps1
python main_uagents.py

5. Inspector and local agents

Copy the inspector URL from the agent output, or open Local agents and select your crew agent.

6. Chat from ASI:One

Copy the printed agent address into ASI:One and send a natural-language request that maps to query_params:

Plan a trip for me from London to Paris starting on 22 April 2026. I am interested in mountains, beaches, and history.

That maps to origin=London, cities=Paris, date_range=starting on 22 April 2026, interests=mountains, beaches, and history.

Optional: example client_agent.py

The example README also documents client_agent.py, a second uAgent that sends trip requests. You can skip it if you use ASI:One. If you run it, point it at the address printed by main_uagents.py (it changes when you change name or port).

Overview

The CrewAI adapter lets you:

  • Run specialized CrewAI roles as one collaborative crew
  • Expose that crew as a uAgent on Agentverse (mailbox + chat)
  • Accept structured query_params or natural-language chat that is extracted into those fields

Trip Planner Example

Standard CrewAI (main.py)

Interactive CLI without uAgents:

main.py
from textwrap import dedent

from crewai import Crew
from dotenv import load_dotenv

from trip_agents import TripAgents
from trip_tasks import TripTasks

load_dotenv()


class TripCrew:
def __init__(self, origin, cities, date_range, interests):
self.cities = cities
self.origin = origin
self.interests = interests
self.date_range = date_range

def run(self):
agents = TripAgents()
tasks = TripTasks()

city_selector_agent = agents.city_selection_agent()
local_expert_agent = agents.local_expert()
travel_concierge_agent = agents.travel_concierge()

identify_task = tasks.identify_task(
city_selector_agent,
self.origin,
self.cities,
self.interests,
self.date_range,
)
gather_task = tasks.gather_task(
local_expert_agent, self.origin, self.interests, self.date_range
)
plan_task = tasks.plan_task(
travel_concierge_agent, self.origin, self.interests, self.date_range
)

crew = Crew(
agents=[city_selector_agent, local_expert_agent, travel_concierge_agent],
tasks=[identify_task, gather_task, plan_task],
verbose=True,
)

result = crew.kickoff()
return result


if __name__ == "__main__":
print("## Welcome to Trip Planner Crew")
print("-------------------------------")
location = input(
dedent(
"""
From where will you be traveling from?
"""
)
)
cities = input(
dedent(
"""
What are the cities options you are interested in visiting?
"""
)
)
date_range = input(
dedent(
"""
What is the date range you are interested in traveling?
"""
)
)
interests = input(
dedent(
"""
What are some of your high level interests and hobbies?
"""
)
)

trip_crew = TripCrew(location, cities, date_range, interests)
result = trip_crew.run()
print("\n\n########################")
print("## Here is your Trip Plan")
print("########################\n")
print(result)

uAgents integration (main_uagents.py)

main_uagents.py
#!/usr/bin/env python3
"""Trip Planner script using CrewAI adapter for uAgents."""

import os
import time

from crewai import Crew
from dotenv import load_dotenv
from uagents_adapter import CrewaiRegisterTool

from trip_agents import TripAgents
from trip_tasks import TripTasks


class TripCrew:
def __init__(self, origin, cities, date_range, interests):
self.cities = cities
self.origin = origin
self.interests = interests
self.date_range = date_range

def run(self):
agents = TripAgents()
tasks = TripTasks()

city_selector_agent = agents.city_selection_agent()
local_expert_agent = agents.local_expert()
travel_concierge_agent = agents.travel_concierge()

identify_task = tasks.identify_task(
city_selector_agent,
self.origin,
self.cities,
self.interests,
self.date_range,
)
gather_task = tasks.gather_task(
local_expert_agent, self.origin, self.interests, self.date_range
)
plan_task = tasks.plan_task(
travel_concierge_agent, self.origin, self.interests, self.date_range
)

crew = Crew(
agents=[city_selector_agent, local_expert_agent, travel_concierge_agent],
tasks=[identify_task, gather_task, plan_task],
verbose=True,
)

result = crew.kickoff()
return result

def kickoff(self, inputs=None):
"""Adapter between uAgents messages and CrewAI."""
if inputs:
self.origin = inputs.get("origin", self.origin)
self.cities = inputs.get("cities", self.cities)
self.date_range = inputs.get("date_range", self.date_range)
self.interests = inputs.get("interests", self.interests)

return self.run()


def main():
load_dotenv()
api_key = os.getenv("AGENTVERSE_API_KEY") or os.getenv("AV_API_KEY")
openai_api_key = os.getenv("OPENAI_API_KEY")
if not api_key:
print("Error: AGENTVERSE_API_KEY not found in environment")
return

if not openai_api_key:
print("Error: OPENAI_API_KEY not found in environment")
return

os.environ["OPENAI_API_KEY"] = openai_api_key

trip_crew = TripCrew("", "", "", "")
register_tool = CrewaiRegisterTool()

query_params = {
"origin": {"type": "str", "required": True},
"cities": {"type": "str", "required": True},
"date_range": {"type": "str", "required": True},
"interests": {"type": "str", "required": True},
}

tool_input = {
"crew_obj": trip_crew,
# Change this so your address is unique
"name": "trip-planner-crew-YOUR_UNIQUE_ID",
"port": 8080,
"description": "A CrewAI agent that helps plan trips based on preferences",
"api_token": api_key,
"mailbox": True,
"query_params": query_params,
"example_query": (
"Plan a trip from New York to Paris in June, "
"I'm interested in art and history other than museums."
),
"return_dict": True,
}

ai_agent_address = os.getenv("AI_AGENT_ADDRESS")
if ai_agent_address:
tool_input["ai_agent_address"] = ai_agent_address

result = register_tool.run(tool_input=tool_input)
print(f"CrewAI agent registration result: {result}")
print(f"Agent address: {result['agent_address']}")

try:
while True:
time.sleep(1)
except KeyboardInterrupt:
print("\nExiting...")


if __name__ == "__main__":
main()

Natural-language queries

Chat text is not passed straight into kickoff. When a user sends a sentence, CrewaiRegisterTool can call an AI formatter uAgent (OpenAI behind the scenes in the logs) to fill query_params: origin, cities, date_range, interests.

  • Omit ai_agent_address to use the adapter package default formatter.
  • Override with ai_agent_address in tool_input, or set AI_AGENT_ADDRESS in .env.
  • The cloned example currently hardcodes ai_agent_address=agent1q0h70caed8ax769shpemapzkyk65uscw4xwk6dc4t3emvp5jdcvqs9xs32y. Prefer the env override so you can change it without editing code.

Key differences in uAgents integration

  1. CrewaiRegisterTool: Registers a CrewAI crew as a uAgent. This is the CrewAI-specific tool (not a generic Langchain register helper). There is no UAgentRegisterTool class.
  2. kickoff: Bridges chat/structured inputs into TripCrew.run().
  3. query_params: Declares the fields the formatter and clients should supply.
  4. example_query: Helps chat clients understand expected phrasing.
  5. return_dict=True: run() then returns a dict with agent_address (not address). The default return type is a string; do not look up a missing "address" key.

Specialized agents in the trip planner

Defined in trip_agents.py:

  1. City Selection Agent: Picks a city from the options
  2. Local Expert: Local experiences and practical detail
  3. Travel Concierge: Itinerary and logistics

Tasks in trip_tasks.py: identify, gather, plan.

Benefits of the uAgents integration

  • Network communication: Reach the crew over the agent network
  • Structured inputs: query_params validation
  • Mailbox: Asynchronous delivery via Agentverse
  • Discovery: Agentverse listing
  • NL processing: Optional formatter agent (ai_agent_address / AI_AGENT_ADDRESS) so chat becomes structured fields
crewai-adapter

Terminal Outputs

uAgents Integration (main_uagents.py)

First terminal:

(venv) abhi@Fetchs-MacBook-Pro test examples % python3 trip_planner/main_uagents.py
INFO: [Trip Planner Crew AI Agent adapters]: Starting agent with address: agent1q2sgs58jzw70e8vvsrlx8k3yukdqc9gwkhp8p7q6tslcxhy0eqtxyq4fv07
INFO: [Trip Planner Crew AI Agent adapters]: Agent 'Trip Planner Crew AI Agent adapters' started with address: agent1q2sgs58jzw70e8vvsrlx8k3yukdqc9gwkhp8p7q6tslcxhy0eqtxyq4fv07
INFO: [Trip Planner Crew AI Agent adapters]: Agent inspector available at https://agentverse.ai/inspect/?uri=http%3A//127.0.0.1%3A8080&address=agent1q2sgs58jzw70e8vvsrlx8k3yukdqc9gwkhp8p7q6tslcxhy0eqtxyq4fv07
INFO: [Trip Planner Crew AI Agent adapters]: Starting server on http://0.0.0.0:8080 (Press CTRL+C to quit)
INFO: [Trip Planner Crew AI Agent adapters]: Starting mailbox client for https://agentverse.ai
INFO: [Trip Planner Crew AI Agent adapters]: Mailbox access token acquired
Connecting agent 'Trip Planner Crew AI Agent adapters' to Agentverse...
INFO: [mailbox]: Successfully registered as mailbox agent in Agentverse
Successfully connected agent 'Trip Planner Crew AI Agent adapters' to Agentverse
Updating agent 'Trip Planner Crew AI Agent adapters' README on Agentverse...
Successfully updated agent 'Trip Planner Crew AI Agent adapters' README on Agentverse

CrewAI agent registration result: Agent 'Trip Planner Crew AI Agent adapters' registered with address: agent1q2sgs58jzw70e8vvsrlx8k3yukdqc9gwkhp8p7q6tslcxhy0eqtxyq4fv07 with mailbox (Parameters: origin, cities, date_range, interests)
INFO: [mailbox]: Successfully registered as mailbox agent in Agentverse
INFO: [Trip Planner Crew AI Agent adapters]: Got a message from agent1qwwng5d939vyaa6d2trnllyltgrndtfd6z44h8ey8a56hf4dcatsytgzm49
INFO: [Trip Planner Crew AI Agent adapters]: Received message model digest: timestamp=datetime.datetime(2025, 4, 21, 10, 13, 39, 989489, tzinfo=datetime.timezone.utc) msg_id=UUID('7930acf1-b16e-4b20-896b-7d801763eaa6') content=[TextContent(type='text', text='Plan a trip for me from london to paris starting on 22nd of April 2025 and I am interested in a mountains beaches and history')]
INFO: [Trip Planner Crew AI Agent adapters]: Got a text message from agent1qwwng5d939vyaa6d2trnllyltgrndtfd6z44h8ey8a56hf4dcatsytgzm49: Plan a trip for me from london to paris starting on 22nd of April 2025 and I am interested in a mountains beaches and history
INFO: [Trip Planner Crew AI Agent adapters]: Using crew object: <__main__.TripCrew object at 0x12c1f79d0>
INFO: [Trip Planner Crew AI Agent adapters]: Extracting parameters using keys: ['origin', 'cities', 'date_range', 'interests']
INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions "HTTP/1.1 200 OK"
INFO: [Trip Planner Crew AI Agent adapters]: Extracted parameters: {'origin': 'london', 'cities': 'paris', 'date_range': '22nd of April 2025', 'interests': 'mountains beaches and history'}
INFO: [Trip Planner Crew AI Agent adapters]: Running crew with extracted parameters
╭─────────────────────────────────────────────────────── Crew Execution Started ───────────────────────────────────────────────────────╮
│ │
│ Crew Execution Started │
│ Name: crew │
│ ID: 1462f3ae-5ce4-4ea3-b1af-5639aac04dd2 │
│ │
│ │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯

🚀 Crew: crew
└── 📋 Task: c181e31b-6b7f-4471-ab8f-fa5f06078365
Status: Executing Task...
[... crew execution continues ...]

Standard CrewAI (main.py)

## Welcome to Trip Planner Crew
-------------------------------
From where will you be traveling from?
> New York

What are the cities options you are interested in visiting?
> Paris, Rome, Barcelona

What is the date range you are interested in traveling?
> June 10-20, 2026

What are some of your high level interests and hobbies?
> Food, art, architecture, and history

[City Selection Specialist] I'll analyze which city would be the best fit based on the traveler's preferences...

########################
## Here is your Trip Plan
########################

# PARIS: 3-DAY FOOD & ART JOURNEY
... itinerary continues ...

ASI:One chat

Copy the agent address into ASI:One and use the example query above.

crewai-adapter
crewai-adapter