Latest Results
docs(langchain): runnable `langchain.mcp` examples (#39976)
Stacked on #39939 — review that first; this branch adds only
`libs/langchain_v1/examples/mcp/`.
Ten self-contained scripts, one idea each. Every one starts whatever MCP
server it needs, so `uv run examples/mcp/<name>.py` is the whole
workflow.
| Example | Shows | Model | Network |
|---|---|:-:|:-:|
| `transports.py` | one adapter over in-memory, stdio, and HTTP | | |
| `remote_server.py` | pointing the adapter at a public MCP server | ✅ |
✅ |
| `multi_server.py` | several servers behind one adapter, tools prefixed
per server | ✅ | |
| `graph_factory.py` | one per-user MCP fleet behind a `langgraph dev`
graph factory | ✅ | |
| `protocol_eras.py` | one agent holding tools from both MCP protocol
eras | ✅ | |
| `tool_errors.py` | a failing tool reaching the model so it can retry |
✅ | |
| `elicitation.py` | a server asking a human mid-call, via `interrupt()`
| ✅ | |
| `destructive_interrupt.py` | gating destructive tools behind approval,
from tool metadata | ✅ | |
| `auth_bearer.py` | a server behind a static bearer token | | |
| `auth_oauth.py` | a full OAuth 2.1 flow with dynamic client
registration | | |
Each was run against a real model (or a real `langgraph dev` server)
before committing, and its output is what the docstring claims.
A few choices worth knowing about:
- **Servers come from FastMCP's own `run_server_in_process`**, not
hand-rolled uvicorn plumbing, so the examples teach the adapter rather
than how to start a server.
- **HTTP appears only where it is the subject.** `multi_server.py` names
its backends over stdio, which is less machinery and a better
illustration, since a fleet addresses each backend independently.
- **`remote_server.py` hits DeepWiki**, a public MCP server, where the
URL is the entire configuration. It prints the tool call so the answer
is visibly the remote server's work rather than the model's memory.
- **`tool_errors.py` pins the model with a system prompt.** Without it
the model answers the arithmetic from memory and the error path never
runs.
- **`destructive_interrupt.py` derives the approval gate from
metadata**, reading each tool's
`metadata["mcp"]["tool"]["annotations"]["destructive_hint"]` to build
the `HumanInTheLoopMiddleware` `interrupt_on` map — so any tool a server
flags as destructive pauses for approval, no tool names hardcoded.
- **`auth_oauth.py` opens a browser tab.** The demo authorization server
auto-approves, so it redirects straight back — but it is the one example
that cannot run unattended.
`graph_factory.py` is registered by a `langgraph.json` and run under
`langgraph dev` rather than invoked directly. It shows a per-user MCP
fleet: one shared `httpx` connection pool for everyone, a per-user
`ClientGroup` built each run, and per-user discovery caching keyed on
the caller's identity read off the injected `ServerRuntime`.
`run_graph_factory_demo.py` is an end-to-end driver that stands up two
guarded MCP servers plus a `langgraph dev` server with custom auth and
runs the graph once per user; `auth.py`, `langgraph.json`, and
`_fleet_servers.py` support it. `_servers.py` holds the small MCP
servers the examples share, `_stdio_server.py` is the entry point
launched as a subprocess over stdio, and neither `_`-prefixed helper is
part of the API being demonstrated.
`examples/*` picks up the same two ruff exemptions `scripts/*` already
has, for printing and for not being a package.
## Release note
No library changes — examples only.
---
*Prepared with the assistance of an AI agent.*
---------
Co-authored-by: Hunter Lovell <hunter@hntrl.io>
Co-authored-by: Hunter Lovell <40191806+hntrl@users.noreply.github.com>
Co-authored-by: Sydney Runkle <sydney@langchain.dev> Latest Branches
0%
-1%
0%
visnu64:fix/reasoning-model-structured-output © 2026 CodSpeed Technology