An allowance for your AI agent. Open-source MCP server and Python SDK for AI agent payment policy enforcement.
Project description
Stipend
An allowance for your AI agent.
A development-time policy engine, audit log, and MCP server for AI agents that handle money. Not production financial infrastructure. The mockable, auditable budget your agent should have before it ever touches a real rail.
60-second demo
pip install stipend
stipend init my-agent && cd my-agent
stipend run "Pay Acme Logistics $4,250 for invoice 14"
> Pay Acme Logistics $4,250 for invoice 14
[resolve] counterparty=acme-logistics → acme_…
[policy] per_txn $25,000 ✓ daily $4,250 / $250,000 ✓
[rail] MOCK_ACH ✓ ETA 2.4s simulated
[payment] pmt_mock_… created status=pending
[payment] pmt_mock_… settled net $4,249.75 (mock)
[audit] written to .stipend/audit.jsonl
Sent (mock). Receipt id: pmt_mock_…
Nothing left your machine. State is at .stipend/state.db. Audit trail is at .stipend/audit.jsonl.
What you get
| Policy engine | YAML-defined per-transaction / daily / monthly caps, recipient allow / deny lists with glob support, approval thresholds. JSON-Schema validated. |
| Audit log | Append-only JSONL with versioned schema. Every decision recorded — who asked, what for, what the engine said. |
| Mock backend | Realistic lifecycle (created → pending → settled) with simulated rail fees. SQLite-backed. Zero network. |
| MCP server | Stdio JSON-RPC. Five tools (pay, charge, refund, policy_check, audit_search) exposed to any MCP client — Claude Desktop, Cursor, Continue, OpenClaw, Hermes. |
| Python SDK | Drop into any agent loop. Top-level verbs for actions, namespaced queries for inspection. |
| AgentRail upgrade path | A stubbed backend slot that raises NotYetAvailable until you flip to AgentRail for production fiat rails. |
Use the SDK
from stipend import Stipend
s = Stipend(policy="policy.yaml", backend="mock")
receipt = s.pay(
recipient="acme-logistics",
amount_cents=425_000,
currency="USD",
memo="Invoice 14",
)
# Inspect what happened.
for entry in s.audit.tail(10):
print(entry.ts, entry.tool, entry.policy_decision, entry.status)
When the policy denies the transaction the SDK raises PolicyDenied. When it's at or
above the approval threshold it raises ApprovalRequired. v0.1 returns the decision
only; the resubmission flow is yours to wire (or it lands in v0.2).
Write a policy
version: 1
agent: dispatch-bot
limits:
per_transaction_cap: { USD: 25_000_00 } # $25,000
daily_cap: { USD: 250_000_00 } # $250,000
monthly_cap: { USD: 1_000_000_00 } # $1,000,000
recipients:
allowed: ["acme-logistics", "carrier-*"]
blocked: ["sanctioned-*"]
approvals:
requires_approval_above: { USD: 10_000_00 } # $10,000
Amounts are integer cents. Allow / deny lists support fnmatch globs. Deny wins ties.
Full reference: docs/policy-reference.md.
Wire into an MCP client
stipend mcp
The server speaks stdio JSON-RPC. To attach Claude Desktop, copy
examples/mcp_client/claude_desktop_config.json
into your Claude config, point it at your policy.yaml, restart Claude Desktop,
and ask the model to pay an invoice.
Cursor and Continue have native MCP support via the same config shape. For
custom clients, see stipend/mcp_server.py — the wire
format is one JSON-RPC object per line over stdio.
Privacy
By default the audit log captures the originating natural-language prompt alongside
the amount, recipient, currency, and memo. The log is plain text at
.stipend/audit.jsonl.
# Omit the prompt from new entries.
stipend run --no-prompt "Pay Acme Logistics $4,250 for invoice 14"
# Trim entries older than a cutoff.
stipend audit prune --older-than 7d
Know what's in your audit log before you commit it to a shared repo or paste it into a bug report.
Security
Stipend is development-time tooling. It does not move real money. The cryptographic, regulatory, and operational concerns of moving real funds belong to AgentRail.
Vulnerabilities? See SECURITY.md for the disclosure path.
Documentation
- Quickstart — install, run, and see the trace block.
- Architecture — the four-part composition, lifecycle, concurrent-write semantics.
- Policy reference — every field, evaluation precedence, glob tie-break example.
- Upgrading to AgentRail — what changes, what stays the same, what's in v0.2 vs v1.
v0.2 roadmap
- HTTP-mode MCP transport (
stipend mcp --http) - Multi-currency policy enforcement
- Velocity rules (
max_per_minute/max_per_hour) - LLM-mode natural-language parser
- Approval-token resubmission flow
- TypeScript SDK
If any of these block your use case today, open an issue.
Local development
git clone https://github.com/agent-rail/stipend.git
cd stipend
pip install -e ".[dev]"
pytest
ruff check stipend tests
pyright stipend
112 tests, 92% coverage. The bar-bearing modules (policy, audit, mock) are above 85% individually.
License
Apache-2.0. See LICENSE.
Made by the team building AgentRail. AgentRail is the financial control plane for autonomous AI agents. Currently in private beta.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file stipend-0.1.0.tar.gz.
File metadata
- Download URL: stipend-0.1.0.tar.gz
- Upload date:
- Size: 53.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
76d59f8c58c99cce50feef4d3f3b9fba5c5349afdb36d21cc9ff380fb31d46f5
|
|
| MD5 |
3fd39466f57a97ff7aab38acd122c5c5
|
|
| BLAKE2b-256 |
62bf580272d6514c08e8d04a35a139a171f91a83274e3ea36e3078c1d5634807
|
Provenance
The following attestation bundles were made for stipend-0.1.0.tar.gz:
Publisher:
ci.yml on Agent-Rail/stipend
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
stipend-0.1.0.tar.gz -
Subject digest:
76d59f8c58c99cce50feef4d3f3b9fba5c5349afdb36d21cc9ff380fb31d46f5 - Sigstore transparency entry: 1658461587
- Sigstore integration time:
-
Permalink:
Agent-Rail/stipend@7bbc2b4b162935a4a04a3d816125daa05e5e1778 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/Agent-Rail
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci.yml@7bbc2b4b162935a4a04a3d816125daa05e5e1778 -
Trigger Event:
push
-
Statement type:
File details
Details for the file stipend-0.1.0-py3-none-any.whl.
File metadata
- Download URL: stipend-0.1.0-py3-none-any.whl
- Upload date:
- Size: 43.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
31205478eb36e0d70f64440031d56239502fc649d0d469311038fb0d8fdacdf3
|
|
| MD5 |
0b78e7a9cf4a94abeead81186af34c61
|
|
| BLAKE2b-256 |
5e3cd76ead459f16a94eef81c185eff1cbbd9796c55fc511624088def60b9e0a
|
Provenance
The following attestation bundles were made for stipend-0.1.0-py3-none-any.whl:
Publisher:
ci.yml on Agent-Rail/stipend
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
stipend-0.1.0-py3-none-any.whl -
Subject digest:
31205478eb36e0d70f64440031d56239502fc649d0d469311038fb0d8fdacdf3 - Sigstore transparency entry: 1658461774
- Sigstore integration time:
-
Permalink:
Agent-Rail/stipend@7bbc2b4b162935a4a04a3d816125daa05e5e1778 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/Agent-Rail
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci.yml@7bbc2b4b162935a4a04a3d816125daa05e5e1778 -
Trigger Event:
push
-
Statement type: