CrewAI
Build a CrewAI agent with Scalekit-authenticated Gmail tools via MCP. CrewAI's MCPServerAdapter connects to a Scalekit MCP URL for automatic tool discovery.
Build a CrewAI agent that reads a user’s Gmail inbox. Scalekit handles OAuth, token storage, and exposes tools over MCP. CrewAI’s MCPServerAdapter discovers the tools and their schemas from the server. Some schemas need a small patch, covered below.
Before you start
Section titled “Before you start”- Create a Gmail connection in AgentKit > Connections. The samples use the connection name
gmail, so change it if yours differs. See Set up a connection. - Have the
.envfile from the Quickstart, and add your OpenAI API key asOPENAI_API_KEYto it. - Create a Virtual MCP server named
gmail-user-toolsthat includes the Gmail tools. See Create a Virtual MCP server. - The samples load
.envwithload_dotenv()frompython-dotenv.
Install
Section titled “Install”pip install crewai "crewai-tools[mcp]" scalekit-sdk-python python-dotenvInitialize
Section titled “Initialize”import osfrom scalekit import ScalekitClientfrom dotenv import find_dotenv, load_dotenv
load_dotenv(find_dotenv())
scalekit_client = ScalekitClient( env_url=os.environ["SCALEKIT_ENVIRONMENT_URL"], client_id=os.environ["SCALEKIT_CLIENT_ID"], client_secret=os.environ["SCALEKIT_CLIENT_SECRET"],)actions = scalekit_client.actionsConnect the user to Gmail
Section titled “Connect the user to Gmail”# Connect the user's Gmail account, and wait until it's ACTIVE before calling toolsconnection_name = "gmail"identifier = "user_123" # your app's unique user ID
response = actions.get_or_create_connected_account( connection_name=connection_name, identifier=identifier)if response.connected_account.status != "ACTIVE": link = actions.get_authorization_link( connection_name=connection_name, identifier=identifier ) print("Authorize Gmail:", link.link) input("Press Enter after authorizing...") # Fetch the account again to pick up the new status response = actions.get_or_create_connected_account( connection_name=connection_name, identifier=identifier )
if response.connected_account.status != "ACTIVE": raise RuntimeError( f"Gmail is {response.connected_account.status}, not ACTIVE. Authorize it and run again." )See Authorize a user for production auth handling.
Build and run the agent
Section titled “Build and run the agent”Get the Virtual MCP server URL and mint a session token, then pass both to MCPServerAdapter. CrewAI discovers all available Gmail tools from the MCP server:
from crewai import Agent, Crew, LLM, Taskfrom crewai_tools import MCPServerAdapterfrom datetime import timedelta
# Retrieve config_id by listing Virtual MCP servers filtered by namelist_response = actions.mcp.list_configs(filter_name="gmail-user-tools")mcp_server_url = list_response.configs[0].mcp_server_urlmcp_id = list_response.configs[0].id
token_response = actions.mcp.create_session_token( mcp_config_id=mcp_id, identifier="user_123", expiry=timedelta(hours=1),)
with MCPServerAdapter({ "url": mcp_server_url, "headers": {"Authorization": f"Bearer {token_response.token}"}, "transport": "streamable-http",}) as tools: agent = Agent( role="Email Assistant", goal="Fetch and summarize the user's unread emails", backstory="You are a helpful assistant with access to the user's Gmail inbox.", tools=tools, llm=LLM( model=os.getenv("LLM_MODEL", "gpt-4o"), base_url=os.getenv("OPENAI_BASE_URL"), api_key=os.getenv("OPENAI_API_KEY"), ), verbose=True, )
task = Task( description="Fetch the last 5 unread emails and provide a brief summary of each.", expected_output="A list of 5 unread emails with subject, sender, and a one-sentence summary.", agent=agent, )
result = Crew(agents=[agent], tasks=[task]).kickoff() print(result)Multi-agent crew
Section titled “Multi-agent crew”CrewAI’s real strength is multi-agent orchestration. For a full example that splits email triage across three specialized agents (scanner, prioritizer, drafter), see the CrewAI email triage cookbook.
Get the MCP server URL
Section titled “Get the MCP server URL”The code above reads mcp_server_url from a Virtual MCP server. Create one in the Scalekit dashboard under AgentKit > Virtual MCP Servers, or with the API. See Create a Virtual MCP server.
API reference
The endpoints this page's code calls, with every field and the SDK method for each: