Least-privilege permissions for AI agents and MCP tools. Record what your agent does, auto-generate a safe policy, and block dangerous tool calls before they happen.
Project description
AgentPerms
Least-privilege permissions for AI agents and MCP tools. Record what your agent does, auto-generate a safe policy, and block dangerous tool calls before they happen.
Your AI agent has sudo. AgentPerms takes it away.
MCP is becoming the standard way AI apps connect to tools and data — which means agents are getting access to your filesystem, your repos, your email, and your database faster than anyone can govern them. Scanners tell you something looks risky. Firewalls make you hand-write YAML. AgentPerms does the missing thing:
record → infer → lock → replay → enforce
Run your agent in dev, record every tool call, infer the minimum permissions it actually needed, generate a policy, prove it blocks attacks, and enforce it in CI and at runtime.
Install
pip install agentperms
The flow
agentperms scan # find MCP configs, flag risky tools & exposures
agentperms lock # pin every tool's identity (detect tool poisoning)
agentperms record --client cursor # route the client through the recording proxy
# ... use your agent normally ...
agentperms infer # traces -> mcp.policy.yaml (least privilege)
agentperms enforce # route the client through the blocking proxy
agentperms replay # prove the policy blocks a pack of attacks
agentperms report # agentperms-report.html
agentperms init # .github/workflows/agentperms.yml
It produces mcp.policy.yaml, mcp.lock, agentperms-report.html, and a CI workflow.
The killer command
agentperms infer
Your agent only used read-only GitHub calls and local
./srcaccess. I generated a least-privilege policy. The agent does not need shell, home directory, secrets, Gmail send, or database write access.
How enforcement works
AgentPerms is a transparent stdio proxy. record/enforce rewrite your MCP client's config so each server launches through agentperms _proxy:
Agent → AgentPerms proxy → MCP server
│
├─ record: log every tools/call
└─ enforce: allow / deny / require-approval before forwarding
Denied calls never reach the server — the client gets a clean JSON-RPC error. Approval-gated calls prompt on your terminal.
Try it offline
A bundled over-privileged demo server lets you see a real block with no setup:
agentperms scan --path examples/vulnerable-mcp-demo # flags ~/.ssh mount + unpinned npx
agentperms replay --policy examples/policies/example.mcp.policy.yaml
Example policy
version: 1
servers:
github:
allowed_tools: [list_repos, read_file, create_issue]
denied_tools: [delete_repo, write_secret, force_push]
filesystem:
allowed_paths: [./src, ./docs]
denied_paths: [~/.ssh, ~/.env, /etc]
denied_patterns: ["*.pem", "*.key"]
approvals:
require_human_approval: [gmail.send_email, github.merge_pr, shell.exec]
redaction: { secrets: true, emails: true, api_keys: true }
Status
v0.1 — supports Claude Desktop, Cursor, VS Code/Copilot, Windsurf, Gemini CLI configs and local stdio MCP servers. Roadmap: HTTP/SSE transport, a Node wrapper, and a live dashboard.
License
MIT
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 agentperms-0.1.0.tar.gz.
File metadata
- Download URL: agentperms-0.1.0.tar.gz
- Upload date:
- Size: 35.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
051f5e402edfef43af58fe689edaa23d8b631f69ba8157eac9373221af8298ef
|
|
| MD5 |
307d70d06fb5b60e020dbb53d301df01
|
|
| BLAKE2b-256 |
cce0d5320a8d766c30c174f360c7103ce9266930446229946e80948cd8b4fa29
|
Provenance
The following attestation bundles were made for agentperms-0.1.0.tar.gz:
Publisher:
release.yml on hasanmehmood/agentperms
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
agentperms-0.1.0.tar.gz -
Subject digest:
051f5e402edfef43af58fe689edaa23d8b631f69ba8157eac9373221af8298ef - Sigstore transparency entry: 1896677818
- Sigstore integration time:
-
Permalink:
hasanmehmood/agentperms@4d6b0349f409799ca2dd07ba6508eec8295a48f8 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/hasanmehmood
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@4d6b0349f409799ca2dd07ba6508eec8295a48f8 -
Trigger Event:
push
-
Statement type:
File details
Details for the file agentperms-0.1.0-py3-none-any.whl.
File metadata
- Download URL: agentperms-0.1.0-py3-none-any.whl
- Upload date:
- Size: 33.8 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 |
89c53d1483db0474ed8fb59b97a377a3c572c5d0af4a00a82a9d8ac7ef27e3fa
|
|
| MD5 |
137a42bec4511dc12f7f9b0beaff5d95
|
|
| BLAKE2b-256 |
a8b17103e2788065066ea0eecb184988c30f893548c72392d30d43761271f286
|
Provenance
The following attestation bundles were made for agentperms-0.1.0-py3-none-any.whl:
Publisher:
release.yml on hasanmehmood/agentperms
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
agentperms-0.1.0-py3-none-any.whl -
Subject digest:
89c53d1483db0474ed8fb59b97a377a3c572c5d0af4a00a82a9d8ac7ef27e3fa - Sigstore transparency entry: 1896678184
- Sigstore integration time:
-
Permalink:
hasanmehmood/agentperms@4d6b0349f409799ca2dd07ba6508eec8295a48f8 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/hasanmehmood
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@4d6b0349f409799ca2dd07ba6508eec8295a48f8 -
Trigger Event:
push
-
Statement type: