Skip to main content

CrewAI

Connect a CrewAI agent to Civic using MCPClient with HTTP transport. CrewAI's MCP integration wraps discovered tools with MCPToolWrapper to make them usable by CrewAI agents.

Prerequisites

  • Python 3.11+
  • A Civic account at app.civic.com with a configured toolkit
  • A Civic token and an Anthropic API key

Installation

pip install crewai anthropic python-dotenv

Environment Variables

CIVIC_URL=https://app.civic.com/hub/mcp?profile=your-toolkit
CIVIC_TOKEN=your-civic-token
ANTHROPIC_API_KEY=your-anthropic-key
Get Your Credentials

How to generate a Civic token and configure toolkit URL parameters

Connecting to Civic

Use MCPClient with HTTPTransport to connect, then wrap the discovered tools with MCPToolWrapper:

import os
import asyncio
from dotenv import load_dotenv
from crewai import Agent, Task, Crew, LLM
from crewai.mcp.client import MCPClient, HTTPTransport
from crewai.tools.mcp_tool_wrapper import MCPToolWrapper

load_dotenv()

CIVIC_URL = os.environ["CIVIC_URL"]
CIVIC_TOKEN = os.environ["CIVIC_TOKEN"]

SERVER_PARAMS = {
"url": CIVIC_URL,
"headers": {"Authorization": f"Bearer {CIVIC_TOKEN}"},
"transport": "streamable-http",
}

async def get_civic_tools():
transport = HTTPTransport(
url=CIVIC_URL,
headers={"Authorization": f"Bearer {CIVIC_TOKEN}"},
streamable=True,
)
async with MCPClient(transport=transport) as client:
raw_tools = await client.list_tools()
return [
MCPToolWrapper(
mcp_server_params=SERVER_PARAMS,
tool_name=t["name"],
tool_schema=t.get("inputSchema", {}),
server_name="civic",
)
for t in raw_tools
]
note

MCPServerAdapter was removed in CrewAI v1.6.1. Use MCPClient + HTTPTransport + MCPToolWrapper as shown above.

Running the Agent

async def main():
tools = await get_civic_tools()

llm = LLM(
model="anthropic/claude-sonnet-4-6",
api_key=os.environ["ANTHROPIC_API_KEY"],
)

assistant = Agent(
role="Personal Assistant",
goal="Help the user with their tasks using available tools",
backstory="You are a capable assistant with access to the user's connected services through Civic.",
tools=tools,
llm=llm,
)

task = Task(
description="What events do I have today?",
expected_output="A list of today's calendar events.",
agent=assistant,
)

crew = Crew(agents=[assistant], tasks=[task])
result = crew.kickoff()
print(result)

asyncio.run(main())

Production Configuration

For production agents, lock to a specific toolkit using the profile URL parameter:

CIVIC_URL=https://app.civic.com/hub/mcp?profile=your-production-toolkit

Reference Implementation

crewai-reference-implementation-civic

Complete implementation with FastAPI chat UI and deployment guide

Next Steps