Python LangGraph Middleware
The Python package is threadplane-middleware. It is the Python LangGraph twin of @threadplane/middleware/langgraph: it binds browser-declared client-tool stubs onto a chat model and routes client-tool-only turns to END.
#Install
The package depends on langchain-core>=0.3.0 and langgraph>=0.3.0.
Install your model provider package separately, for example langchain-openai when using ChatOpenAI.
#Bind tools per run
Call bind_client_tools() inside your agent node. The browser sends the tool catalog with each run, so the model-visible tool list is request-scoped.
The helper reads state["tools"] first and falls back to state["client_tools"]. It appends each client tool as an explicit OpenAI function-tool dict:
#Route after the agent
Use route_after_agent() from a LangGraph conditional edge. It returns the server tools node name when the last model message contains a server or unknown tool call. It returns __end__ when the turn has only client tool calls or no tool calls.
You can override the returned route labels:
#Helper surface
| Helper | Purpose |
|---|---|
client_tool_specs(state) | Convert the run catalog into OpenAI function-tool dicts. |
client_tool_names(state) | Return the set of client-declared tool names. |
has_client_tool_call(state) | Check whether the last message calls a known client tool. |
has_server_tool_call(state, server_tool_names) | Check whether the last message calls a server or unknown tool. |
last_message(state) | Return the last message from state["messages"], or None. |
#Frontend contract
The middleware does not execute browser tools. The frontend still needs to send the catalog, observe the model tool call, execute the local function or UI interaction, and resume the graph with a ToolMessage containing the result.