本文介绍如何搭建基于Chrome开发者工具多客户端协议(MCP)的智能对话代理。通过整合chrome-devtools-mcp和LangChain框架,实现了自动注册MCP工具、支持Ollama/OpenAI双模型后端、异步非阻塞运行的Chat Agent。文章详细说明了环境配置方法,包括Chrome调试模式启动命令和Node.js环境准备,并提供了可直接运行的Python完整代码。该代理支持网页操作指令如打开网页、截图和网络请求分析等功能,通过LangGraph构建状态图实现对话流程管理。代码展示了模型绑定、工具自动发现和异步交互的实现方式,为开发者提供了开箱即用的MCP集成方案。
效果


简介 ✨
本文示例展示了一个稳定的 MCP Chat Agent:
- 自动注册并绑定 MCP 工具(无需手动查找工具)
- 支持 Ollama / OpenAI 两种模型
- 异步运行,不会阻塞主线程
下面是使用前的准备和代码说明。
环境与准备 🔧
- 启动 Chrome(带远程调试端口):
macOS
bash
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --remote-debugging-port=9222 --user-data-dir=/tmp/chrome-profile-stable
Linux
bash
/usr/bin/google-chrome --remote-debugging-port=9222 --user-data-dir=/tmp/chrome-profile-stable

Windows
bash
"C:\Program Files\Google\Chrome\Application\chrome.exe" --remote-debugging-port=9222 --user-data-dir="%TEMP%\chrome-profile-stable"
要安装node环境
bash
npx -y chrome-devtools-mcp@latest --browser-url=http://127.0.0.1:9222

请确保 Chrome 已用
--remote-debugging-port=9222启动,且npx -y chrome-devtools-mcp@latest能单独运行。
- Python 环境需要安装对应依赖(示例中使用的包有
langchain_ollama,langchain_openai,langchain_mcp_adapters,langgraph等)。
完整代码(可直接保存并运行)
下面是 new_chat_agent.py 的完整代码:
python
#!/usr/bin/env python3
"""
最终稳定版 MCP Chat Agent
- 自动注册 MCP 工具(无需手动找)
- 支持 Ollama / OpenAI 二选一
- 不会阻塞 / 不会 silent
"""
import asyncio
from typing import Annotated, TypedDict
from langchain_ollama import ChatOllama
from langchain_openai import ChatOpenAI
from langchain_mcp_adapters.client import MultiServerMCPClient
from langgraph.graph import StateGraph, START
from langgraph.prebuilt import ToolNode, tools_condition
from langgraph.checkpoint.memory import MemorySaver
from langgraph.graph.message import add_messages
# ================== 配置 ==================
OPENAI_API_KEY = "sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
OPENAI_API_BASE = "https://dashscope.aliyuncs.com/compatible-mode/v1"
class State(TypedDict):
messages: Annotated[list, add_messages]
class MCPAgent:
def __init__(self, backend: str = "ollama"):
print("🚀 初始化 MCPAgent", flush=True)
# -------- 模型选择 --------
if backend == "ollama":
self.llm = ChatOllama(
model="qwen2.5:7b",
temperature=0.7,
)
print("🔹 使用 Ollama", flush=True)
else:
self.llm = ChatOpenAI(
model="qwen3-30b-a3b-instruct-2507",
temperature=0.7,
api_key=OPENAI_API_KEY,
base_url=OPENAI_API_BASE,
)
print("🔹 使用 OpenAI API", flush=True)
# -------- MCP 工具(关键)--------
print("🔄 连接 chrome-devtools-mcp(不会阻塞)", flush=True)
client = MultiServerMCPClient(
{
"chrome": {
"transport": "stdio",
"command": "npx",
"args": [
"-y",
"chrome-devtools-mcp@latest",
"--browser-url=http://127.0.0.1:9222",
],
}
}
)
# ⚠️ get_tools 是唯一需要等的地方
self.tools = asyncio.run(client.get_tools())
if not self.tools:
raise RuntimeError("❌ MCP 工具为空,请确认 Chrome 是否启动")
print(f"✅ 已自动注册 {len(self.tools)} 个 MCP 工具", flush=True)
# ⭐ 核心:直接 bind_tools,不要自己管工具
self.llm = self.llm.bind_tools(self.tools)
# -------- LangGraph --------
self.graph = self._build_graph()
self.history = []
def _agent(self, state: State):
return {"messages": [self.llm.invoke(state["messages"]) ]}
def _build_graph(self):
g = StateGraph(State)
g.add_node("agent", self._agent)
g.add_node("tools", ToolNode(self.tools))
g.add_edge(START, "agent")
g.add_conditional_edges("agent", tools_condition)
g.add_edge("tools", "agent")
return g.compile(checkpointer=MemorySaver())
async def run(self):
print("\n🤖 MCP Chat Agent 已启动", flush=True)
print("示例:", flush=True)
print(" 打开 https://www.baidu.com", flush=True)
print(" 截图当前页面", flush=True)
print(" 列出 network 里的 JSON 请求\n", flush=True)
while True:
user = input("你: ").strip()
if user in ("exit", "quit"):
break
self.history.append(("user", user))
async for event in self.graph.astream_events(
{"messages": self.history},
config={"configurable": {"thread_id": "default"}},
version="v2",
):
if event["event"] == "on_chat_model_stream":
chunk = event["data"]["chunk"]
if chunk.content:
print(chunk.content, end="", flush=True)
elif event["event"] == "on_tool_start":
print(f"\n🛠️ 调用工具:{event['name']}", flush=True)
elif event["event"] == "on_tool_end":
print("\n✅ 工具执行完成", flush=True)
print()
# ================== 启动 ==================
if __name__ == "__main__":
try:
choice = input("选择模型(1=Ollama,2=OpenAI):").strip()
backend = "ollama" if choice != "2" else "openai"
agent = MCPAgent(backend=backend)
asyncio.run(agent.run())
except Exception as e:
print(f"\n❌ 启动失败:{e}", flush=True)
print("\n排查顺序:", flush=True)
print("1. Chrome 是否用 --remote-debugging-port=9222 启动", flush=True)
print("2. npx -y chrome-devtools-mcp@latest 是否能单独运行", flush=True)
print("3. node / npm 是否正常", flush=True)
关键点解析 💡
- 自动注册 MCP 工具 :通过
MultiServerMCPClient(...).get_tools()自动发现并注册 chrome-devtools-mcp 提供的工具集合。 - 绑定工具到 LLM :使用
self.llm.bind_tools(self.tools),让 LLM 可以直接以工具调用的方式操控浏览器。 - LangGraph 驱动 :使用
StateGraph与ToolNode管理对话和工具调用的流程,并以MemorySaver做检查点。 - 运行模式:交互式命令行会持续接收用户输入,并以事件流打印模型输出与工具调用状态。
使用示例 🧪
- 启动 Chrome(见上文命令)。
- 运行脚本:
bash
python new_chat_agent.py

-
根据提示选择模型(1=Ollama,2=OpenAI),然后在命令行输入如:
打开 https://www.baidu.com
截图当前页面
列出 network 里的 JSON 请求
Agent 会根据工具能力返回结果并在终端打印执行过程。
参考:
https://github.com/ChromeDevTools/chrome-devtools-mcp
如果本文对你有帮助,欢迎点赞 + 关注,你的关注是我持续更新的最大动力 🙏