v0.1 — Beta
Use agent-scoped keys. All framework integrations accept an apiKey parameter. Always pass an agent-scoped key, not your operator key. Agent keys are bound to a single wallet and cannot modify policy or provision new accounts.

LangChain / LangGraph

MPPPal ships as a LangChain tool. Drop it into any LangChain agent or LangGraph node — the agent can check balances, make transfers, and open MPP sessions as part of its reasoning loop.

bash
npm install @mpppal/langchain
typescript
import { MPPPalTool } from "@mpppal/langchain";
import { ChatAnthropic } from "@langchain/anthropic";
import { AgentExecutor, createToolCallingAgent } from "langchain/agents";

const mpppal = new MPPPalTool({
  walletId: process.env.MPPPAL_WALLET_ID,
  apiKey: process.env.MPPPAL_AGENT_KEY,
});

const agent = createToolCallingAgent({
  llm: new ChatAnthropic({ model: "claude-sonnet-4-6" }),
  tools: [mpppal],
  prompt,
});

const executor = new AgentExecutor({ agent, tools: [mpppal] });

const result = await executor.invoke({
  input: "Check my USDC balance, then pay research-sub-agent $8.50 for the data task it completed.",
});
// Agent calls mpppal.getBalance(), reasons, then calls mpppal.transfer()

Available tool functions

FunctionDescription
mpppal_get_balanceReturns current USDC balance for the agent's wallet
mpppal_transferSends USDC to a recipient. Requires to, amount, memo.
mpppal_get_transactionsReturns recent transaction history
mpppal_open_sessionOpens an MPP session with a spending cap for a provider
mpppal_close_sessionCloses an open session and triggers on-chain settlement

CrewAI

MPPPal integrates as a CrewAI tool, available to any agent in a crew. Each crew member that needs to make payments should be provisioned its own MPPPal wallet with an appropriate policy for its role.

bash
pip install mpppal-crewai
python
from crewai import Agent, Task, Crew
from mpppal.crewai import MPPPalTool

payment_tool = MPPPalTool(
    wallet_id=os.environ["MPPPAL_WALLET_ID"],
    api_key=os.environ["MPPPAL_AGENT_KEY"],
)

orchestrator = Agent(
    role="Orchestrator",
    goal="Coordinate research tasks and pay sub-agents upon completion",
    tools=[payment_tool],
    verbose=True,
)

pay_task = Task(
    description="Pay the DataFetch agent $3.20 USDC for completing task-88. Memo: task-88-reward.",
    agent=orchestrator,
)

crew = Crew(agents=[orchestrator], tasks=[pay_task])
crew.kickoff()

OpenAI Agents SDK

MPPPal wraps as an OpenAI Agents SDK tool executor. Compatible with any model that supports tool use.

bash
npm install @mpppal/openai-agents
typescript
import { Agent, run } from "@openai/agents";
import { mpppalTools } from "@mpppal/openai-agents";

const agent = new Agent({
  name: "PaymentAgent",
  model: "gpt-4o",
  instructions: `You are a payment agent. When asked to pay for a completed task,
    verify the balance is sufficient, then execute the transfer.
    Always include the task ID in the memo field.`,
  tools: mpppalTools({
    walletId: process.env.MPPPAL_WALLET_ID,
    apiKey: process.env.MPPPAL_AGENT_KEY,
  }),
});

const result = await run(agent, "Pay acct_03x1m7 $12.00 USDC for completing task-42.");
console.log(result.finalOutput);
// "Payment of $12.00 USDC sent to acct_03x1m7. Tx: 5j4Kz9qX... settled."

What agents cannot do

All framework integrations expose only the agent-facing surface. Regardless of which framework you use, the agent cannot:

  • Modify spending policy
  • Pause or unpause its own wallet
  • Provision new wallets
  • Access other agents' wallets
  • Rotate or create API keys

These constraints are enforced by the agent-scoped API key at the API layer — not just by the framework integration.

Idempotency in agentic loops

Agents in reasoning loops may retry a payment action if the first response is ambiguous. All framework integrations derive a deterministic idempotency key from the task context to prevent double payments:

typescript
new MPPPalTool({
  walletId: process.env.MPPPAL_WALLET_ID,
  apiKey: process.env.MPPPAL_AGENT_KEY,
  idempotencyStrategy: "task-scoped",
  // derives key from task_id + operation name
  // same logical payment in the same task always maps to the same key
})