Integrating the Model Context Protocol (MCP) with LangChain has four steps: configure an MCP client for each server, discover the server’s tools, pass those tools to a LangChain agent, and keep the client alive until calls finish. Python and JavaScript follow that same pattern, but their current adapters, error behavior, and cleanup APIs differ.
This guide shows both implementations, local stdio and remote HTTP transports, authentication, multi-server naming, lifecycle management, failure handling, and approval for destructive tools. Pin the package versions you deploy: Python’s current langchain.mcp namespace is beta, while JavaScript documentation also contains older MultiServerMCPClient examples.
The MCP-to-LangChain integration model
An MCP server advertises tools. An adapter reads those definitions and converts them into LangChain tools. Your agent then receives the adapted tools exactly as it would receive a native LangChain tool.
- Install and pin LangChain, the language adapter, and your model integration.
- Describe each MCP server using
stdioor HTTP transport, plus credentials where required. - Discover tools with
list_tools()in Python orlistTools()in the current JavaScript adapter. - Pass the resulting collection to
create_agent. - Keep sessions open while the agent runs, then close them in cleanup code.
Tool discovery and agent construction are separate operations. Discovering a tool does not execute it; execution occurs only when the model selects it.
Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstall#1 Best Overall
Choose an adapter and pin versions
Python options
The current LangChain documentation describes langchain.mcp, installed with langchain[mcp]>=1.4.0. The documentation explicitly labels this namespace beta, so its API may change. LangChain support material also discusses the separate langchain-mcp-adapters package, whose primary client is MultiServerMCPClient. Do not mix imports, configuration objects, or lifecycle methods from those two generations.
JavaScript options
The current @langchain/mcp-adapters README uses MCPAdapter. Broader JavaScript documentation still shows MultiServerMCPClient. Both describe the same adapter pattern, but their constructors and cleanup methods are not interchangeable. The examples below use the current MCPAdapter interface; if your pinned package exposes only MultiServerMCPClient, follow that package’s matching documentation instead.
Model compatibility
Adapters expose standard LangChain tools, so they can be used with supported OSS chat-model integrations such as ChatOpenAI and ChatAnthropic. This does not configure provider credentials for you, nor does it guarantee that every model handles every tool schema identically.
Python: connect MCP tools to an agent
Install and configure credentials
python -m venv .venv
source .venv/bin/activate
pip install "langchain[mcp]>=1.4.0" langchain-openai
export OPENAI_API_KEY="your-key"
Use a lock file or constraints file in production. Keep bearer tokens, API keys, and private URLs in environment variables or a secret manager.
Current langchain.mcp pattern
The following illustrates the documented sequence. Adapter constructor details can change while the namespace is beta, so verify the exact configuration keys against the version you pin.
Rank #2
import asyncio
import os
from langchain.agents import create_agent
from langchain.mcp import MCPAdapter
from langchain_openai import ChatOpenAI
async def main():
adapter = MCPAdapter(
servers={
"local_tools": {
"transport": "stdio",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"],
},
"remote_tools": {
"transport": "http",
"url": os.environ["MCP_SERVER_URL"],
"headers": {
"Authorization": f"Bearer {os.environ['MCP_BEARER_TOKEN']}"
},
},
}
)
try:
tools = await adapter.list_tools()
model = ChatOpenAI(model="gpt-4.1-mini", temperature=0)
agent = create_agent(
model=model,
tools=tools,
system_prompt="Use MCP tools when they are appropriate. Explain failures clearly.",
)
result = await agent.ainvoke({
"messages": [{"role": "user", "content": "List the files in /tmp."}]
})
print(result["messages"][-1].content)
finally:
close = getattr(adapter, "close", None)
if close is not None:
await close()
if __name__ == "__main__":
asyncio.run(main())
The local entry launches a server process and communicates over standard input and output. The remote entry uses an HTTP endpoint and an authorization header. A private server still needs network reachability from the process running your agent.
Using the separate langchain-mcp-adapters package
Support material commonly shows this alternative:
pip install langchain-mcp-adapters langchain-openai
from langchain_mcp_adapters.client import MultiServerMCPClient
client = MultiServerMCPClient({
"local": {
"transport": "stdio",
"command": "npx",
"args": ["-y", "your-mcp-server"],
},
"hosted": {
"transport": "sse",
"url": "https://example.invalid/mcp/sse",
"headers": {"Authorization": "Bearer ${MCP_TOKEN}"},
},
})
tools = await client.get_tools()
agent = create_agent(model, tools=tools)
Treat this as a different API generation: its discovery method is typically get_tools() (or load_mcp_tools in lower-level usage), not the beta namespace’s list_tools(). Confirm the package’s current transport and authentication names before deployment.
JavaScript and TypeScript: use the current MCPAdapter
Install
npm install @langchain/mcp-adapters @langchain/core @langchain/langgraph @langchain/openai
Remote HTTP and local stdio in one agent
import { MCPAdapter } from "@langchain/mcp-adapters";
import { createAgent } from "@langchain/langgraph/prebuilt";
import { ChatOpenAI } from "@langchain/openai";
const adapter = new MCPAdapter({
servers: {
local_tools: {
transport: "stdio",
command: "npx",
args: ["-y", "your-mcp-server"]
},
remote_tools: {
transport: "http",
url: process.env.MCP_SERVER_URL,
headers: { Authorization: `Bearer ${process.env.MCP_BEARER_TOKEN}` }
}
}
});
try {
const tools = await adapter.listTools();
const agent = createAgent({
model: new ChatOpenAI({ model: "gpt-4.1-mini", temperature: 0 }),
tools
});
const result = await agent.invoke({
messages: [{ role: "user", content: "Use the available tool to summarize the current status." }]
});
console.log(result.messages.at(-1)?.content);
} catch (error) {
console.error("MCP or agent call failed:", error);
} finally {
await adapter.close();
}
Keep the adapter open for every invocation that may call an MCP tool. Closing it immediately after discovery leaves later tool calls without a live session. In a long-running service, create one managed adapter per process or worker and close it during shutdown.
Name collisions with multiple servers
Two servers can publish the same tool name. Prefix names with the server name when your adapter or application exposes that option, such as jira_search and slack_search. This makes prompts, logs, and approval rules unambiguous.
Older MultiServerMCPClient examples
Older JavaScript documentation uses a client configured with a map of servers, then calls getTools() and passes those tools to createAgent. It is still useful when your installed package exposes that class, but do not combine its imports with the newer MCPAdapter code. The README also describes negotiation between modern and legacy modes; explicit modern mode requires MCP revision 2026-07-28. Avoid hard-coding a revision unless both server and client require it.
Transport, authentication and deployment choices
| Transport | Use it when | Operational considerations |
|---|---|---|
stdio |
The server runs locally and can be launched by your process. | Set the executable and arguments; capture stderr separately so protocol messages on stdout are not corrupted. |
| HTTP/streamable HTTP | The server is hosted remotely or shared by several agents. | Configure URL, headers, timeouts and TLS; ensure the agent host can reach the endpoint. |
| SSE or other legacy mode | An older server or adapter requires it. | Check both package and server generations before copying an SSE example. |
Never place real tokens in source files, screenshots, prompts, or public repositories. For self-hosted Jira, Slack, or Confluence servers, authentication and network access belong to the MCP server boundary as well as the LangChain process.
Error handling and lifecycle
Python tool errors versus connection failures
When an MCP server returns a tool result marked isError=True, the Python integration represents it as a LangChain ToolMessage with status="error". The model can often explain or recover from that result. A dropped transport, failed handshake, or closed session raises instead, because no tool result reached the model. Catch those exceptions around the agent call, log the server name and operation, and decide whether a retry is safe.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
JavaScript exceptions
The JavaScript adapter documentation describes an isError: true tool result as a thrown ToolException. Wrap direct tool calls and, where appropriate, the entire agent invocation in try/catch. Distinguish a server-declared failure from a timeout, authentication error, or disconnected adapter before retrying.
Structured results and multimodal content
Python exposes structured MCP content as an artifact, while text and multimodal parts appear through standardized content blocks. Preserve artifacts when downstream code needs machine-readable fields instead of parsing the model-facing text.
Human approval for risky tools
MCP metadata can include server identity, annotations, and destructive-operation hints. Use those hints to route deletion, sending, purchasing, or permission-changing tools through LangGraph human-in-the-loop approval. Elicitation is a separate MCP capability: the server can pause a tool call and request input from a person. Neither feature is an automatic security boundary; define which tools require approval, validate arguments, and audit the decision.
Testing and production checklist
- Pin the adapter, LangChain, model integration, and server versions.
- Run a discovery-only check and record tool names and schemas before enabling execution.
- Test both a successful call and a server-declared error.
- Test expired credentials, unreachable HTTP endpoints, and a terminated local process.
- Keep secrets in environment variables or a secret manager.
- Set timeouts and bounded retries for idempotent operations only.
- Keep adapters alive through all calls and close them on worker shutdown.
- Use server prefixes when names collide.
- Require human approval for destructive actions.
Or skip the browser setup
If your MCP agent needs website images or PDFs, ScreenshotNeo provides an HTTP screenshot API and an MCP server. It accepts cookie and consent banners before capture, removes more than 60 known consent platforms plus newsletter popups and chat widgets, and bills only clean shots: bot checks, CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed. Every response reports the page verdict and billing status in X-Page-Verdict and X-Billed headers.
Recommended Free Tools
One request is enough:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
See the ScreenshotNeo documentation for the 63 capture options, including full-page lazy-image loading, CSS-selector elements, dark mode, device presets, retina scale, PDF paper and page settings, custom CSS or JavaScript, clicks, waits, blocking rules, headers, cookies, user agents, authorization, timezone, geolocation, transparency, resizing, TTL caching, signed image links, asynchronous webhooks, bulk capture of up to 100 URLs, usage data, and the OpenAPI specification.
Python
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)
Node.js
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot failed: ${res.status}`);
const fs = await import('node:fs/promises');
await fs.writeFile('shot.webp', Buffer.from(await res.arrayBuffer()));
ScreenshotNeo also exposes an MCP server, so Claude, Cursor, and other MCP clients can take screenshots through tools such as take_screenshot, get_page_info, and capture_pdf. The Free plan includes 1,000 shots per month with no card; paid plans start at $5 for 3,000 shots, and every feature is available on every plan. Create a free ScreenshotNeo account.
Common problems and fixes
Import or constructor errors
Cause: code from langchain.mcp, langchain-mcp-adapters, and older JavaScript clients was mixed. Fix: inspect installed versions, choose one API generation, and align imports, discovery method, and close method.
No tools are discovered
Cause: the server process failed to start, the URL is wrong, or authentication was rejected. Fix: run the server independently, inspect stderr and HTTP status, verify environment variables, and test network access from the agent host.
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Repair Windows errors before they cause bigger problems3Fix the driver behind crashes, sound loss and screen glitchesAgent answers without calling a tool
Cause: tools were never passed to create_agent, the prompt did not require a tool, or the model declined because the schema did not fit. Fix: print the discovered tool names, pass the exact collection to the agent, and test with a request that clearly requires one tool.
Best Value
Calls fail after the first request
Cause: the adapter was closed too early or a persistent session expired. Fix: keep it open for the agent lifetime, close only during cleanup, and recreate the session after a transport failure.
Destructive action runs unexpectedly
Cause: discovery metadata was treated as enforcement. Fix: implement an explicit approval gate, validate arguments, and deny high-risk tools by default.
FAQ
Can I connect Jira, Slack and Confluence MCP servers at once?
Yes. Configure each server in the same adapter, discover the combined tool set, and prefix names with the server identity to avoid collisions. Each server still needs its own reachable endpoint and credentials.
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Can I use Anthropic models with MCP servers in LangChain?
Yes, where the corresponding LangChain model integration is configured. The adapter supplies standard LangChain tools; provider authentication and model-specific tool behavior remain separate concerns.
Is a remote MCP host required?
No. Local stdio servers are supported and are often simplest for development. Use HTTP when the server is hosted, shared, or isolated from the agent process.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

