Loomal

Playwright MCP server in LangChain.

No config file here — you wire playwright-mcp into LangChain in code, via langchain-mcp-adapters, and your agent gets browser tools like any other tool list.

Unlike editor clients, LangChain has no MCP settings file — servers are declared in code through the langchain-mcp-adapters package, which converts MCP tools into LangChain tool objects. That's a feature for playwright-mcp: your agent's browser becomes part of the program, spun up per run, configured per environment, testable like everything else.

Microsoft's playwright-mcp (33.7k stars on GitHub, npm package @playwright/mcp) exposes navigation, clicking, typing, and accessibility-tree snapshots as tools — exactly the primitives a LangChain agent needs for web tasks that plain HTTP fetching can't do.

Install the pieces

Two runtimes are involved: Python for LangChain, Node for the server. Install the adapter with pip install langchain-mcp-adapters (plus langgraph if you'll use the prebuilt agent), and make sure node and npx resolve in the same environment your Python process runs in — the client literally spawns npx as a subprocess.

Run npx playwright install chromium once so the browser binary exists before your agent's first call.

Declare the server in code

MultiServerMCPClient takes a dict of server definitions. For a local stdio server like playwright-mcp, that's the command and args you'd otherwise put in an editor's JSON config:

agent.py
from langchain_mcp_adapters.client import MultiServerMCPClient
from langgraph.prebuilt import create_react_agent

client = MultiServerMCPClient({
    "playwright": {
        "transport": "stdio",
        "command": "npx",
        "args": ["@playwright/mcp@latest", "--headless"],
    }
})

tools = await client.get_tools()
agent = create_react_agent(model, tools)
result = await agent.ainvoke(
    {"messages": "Open https://example.com and summarize the page."}
)

Notes on the pattern

Everything here is async — get_tools and the agent invocation need an event loop, so run inside asyncio.run() or an async framework. The client manages the server subprocess lifecycle for you.

--headless is the right default in LangChain: these agents typically run in scripts, services, or notebooks where a browser window is unwanted (and on servers, impossible without a display). Drop the flag locally if you want to watch a run.

playwright-mcp contributes 20+ tools. If your agent gets distracted by the full set, filter the tools list after get_tools() to the handful you need — browser_navigate, browser_snapshot, browser_click cover most read-and-interact tasks.

Troubleshooting in LangChain

FileNotFoundError on npx: the Python process can't see Node. This bites hardest in Docker images and CI, where the Python base image has no Node at all — install Node in the image, or run playwright-mcp as a separate HTTP service (npx @playwright/mcp@latest --port 8931) and point the client at the URL with transport streamable_http instead of stdio.

Hangs on first use: npx is downloading the package or Chromium. Pre-install both in your image build step, not at runtime.

RuntimeError about event loops: you called the async API from sync code. Wrap your entrypoint in asyncio.run(); in notebooks, await directly at the top level.

Tool calls failing on element targeting: have the agent call browser_snapshot before interacting — the snapshot's element refs are how clicks and fills are addressed.

The listing

playwright-mcp's live entry on the Loomal index is at https://loomal.ai/marketplace/playwright-mcp, with its tool list probed from the running server. Loomal is machine-queryable, which fits the LangChain world specifically: an agent can discover a server there, read its capabilities, and — for claimed listings with hosted endpoints — pay per call in USDC over x402 rather than carrying API keys.

FAQ

How do I use Playwright MCP with LangChain?

Install langchain-mcp-adapters, create a MultiServerMCPClient with a stdio server definition (command npx, args ["@playwright/mcp@latest"]), and call await client.get_tools(). The returned tools plug straight into create_react_agent or any LangChain agent that accepts a tool list.

There's no config file for LangChain MCP?

Correct — configuration is the Python (or JS) code itself. The server definition dict plays the role that mcp.json plays in editors, which means you can vary it per environment, build it from settings, or construct it dynamically at runtime.

How do I run this where Node isn't installed?

Either add Node to the runtime image, or split the architecture: run npx @playwright/mcp@latest --port 8931 as its own service and connect with transport streamable_http and the service URL. The second option also lets several agent workers share one browser server.

Why does my agent fail to click things?

playwright-mcp targets elements by refs from its accessibility snapshot, not by CSS selectors the model invents. Make sure the flow calls browser_snapshot first; agents prompted to 'snapshot, then interact' succeed far more reliably than ones that click blind.

Browse more MCP servers for LangChain.

The Loomal index is queryable by humans and agents alike.

Explore the marketplace