mayi
The agent proposes. Your rules decide.
Website and live demo · PyPI · Guide
mayi (as in "may I?") enforces who controls each argument of an AI agent's tool call. Permissions usually say which tool an agent may call. They do not say which value it may pass, so refund(40) and refund(9000) look the same. mayi sits between the agent and your tools and gives every argument one owner:
| Owner | What happens |
|---|---|
| application | your app supplies the value; whatever the model proposed is thrown away |
| model | free text, checked for type, length, allowlists and forbidden content |
| human | a single-use, expiring approval, or a bounded limit with a session budget |
| derived | computed by a formula a human wrote |
The rules are plain code. There is no second model judging the first. Anything not in the catalog is rejected.
Try it
pip install mayi
mayi demo
Open the console at http://127.0.0.1:8787/console (key: demo-app-key). To watch a real Claude model get a hidden attack, run mayi try-model in a second window with ANTHROPIC_API_KEY set.
Use it with your own tools
mayi init # writes catalog.yaml and tools.json
mayi check catalog.yaml # validate your rules
mayi serve # prints an agent key and an app key
Edit catalog.yaml to say who controls each argument. Your app opens a session with the values it controls; the agent calls POST /v1/call; held calls wait in the console for a person. Budgets total per session by default; pass budget_key (a customer id, say) when your app opens a session to total over a customer instead. More in the guide.
Results
| Test | Without mayi | With mayi |
|---|---|---|
| AgentDojo banking, 9 injection tasks (replayed) | 9 / 9 succeed | 0 / 9 |
| InjecAgent, 2,108 attack cases (replayed) | 2,108 / 2,108 | 0 / 2,108 |
| Live Claude Haiku 4.5, 64 runs | 8 of 64 ran | 0 of 64 |
The replayed tests measure what happens after a fooled agent proposes the call, not how often models are fooled. The live test used two models and eight injections written by the author. Details, including where it did not help, are in the guide.
Works with
Tested: the official MCP Python client (SDK 1.30 and 2.2) through mayi mcp-proxy, the OpenAI Agents SDK, CrewAI, LangGraph and the Anthropic SDK. Not yet tested: Claude Desktop, Claude Code, Cursor and other MCP hosts. Reports from people who try them are welcome.
What is included
- Gateway with an audit log and a console; MCP proxy that puts any MCP server behind the same rules
- Single-use approvals signed with HMAC or Ed25519, two-person approval, session budgets, rate limits
mayi proveto check a catalog for broken invariants, with counterexamples- Adapters for the OpenAI Agents SDK and CrewAI, and a TypeScript client
Limits
- No outside security review yet. Do not use mayi alone to protect tools that move money.
- It checks free text the model writes but does not judge what it means.
- The copied-value check is a heuristic. Paraphrased, translated or spelled-out values get through.
- It is not a new idea. Progent and CaMeL came first; the guide compares them.
If mayi is useful
A star on GitHub helps other people find it. If you try it with a host or framework that is not listed above, please open an issue and say what worked and what broke.
Run the tests
pip install pytest hypothesis && python3 -m pytest -q
Contributing and security
See CONTRIBUTING.md and the roadmap. To report a vulnerability, read SECURITY.md.
License
Apache-2.0. See LICENSE.
Metadata
Release files for mayi 0.2.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| mayi-0.2.1.tar.gz | 98.6 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| mayi-0.2.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 172.5 kB
Release files / mayi-0.2.1.tar.gz
| Download URL | mayi-0.2.1.tar.gz |
|---|---|
| Size | 98.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
cf13072cdb380189dd3c6058a214106532625a1f8f142f06dba8cdd732e165af
|
|
BLAKE2b-256 checksum How to use checksums |
c4ad9b50a6dcc28680e80f92898fe90f2a5c3762e26fac833a9556af0f089e86
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.7
|
Release files / mayi-0.2.1-py3-none-any.whl
| Download URL | mayi-0.2.1-py3-none-any.whl |
|---|---|
| Size | 73.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
fc4b7583e965fa3eb94e8db160f2b27b24858d61de787875239220d16186af91
|
|
BLAKE2b-256 checksum How to use checksums |
333206579ff5821f5141eada65c497b466ca498e72293f8406863cd2b055d700
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.7
|
Security for mayi 0.2.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.