LangChain¶
Use the package with langchain-mcp-adapters to load the server tools into a LangChain agent.
Install¶
pdm add "tavily-fastmcp[langchain]"
For LangGraph workflows:
pdm add "tavily-fastmcp[langchain]" langgraph
For local development from this repository:
pdm install -G :all
Agent over MCP¶
This pattern lets the model decide when to search, extract source pages, crawl a site, or request a Tavily research report.
import asyncio
from langchain.agents import create_agent
from langchain_mcp_adapters.client import MultiServerMCPClient
async def main() -> None:
client = MultiServerMCPClient(
{
"tavily": {
"transport": "stdio",
"command": "python",
"args": ["-m", "tavily_fastmcp.server", "--transport", "stdio"],
"env": {"TAVILY_API_KEY": "tvly-your-key-here"},
}
}
)
tools = await client.get_tools()
agent = create_agent(
model="openai:gpt-5",
tools=tools,
system_prompt=(
"Use Tavily for current web research. Use tavily.search for broad "
"discovery, tavily.extract for source reading, and tavily.research "
"for synthesized reports."
),
)
result = await agent.ainvoke(
{
"messages": [
{
"role": "user",
"content": "Find current MCP client setup guidance and cite the best sources.",
}
]
}
)
print(result)
asyncio.run(main())
Direct Service Agent Tooling¶
For scripts that do not need MCP transport, call the typed service directly and wrap only the operations your agent should use.
from tavily_fastmcp.service import LangChainTavilyService
from tavily_fastmcp.settings import get_settings
service = LangChainTavilyService(get_settings())
def web_research(query: str) -> str:
response = service.search_from_model(
query=query,
search_depth="advanced",
max_results=5,
include_answer=True,
)
urls = "\n".join(hit.url for hit in response.results)
return f"{response.answer or 'No direct answer returned.'}\n\nSources:\n{urls}"
LangGraph Tool Node¶
Use LangGraph when you want explicit state transitions around Tavily tools. This
pattern loads the MCP tools once and routes model tool calls through ToolNode.
import asyncio
from langchain_openai import ChatOpenAI
from langchain_mcp_adapters.client import MultiServerMCPClient
from langgraph.graph import START, MessagesState, StateGraph
from langgraph.prebuilt import ToolNode, tools_condition
async def main() -> None:
client = MultiServerMCPClient(
{
"tavily": {
"transport": "stdio",
"command": "python",
"args": ["-m", "tavily_fastmcp.server", "--transport", "stdio"],
"env": {"TAVILY_API_KEY": "tvly-your-key-here"},
}
}
)
tools = await client.get_tools()
model = ChatOpenAI(model="gpt-5").bind_tools(tools)
async def call_model(state: MessagesState) -> dict:
response = await model.ainvoke(state["messages"])
return {"messages": [response]}
graph_builder = StateGraph(MessagesState)
graph_builder.add_node("agent", call_model)
graph_builder.add_node("tools", ToolNode(tools))
graph_builder.add_edge(START, "agent")
graph_builder.add_conditional_edges("agent", tools_condition)
graph_builder.add_edge("tools", "agent")
graph = graph_builder.compile()
result = await graph.ainvoke(
{
"messages": [
{
"role": "user",
"content": "Map the FastMCP docs site and identify the pages about prompts.",
}
]
}
)
print(result["messages"][-1].content)
asyncio.run(main())
Tool Routing¶
Use
tavily.searchfor broad discovery and current facts.Use
tavily.extractwhen the agent already has URLs and needs page text.Use
tavily.mapbefore extraction when the agent needs a site’s URL structure.Use
tavily.crawlfor multi-page inspection on one domain.Use
tavily.researchfor synthesized reports across multiple sources.