Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

45 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

agentctl

License: Apache-2.0 Python 3.11+

Local control data for agent tool use. agentctl validates reviewed tool catalogs, detects catalog drift, evaluates local policy, records approvals and audit data, and compiles one reviewed MCP tools/list capture into a catalog.

It is local-only. It does not connect to a host, execute tools, infer tool risk, or enforce host behavior.

TL;DR

The problem: An agent host can expose tools, but a developer needs reviewed, stable local data before the host acts on a tool call.

The solution: agentctl validates a catalog, locks it, detects drift, and evaluates one declared call. It can also create local approval and audit records and import a catalog from one reviewed MCP capture.

Feature What it does
Reviewed catalogs Validates tool identity, input schemas, risk kind, and review data.
Deterministic locks Creates a stable lockfile from a validated catalog.
Drift checks Reports safe and unsafe changes before policy evaluation.
Local approvals Records one durable approval request and resolution.
Audit chain Verifies local, append-only approval and action-report records.
MCP import Compiles one complete captured tools/list result with human review data.

Quick example

# Inspect the machine-readable contract.
python3 -m agentctl capabilities --json

# Compile one complete saved MCP tools/list result and a human review file.
python3 -m agentctl adapters plan \
  --adapter=mcp-tools-list-v1 \
  --input=capture.json \
  --review=review.json \
  --destination=agent-tools.json \
  --json > plan.json

# Write the reviewed catalog, then make a deterministic lockfile.
python3 -m agentctl tools import --plan=plan.json --json
python3 -m agentctl tools lock \
  --catalog=agent-tools.json --out=agent-tools.lock.json --json

# Check the catalog before an agent host makes a policy request.
python3 -m agentctl tools diff \
  --lock=agent-tools.lock.json --catalog=agent-tools.json --json

Design principles

  • Local control data: Catalogs, locks, approvals, and audit records are local files.
  • Human review supplies risk: A capture does not set or override risk, approval, writable-root, or command-allowlist data.
  • Fail closed: Unknown, partial, malformed, or unreviewed input fails.
  • Stable automation: JSON results use one envelope on standard output.
  • Host separation: The host remains responsible for discovery, execution, and enforcement.

Install

agentctl needs Python 3.11 or later and uses the Python standard library at runtime.

From a source checkout

git clone https://github.com/Ozhiaki/agentctl.git
cd agentctl
python3 -m pip install .
agentctl capabilities --json

In a virtual environment

python3 -m venv .venv
. .venv/bin/activate
python3 -m pip install .
python3 -m agentctl doctor --json

Build a wheel

python3 -m pip wheel . --no-deps --wheel-dir dist
python3 -m pip install dist/agentctl-0.4.0-py3-none-any.whl

There is no package-manager formula or install script at this time.

Quick start

  1. Create a reviewed catalog or create a plan from one complete MCP capture.
  2. Validate and lock the catalog.
  3. Run tools diff when freshness matters.
  4. Run policy check for one declared tool call.
  5. When policy returns ask, use the durable approval workflow if the host needs a local approval record.
python3 -m agentctl tools validate --catalog=agent-tools.json --json
python3 -m agentctl tools lock --catalog=agent-tools.json --out=agent-tools.lock.json --json
python3 -m agentctl policy check \
  --lock=agent-tools.lock.json \
  --tool=github.create_issue \
  --args=args.json \
  --cwd=/absolute/path \
  --json

Project policy profiles

v0.4 adds one explicit, reviewed JSON profile. It binds the catalog and lock that a project uses. It can also select local agent and host labels and apply narrow approval overlays. A profile is not discovered from the environment or a home directory. Pass its path with --policy-profile every time.

Do not put secrets, tokens, keys, or personal data in identity metadata. Metadata is returned by inspection and policy results.

Create and validate a profile

  1. Validate the reviewed catalog and read data.catalog_hash.
  2. Create or verify the lock and read data.lock_hash.
  3. Create a project_policy_profile.v1 JSON file at or above the catalog and lock. Use only relative POSIX paths below the profile directory.
  4. Validate it before a host uses it.
python3 -m agentctl tools validate --catalog=agent-tools.json --json
python3 -m agentctl tools lock \
  --catalog=agent-tools.json --out=agent-tools.lock.json --json

# Copy the two returned hashes into policy.json. Do not hash file bytes.
python3 -m agentctl profiles validate --policy-profile=policy.json --json
python3 -m agentctl profiles show \
  --policy-profile=policy.json --fields=profile,catalog,rules --json

A minimal profile has empty agents, hosts, and rules, with both identity defaults set to null:

{
  "profile_version": "1",
  "profile_id": "example-project",
  "catalog": {"path": "agent-tools.json", "hash": "sha256:..."},
  "lock": {"path": "agent-tools.lock.json", "hash": "sha256:..."},
  "identity_defaults": {"agent_id": null, "host_id": null},
  "agents": [],
  "hosts": [],
  "rules": []
}

Use the profile for a decision and use policy explain to review the selected rule. The command decides local policy only. It does not prove host execution.

python3 -m agentctl policy check \
  --policy-profile=policy.json --tool=docs.read --args=args.json \
  --cwd=/absolute/project --json
python3 -m agentctl policy explain \
  --policy-profile=policy.json --tool=docs.read --args=args.json \
  --cwd=/absolute/project --json

