Why LangChain + MoltPe

LangChain is the most common framework for production LLM apps in Python: retrieval chains, ReAct agents, LangGraph state machines. Once those agents leave the demo stage, they start needing to spend money — pay for premium search APIs, buy geospatial or financial data, rent GPU time, tip other agents that solved a subproblem. Hardcoding a single shared Stripe key is the usual answer, and it is the wrong one: one hallucinated tool call and the whole team's credit card is hostage.

MoltPe gives each LangChain agent an isolated USDC wallet with a server-enforced spending policy. The agent cannot exceed the per-call cap, cannot pay outside the allowed recipients, cannot touch another agent's funds. When the LLM picks a tool, the wallet stays safe regardless of what arguments it hallucinated.

Three concrete reasons to combine them:

If you are new to the underlying primitives, read AI Agent Wallet Explained and the x402 Protocol Guide first — this post focuses on the integration mechanics.

Prerequisites

You need four things: Python 3.10+, a LangChain project, an OpenAI API key (or any LangChain-compatible chat model), and a MoltPe agent token. Install the packages and export the environment variables.

pip install "langchain>=0.3" "langchain-openai>=0.3" requests pydantic

export OPENAI_API_KEY="sk-..."
export MOLTPE_AGENT_TOKEN="mpt_live_..."
export MOLTPE_BASE_URL="https://api.moltpe.com"

Create the agent in the MoltPe dashboard, set its initial policy (for example: $0.10 per call, $5.00 per day, allowed networks: polygon, base), fund the wallet with test USDC from the dashboard faucet, and copy the agent token. Never commit the token — it authenticates the wallet.

Approach 1: Tool Wrapper (REST)

The most direct integration is to wrap MoltPe REST endpoints as LangChain BaseTool classes. LangChain's function-calling agent exposes each tool's Pydantic schema to the LLM, the LLM picks a tool and fills the arguments, and your code forwards them to MoltPe with the agent token.

Below is a single-file module that defines three tools: check_balance, send_payment, and call_x402_endpoint. Save it as moltpe_tools.py.

"""MoltPe tools for LangChain agents. REST-backed, policy-enforced server-side."""
import os
from typing import Optional
import requests
from langchain_core.tools import BaseTool
from pydantic import BaseModel, Field

BASE_URL = os.environ["MOLTPE_BASE_URL"]
TOKEN = os.environ["MOLTPE_AGENT_TOKEN"]
HEADERS = {"Authorization": f"Bearer {TOKEN}", "Content-Type": "application/json"}


class _BalanceArgs(BaseModel):
    pass


class CheckBalanceTool(BaseTool):
    name: str = "check_balance"
    description: str = "Return the agent's current USDC balance in USD."
    args_schema: type = _BalanceArgs

    def _run(self) -> str:
        r = requests.get(f"{BASE_URL}/v1/wallet/balance", headers=HEADERS, timeout=10)
        r.raise_for_status()
        data = r.json()
        return f"{data['usdc_balance']} USDC on {data['network']}"


class _PaymentArgs(BaseModel):
    recipient_wallet: str = Field(description="0x-prefixed wallet address")
    amount_usd: float = Field(description="Amount in USD, e.g. 0.25")
    memo: Optional[str] = Field(default=None, description="Human-readable purpose")


class SendPaymentTool(BaseTool):
    name: str = "send_payment"
    description: str = "Send USDC to a wallet address. Subject to MoltPe spending policy."
    args_schema: type = _PaymentArgs

    def _run(self, recipient_wallet: str, amount_usd: float, memo: Optional[str] = None) -> str:
        body = {"to": recipient_wallet, "amount_usd": amount_usd, "memo": memo}
        r = requests.post(f"{BASE_URL}/v1/payments", headers=HEADERS, json=body, timeout=30)
        if r.status_code == 403:
            return f"Rejected by policy: {r.json().get('error')}"
        r.raise_for_status()
        return f"Sent ${amount_usd} USDC. Tx: {r.json()['tx_hash']}"


class _X402Args(BaseModel):
    url: str = Field(description="HTTPS URL of the x402-enabled endpoint")
    method: str = Field(default="GET", description="HTTP method")
    max_payment_usd: float = Field(default=0.10, description="Hard cap for this call in USD")


