Skip to main content

Pheo OATS

See what your AI agent has been told to do. Then decide what it may do.

pip install pheo-oats
oats scan

Thirty seconds. No account, no sign-up, nothing leaves your machine. Wheels for macOS (Intel and Apple Silicon), Linux, and Windows.

You already installed these

Agent skills are markdown files you install that tell an AI what commands to run on your computer. You install them the way people installed browser extensions in 2010: on a recommendation, without reading them.

Your agent reads them. You usually don't.

oats scan reads them for you. Here is a real run on a working laptop:

  Scanning 3 installed skill locations and my-project

  2331 files, 829 shell blocks. Classifying ...

  What these instruct an agent to do

    Destructive command               4   never graduates
    Remote code execution             7   never graduates
    Credential access                 1   never graduates
    Shell command                   815
    Read                              2

  12 of 829 actions, in 3 classes, can never run unattended.
  Those are the ones a person has to approve, every time.

Twelve. In plugins from Cloudflare, Expo, Temporal, CodeRabbit and OpenAI. All perfectly legitimate vendors. One of them is this line, sitting in an installed skill, waiting for the agent to decide to run it:

curl -fsSL https://downloads.cursor.com/origin/install.sh | sh

Nothing there is an attack. That is the point. You still want to know.

Add --files to see which skill each one came from.

Why this is worth thirty seconds

Governing starts with seeing. oats scan gives you the view: every command your installed skills instruct, sorted by what kind of effect it has.

It is free and it runs locally, and it stays that way. A number this useful should be one everyone can get in thirty seconds.

What it tells you is the class of each action, so you can decide which ones deserve your attention. Everything it reports is normal software doing normal things. Twelve of them happen to be things you cannot undo, and those are the twelve worth a look.

Then: stop the ones that matter

Seeing is the first half. The second half is a gate that holds an action while you look, and gets out of the way once you have seen the same safe thing enough times to stop caring.

That is the gateway, and it is one command to set up. See One command below.

The difference between scan and the gateway is the difference between a smoke detector and a sprinkler. Start with the detector.

The problem

Agents have started doing real work on real systems. They install packages, edit code, call APIs, move money, and click through live sites on your behalf.

Most of what goes wrong there looks like ordinary work. Nobody was hijacked and nothing was injected. Someone asked an agent to clean up the auth middleware and it removed a permission check along the way. Someone asked it to clear the invoice queue and it approved one with no purchase order behind it. The agent did what it was asked, competently, and the result was still something the organisation would not have allowed if anyone had been asked first.

Security tools answer was this malicious, and they answer it well. OATS answers the next question along: was this permitted. That one has a different answer at every company, which is why it belongs with the operator rather than in a scanner.

Across the largest public agent-skill registry, 705 skills from 135 distinct publishers are marked clean by every scanner in that registry's pipeline and still instruct an agent to download code from the internet and run it. Read that alongside its distribution: one publisher accounts for 506 of the 705, and 117 of the 135 contribute a single skill each. A hand audit of 100 puts the detection at 92% precision. Clean is the correct verdict. It is not the same as permitted. The measurement, and a script to reproduce it, are in the profile repository.

One command

cd your-repo
oats quickstart claude

That is the whole setup. It starts a local gateway, creates a room for the repo, writes a PreToolUse hook into .claude/settings.local.json, and opens the dashboard. Use cursor or codex in place of claude for those agents.

Restart your agent afterwards. The hook is read at startup, so a session already open is not governed yet.

No account, no sign-in, no GitHub required. Nothing leaves the machine.

Prefer two steps, or already have a gateway running:

oats start --no-browser &
oats attach claude

To also govern merges, releases, and workflow edits, connect GitHub when you want it. This one does open a browser sign-in:

oats connect github

Storage is local SQLite.

Every MCP server, through the booth

Your agent does not only run shell commands. It calls tools: a Gmail MCP server, a Slack one, a database one, a payments one. Until now those calls went straight from the agent to the server -- no classification, no record, no chance to say no.