For JSON pipelines, use --from-stdin instead of a file path:

printf '%s' '{"path":"README.md"}' | python3 -m agentctl policy check \
  --policy-profile=policy.json --tool=docs.read --from-stdin \
  --cwd=/absolute/project --json

--catalog=- and policy check --args=- remain available in v0.4, but emit DEPRECATED. Use the declared --from-stdin form. In JSON mode the warning is only in the envelope. In human mode it is one standard-error line.

Commands

All commands support --json. JSON output goes to standard output. On an error, the first error message also goes to standard error.

Area Commands Purpose
Contract capabilities, schema, doctor, robot-docs guide, conformance Inspect the declared CLI contract and local health.
Catalog tools validate, tools lock, tools diff Validate, lock, and compare reviewed catalog data.
Profiles profiles validate, profiles show Validate and inspect an explicitly selected project policy profile.
Policy policy check, policy explain Evaluate and explain one lock-only or profile-aware policy decision.
State state init Create an explicit local state directory.
Approvals approvals create, list, show, resolve, cancel, report-action Record a local approval lifecycle and host action reports.
Audit audit list, audit verify Inspect and verify the local audit chain.
Adapters adapters list, adapters plan, tools import Plan and import one reviewed MCP capture.

Use agentctl capabilities --json for every declared flag, input type, error code, schema, and example.

Adapter input

mcp-tools-list-v1 accepts one complete JSON object with only a tools array. Each captured tool has name, description, and inputSchema. The separate review file supplies server_id, review metadata, and exactly one item for each captured tool.

If an MCP response has nextCursor, first save all pages and create one input object with the combined tools array. agentctl does not read additional pages or combine server captures.

Architecture

reviewed catalog ──> validate ──> lock ──> diff ──> policy check
                                             │
                                             └──> approval and audit records

saved MCP tools/list + human review ──> adapters plan ──> tools import ──> catalog

The plan command is read-only. Import writes only the reviewed catalog. Neither command starts a host, runs a tool, or creates an audit event.

Comparison

Capability agentctl MCP host Manual JSON files
Execute a tool No Yes No
Validate reviewed tool metadata Yes Host-specific Manual
Lock and detect catalog drift Yes Host-specific Manual
Local approval and audit records Yes Host-specific No
Connect to live MCP No Yes No

Use agentctl when a cooperating host needs local reviewed control data. Use a host when you need discovery, transport, or execution.

Troubleshooting

NOT_FOUND for a catalog, lock, or plan

Check the input path and ensure its parent directory exists for output files.

python3 -m agentctl tools validate --catalog=agent-tools.json --json

ADAPTER_REVIEW_MISMATCH

The review must contain each captured tool source name exactly once. Add the missing review item or remove the extra item.

STATE_CONFLICT during tools import

The target has different catalog content. Inspect the difference before an explicit replacement.

python3 -m agentctl tools import --plan=plan.json --dry-run --json
python3 -m agentctl tools import --plan=plan.json --force --yes --json

A durable command cannot find state

Create and pass an explicit absolute state directory.

python3 -m agentctl state init --state-dir=/absolute/state --json

JSON output does not parse

Use --json before or after the command path. Read diagnostics from standard error, not standard output.

Limitations

  • No live MCP discovery, paging, host plug-ins, remote registry, or network use.
  • No tool execution, sandboxing, or host enforcement.
  • No automatic risk or approval classification.
  • One plan represents one server capture; catalog merge is not supported.
  • Import does not prove a catalog came from its stated capture or review file.

FAQ

Does agentctl execute tools?

No. A cooperating host executes tools and enforces its own rules.

Does agentctl connect to an MCP server?

No. It reads a saved, complete MCP tools/list result from a local file or standard input.

Does import create an audit event?

No. Import writes reviewed catalog data and does not use the durable state directory.

Can agentctl choose a risk class for me?

No. The review file supplies all policy-relevant facts.

Can I use it without durable approvals?

Yes. Catalog, lock, diff, policy, and adapter commands work without a state directory.

Development

python3 -m unittest discover -s tests
python3 -m agentctl conformance --profile=release-self-check --json

About Contributions

About Contributions: Please don't take this the wrong way, but I do not accept outside contributions for any of my projects. I simply don't have the mental bandwidth to review anything, and it's my name on the thing, so I'm responsible for any problems it causes; thus, the risk-reward is highly asymmetric from my perspective. I'd also have to worry about other "stakeholders," which seems unwise for tools I mostly make for myself for free. Feel free to submit issues, and even PRs if you want to illustrate a proposed fix, but know I won't merge them directly. Instead, I'll have Claude or Codex review submissions via gh and independently decide whether and how to address them. Bug reports in particular are welcome. Sorry if this offends, but I want to avoid wasted time and hurt feelings. I understand this isn't in sync with the prevailing open-source ethos that seeks community contributions, but it's the only way I can move at this velocity and keep my sanity.

License

Apache-2.0. See LICENSE.

About

Local control plane for agent tool use. Validate reviewed tool catalogs, create deterministic lockfiles, detect drift, check policy, record durable approvals and audit events, and compile one reviewed MCP tools/list capture into an importable catalog. Local-only; it does not execute tools or enforce hosts.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages