Skip to main content
Glama

PayPilot — agentic commerce operator for PayPal

Natural language in, PayPal operations out. PayPilot is a solo-built entry for the PayPal AI Hackathon, targeting the main prizes and Best Use of Agentic Commerce.

Say "Invoice Acme Corp $1,250 due in 30 days", "Who hasn't paid yet?", or "Refund the last payment from John" — a tool-calling agent turns it into real PayPal REST API calls through a self-hosted MCP server.

What it does

  • 8 PayPal tools over a self-hosted MCP server (Streamable HTTP): invoice_create, invoice_send, invoice_remind, invoice_list, invoice_status, payment_search, refund_payment, account_summary

  • Agent loop (paypilot/agent.py): a compact ReAct-style tool-calling loop over any OpenAI-compatible chat endpoint. No heavy framework, no silent fallbacks — an unconfigured model raises a clear error.

  • PayPal REST client (paypilot/paypal_client.py): OAuth2 client-credentials, Invoices v2 (create/get/list/send/remind/cancel), Transaction Search (payment lookup), Payments v2 refunds. All network I/O goes through an injectable transport.

  • Mock transport (paypilot/transport.py): an in-memory PayPal simulation (OAuth, invoice lifecycle with real state transitions, transaction search, refunds) so the whole suite runs without credentials.

  • Web demo (paypilot/web.py + webui/index.html): chat UI that shows every tool call the agent makes.

Related MCP server: PayPal MCP Server

Quickstart

python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt

# run the tests (mock backend, no credentials needed)
python -m pytest

# start the MCP server (mock backend by default)
PAYPILOT_TRANSPORT=mock python -m paypilot.mcp_server

# start the web demo (needs a model; see below)
PAYPILOT_TRANSPORT=mock \
PAYPILOT_MODEL_BASE_URL=http://127.0.0.1:11435/v1 \
PAYPILOT_MODEL_ID=nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B \
python -m paypilot.web
# open http://127.0.0.1:8931/

Real PayPal sandbox setup

  1. Go to https://developer.paypal.com/dashboard/applications/sandbox and log in with a PayPal developer account.

  2. Create an app (or open the default one) and copy the Client ID and Secret.

  3. Export them:

    export PAYPAL_CLIENT_ID="your-sandbox-client-id"
    export PAYPAL_CLIENT_SECRET="your-sandbox-client-secret"
    export PAYPAL_MODE=sandbox   # the default; use "live" only deliberately
  4. Run the live smoke test (full invoice lifecycle against api-m.sandbox.paypal.com, with cleanup):

    python scripts/sandbox-smoke.py

    Without credentials it exits 2 with these instructions; nothing is fabricated. To also smoke-test refunds, set PAYPAL_SMOKE_CAPTURE_ID to a real sandbox capture id (refunds need a completed payment).

Unset PAYPILOT_TRANSPORT (or set it to anything but mock) to use the real sandbox backend in the MCP server and web demo.

Model configuration

The agent needs an OpenAI-compatible chat-completions endpoint with tool calling:

export PAYPILOT_MODEL_BASE_URL="http://127.0.0.1:11434/v1"
export PAYPILOT_MODEL_API_KEY="..."   # if the endpoint needs one
export PAYPILOT_MODEL_ID="model-id"

Without it, the agent raises ConfigurationError naming the missing variables instead of pretending to work.

Security model

  • Human confirmation for money-moving tools. In the web UI, refund_payment and invoice_send are never executed straight from the model. The /api/chat response lists them under pending_actions; nothing happens until a person clicks Confirm (POST /api/confirm {"action_id": ...}) or Cancel (POST /api/cancel). Pending actions are single-use and expire after 10 minutes.

  • API key. Set PAYPILOT_API_KEY to require Authorization: Bearer <key> (or X-API-Key) on /api/chat, /api/confirm and /api/cancel. The web page prompts for it once and keeps it in the browser's localStorage.

  • Real PayPal needs a key. Without PAYPILOT_API_KEY, the web endpoints only run against the in-memory mock (PAYPILOT_TRANSPORT=mock); a sandbox or live backend returns 503.

  • Safe binds. python -m paypilot.web and python -m paypilot.mcp_server default to 127.0.0.1. The web server refuses a non-loopback --host without PAYPILOT_API_KEY, except for an explicit mock-only public demo (PAYPILOT_ALLOW_UNAUTHENTICATED_DEMO=1 with PAYPILOT_TRANSPORT=mock, which deploy/write_env.py sets for the hosted demo). The MCP server has no auth of its own, so it refuses non-loopback binds unless PAYPILOT_MCP_ALLOW_REMOTE=1 (only behind an authenticating proxy). MCP clients are expected to show their own per-tool approval prompt before calling refund_payment.

Project layout

paypilot/
  paypal_client.py   PayPal REST client (OAuth, invoices, search, refunds)
  transport.py       UrllibTransport (real) + MockPayPalTransport (tests)
  tools.py           shared tool specs + dispatcher (agent/MCP/web)
  agent.py           tool-calling agent loop + model clients
  mcp_server.py      self-hosted MCP server (Streamable HTTP, 8 tools)
  web.py             FastAPI demo UI backend
  netenv.py          localhost proxy-env sanitizer (test env fix)
webui/index.html     demo chat page
tests/               full suite (mock backend; MCP over real HTTP)
scripts/sandbox-smoke.py  live sandbox lifecycle test

License

MIT. Built solo for the PayPal AI Hackathon.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    A Model Context Protocol server that provides comprehensive integration with PayPal's APIs, enabling seamless interaction with payment processing, invoicing, subscription management, and business operations through a standardized interface.
    7
    Apache 2.0
  • A
    license
    Not graded
    quality
    D
    maintenance
    A Python implementation that enables Large Language Models to interact with PayPal's APIs through function calling, supporting features like invoices, orders, products, subscriptions, and transactions.
    1
    MIT
  • A
    license
    Not graded
    quality
    F
    maintenance
    Enables integration with PayPal APIs for managing invoices, payments, disputes, subscriptions, and more through natural language.
    474 npm
    13
    Apache 2.0
  • A
    license
    A
    quality
    C
    maintenance
    A lightweight MCP server that connects to the PayPal REST API, handling token lifecycle automatically and providing read-only tools for transactions, invoices, orders, disputes, and subscriptions by default.
    11
    10 npm
    MIT