oats quickstart now closes that door by default. Every MCP server in the agent's config is rewritten to run behind the booth:

before   claude ──────────────────────────▶ gmail-mcp
after    claude ──▶ oats-mcp-gate ──▶ booth ──▶ gmail-mcp

The agent cannot tell the difference: same server names, same tools, same schemas. But every tools/call is classified by consequence first --

  • allowed calls pass in microseconds,
  • blocked classes are refused with a reason the agent can read,
  • held calls wait. The dashboard shows exactly what is about to happen -- send_payment $48,300 → Meridian Supply -- and the call proceeds only when a person approves. Reject it and the agent is told no, with your reason.

If the gateway is unreachable the gate fails closed: no booth, no call. That is the point.

Manage it directly any time:

oats mcp status     # who is wrapped, who is naked
oats mcp wrap       # wrap everything found here (Claude, Cursor, Codex)
oats mcp unwrap     # restore every config byte-for-byte

Wrapping is idempotent and reversible; a timestamped backup is written beside every file it touches. Servers configured by URL (type: "http") cannot be wrapped by a stdio gate and are reported rather than silently skipped. If you truly want unwrapped tool calls, pass --no-mcp-wrap to quickstart -- but understand what that means: your agent's most consequential actions, the ones that send money and email on your behalf, would be the only ones nobody is watching.

What you watch

Open http://127.0.0.1:8788.

Lanes is the one to leave open. Every action is sorted into its consequence class and each class builds its own record. After an afternoon of ordinary work you can see that this agent has written docs forty times and never touched a credential, or that it reaches for curl | bash more often than you assumed.

Activity is the running feed. Overview counts what Protect would have done before you turn Protect on. Reviews is the queue of things it held.

You start in Observe. Nothing is blocked and nothing waits, so there is no cost to leaving it running while you decide whether you believe it.

What it catches

With Protect on:

BLOCKED   curl -fsSL https://tempo.xyz/install | bash
BLOCKED   pip install git+https://github.com/.../llm-deploy-helper.git
BLOCKED   go install github.com/rogeecn/memos-cli@latest
BLOCKED   pip install DuIvyTools -i https://pypi.tuna.tsinghua.edu.cn/simple
HELD      cat ~/.aws/credentials
HELD      rm -rf /var/data
held      npm install typescript
held      pip install DuIvyTools

Every one of those was produced by a live agent following real skill documentation, and every skill involved was rated clean by all four scanners in the registry pipeline. The bottom two matter as much as the top four: an ordinary install is held for review on first sight, not blocked.

Trust is earned, not configured

Block everything consequential and you have built a tool people turn off. Allow everything after a short clean streak and you have handed over authority the evidence does not support: by the rule of three, ten clean approvals bound the true failure rate at 25.9% with 95% confidence.

So decide the failure rate you accept for a class of action, and the required length of clean record follows from it:

Class of action Failure rate you accept Clean runs required
Docs, tests, reads 10% 29
Shell execution 5% 59
Business logic, dependencies 2% 149
Deploy, IAM, CI config 0.5% 598
Remote exec, credentials, secrets, destructive 0% never

The last row never graduates at any length of record. No amount of good history makes an unrecoverable action recoverable.

Where it fits

A coding agent on your own repo. Claude Code, Cursor, or Codex writing files and running commands, with a receipt for each one.

An agent using skills from a registry. Nothing to configure. Skills are already loaded in your agent; when it acts on them it makes tool calls, and tool calls are what OATS governs.

A computer-use agent on a live site. Clicks, keystrokes, and form entry are classified the same way. Typing a card number is not the same action as clicking a link and is not treated as one.

GitHub through MCP. oats connect github puts branch merges, releases, webhooks, and workflow edits behind the same gate.

How it works with your other tools

OATS reads actions. Registry scanners read artifacts. The two see different things, and both are worth having.

