Skip to main content

langchain-preloop

LangChain / LangGraph integration for Preloop — the open-source AI agent control plane. Preloop sits between your agent and its tools and gives you, in one Apache-2.0, self-hostable layer:

  • MCP firewall — every tool call is matched against CEL policy and can be allowed, denied, or paused for a human.
  • Human-in-the-loop approvals — out-of-band approve/deny from Slack, webhook, email, or mobile, with the agent's reasoning, the tool, and the arguments shown to the approver.
  • Model gateway — a unified gateway to OpenAI/Anthropic and 100+ models.
  • Budgets & rate limits — per-key/user/team cost tracking and caps.
  • Tamper-evident audit ledger — a hash-chained, append-only record of who approved what, when, why, and under which policy version — exportable as compliance evidence.

Preloop is a remote MCP server (streamable-HTTP at /mcp/v1). This package lets any LangChain or LangGraph agent route its tool calls through that control plane.

Positioning note: Preloop is a full control plane — firewall, gateway, budgets, and audit — not only an approval button. The approval workflow is the most differentiated piece, but this package exposes the whole surface.

Install

pip install langchain-preloop

Requires Python ≥ 3.11. Pulls in langchain-core, langchain-mcp-adapters, httpx, and pydantic.

Configure

The client resolves config like the preloop CLI does (constructor args override environment):

Setting Env var Default
token PRELOOP_TOKEN (none)
base_url PRELOOP_URL https://preloop.ai

token is a Preloop API key (create one in the web UI) or an OAuth access token, sent as Authorization: Bearer <token>. OAuth-capable clients can omit the token and complete OAuth 2.1 Dynamic Client Registration instead (Preloop publishes /.well-known/oauth-authorization-server). Self-hosters point base_url at their own origin; the /mcp/v1 path is appended automatically.

Three ways to use it

1. Gate your own tools behind Preloop (wrap_with_preloop) — the headline

Wrap any LangChain BaseTool so that, before it runs, Preloop evaluates the call against policy and — when policy requires it — escalates to a human. The underlying tool executes only if approved; otherwise the agent gets the denial reason back. Same name, same schema, no rewrite of your tool.

from langchain_preloop import PreloopClient, wrap_with_preloop
from langchain_core.tools import tool

@tool
def refund_customer(customer_id: str, amount_usd: float) -> str:
    """Issue a refund to a customer."""
    ...

client = PreloopClient(token="pl_...", base_url="https://preloop.ai")

# Drop-in replacement the agent can call exactly like the original tool.
governed_refund = wrap_with_preloop(refund_customer, client)

# In a LangGraph agent:
from langgraph.prebuilt import create_react_agent
agent = create_react_agent(model, tools=[governed_refund])

By default the wrapped tool blocks and polls Preloop until the approval resolves, then returns Preloop's auto-executed result. Pass poll=False to return immediately on a pending decision, or policy="my-workflow" to route to a named approval workflow.

2. Load Preloop's governed tools (PreloopToolkit)

Connect to a Preloop instance and get back the live, policy-filtered tool set as LangChain tools — Preloop's built-in governance tools plus any external MCP server you've registered behind Preloop (it proxies them through the same firewall). The tools/list is filtered to exactly what the presented token's policy allows.

from langchain_preloop import PreloopToolkit

toolkit = PreloopToolkit(token="pl_...", base_url="https://preloop.ai")
tools = toolkit.get_tools()          # sync
# tools = await toolkit.aget_tools() # async

# Or the functional form:
from langchain_preloop import get_preloop_tools, aget_preloop_tools
tools = get_preloop_tools(token="pl_...")

Built-in tools surfaced (subject to policy): request_approval, get_approval_status, search, get_issue, create_issue, update_issue, add_comment, update_comment, get_pull_request, create_pull_request, update_pull_request, estimate_compliance, improve_compliance.

3. Standalone approval primitives

Typed BaseTools for the two human-approval primitives, usable without negotiating the full MCP tool list:

from langchain_preloop import (
    PreloopClient,
    PreloopRequestApprovalTool,
    PreloopApprovalStatusTool,
)

client = PreloopClient(token="pl_...")
approve = PreloopRequestApprovalTool(client=client)
status = PreloopApprovalStatusTool(client=client)

result = approve.invoke({
    "operation": "wire_payment",
    "context": "Wire $5,000 to vendor ACME for invoice #42.",
    "reasoning": "Invoice approved in the finance channel; vendor verified.",
})

request_approval returns either a synchronous grant or a pending_approval payload with a request_id; poll it with get_approval_status. When a request is approved, Preloop auto-executes the gated tool and returns the result inline under tool_result.

How it connects

Tool calls go over MCP streamable-HTTP to <base_url>/mcp/v1 with Authorization: Bearer <token> and Accept: application/json, text/event-stream. The toolkit is built on langchain-mcp-adapters so MCP tool schemas are converted to LangChain tools for you.

Development & tests

pip install -e ".[test]"

# Unit tests — no network, mock transport:
pytest tests/unit_tests

# Standard langchain-tests suites + live integration tests
# (requires a real Preloop instance):
PRELOOP_TOKEN=pl_xxx PRELOOP_URL=https://staging.preloop.ai pytest tests

Unit tests include the langchain-tests ToolsUnitTests standard suite for both standalone tools; the integration tests include the matching ToolsIntegrationTests suites and are skipped unless PRELOOP_TOKEN is set.

License

Apache-2.0, matching the Preloop open-source core.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

langchain_preloop-0.1.0.tar.gz (19.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

langchain_preloop-0.1.0-py3-none-any.whl (19.3 kB view details)

Uploaded Python 3

File details

Details for the file langchain_preloop-0.1.0.tar.gz.

File metadata

  • Download URL: langchain_preloop-0.1.0.tar.gz
  • Upload date:
  • Size: 19.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for langchain_preloop-0.1.0.tar.gz
Algorithm Hash digest
SHA256 3051ac696ef3304795ca08900f437e77d55cefd3a403c10b8a9d1da167ab2893
MD5 f2e910bf6051e17665e40427a8fd2af2
BLAKE2b-256 2cb5f0b8445c7f6888a135961720e31eb487f9bd9e3752a129654995bfdc858b

See more details on using hashes here.

File details

Details for the file langchain_preloop-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for langchain_preloop-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 3de51492a3c5c33144ac8e9f0e63c09947c4d4b0140fd0b504b2d4155056cb2d
MD5 ab4664d51a097637ae9cc931ba399c74
BLAKE2b-256 e8cbbb41d75313c0c5806dc5ced1635964c7de6e4945c6ae359ab326874144e1

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 files

0.0.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page