I am getting some error when i tried integrating vapi mcp in crewai. I tried using the Stdio Transport from crewai but it giving me this error:
**Error:**
Tool Usage Failed │
│ Name: create_assistant │
│ Error: Event loop is closed
Thought: I am unable to create an assistant due to an "Event loop is closed" error. This prevents me from proceeding with the call initiation as I need an assistant ID. Since I cannot interact with the Vapi MCP server to create an assistant or make a call, I cannot fulfill the request to make a real outbound call. I must report this limitation.
Final Answer: ## Client Query
The client requested an outbound call to '+2348160487016' regarding a 'new_auto_insurance_quote'.
## Information Provided
Due to a technical error ("Event loop is closed") preventing the creation of an assistant and subsequent call initiation via the Vapi MCP server, no information could be provided to the client.
## Outcome
Human handoff recommended.
## Reason for Human Handoff
The AI encountered a critical error ("Event loop is closed") when attempting to create an assistant, which is a prerequisite for initiating an outbound call. This technical limitation prevents the AI from performing the requested task of making the call and engaging with the client. Therefore, a human agent is required to manually initiate the call and address the client's 'new_auto_insurance_quote' query.
This is my code for the crew.py file:
from crewai import Agent, Crew, Process, Task
from crewai import LLM
from crewai_tools import DirectorySearchTool
from crewai.knowledge.source.pdf_knowledge_source import PDFKnowledgeSource
from crewai_tools import MCPServerAdapter
from mcp import StdioServerParameters
import os
from dotenv import load_dotenv
load_dotenv()
# Load Vapi specific IDs from .env
VAPI_API_KEY = os.getenv("VAPI_API_KEY")
# Define shared LLM for all agents
llm_1 = LLM(
model="openrouter/google/gemini-2.5-flash-preview-05-20",
base_url="https://openrouter.ai/api/v1",
api_key=os.getenv("OPENROUTER_API_KEY"),
max_tokens=15000,
temperature=0.2,
stream=True,
)
# Tool for semantic search within the 'knowledge' directory.
policy_search_tool = DirectorySearchTool(directory='c:\\Users\\user\\Desktop\\AI\\Insurance AI agent\\insure_agent\\knowledge')
# Defines a source for specific PDF files.
pdf_source = PDFKnowledgeSource(
file_paths=["Car Insurance Policy Documents.pdf", "Insurance plan database.pdf",
"Premium Calculation Rules.pdf", "Discount Program Information.pdf",
"Regulatory Compliance Information.pdf", "Claims Process Documentation.pdf", "Customer FAQ Documents.pdf"
]
)
# Create a StdioServerParameters object
server_params=StdioServerParameters(
command="npx",
args=[
"-y",
"@vapi-ai/mcp-server"
],
env={"VAPI_TOKEN": "YOUR_VAPI_API_KEY"}
)
with MCPServerAdapter(server_params) as tools:
print(f"Available tools from Stdio MCP server: {[tool.name for tool in tools]}")
# Define Agent, Task, and Crew at the module level
VoiceSupportAgent = Agent(
role="Proactive AI Voice Outreach Specialist for Car Insurance",
goal="Utilize the create_call tools from a remote vapi MCP server via Streamable HTTP to call '{phone_number}'. To efficiently and empathetically handle outbound client calls, provide accurate easy-to-understand car insurance information using the company's knowledge base and judiciously determine when to escalate to a human agent, always ensuring a positive client interaction and adherence to company policy",
backstory=(
"As an AI Voice Outreach Specialist, I excel in clear, empathetic, and professional client communication for car insurance needs through the vapi MCP for outbound calls. "
"I proactively engage clients, understand their requirements, and use our comprehensive knowledge base (policies, FAQs) to provide accurate, simplified answers. "
"I'm programmed to identify when a human agent is needed for complex or sensitive issues, ensuring a smooth handoff. "
"I operate strictly by company guidelines, prioritizing client satisfaction and data security."
),
tools=tools,
llm=llm_1,
verbose=True,
)
HandleOutboundClientCall = Task(
description=(
"Make a real outbound car insurance call to '{phone_number}' regarding '{call_reason}' with the vapi MCP server.\n"
"Your process:\n"
"1. Initiate Call: Greet client, confirm their identity for {phone_number}. State your name (AI Voice Specialist, Car Insurance Team) and the call's purpose ('{call_reason}').\n"
"2. Understand Needs: Empathetically discuss and fully understand the client's car insurance query or concerns.\n"
"3. Provide Information: Use available tools (knowledge base, MCP tools) to find and deliver accurate, clear information on policy details, claims, coverage, discounts, etc.\n"
"4. Resolve or Escalate: \n"
" a. If query is resolvable with knowledge base, provide a full answer.\n"
" b. If knowledge base is insufficient, query is too complex, or client requests a human, clearly state the need for human agent intervention. Do NOT guess or provide information beyond documented knowledge.\n"
"5. Conclude Call: Summarize key points if applicable. Thank the client. If escalating, inform them of the next steps.\n\n"
"Maintain a professional, empathetic, and helpful tone. IMPORTANT: Your final output for this task MUST be a markdown document formatted according to the guardrail. Do not output a JSON function call as your final answer."
),
expected_output=(
"A well-structured markdown document summarizing the call. The document MUST include the following sections with appropriate markdown headings:\n"
"## Client Query\n"
"The main question or issue raised by the client.\n\n"
"## Information Provided\n"
"Key information or answers given to the client based on the knowledge base.\n\n"
"## Outcome\n"
"A brief description of how the call concluded (e.g., 'Query resolved', 'Human handoff recommended').\n\n"
"## Reason for Human Handoff\n"
"If handoff was recommended, provide a brief reason (e.g., 'Knowledge base insufficient', 'Client request', 'Complex query'). If no handoff, this section can state 'N/A' or be briefly explained as not needed.\n\n"
"The entire summary must be factual, directly reflect the interaction, and strictly follow this markdown structure."
),
agent=VoiceSupportAgent,
guardrail=(
"Make a real call using the vapi MCP server and ensure the output is formatted as a well-structured markdown document. "
"The document must include the following sections with appropriate markdown headings: "
"'Client Query', 'Information Provided', 'Outcome', and when applicable, 'Reason for Human Handoff'. "
"Use proper markdown formatting including headers (##), bullet points, and emphasis where appropriate. "
"DO NOT HALLUCINATE INFORMATION. Only include information that is factually present in the knowledge base. "
"If the call does not connect or work properly, explicitly state this in the 'Outcome' section rather than "
"fabricating conversation details. Be honest about any technical issues or limitations encountered. "
"Ensure all required sections are present and contain comprehensive and accurate information."
),
markdown=True,
output_file="Output/Call-report.md",
)
crew = Crew(
agents=[VoiceSupportAgent],
tasks=[HandleOutboundClientCall],
verbose=True,
process=Process.sequential,
knowledge_sources=[pdf_source],
)
Main.py:
#!/usr/bin/env python
import warnings
from dotenv import load_dotenv
from insure_agent.crew import crew as ai_voice_crew_instance
from opik.integrations.crewai import track_crewai
import opik
# Load environment variables from .env file
load_dotenv()
warnings.filterwarnings("ignore", category=SyntaxWarning, module="pysbd")
def run():
"""
Run the crew.
"""
inputs = {
"phone_number": "+448160483515",
"call_reason": "new_auto_insurance_quote"
}
return ai_voice_crew_instance.kickoff(inputs=inputs)
I also tried the SSE Transport and Streamable HTTP Transport from crewai but its still given me the same error. What can i do?
This is the link to vapi mcp doc page: https://docs.vapi.ai/sdk/mcp-server