Hands‑On MCP: Integrate Amap and Browser MCP Servers so Agents Can Call Any Tool
This tutorial walks through the MCP architecture, shows how to install @langchain/mcp-adapters, connect real Amap and Playwright MCP servers to a LangGraph ReAct agent, combine multiple servers, choose between stdio and HTTP transports, and avoid common production pitfalls.
Architecture Overview
The system consists of three decoupled layers:
Agent layer : a LangGraph ReAct agent that decides which tool to invoke.
Adapter layer : @langchain/mcp-adapters converts any MCP tool into a LangChain Tool object via MultiServerMCPClient.
Server layer : the actual MCP server, which can run as a local subprocess (stdio) or as a remote HTTP/SSE service.
┌─────────────────────────────────────────────────────┐
│ Your Application Layer │
│ ┌──────────────────────────────────────────────┐ │
│ │ LangGraph ReAct Agent │ │
│ │ (LLM + tool‑selection logic + state) │ │
│ └───────────────────┬──────────────────────────┘ │
│ │ Call Tool │
│ ┌───────────────────▼──────────────────────────┐ │
│ │ @langchain/mcp-adapters │ │
│ │ MultiServerMCPClient (tool proxy layer) │ │
│ └──────┬────────────┬──────────────┬───────────┘ │
└─────────┼────────────┼──────────────┼─────────────┘
│ │ │
stdio HTTP SSE
▼ ▼ ▼
┌───────────┐ ┌──────────┐ ┌──────────────┐
│ Amap │ │ Browser │ │ File System │
│ Server │ │ Server │ │ Server │
└───────────┘ └──────────┘ └──────────────┘Environment Setup
npm init -y
npm install @langchain/mcp-adapters @langchain/langgraph @langchain/core
# OpenAI backend
npm install @langchain/openai
# or Anthropic backend
npm install @langchain/anthropicThe adapter package is at version 0.6.0 and supports three transport modes: stdio, streamable-http, and sse.
Connecting the Amap MCP Server
Obtain a Web‑service API key from the Amap Open Platform and install the official MCP server: npm install -g @amap/amap-maps-mcp-server Core Node.js code creates a MultiServerMCPClient that launches the Amap server via stdio, loads all exposed tools, and builds a ReAct agent:
import { MultiServerMCPClient } from "@langchain/mcp-adapters";
import { createReactAgent } from "@langchain/langgraph/prebuilt";
import { ChatOpenAI } from "@langchain/openai";
async function buildAmapAgent() {
const client = new MultiServerMCPClient({
amap: {
transport: "stdio",
command: "npx",
args: ["-y", "@amap/amap-maps-mcp-server"],
env: { AMAP_MAPS_API_KEY: process.env.AMAP_API_KEY! },
},
});
const tools = await client.getTools();
console.log("Loaded tools:", tools.map(t => t.name));
const agent = createReactAgent({
llm: new ChatOpenAI({ model: "gpt-4o", temperature: 0 }),
tools,
});
return { agent, client };
}
async function main() {
const { agent, client } = await buildAmapAgent();
try {
const result = await agent.invoke({
messages: [{ role: "user", content: "帮我查一下北京故宫附近500米内的餐厅,给我推荐3家" }],
});
console.log(result.messages.at(-1)?.content);
} finally {
await client.close();
}
}
main().catch(console.error);Running the script triggers the maps_around_search tool and returns real location data.
Connecting the Playwright Browser MCP Server
The browser server enables page navigation, clicks, form filling, and screenshots.
npm install -g @playwright/mcp
npx playwright install chromium import { MultiServerMCPClient } from "@langchain/mcp-adapters";
import { createReactAgent } from "@langchain/langgraph/prebuilt";
import { ChatAnthropic } from "@langchain/anthropic";
async function buildBrowserAgent() {
const client = new MultiServerMCPClient({
playwright: {
transport: "stdio",
command: "npx",
args: ["@playwright/mcp", "--headless", "--browser", "chromium"],
},
});
const tools = await client.getTools();
const agent = createReactAgent({
llm: new ChatAnthropic({ model: "claude-opus-4-5", temperature: 0 }),
tools,
});
return { agent, client };
}
async function main() {
const { agent, client } = await buildBrowserAgent();
try {
const result = await agent.invoke({
messages: [{ role: "user", content: "打开 https://news.ycombinator.com,告诉我今天排名第一的文章标题和链接" }],
});
console.log(result.messages.at(-1)?.content);
} finally {
await client.close();
}
}
main().catch(console.error);The agent navigates to Hacker News, extracts the top story, and returns its title and link.
Using Multiple MCP Servers Simultaneously
Complex agents can combine Amap, Playwright, and a file‑system server in a single client.
import { MultiServerMCPClient } from "@langchain/mcp-adapters";
import { createReactAgent } from "@langchain/langgraph/prebuilt";
import { ChatOpenAI } from "@langchain/openai";
async function buildSuperAgent() {
const client = new MultiServerMCPClient({
amap: {
transport: "stdio",
command: "npx",
args: ["-y", "@amap/amap-maps-mcp-server"],
env: { AMAP_MAPS_API_KEY: process.env.AMAP_API_KEY! },
},
browser: {
transport: "stdio",
command: "npx",
args: ["@playwright/mcp", "--headless"],
},
filesystem: {
transport: "stdio",
command: "npx",
args: ["-y", "@modelcontextprotocol/server-filesystem", "/tmp/agent-workspace"],
},
});
const tools = await client.getTools();
console.log(`Loaded ${tools.length} tools`);
const selectedTools = tools.filter(t => [
"maps_text_search",
"maps_around_search",
"maps_direction_walking",
"browser_navigate",
"browser_get_text",
"browser_screenshot",
"read_file",
"write_file",
].includes(t.name));
const agent = createReactAgent({
llm: new ChatOpenAI({ model: "gpt-4o", temperature: 0 }),
tools: selectedTools,
});
return { agent, client };
}
async function main() {
const { agent, client } = await buildSuperAgent();
try {
const result = await agent.invoke({
messages: [{
role: "user",
content: `帮我完成以下任务:
1. 查询上海陆家嘴附近的咖啡店,取前5家
2. 把结果整理成 JSON 格式
3. 保存到 /tmp/agent-workspace/coffee-shops.json`,
}],
});
console.log(result.messages.at(-1)?.content);
} finally {
await client.close();
}
}
main().catch(console.error);Advanced: HTTP Transport for Remote MCP Servers
Production environments often use HTTP (or SSE for legacy servers). Example configuration:
import { MultiServerMCPClient } from "@langchain/mcp-adapters";
const client = new MultiServerMCPClient({
company_tools: {
transport: "http",
url: "https://internal.example.com/mcp",
headers: { Authorization: `Bearer ${process.env.INTERNAL_API_TOKEN}` },
reconnectAttempts: 3,
reconnectDelay: 1000,
},
legacy_service: {
transport: "sse",
url: "https://legacy.example.com/mcp/sse",
headers: { "X-API-Key": process.env.LEGACY_KEY },
},
});
const tools = await client.getTools();stdio vs HTTP – How to Choose?
┌─────────────────┬─────────────────┬──────────────────┐
│ Feature │ stdio │ HTTP / SSE │
├─────────────────┼─────────────────┼──────────────────┤
│ Deployment │ Local process │ Local or remote │
│ Latency │ <1 ms (very low)│ Network latency │
│ Scalability │ Single‑machine │ Horizontal scale │
│ Security │ Process isolation│ Requires auth │
│ Typical use │ Local tools / dev│ Team‑shared / prod│
└─────────────────┴─────────────────┴──────────────────┘Use stdio for local tools such as Amap and Playwright; use HTTP/SSE for internal APIs or SaaS services.
Production Pitfalls – Five Common Issues
Forgot to close the client – Omitting await client.close() leaks subprocesses or HTTP connections. Wrap usage in try / finally or a factory that implements using (TS 5.2+).
Tool name collisions – Different servers may expose tools with identical names. MultiServerMCPClient prefixes them as serverName__toolName (e.g., amap__maps_text_search vs browser__browser_navigate).
Environment variables not passed to subprocess – In stdio mode the child inherits the parent environment, but you can explicitly set env to add or override variables such as AMAP_MAPS_API_KEY.
Too many tools overload LLM context – Loading dozens of tools can consume many tokens. Filter tools per task or pre‑heat a curated list at startup.
Server start‑up latency causes timeouts – getTools() is asynchronous; initializing the client on every request adds seconds. Cache the tool list or pre‑warm at application start.
Summary
@langchain/mcp-adaptersis the glue that turns any MCP server into a LangChain Tool, enabling agents to extend capabilities without code changes.
Use stdio for local tools (Amap, Playwright) and http / sse for remote services. MultiServerMCPClient supports parallel connection to multiple servers, providing a unified tool set.
Control the number of loaded tools; filter by relevance to keep LLM context size manageable.
Manage client lifecycles with try / finally and client.close(), and consider pre‑warming tools at startup.
References
[1] Amap Open Platform: https://lbs.amap.com/
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
James' Growth Diary
I am James, focusing on AI Agent learning and growth. I continuously update two series: “AI Agent Mastery Path,” which systematically outlines core theories and practices of agents, and “Claude Code Design Philosophy,” which deeply analyzes the design thinking behind top AI tools. Helping you build a solid foundation in the AI era.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