class CallX402EndpointTool(BaseTool):
    name: str = "call_x402_endpoint"
    description: str = "Call a paid HTTP endpoint. MoltPe handles the 402 negotiation and retry."
    args_schema: type = _X402Args

    def _run(self, url: str, method: str = "GET", max_payment_usd: float = 0.10) -> str:
        body = {"target_url": url, "method": method, "max_payment_usd": max_payment_usd}
        r = requests.post(f"{BASE_URL}/v1/x402/proxy", headers=HEADERS, json=body, timeout=60)
        r.raise_for_status()
        return r.text  # Resource body from the target server

A realistic response from the proxy endpoint looks like this — your agent sees the resource with the payment receipt attached as a header so it can log what it spent.

{
  "status": 200,
  "payment_receipt": { "amount_usd": 0.002, "tx_hash": "0xabc123...", "network": "polygon" },
  "body": { "data": "premium content here" }
}

Approach 2: MCP Adapter

If your agent also runs inside an MCP-aware host (Claude Code, Cursor, OpenAI Assistants with MCP), duplicating tool logic is annoying. MoltPe ships a first-class MCP server at https://mcp.moltpe.com exposing the same verbs: check_balance, send_payment, list_transactions, call_x402_endpoint, agent_info. LangChain's langchain-mcp-adapters package converts those MCP tools into LangChain BaseTools at runtime.

pip install langchain-mcp-adapters
"""Bind MoltPe's MCP server to a LangChain agent. One source of truth for tools."""
import asyncio
from langchain_mcp_adapters.client import MultiServerMCPClient

async def load_moltpe_tools():
    client = MultiServerMCPClient({
        "moltpe": {
            "transport": "streamable_http",
            "url": "https://mcp.moltpe.com/v1/sse",
            "headers": {"Authorization": f"Bearer {os.environ['MOLTPE_AGENT_TOKEN']}"},
        }
    })
    tools = await client.get_tools()
    return tools

tools = asyncio.run(load_moltpe_tools())

The tradeoffs: the MCP adapter gives you one tool definition that works across hosts and updates when MoltPe ships new verbs — no redeploy. The REST wrapper gives you a synchronous code path that is easier to unit test and trace with LangSmith. Teams running only LangChain usually pick the REST wrapper. Teams running the same agent in Claude Code and a LangGraph server pick MCP. For background on why MCP matters here, see the MCP Server for AI Agent Payments guide.

End-to-End Example

Below is a runnable LangChain agent that uses the REST wrapper from Approach 1 to research a topic via a paid search API and write a summary. The agent decides when to pay and how much, constrained by the per-call cap and the MoltPe policy.

"""Research agent with its own wallet. Pays per search, summarizes, reports spend."""
from langchain_openai import ChatOpenAI
from langchain.agents import AgentExecutor, create_tool_calling_agent
from langchain_core.prompts import ChatPromptTemplate

from moltpe_tools import CheckBalanceTool, SendPaymentTool, CallX402EndpointTool

llm = ChatOpenAI(model="gpt-4o", temperature=0)

tools = [CheckBalanceTool(), SendPaymentTool(), CallX402EndpointTool()]

prompt = ChatPromptTemplate.from_messages([
    ("system",
     "You are a research agent with a USDC wallet. "
     "Use call_x402_endpoint to query paid search at https://search.example.com/v1/query. "
     "Set max_payment_usd to 0.01 for each search. "
     "Always call check_balance before and after. "
     "If a payment is rejected by policy, stop and explain why."),
    ("human", "{input}"),
    ("placeholder", "{agent_scratchpad}"),
])

agent = create_tool_calling_agent(llm, tools, prompt)
executor = AgentExecutor(agent=agent, tools=tools, verbose=True, max_iterations=5)

result = executor.invoke({
    "input": "Find three recent primary sources on x402 adoption in 2026 and summarize them."
})
print(result["output"])

When you run this, the trace shows: check_balancecall_x402_endpoint (3 times at $0.002 each) → check_balance → final summary. Total spend is bounded by the policy and visible in the MoltPe dashboard. If the LLM tries to call the search endpoint with max_payment_usd=100, MoltPe rejects the proxy call with HTTP 403 and a policy_violation error — the agent sees the failure, apologizes, and stops. For a broader quickstart that is framework-agnostic, see the 5-minute developer quickstart.

Common Pitfalls