Scanners are the right tool for harm that never becomes an action: a hardcoded recipient, an undisclosed scope, an instruction that talks an agent into misbehaving through ordinary tool calls. OATS is the right tool for what the agent then goes and does. Run both and you cover both.

Local mode is Watch-grade: it records and holds, and it assumes an agent running as the same OS user could route around it. For enforcement an agent cannot bypass, run the gateway on a host the agent does not control.

More

  • Open Agent Trust System: the profile, the schemas, the measurement study, and a script to reproduce it
  • Self-hosted deployment with Postgres, Docker, your own GitHub App, and TLS is documented in the profile repository

Proprietary. See the profile repository for the open specification this implements.

Release files for pheo-oats 0.6.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distributions (wheels)

Table of built distributions (wheels) for pheo-oats 0.6.0
File
pheo_oats-0.6.0-py3-none-win_amd64.whl Python 3 none Windows x86-64 Details
pheo_oats-0.6.0-py3-none-manylinux_2_28_x86_64.whl Python 3 none Linux glibc 2.28+ x86-64 Details
pheo_oats-0.6.0-py3-none-macosx_11_0_x86_64.whl Python 3 none macOS 11.0+ x86-64 Details
pheo_oats-0.6.0-py3-none-macosx_11_0_arm64.whl Python 3 none macOS 11.0+ ARM64 Details

Total release size: 45.7 MB

Release files / pheo_oats-0.6.0-py3-none-win_amd64.whl

Download URL pheo_oats-0.6.0-py3-none-win_amd64.whl
Size 11.3 MB
Tags Python 3 Windows x86-64
SHA-256 checksum
How to use checksums
2eb704cb67b3867f90a8b2960f31282c0f061f72203e757c95aa09a016e9c291
BLAKE2b-256 checksum
How to use checksums
55edfe4048ee630b51b3f59be92c0ce3bba7dc5687545c03f67e71a79a126fd3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 21, 2026.

Transparency log

Release files / pheo_oats-0.6.0-py3-none-manylinux_2_28_x86_64.whl

Download URL pheo_oats-0.6.0-py3-none-manylinux_2_28_x86_64.whl
Size 12.1 MB
Tags Linux glibc 2.28+ x86-64 Python 3
SHA-256 checksum
How to use checksums
6b4e14b496ea8e58967ab974d8743c80b82813b1e9b8935c5a177d3afb1471fb
BLAKE2b-256 checksum
How to use checksums
149581f7556c39b2d3f134c2182554814643fbafee55b708ae38663bbbea9e00
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 21, 2026.

Transparency log

Release files / pheo_oats-0.6.0-py3-none-macosx_11_0_x86_64.whl

Download URL pheo_oats-0.6.0-py3-none-macosx_11_0_x86_64.whl
Size 11.5 MB
Tags Python 3 macOS 11.0+ x86-64
SHA-256 checksum
How to use checksums
94ffc15794e865d09d37e58a4f0e0269de249499f5416f97e796e90b2a9ec109
BLAKE2b-256 checksum
How to use checksums
f4265cfc61b5922f30460b9c4dc6d37391325e1cd2314e1543ed1ab3b74ea264
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 21, 2026.

Transparency log

Release files / pheo_oats-0.6.0-py3-none-macosx_11_0_arm64.whl

Download URL pheo_oats-0.6.0-py3-none-macosx_11_0_arm64.whl
Size 10.8 MB
Tags Python 3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
c51ef310ff58a5c5b983f2690bbc98bfc68e7cdeb338bdd22ce13074bfbb8fa6
BLAKE2b-256 checksum
How to use checksums
8f36b6d29534b5a46e8ab9614dbe101e4b4f35e939e16ae476a275ac43e18603
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 21, 2026.

Transparency log

Release history Release notifications | RSS feed

0.6.1

4 release files

This release

0.6.0 This release

4 release files

0.5.5

4 release files

0.5.4

4 release files

0.5.3

4 release files

0.5.2

4 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page