Tools from an MCP server
An MCP server is a separate program that offers tools over a standard protocol. Give an agent mcps=[...] and CrewAI starts it and hands its tools over.
Lesson 8's tool lived in the same file as the crew. In a real shop the order system belongs to another team, which can publish its tools as an MCP server (Model Context Protocol). Any MCP client can use them, CrewAI included.
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("orders")
ORDERS = {"A17": "shipped on 3 March", "C40": "waiting for stock"}
@mcp.tool()
def lookup_order(order_id: str) -> str:
"""Look up an order's shipping status by its id, such as A17."""
status = ORDERS.get(order_id)
return f"{order_id} {status}." if status else f"{order_id} is not an order we have."
if __name__ == "__main__":
mcp.run()This server uses FastMCP from the mcp package, which CrewAI installs. The tool is lesson 8's lookup. mcp.run() talks over standard input and output, so a client starts it as a subprocess.
from crewai import Agent, Crew, Task
from crewai.mcp import MCPServerStdio
from shop_llm import ShopLLM
clerk = Agent(
role="Order clerk", goal="Find the status of customers' orders",
backstory="You can look up any order.", llm=ShopLLM(model="shop"),
mcps=[MCPServerStdio(command="python", args=["orders_server.py"])],
)
task = Task(description="Answer the customer: {question}",
expected_output="The order's status in one sentence.", agent=clerk)
crew = Crew(agents=[clerk], tasks=[task])MCPServerStdio says how to start the server: the command and its arguments. The agent gets no tools=; mcps= brings them.
result = crew.kickoff(inputs={"question": "Where is my order C40?"})
print(result.raw)
print(result.tasks_output[0].messages[2]["tool_calls"][0]["function"]["name"])CrewAI started the server, asked it for its tools, and turned each into a CrewAI tool. The name the model saw is lookup_order prefixed with the command that starts the server, which is why lesson 9's model matches tool names by their ending. The server ran the lookup and its answer came back like any tool result.
The python in command must be the Python that has mcp installed, which it is when your environment is active. The same field takes MCPServerHTTP for a server running elsewhere, and create_static_tool_filter from crewai.mcp.filters limits which of a server's tools an agent gets.
- Add a second tool to the server, such as
order_total, and print the names the agent gets. - Change
argsto a file that does not exist and read what the agent does. - Ask about B22 and read the answer from the server.
Little by little, you're building something great.